summaryrefslogtreecommitdiffstats
path: root/qmake/library
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/library')
-rw-r--r--qmake/library/ioutils.cpp64
-rw-r--r--qmake/library/ioutils.h14
-rw-r--r--qmake/library/proitems.cpp66
-rw-r--r--qmake/library/proitems.h22
-rw-r--r--qmake/library/qmake_global.h14
-rw-r--r--qmake/library/qmakebuiltins.cpp44
-rw-r--r--qmake/library/qmakeevaluator.cpp155
-rw-r--r--qmake/library/qmakeevaluator.h20
-rw-r--r--qmake/library/qmakeevaluator_p.h14
-rw-r--r--qmake/library/qmakeglobals.cpp14
-rw-r--r--qmake/library/qmakeglobals.h15
-rw-r--r--qmake/library/qmakeparser.cpp436
-rw-r--r--qmake/library/qmakeparser.h33
-rw-r--r--qmake/library/qmakevfs.cpp14
-rw-r--r--qmake/library/qmakevfs.h14
15 files changed, 657 insertions, 282 deletions
diff --git a/qmake/library/ioutils.cpp b/qmake/library/ioutils.cpp
index 8dd88bf9a5..04be215246 100644
--- a/qmake/library/ioutils.cpp
+++ b/qmake/library/ioutils.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
@@ -100,11 +100,18 @@ QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName)
}
inline static
+bool isSpecialChar(ushort c, const uchar (&iqm)[16])
+{
+ if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))))
+ return true;
+ return false;
+}
+
+inline static
bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
{
for (int x = arg.length() - 1; x >= 0; --x) {
- ushort c = arg.unicode()[x].unicode();
- if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))))
+ if (isSpecialChar(arg.unicode()[x].unicode(), iqm))
return true;
}
return false;
@@ -119,7 +126,7 @@ QString IoUtils::shellQuoteUnix(const QString &arg)
}; // 0-32 \'"$`<>|;&(){}*?#!~[]
if (!arg.length())
- return QString::fromLatin1("\"\"");
+ return QString::fromLatin1("''");
QString ret(arg);
if (hasSpecialChars(ret, iqm)) {
@@ -140,23 +147,38 @@ QString IoUtils::shellQuoteWin(const QString &arg)
0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
};
+ // Shell meta chars that need escaping.
+ static const uchar ism[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
+ }; // &()<>^|
if (!arg.length())
return QString::fromLatin1("\"\"");
QString ret(arg);
if (hasSpecialChars(ret, iqm)) {
- // Quotes are escaped and their preceding backslashes are doubled.
- // It's impossible to escape anything inside a quoted string on cmd
- // level, so the outer quoting must be "suspended".
- ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\"\\1\\1\\^\"\""));
- // The argument must not end with a \ since this would be interpreted
- // as escaping the quote -- rather put the \ behind the quote: e.g.
- // rather use "foo"\ than "foo\"
- int i = ret.length();
- while (i > 0 && ret.at(i - 1) == QLatin1Char('\\'))
- --i;
- ret.insert(i, QLatin1Char('"'));
+ // The process-level standard quoting allows escaping quotes with backslashes (note
+ // that backslashes don't escape themselves, unless they are followed by a quote).
+ // Consequently, quotes are escaped and their preceding backslashes are doubled.
+ ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\""));
+ // Trailing backslashes must be doubled as well, as they are followed by a quote.
+ ret.replace(QRegExp(QLatin1String("(\\\\+)$")), QLatin1String("\\1\\1"));
+ // However, the shell also interprets the command, and no backslash-escaping exists
+ // there - a quote always toggles the quoting state, but is nonetheless passed down
+ // to the called process verbatim. In the unquoted state, the circumflex escapes
+ // meta chars (including itself and quotes), and is removed from the command.
+ bool quoted = true;
+ for (int i = 0; i < ret.length(); i++) {
+ QChar c = ret.unicode()[i];
+ if (c.unicode() == '"')
+ quoted = !quoted;
+ else if (!quoted && isSpecialChar(c.unicode(), ism))
+ ret.insert(i++, QLatin1Char('^'));
+ }
+ if (!quoted)
+ ret.append(QLatin1Char('^'));
+ ret.append(QLatin1Char('"'));
ret.prepend(QLatin1Char('"'));
}
return ret;
diff --git a/qmake/library/ioutils.h b/qmake/library/ioutils.h
index ba6e2708cb..b726ce3e09 100644
--- a/qmake/library/ioutils.h
+++ b/qmake/library/ioutils.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp
index 97cc590d84..a610da6b69 100644
--- a/qmake/library/proitems.cpp
+++ b/qmake/library/proitems.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
@@ -159,6 +159,18 @@ QString &ProString::toQString(QString &tmp) const
return tmp.setRawData(m_string.constData() + m_offset, m_length);
}
+/*!
+ * \brief ProString::prepareExtend
+ * \param extraLen number of new characters to be added
+ * \param thisTarget offset to which current contents should be moved
+ * \param extraTarget offset at which new characters will be added
+ * \return pointer to storage location for new characters
+ *
+ * Prepares the string for adding new characters.
+ * If the string is detached and has enough space, it will be changed in place.
+ * Otherwise, it will be replaced with a new string object, thus detaching.
+ * In either case, the hash will be reset.
+ */
QChar *ProString::prepareExtend(int extraLen, int thisTarget, int extraTarget)
{
if (m_string.isDetached() && m_length + extraLen <= m_string.capacity()) {
@@ -386,6 +398,20 @@ void ProStringList::removeAll(const char *str)
remove(i);
}
+void ProStringList::removeEach(const ProStringList &value)
+{
+ foreach (const ProString &str, value)
+ if (!str.isEmpty())
+ removeAll(str);
+}
+
+void ProStringList::removeEmpty()
+{
+ for (int i = size(); --i >= 0;)
+ if (at(i).isEmpty())
+ remove(i);
+}
+
void ProStringList::removeDuplicates()
{
int n = size();
@@ -405,6 +431,13 @@ void ProStringList::removeDuplicates()
erase(begin() + j, end());
}
+void ProStringList::insertUnique(const ProStringList &value)
+{
+ foreach (const ProString &str, value)
+ if (!str.isEmpty() && !contains(str))
+ append(str);
+}
+
ProStringList::ProStringList(const QStringList &list)
{
reserve(list.size());
@@ -452,4 +485,23 @@ ProFile::~ProFile()
{
}
+ProString ProFile::getStr(const ushort *&tPtr)
+{
+ uint len = *tPtr++;
+ ProString ret(items(), tPtr - tokPtr(), len);
+ ret.setSource(this);
+ tPtr += len;
+ return ret;
+}
+
+ProKey ProFile::getHashStr(const ushort *&tPtr)
+{
+ uint hash = *tPtr++;
+ hash |= (uint)*tPtr++ << 16;
+ uint len = *tPtr++;
+ ProKey ret(items(), tPtr - tokPtr(), len, hash);
+ tPtr += len;
+ return ret;
+}
+
QT_END_NAMESPACE
diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h
index 28178ac9a6..9430d28521 100644
--- a/qmake/library/proitems.h
+++ b/qmake/library/proitems.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
@@ -138,6 +138,7 @@ public:
int toInt(bool *ok = 0, int base = 10) const { return toQString().toInt(ok, base); } // XXX optimize
short toShort(bool *ok = 0, int base = 10) const { return toQString().toShort(ok, base); } // XXX optimize
+ uint hash() const { return m_hash; }
static uint hash(const QChar *p, int n);
ALWAYS_INLINE QStringRef toQStringRef() const { return QStringRef(&m_string, m_offset, m_length); }
@@ -239,9 +240,13 @@ public:
QString join(const QString &sep) const;
QString join(QChar sep) const;
+ void insertUnique(const ProStringList &value);
+
void removeAll(const ProString &str);
void removeAll(const char *str);
+ void removeEach(const ProStringList &value);
void removeAt(int idx) { remove(idx); }
+ void removeEmpty();
void removeDuplicates();
bool contains(const ProString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
@@ -347,6 +352,9 @@ public:
bool isHostBuild() const { return m_hostBuild; }
void setHostBuild(bool host_build) { m_hostBuild = host_build; }
+ ProString getStr(const ushort *&tPtr);
+ ProKey getHashStr(const ushort *&tPtr);
+
private:
ProItemRefCount m_refCount;
QString m_proitems;
diff --git a/qmake/library/qmake_global.h b/qmake/library/qmake_global.h
index 3bb9d9955f..8f2eb5fd33 100644
--- a/qmake/library/qmake_global.h
+++ b/qmake/library/qmake_global.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index b735822806..02d5d5dd31 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
@@ -214,12 +214,12 @@ static QString windowsErrorCode()
NULL);
QString ret = QString::fromWCharArray(string);
LocalFree((HLOCAL)string);
- return ret;
+ return ret.trimmed();
}
#endif
-static QString
-quoteValue(const ProString &val)
+QString
+QMakeEvaluator::quoteValue(const ProString &val)
{
QString ret;
ret.reserve(val.size());
@@ -362,7 +362,7 @@ QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::Open
{
QString errStr;
if (!m_vfs->writeFile(fn, mode, contents, &errStr)) {
- evalError(fL1S("Cannot write %1file %2: %3.")
+ evalError(fL1S("Cannot write %1file %2: %3")
.arg(ctx, QDir::toNativeSeparators(fn), errStr));
return ReturnFalse;
}
@@ -1121,7 +1121,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
switch (func_t) {
case T_DEFINED: {
if (args.count() < 1 || args.count() > 2) {
- evalError(fL1S("defined(function, [\"test\"|\"replace\"])"
+ evalError(fL1S("defined(function, [\"test\"|\"replace\"|\"var\"])"
" requires one or two arguments."));
return ReturnFalse;
}
@@ -1202,15 +1202,13 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
VisitReturn ret = ReturnFalse;
ProFile *pro = m_parser->parsedProBlock(args.join(statics.field_sep),
m_current.pro->fileName(), m_current.line);
- if (pro) {
- if (m_cumulative || pro->isOk()) {
- m_locationStack.push(m_current);
- visitProBlock(pro, pro->tokPtr());
- ret = ReturnTrue; // This return value is not too useful, but that's qmake
- m_current = m_locationStack.pop();
- }
- pro->deref();
+ if (m_cumulative || pro->isOk()) {
+ m_locationStack.push(m_current);
+ visitProBlock(pro, pro->tokPtr());
+ ret = ReturnTrue; // This return value is not too useful, but that's qmake
+ m_current = m_locationStack.pop();
}
+ pro->deref();
return ret;
}
case T_IF: {
@@ -1584,7 +1582,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (rHand == INVALID_HANDLE_VALUE) {
- evalError(fL1S("Cannot open() reference file %1: %2.").arg(rfn, windowsErrorCode()));
+ evalError(fL1S("Cannot open reference file %1: %2").arg(rfn, windowsErrorCode()));
return ReturnFalse;
}
FILETIME ft;
@@ -1594,7 +1592,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
GENERIC_WRITE, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (wHand == INVALID_HANDLE_VALUE) {
- evalError(fL1S("Cannot open() %1: %2.").arg(tfn, windowsErrorCode()));
+ evalError(fL1S("Cannot open %1: %2").arg(tfn, windowsErrorCode()));
return ReturnFalse;
}
SetFileTime(wHand, 0, 0, &ft);
@@ -1689,7 +1687,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
if (mode == CacheAdd)
newval += diffval;
else
- removeEach(&newval, diffval);
+ newval.removeEach(diffval);
}
if (oldval != newval) {
if (target != TargetStash || !m_stashfile.isEmpty()) {
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index 9b5291a08e..5ed14caf76 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
@@ -58,6 +58,9 @@
#ifdef Q_OS_UNIX
#include <unistd.h>
#include <sys/utsname.h>
+# ifdef Q_OS_BSD4
+# include <sys/sysctl.h>
+# endif
#else
#include <windows.h>
#endif
@@ -70,6 +73,39 @@ QT_BEGIN_NAMESPACE
#define fL1S(s) QString::fromLatin1(s)
+// we can't use QThread in qmake
+// this function is a merger of QThread::idealThreadCount from qthread_win.cpp and qthread_unix.cpp
+static int idealThreadCount()
+{
+#ifdef PROEVALUATOR_THREAD_SAFE
+ return QThread::idealThreadCount();
+#elif defined(Q_OS_WIN)
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ return sysinfo.dwNumberOfProcessors;
+#else
+ // there are a couple more definitions in the Unix QThread::idealThreadCount, but
+ // we don't need them all here
+ int cores = 1;
+# if defined(Q_OS_BSD4)
+ // FreeBSD, OpenBSD, NetBSD, BSD/OS, Mac OS X
+ size_t len = sizeof(cores);
+ int mib[2];
+ mib[0] = CTL_HW;
+ mib[1] = HW_NCPU;
+ if (sysctl(mib, 2, &cores, &len, NULL, 0) != 0) {
+ perror("sysctl");
+ }
+# elif defined(_SC_NPROCESSORS_ONLN)
+ // the rest: Linux, Solaris, AIX, Tru64
+ cores = (int)sysconf(_SC_NPROCESSORS_ONLN);
+ if (cores == -1)
+ return 1;
+# endif
+ return cores;
+#endif
+}
+
QMakeBaseKey::QMakeBaseKey(const QString &_root, const QString &_stash, bool _hostBuild)
: root(_root), stash(_stash), hostBuild(_hostBuild)
@@ -222,24 +258,6 @@ uint QMakeEvaluator::getBlockLen(const ushort *&tokPtr)
return len;
}
-ProString QMakeEvaluator::getStr(const ushort *&tokPtr)
-{
- uint len = *tokPtr++;
- ProString ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len);
- ret.setSource(m_current.pro);
- tokPtr += len;
- return ret;
-}
-
-ProKey QMakeEvaluator::getHashStr(const ushort *&tokPtr)
-{
- uint hash = getBlockLen(tokPtr);
- uint len = *tokPtr++;
- ProKey ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len, hash);
- tokPtr += len;
- return ret;
-}
-
void QMakeEvaluator::skipStr(const ushort *&tokPtr)
{
uint len = *tokPtr++;
@@ -278,7 +296,8 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil
switch (unicode) {
case '"':
case '\'':
- quote = unicode;
+ if (!quote)
+ quote = unicode;
hadWord = true;
break;
case ' ':
@@ -314,34 +333,6 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil
return ret;
}
-static void zipEmpty(ProStringList *value)
-{
- for (int i = value->size(); --i >= 0;)
- if (value->at(i).isEmpty())
- value->remove(i);
-}
-
-static void insertUnique(ProStringList *varlist, const ProStringList &value)
-{
- foreach (const ProString &str, value)
- if (!str.isEmpty() && !varlist->contains(str))
- varlist->append(str);
-}
-
-static void removeAll(ProStringList *varlist, const ProString &value)
-{
- for (int i = varlist->size(); --i >= 0; )
- if (varlist->at(i) == value)
- varlist->remove(i);
-}
-
-void QMakeEvaluator::removeEach(ProStringList *varlist, const ProStringList &value)
-{
- foreach (const ProString &str, value)
- if (!str.isEmpty())
- removeAll(varlist, str);
-}
-
static void replaceInList(ProStringList *varlist,
const QRegExp &regexp, const QString &replace, bool global, QString &tmp)
{
@@ -421,6 +412,7 @@ void QMakeEvaluator::evaluateExpression(
const ushort *&tokPtr, ProStringList *ret, bool joined)
{
debugMsg(2, joined ? "evaluating joined expression" : "evaluating expression");
+ ProFile *pro = m_current.pro;
if (joined)
*ret << ProString();
bool pending = false;
@@ -436,35 +428,35 @@ void QMakeEvaluator::evaluateExpression(
m_current.line = *tokPtr++;
break;
case TokLiteral: {
- const ProString &val = getStr(tokPtr);
+ const ProString &val = pro->getStr(tokPtr);
debugMsg(2, "literal %s", dbgStr(val));
addStr(val, ret, pending, joined);
break; }
case TokHashLiteral: {
- const ProKey &val = getHashStr(tokPtr);
+ const ProKey &val = pro->getHashStr(tokPtr);
debugMsg(2, "hashed literal %s", dbgStr(val.toString()));
addStr(val, ret, pending, joined);
break; }
case TokVariable: {
- const ProKey &var = getHashStr(tokPtr);
+ const ProKey &var = pro->getHashStr(tokPtr);
const ProStringList &val = values(map(var));
debugMsg(2, "variable %s => %s", dbgKey(var), dbgStrList(val));
addStrList(val, tok, ret, pending, joined);
break; }
case TokProperty: {
- const ProKey &var = getHashStr(tokPtr);
+ const ProKey &var = pro->getHashStr(tokPtr);
const ProString &val = propertyValue(var);
debugMsg(2, "property %s => %s", dbgKey(var), dbgStr(val));
addStr(val, ret, pending, joined);
break; }
case TokEnvVar: {
- const ProString &var = getStr(tokPtr);
+ const ProString &var = pro->getStr(tokPtr);
const ProString &val = ProString(m_option->getEnv(var.toQString(m_tmp1)));
debugMsg(2, "env var %s => %s", dbgStr(var), dbgStr(val));
addStr(val, ret, pending, joined);
break; }
case TokFuncName: {
- const ProKey &func = getHashStr(tokPtr);
+ const ProKey &func = pro->getHashStr(tokPtr);
debugMsg(2, "function %s", dbgKey(func));
addStrList(evaluateExpandFunction(func, tokPtr), tok, ret, pending, joined);
break; }
@@ -529,6 +521,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
{
traceMsg("entering block");
ProStringList curr;
+ ProFile *pro = m_current.pro;
bool okey = true, or_op = false, invert = false;
uint blockLen;
while (ushort tok = *tokPtr++) {
@@ -588,7 +581,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
blockLen = getBlockLen(tokPtr);
ret = visitProBlock(tokPtr);
} else if (okey != or_op) {
- const ProKey &variable = getHashStr(tokPtr);
+ const ProKey &variable = pro->getHashStr(tokPtr);
uint exprLen = getBlockLen(tokPtr);
const ushort *exprPtr = tokPtr;
tokPtr += exprLen;
@@ -608,7 +601,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
case TokTestDef:
case TokReplaceDef:
if (m_cumulative || okey != or_op) {
- const ProKey &name = getHashStr(tokPtr);
+ const ProKey &name = pro->getHashStr(tokPtr);
blockLen = getBlockLen(tokPtr);
visitProFunctionDef(tok, name, tokPtr);
traceMsg("defined %s function %s",
@@ -788,8 +781,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop(
forever {
if (infinite) {
if (!variable.isEmpty())
- m_valuemapStack.top()[variable] = ProStringList(ProString(QString::number(index++)));
- if (index > 1000) {
+ m_valuemapStack.top()[variable] = ProStringList(ProString(QString::number(index)));
+ if (++index > 1000) {
evalError(fL1S("Ran into infinite loop (> 1000 iterations)."));
break;
}
@@ -880,24 +873,24 @@ void QMakeEvaluator::visitProVariable(
switch (tok) {
default: // whatever - cannot happen
case TokAssign: // =
- zipEmpty(&varVal);
+ varVal.removeEmpty();
// FIXME: add check+warning about accidental value removal.
// This may be a bit too noisy, though.
m_valuemapStack.top()[varName] = varVal;
debugMsg(2, "assigning");
break;
case TokAppendUnique: // *=
- insertUnique(&valuesRef(varName), varVal);
+ valuesRef(varName).insertUnique(varVal);
debugMsg(2, "appending unique");
break;
case TokAppend: // +=
- zipEmpty(&varVal);
+ varVal.removeEmpty();
valuesRef(varName) += varVal;
debugMsg(2, "appending");
break;
case TokRemove: // -=
if (!m_cumulative) {
- removeEach(&valuesRef(varName), varVal);
+ valuesRef(varName).removeEach(varVal);
} else {
// We are stingy with our values.
}
@@ -998,6 +991,7 @@ void QMakeEvaluator::loadDefaults()
vars[ProKey("QMAKE_QMAKE")] << ProString(m_option->qmake_abslocation);
if (!m_option->qmake_args.isEmpty())
vars[ProKey("QMAKE_ARGS")] = ProStringList(m_option->qmake_args);
+ vars[ProKey("QMAKE_HOST.cpu_count")] = ProString(QString::number(idealThreadCount()));
#if defined(Q_OS_WIN32)
vars[ProKey("QMAKE_HOST.os")] << ProString("Windows");
@@ -1270,14 +1264,13 @@ void QMakeEvaluator::setupProject()
void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where)
{
if (!cmds.isEmpty()) {
- if (ProFile *pro = m_parser->parsedProBlock(cmds, where, -1)) {
- if (pro->isOk()) {
- m_locationStack.push(m_current);
- visitProBlock(pro, pro->tokPtr());
- m_current = m_locationStack.pop();
- }
- pro->deref();
+ ProFile *pro = m_parser->parsedProBlock(cmds, where, -1);
+ if (pro->isOk()) {
+ m_locationStack.push(m_current);
+ visitProBlock(pro, pro->tokPtr());
+ m_current = m_locationStack.pop();
}
+ pro->deref();
}
}
@@ -1757,14 +1750,12 @@ bool QMakeEvaluator::evaluateConditional(const QString &cond, const QString &whe
{
bool ret = false;
ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar);
- if (pro) {
- if (pro->isOk()) {
- m_locationStack.push(m_current);
- ret = visitProBlock(pro, pro->tokPtr()) == ReturnTrue;
- m_current = m_locationStack.pop();
- }
- pro->deref();
+ if (pro->isOk()) {
+ m_locationStack.push(m_current);
+ ret = visitProBlock(pro, pro->tokPtr()) == ReturnTrue;
+ m_current = m_locationStack.pop();
}
+ pro->deref();
return ret;
}
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
index 73fd5bb82f..a60adde84e 100644
--- a/qmake/library/qmakeevaluator.h
+++ b/qmake/library/qmakeevaluator.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
@@ -150,8 +150,6 @@ public:
{ return b ? ReturnTrue : ReturnFalse; }
static ALWAYS_INLINE uint getBlockLen(const ushort *&tokPtr);
- ProString getStr(const ushort *&tokPtr);
- ProKey getHashStr(const ushort *&tokPtr);
void evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined);
static ALWAYS_INLINE void skipStr(const ushort *&tokPtr);
static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr);
@@ -243,8 +241,6 @@ public:
#endif
QByteArray getCommandOutput(const QString &args) const;
- static void removeEach(ProStringList *varlist, const ProStringList &value);
-
QMakeEvaluator *m_caller;
#ifdef PROEVALUATOR_CUMULATIVE
bool m_cumulative;
@@ -254,6 +250,8 @@ public:
enum { m_skipLevel = 0 };
#endif
+ static QString quoteValue(const ProString &val);
+
#ifdef PROEVALUATOR_DEBUG
void debugMsgInternal(int level, const char *fmt, ...) const;
void traceMsgInternal(const char *fmt, ...) const;
diff --git a/qmake/library/qmakeevaluator_p.h b/qmake/library/qmakeevaluator_p.h
index dd63bcea02..e000fc9cf5 100644
--- a/qmake/library/qmakeevaluator_p.h
+++ b/qmake/library/qmakeevaluator_p.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
diff --git a/qmake/library/qmakeglobals.cpp b/qmake/library/qmakeglobals.cpp
index aeb8a6c803..55ce404410 100644
--- a/qmake/library/qmakeglobals.cpp
+++ b/qmake/library/qmakeglobals.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
diff --git a/qmake/library/qmakeglobals.h b/qmake/library/qmakeglobals.h
index 6950d32807..de46ebbe74 100644
--- a/qmake/library/qmakeglobals.h
+++ b/qmake/library/qmakeglobals.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
@@ -135,6 +135,7 @@ public:
bool initProperties();
# else
void setProperties(const QHash<QString, QString> &props);
+ void setProperties(const QHash<ProKey, ProString> &props) { properties = props; }
# endif
ProString propertyValue(const ProKey &name) const { return properties.value(name); }
#endif
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp
index 3065d4dd5a..3fd7957bc0 100644
--- a/qmake/library/qmakeparser.cpp
+++ b/qmake/library/qmakeparser.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
@@ -209,10 +209,7 @@ ProFile *QMakeParser::parsedProBlock(
const QString &contents, const QString &name, int line, SubGrammar grammar)
{
ProFile *pro = new ProFile(name);
- if (!read(pro, contents, line, grammar)) {
- delete pro;
- pro = 0;
- }
+ read(pro, contents, line, grammar);
return pro;
}
@@ -232,7 +229,8 @@ bool QMakeParser::read(ProFile *pro, ParseFlags flags)
fL1S("Cannot read %1: %2").arg(pro->fileName(), errStr));
return false;
}
- return read(pro, content, 1, FullGrammar);
+ read(pro, content, 1, FullGrammar);
+ return true;
}
void QMakeParser::putTok(ushort *&tokPtr, ushort tok)
@@ -272,7 +270,7 @@ void QMakeParser::finalizeHashStr(ushort *buf, uint len)
buf[-2] = (ushort)(hash >> 16);
}
-bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar grammar)
+void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar grammar)
{
m_proFile = pro;
m_lineNo = line;
@@ -322,7 +320,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
m_canElse = false;
freshLine:
m_state = StNew;
- m_invert = false;
+ m_invert = 0;
m_operator = NoOperator;
m_markLine = m_lineNo;
m_inError = false;
@@ -579,7 +577,6 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
parseError(fL1S("Missing %1 terminator [found %2]")
.arg(QChar(term))
.arg(c ? QString(c) : QString::fromLatin1("end-of-line")));
- pro->setOk(false);
m_inError = true;
// Just parse on, as if there was a terminator ...
} else {
@@ -606,7 +603,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
quote = 0;
goto nextChr;
} else if (c == '!' && ptr == xprPtr && context == CtxTest) {
- m_invert ^= true;
+ m_invert++;
goto nextChr;
}
} else if (c == '\'' || c == '"') {
@@ -663,20 +660,20 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
parseError(fL1S("Extra characters after test expression."));
else
parseError(fL1S("Opening parenthesis without prior test name."));
- pro->setOk(false);
ptr = buf; // Put empty function name
}
*ptr++ = TokTestCall;
term = ':';
goto funcCall;
} else if (c == '!' && ptr == xprPtr) {
- m_invert ^= true;
+ m_invert++;
goto nextChr;
} else if (c == ':') {
FLUSH_LHS_LITERAL();
finalizeCond(tokPtr, buf, ptr, wordCount);
+ warnOperator("in front of AND operator");
if (m_state == StNew)
- parseError(fL1S("And operator without prior condition."));
+ parseError(fL1S("AND operator without prior condition."));
else
m_operator = AndOperator;
nextItem:
@@ -685,26 +682,33 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
} else if (c == '|') {
FLUSH_LHS_LITERAL();
finalizeCond(tokPtr, buf, ptr, wordCount);
+ warnOperator("in front of OR operator");
if (m_state != StCond)
- parseError(fL1S("Or operator without prior condition."));
+ parseError(fL1S("OR operator without prior condition."));
else
m_operator = OrOperator;
goto nextItem;
} else if (c == '{') {
FLUSH_LHS_LITERAL();
finalizeCond(tokPtr, buf, ptr, wordCount);
+ if (m_operator == AndOperator) {
+ languageWarning(fL1S("Excess colon in front of opening brace."));
+ m_operator = NoOperator;
+ }
+ failOperator("in front of opening brace");
flushCond(tokPtr);
+ m_state = StNew; // Reset possible StCtrl, so colons get rejected.
++m_blockstack.top().braceLevel;
- if (grammar == TestGrammar) {
+ if (grammar == TestGrammar)
parseError(fL1S("Opening scope not permitted in this context."));
- pro->setOk(false);
- }
goto nextItem;
} else if (c == '}') {
FLUSH_LHS_LITERAL();
finalizeCond(tokPtr, buf, ptr, wordCount);
- flushScopes(tokPtr);
+ m_state = StNew; // De-facto newline
closeScope:
+ flushScopes(tokPtr);
+ failOperator("in front of closing brace");
if (!m_blockstack.top().braceLevel) {
parseError(fL1S("Excess closing brace."));
} else if (!--m_blockstack.top().braceLevel
@@ -736,13 +740,12 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
doOp:
FLUSH_LHS_LITERAL();
flushCond(tokPtr);
+ acceptColon("in front of assignment");
putLineMarker(tokPtr);
if (grammar == TestGrammar) {
parseError(fL1S("Assignment not permitted in this context."));
- pro->setOk(false);
} else if (wordCount != 1) {
parseError(fL1S("Assignment needs exactly one word on the left hand side."));
- pro->setOk(false);
// Put empty variable name.
} else {
putBlock(tokPtr, buf, ptr - buf);
@@ -811,7 +814,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
} else if (context == CtxPureValue) {
putTok(tokPtr, TokValueTerminator);
} else {
- bogusTest(tokPtr);
+ bogusTest(tokPtr, QString());
}
} else if (context == CtxValue) {
FLUSH_VALUE_LIST();
@@ -822,6 +825,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
putTok(tokPtr, TokValueTerminator);
} else {
finalizeCond(tokPtr, buf, ptr, wordCount);
+ warnOperator("at end of line");
}
if (!cur)
break;
@@ -837,15 +841,12 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
}
flushScopes(tokPtr);
- if (m_blockstack.size() > 1) {
+ if (m_blockstack.size() > 1 || m_blockstack.top().braceLevel)
parseError(fL1S("Missing closing brace(s)."));
- pro->setOk(false);
- }
while (m_blockstack.size())
leaveScope(tokPtr);
tokBuff.resize(tokPtr - (ushort *)tokBuff.constData()); // Reserved capacity stays
*pro->itemsRef() = tokBuff;
- return true;
#undef FLUSH_VALUE_LIST
#undef FLUSH_LITERAL
@@ -918,39 +919,90 @@ void QMakeParser::flushCond(ushort *&tokPtr)
}
}
-void QMakeParser::finalizeTest(ushort *&tokPtr)
+void QMakeParser::warnOperator(const char *msg)
{
- flushScopes(tokPtr);
- putLineMarker(tokPtr);
- if (m_operator != NoOperator) {
- putTok(tokPtr, (m_operator == AndOperator) ? TokAnd : TokOr);
+ if (m_invert) {
+ languageWarning(fL1S("Stray NOT operator %1.").arg(fL1S(msg)));
+ m_invert = 0;
+ }
+ if (m_operator == AndOperator) {
+ languageWarning(fL1S("Stray AND operator %1.").arg(fL1S(msg)));
+ m_operator = NoOperator;
+ } else if (m_operator == OrOperator) {
+ languageWarning(fL1S("Stray OR operator %1.").arg(fL1S(msg)));
m_operator = NoOperator;
}
+}
+
+bool QMakeParser::failOperator(const char *msg)
+{
+ bool fail = false;
if (m_invert) {
- putTok(tokPtr, TokNot);
- m_invert = false;
+ parseError(fL1S("Unexpected NOT operator %1.").arg(fL1S(msg)));
+ m_invert = 0;
+ fail = true;
+ }
+ if (m_operator == AndOperator) {
+ parseError(fL1S("Unexpected AND operator %1.").arg(fL1S(msg)));
+ m_operator = NoOperator;
+ fail = true;
+ } else if (m_operator == OrOperator) {
+ parseError(fL1S("Unexpected OR operator %1.").arg(fL1S(msg)));
+ m_operator = NoOperator;
+ fail = true;
+ }
+ return fail;
+}
+
+bool QMakeParser::acceptColon(const char *msg)
+{
+ if (m_operator == AndOperator)
+ m_operator = NoOperator;
+ return !failOperator(msg);
+}
+
+void QMakeParser::putOperator(ushort *&tokPtr)
+{
+ if (m_operator== AndOperator) {
+ // A colon must be used after else and for() if no brace is used,
+ // but in this case it is obviously not a binary operator.
+ if (m_state == StCond)
+ putTok(tokPtr, TokAnd);
+ m_operator = NoOperator;
+ } else if (m_operator == OrOperator) {
+ putTok(tokPtr, TokOr);
+ m_operator = NoOperator;
}
+}
+
+void QMakeParser::finalizeTest(ushort *&tokPtr)
+{
+ flushScopes(tokPtr);
+ putLineMarker(tokPtr);
+ putOperator(tokPtr);
+ if (m_invert & 1)
+ putTok(tokPtr, TokNot);
+ m_invert = 0;
m_state = StCond;
m_canElse = true;
}
-void QMakeParser::bogusTest(ushort *&tokPtr)
+void QMakeParser::bogusTest(ushort *&tokPtr, const QString &msg)
{
+ if (!msg.isEmpty())
+ parseError(msg);
flushScopes(tokPtr);
m_operator = NoOperator;
- m_invert = false;
+ m_invert = 0;
m_state = StCond;
m_canElse = true;
- m_proFile->setOk(false);
}
void QMakeParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount)
{
if (wordCount != 1) {
- if (wordCount) {
- parseError(fL1S("Extra characters after test expression."));
- bogusTest(tokPtr);
- }
+ if (wordCount)
+ bogusTest(tokPtr, fL1S("Extra characters after test expression."));
return;
}
@@ -961,10 +1013,8 @@ void QMakeParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wor
if (uce == ptr) {
m_tmp.setRawData((QChar *)uc + 4, nlen);
if (!m_tmp.compare(statics.strelse, Qt::CaseInsensitive)) {
- if (m_invert || m_operator != NoOperator) {
- parseError(fL1S("Unexpected operator in front of else."));
+ if (failOperator("in front of else"))
return;
- }
BlockScope &top = m_blockstack.top();
if (m_canElse && (!top.special || top.braceLevel)) {
// A list of tests (the last one likely with side effects),
@@ -1009,18 +1059,18 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
const QString *defName;
ushort defType;
if (m_tmp == statics.strfor) {
- if (m_invert || m_operator == OrOperator) {
- // '|' could actually work reasonably, but qmake does nonsense here.
- parseError(fL1S("Unexpected operator in front of for()."));
- bogusTest(tokPtr);
+ if (!acceptColon("in front of for()")) {
+ bogusTest(tokPtr, QString());
return;
}
flushCond(tokPtr);
putLineMarker(tokPtr);
+ --ptr;
+ Q_ASSERT(*ptr == TokFuncTerminator);
if (*uce == (TokLiteral|TokNewStr)) {
nlen = uce[1];
uc = uce + 2 + nlen;
- if (*uc == TokFuncTerminator) {
+ if (uc == ptr) {
// for(literal) (only "ever" would be legal if qmake was sane)
putTok(tokPtr, TokForLoop);
putHashStr(tokPtr, (ushort *)0, (uint)0);
@@ -1061,8 +1111,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
defType = TokTestDef;
deffunc:
if (m_invert) {
- parseError(fL1S("Unexpected operator in front of function definition."));
- bogusTest(tokPtr);
+ bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of function definition."));
return;
}
flushScopes(tokPtr);
@@ -1070,10 +1119,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
if (*uce == (TokLiteral|TokNewStr)) {
uint nlen = uce[1];
if (uce[nlen + 2] == TokFuncTerminator) {
- if (m_operator != NoOperator) {
- putTok(tokPtr, (m_operator == AndOperator) ? TokAnd : TokOr);
- m_operator = NoOperator;
- }
+ putOperator(tokPtr);
putTok(tokPtr, defType);
putHashStr(tokPtr, uce + 2, nlen);
enterScope(tokPtr, true, StCtrl);
@@ -1086,14 +1132,12 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
} else if (m_tmp == statics.strreturn) {
if (m_blockstack.top().nest & NestFunction) {
if (argc > 1) {
- parseError(fL1S("return() requires zero or one argument."));
- bogusTest(tokPtr);
+ bogusTest(tokPtr, fL1S("return() requires zero or one argument."));
return;
}
} else {
if (*uce != TokFuncTerminator) {
- parseError(fL1S("Top-level return() requires zero arguments."));
- bogusTest(tokPtr);
+ bogusTest(tokPtr, fL1S("Top-level return() requires zero arguments."));
return;
}
}
@@ -1106,19 +1150,16 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
defType = TokBreak;
ctrlstm:
if (*uce != TokFuncTerminator) {
- parseError(fL1S("%1() requires zero arguments.").arg(m_tmp));
- bogusTest(tokPtr);
+ bogusTest(tokPtr, fL1S("%1() requires zero arguments.").arg(m_tmp));
return;
}
if (!(m_blockstack.top().nest & NestLoop)) {
- parseError(fL1S("Unexpected %1().").arg(m_tmp));
- bogusTest(tokPtr);
+ bogusTest(tokPtr, fL1S("Unexpected %1().").arg(m_tmp));
return;
}
ctrlstm2:
if (m_invert) {
- parseError(fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp));
- bogusTest(tokPtr);
+ bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp));
return;
}
finalizeTest(tokPtr);
@@ -1128,8 +1169,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
} else if (m_tmp == statics.stroption) {
if (m_state != StNew || m_blockstack.top().braceLevel || m_blockstack.size() > 1
|| m_invert || m_operator != NoOperator) {
- parseError(fL1S("option() must appear outside any control structures."));
- bogusTest(tokPtr);
+ bogusTest(tokPtr, fL1S("option() must appear outside any control structures."));
return;
}
if (*uce == (TokLiteral|TokNewStr)) {
@@ -1210,4 +1250,258 @@ void QMakeParser::message(int type, const QString &msg) const
m_handler->message(type, msg, m_proFile->fileName(), m_lineNo);
}
+#ifdef PROPARSER_DEBUG
+
+#define BOUNDS_CHECK(need) \
+ do { \
+ int have = limit - offset; \
+ if (have < (int)need) { \
+ *outStr += fL1S("<out of bounds (need %1, got %2)>").arg(need).arg(have); \
+ return false; \
+ } \
+ } while (0)
+
+static bool getRawUshort(const ushort *tokens, int limit, int &offset, ushort *outVal, QString *outStr)
+{
+ BOUNDS_CHECK(1);
+ uint val = tokens[offset++];
+ *outVal = val;
+ return true;
+}
+
+static bool getUshort(const ushort *tokens, int limit, int &offset, ushort *outVal, QString *outStr)
+{
+ *outStr += fL1S(" << H(");
+ if (!getRawUshort(tokens, limit, offset, outVal, outStr))
+ return false;
+ *outStr += QString::number(*outVal) + QLatin1Char(')');
+ return true;
+}
+
+static bool getRawUint(const ushort *tokens, int limit, int &offset, uint *outVal, QString *outStr)
+{
+ BOUNDS_CHECK(2);
+ uint val = tokens[offset++];
+ val |= (uint)tokens[offset++] << 16;
+ *outVal = val;
+ return true;
+}
+
+static bool getUint(const ushort *tokens, int limit, int &offset, uint *outVal, QString *outStr)
+{
+ *outStr += fL1S(" << I(");
+ if (!getRawUint(tokens, limit, offset, outVal, outStr))
+ return false;
+ *outStr += QString::number(*outVal) + QLatin1Char(')');
+ return true;
+}
+
+static bool getRawStr(const ushort *tokens, int limit, int &offset, int strLen, QString *outStr)
+{
+ BOUNDS_CHECK(strLen);
+ *outStr += fL1S("L\"");
+ bool attn = false;
+ for (int i = 0; i < strLen; i++) {
+ ushort val = tokens[offset++];
+ switch (val) {
+ case '"': *outStr += fL1S("\\\""); break;
+ case '\n': *outStr += fL1S("\\n"); break;
+ case '\r': *outStr += fL1S("\\r"); break;
+ case '\t': *outStr += fL1S("\\t"); break;
+ case '\\': *outStr += fL1S("\\\\"); break;
+ default:
+ if (val < 32 || val > 126) {
+ *outStr += (val > 255 ? fL1S("\\u") : fL1S("\\x")) + QString::number(val, 16);
+ attn = true;
+ continue;
+ }
+ if (attn && isxdigit(val))
+ *outStr += fL1S("\"\"");
+ *outStr += QChar(val);
+ break;
+ }
+ attn = false;
+ }
+ *outStr += QLatin1Char('"');
+ return true;
+}
+
+static bool getStr(const ushort *tokens, int limit, int &offset, QString *outStr)
+{
+ *outStr += fL1S(" << S(");
+ ushort len;
+ if (!getRawUshort(tokens, limit, offset, &len, outStr))
+ return false;
+ if (!getRawStr(tokens, limit, offset, len, outStr))
+ return false;
+ *outStr += QLatin1Char(')');
+ return true;
+}
+
+static bool getHashStr(const ushort *tokens, int limit, int &offset, QString *outStr)
+{
+ *outStr += fL1S(" << HS(");
+ uint hash;
+ if (!getRawUint(tokens, limit, offset, &hash, outStr))
+ return false;
+ ushort len;
+ if (!getRawUshort(tokens, limit, offset, &len, outStr))
+ return false;
+ const QChar *chars = (const QChar *)tokens + offset;
+ if (!getRawStr(tokens, limit, offset, len, outStr))
+ return false;
+ uint realhash = ProString::hash(chars, len);
+ if (realhash != hash)
+ *outStr += fL1S(" /* Bad hash ") + QString::number(hash) + fL1S(" */");
+ *outStr += QLatin1Char(')');
+ return true;
+}
+
+static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent);
+
+static bool getSubBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent,
+ const char *scope)
+{
+ *outStr += fL1S("\n /* %1 */ ").arg(offset, 5)
+ + QString(indent * 4, QLatin1Char(' '))
+ + fL1S("/* ") + fL1S(scope) + fL1S(" */");
+ uint len;
+ if (!getUint(tokens, limit, offset, &len, outStr))
+ return false;
+ if (len) {
+ BOUNDS_CHECK(len);
+ int tmpOff = offset;
+ offset += len;
+ forever {
+ if (!getBlock(tokens, offset, tmpOff, outStr, indent + 1))
+ break; // Error was already reported, try to continue
+ if (tmpOff == offset)
+ break;
+ *outStr += QLatin1Char('\n') + QString(20 + indent * 4, QLatin1Char(' '))
+ + fL1S("/* Warning: Excess tokens follow. */");
+ }
+ }
+ return true;
+}
+
+static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent)
+{
+ static const char * const tokNames[] = {
+ "TokTerminator",
+ "TokLine",
+ "TokAssign", "TokAppend", "TokAppendUnique", "TokRemove", "TokReplace",
+ "TokValueTerminator",
+ "TokLiteral", "TokHashLiteral", "TokVariable", "TokProperty", "TokEnvVar",
+ "TokFuncName", "TokArgSeparator", "TokFuncTerminator",
+ "TokCondition", "TokTestCall",
+ "TokReturn", "TokBreak", "TokNext",
+ "TokNot", "TokAnd", "TokOr",
+ "TokBranch", "TokForLoop",
+ "TokTestDef", "TokReplaceDef"
+ };
+
+ while (offset != limit) {
+ *outStr += fL1S("\n /* %1 */").arg(offset, 5)
+ + QString(indent * 4, QLatin1Char(' '));
+ BOUNDS_CHECK(1);
+ ushort tok = tokens[offset++];
+ ushort maskedTok = tok & TokMask;
+ if (maskedTok >= sizeof(tokNames)/sizeof(tokNames[0])
+ || (tok & ~(TokNewStr | TokQuoted | TokMask))) {
+ *outStr += fL1S(" << {invalid token %1}").arg(tok);
+ return false;
+ }
+ *outStr += fL1S(" << H(") + fL1S(tokNames[maskedTok]);
+ if (tok & TokNewStr)
+ *outStr += fL1S(" | TokNewStr");
+ if (tok & TokQuoted)
+ *outStr += fL1S(" | TokQuoted");
+ *outStr += QLatin1Char(')');
+ bool ok;
+ switch (maskedTok) {
+ case TokFuncTerminator: // Recursion, but not a sub-block
+ return true;
+ case TokArgSeparator:
+ case TokValueTerminator: // Not recursion
+ case TokTerminator: // Recursion, and limited by (sub-)block length
+ case TokCondition:
+ case TokReturn:
+ case TokBreak:
+ case TokNext:
+ case TokNot:
+ case TokAnd:
+ case TokOr:
+ ok = true;
+ break;
+ case TokTestCall:
+ ok = getBlock(tokens, limit, offset, outStr, indent + 1);
+ break;
+ case TokBranch:
+ ok = getSubBlock(tokens, limit, offset, outStr, indent, "then branch");
+ if (ok)
+ ok = getSubBlock(tokens, limit, offset, outStr, indent, "else branch");
+ break;
+ default:
+ switch (maskedTok) {
+ case TokAssign:
+ case TokAppend:
+ case TokAppendUnique:
+ case TokRemove:
+ case TokReplace:
+ // The parameter is the sizehint for the output.
+ // fallthrough
+ case TokLine: {
+ ushort dummy;
+ ok = getUshort(tokens, limit, offset, &dummy, outStr);
+ break; }
+ case TokLiteral:
+ case TokEnvVar:
+ ok = getStr(tokens, limit, offset, outStr);
+ break;
+ case TokHashLiteral:
+ case TokVariable:
+ case TokProperty:
+ ok = getHashStr(tokens, limit, offset, outStr);
+ break;
+ case TokFuncName:
+ ok = getHashStr(tokens, limit, offset, outStr);
+ if (ok)
+ ok = getBlock(tokens, limit, offset, outStr, indent + 1);
+ break;
+ case TokForLoop:
+ ok = getHashStr(tokens, limit, offset, outStr);
+ if (ok)
+ ok = getSubBlock(tokens, limit, offset, outStr, indent, "iterator");
+ if (ok)
+ ok = getSubBlock(tokens, limit, offset, outStr, indent, "body");
+ break;
+ case TokTestDef:
+ case TokReplaceDef:
+ ok = getHashStr(tokens, limit, offset, outStr);
+ if (ok)
+ ok = getSubBlock(tokens, limit, offset, outStr, indent, "body");
+ break;
+ default:
+ Q_ASSERT(!"unhandled token");
+ }
+ }
+ if (!ok)
+ return false;
+ }
+ return true;
+}
+
+QString QMakeParser::formatProBlock(const QString &block)
+{
+ QString outStr;
+ outStr += fL1S("\n << TS(");
+ int offset = 0;
+ getBlock(reinterpret_cast<const ushort *>(block.constData()), block.length(),
+ offset, &outStr, 0);
+ outStr += QLatin1Char(')');
+ return outStr;
+}
+
+#endif // PROPARSER_DEBUG
+
QT_END_NAMESPACE
diff --git a/qmake/library/qmakeparser.h b/qmake/library/qmakeparser.h
index f8bbe905c3..dfea1ddfdf 100644
--- a/qmake/library/qmakeparser.h
+++ b/qmake/library/qmakeparser.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
@@ -96,6 +96,10 @@ public:
void discardFileFromCache(const QString &fileName);
+#ifdef PROPARSER_DEBUG
+ static QString formatProBlock(const QString &block);
+#endif
+
private:
enum ScopeNesting {
NestNone = 0,
@@ -130,7 +134,7 @@ private:
};
bool read(ProFile *pro, ParseFlags flags);
- bool read(ProFile *pro, const QString &content, int line, SubGrammar grammar);
+ void read(ProFile *pro, const QString &content, int line, SubGrammar grammar);
ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok);
ALWAYS_INLINE void putBlockLen(ushort *&tokPtr, uint len);
@@ -144,8 +148,12 @@ private:
const ushort *cur, const QString &in);
void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
+ void warnOperator(const char *msg);
+ bool failOperator(const char *msg);
+ bool acceptColon(const char *msg);
+ void putOperator(ushort *&tokPtr);
void finalizeTest(ushort *&tokPtr);
- void bogusTest(ushort *&tokPtr);
+ void bogusTest(ushort *&tokPtr, const QString &msg);
void enterScope(ushort *&tokPtr, bool special, ScopeState state);
void leaveScope(ushort *&tokPtr);
void flushCond(ushort *&tokPtr);
@@ -153,7 +161,10 @@ private:
void message(int type, const QString &msg) const;
void parseError(const QString &msg) const
- { message(QMakeParserHandler::ParserError, msg); }
+ {
+ message(QMakeParserHandler::ParserError, msg);
+ m_proFile->setOk(false);
+ }
void languageWarning(const QString &msg) const
{ message(QMakeParserHandler::ParserWarnLanguage, msg); }
void deprecationWarning(const QString &msg) const
@@ -168,7 +179,7 @@ private:
int m_markLine; // Put marker for this line
bool m_inError; // Current line had a parsing error; suppress followup error messages
bool m_canElse; // Conditionals met on previous line, but no scope was opened
- bool m_invert; // Pending conditional is negated
+ int m_invert; // Pending conditional is negated
enum { NoOperator, AndOperator, OrOperator } m_operator; // Pending conditional is ORed/ANDed
QString m_tmp; // Temporary for efficient toQString
diff --git a/qmake/library/qmakevfs.cpp b/qmake/library/qmakevfs.cpp
index 125d074ce3..613e4e90d7 100644
--- a/qmake/library/qmakevfs.cpp
+++ b/qmake/library/qmakevfs.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$
diff --git a/qmake/library/qmakevfs.h b/qmake/library/qmakevfs.h
index 80e0eec07b..8eeae15dcc 100644
--- a/qmake/library/qmakevfs.h
+++ b/qmake/library/qmakevfs.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@@ -10,9 +10,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
@@ -23,8 +23,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$