summaryrefslogtreecommitdiffstats
path: root/qmake
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2016-07-19 19:51:41 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2016-07-19 20:14:40 +0200
commit782ebeada125e3d8a293c7806e34cc737c30ddda (patch)
tree5516ad24a7532d650289758abd5e92a35bc2240e /qmake
parent091df96fb8da356dc9de81dc390f55e66d4d7c01 (diff)
parent62cbb434579a56871f0917bc306d592055381c00 (diff)
Merge remote-tracking branch 'origin/5.7' into dev
Conflicts: qmake/library/qmakebuiltins.cpp qmake/library/qmakeevaluator.cpp qmake/library/qmakeevaluator.h qmake/project.h QMakeEvaluator: * evaluateConditional(): one side changed return type, the other changed a parameter type. * split_value_list(): one side changed a parameter adjacent to where ... * expandVariableReferences(): ... the other killed one overload and changed the survivor src/corelib/io/qlockfile_unix.cpp One side changed a #if condition, the other moved NETBSD's part of what it controlled. src/corelib/tools/qdatetime.cpp One side fixed a reachable Q_UNREACHABLE in toMSecsSinceEpoch(), the other moved it from the private class to the public one, in the midst of the "short date-time" optimization, which confused diff entirely. One side changed a QStringLiteral to QLatin1String, the other rewrote adjoining code. src/network/kernel/qauthenticator.cpp Both rewrote a line, equivalently; kept the dev version. src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h One side changed #if-ery that the other removed. tools/configure/configureapp.cpp One side added a check to -target parsing; the other killed -target. tests/auto/testlib/selftests/expected_cmptest.lightxml tests/auto/testlib/selftests/expected_cmptest.teamcity tests/auto/testlib/selftests/expected_cmptest.txt tests/auto/testlib/selftests/expected_cmptest.xml tests/auto/testlib/selftests/expected_cmptest.xunitxml Regenerated using generate_expected_output.py I note that quite a few other expected_* come out changed, now. There was no git-conflict in src/widgets/kernel/qformlayout.cpp but it didn't compile; one side removed some unused methods; the other found uses for one of them. Put FixedColumnMatrix<>::removeRow(int) back for its new user. Change-Id: I8cc2a71add48c0a848e13cfc47b5a7754e8ca584
Diffstat (limited to 'qmake')
-rw-r--r--qmake/library/qmakebuiltins.cpp13
-rw-r--r--qmake/library/qmakeevaluator.cpp186
-rw-r--r--qmake/library/qmakeevaluator.h19
-rw-r--r--qmake/library/qmakeparser.cpp15
-rw-r--r--qmake/project.cpp9
-rw-r--r--qmake/project.h2
6 files changed, 151 insertions, 93 deletions
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index 1d2b806a26..74d24aacf4 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -1131,7 +1131,11 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
QString rstr = QDir::cleanPath(
QDir(args.count() > 1 ? args.at(1).toQString(m_tmp2) : currentDirectory())
.absoluteFilePath(args.at(0).toQString(m_tmp1)));
- ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
+ ret << (rstr.isSharedWith(m_tmp1)
+ ? args.at(0)
+ : args.count() > 1 && rstr.isSharedWith(m_tmp2)
+ ? args.at(1)
+ : ProString(rstr).setSource(args.at(0)));
}
break;
case E_RELATIVE_PATH:
@@ -1305,7 +1309,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnFalse;
case T_REQUIRES:
#ifdef PROEVALUATOR_FULL
- checkRequirements(args);
+ if (checkRequirements(args) == ReturnError)
+ return ReturnError;
#endif
return ReturnFalse; // Another qmake breakage
case T_EVAL: {
@@ -1327,8 +1332,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
evalError(fL1S("if(condition) requires one argument."));
return ReturnFalse;
}
- return returnBool(evaluateConditional(args.at(0).toQStringRef(),
- m_current.pro->fileName(), m_current.line));
+ return evaluateConditional(args.at(0).toQStringRef(),
+ m_current.pro->fileName(), m_current.line);
}
case T_CONFIG: {
if (args.count() < 1 || args.count() > 2) {
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index b0def45447..9d7ed2099b 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -405,7 +405,7 @@ static ALWAYS_INLINE void addStrList(
}
}
-void QMakeEvaluator::evaluateExpression(
+QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateExpression(
const ushort *&tokPtr, ProStringList *ret, bool joined)
{
debugMsg(2, joined ? "evaluating joined expression" : "evaluating expression");
@@ -455,12 +455,15 @@ void QMakeEvaluator::evaluateExpression(
case TokFuncName: {
const ProKey &func = pro->getHashStr(tokPtr);
debugMsg(2, "function %s", dbgKey(func));
- addStrList(evaluateExpandFunction(func, tokPtr), tok, ret, pending, joined);
+ ProStringList val;
+ if (evaluateExpandFunction(func, tokPtr, &val) == ReturnError)
+ return ReturnError;
+ addStrList(val, tok, ret, pending, joined);
break; }
default:
debugMsg(2, "evaluated expression => %s", dbgStrList(*ret));
tokPtr--;
- return;
+ return ReturnTrue;
}
}
}
@@ -532,7 +535,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
case TokAppendUnique:
case TokRemove:
case TokReplace:
- visitProVariable(tok, curr, tokPtr);
+ ret = visitProVariable(tok, curr, tokPtr);
+ if (ret == ReturnError)
+ break;
curr.clear();
continue;
case TokBranch:
@@ -692,9 +697,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
continue;
default: {
const ushort *oTokPtr = --tokPtr;
- evaluateExpression(tokPtr, &curr, false);
- if (tokPtr != oTokPtr)
- continue;
+ ret = evaluateExpression(tokPtr, &curr, false);
+ if (ret == ReturnError || tokPtr != oTokPtr)
+ break;
}
Q_ASSERT_X(false, "visitProBlock", "unexpected item type");
continue;
@@ -727,7 +732,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop(
int index = 0;
ProKey variable;
ProStringList oldVarVal;
- ProString it_list = expandVariableReferences(exprPtr, 0, true).at(0);
+ ProStringList it_list_out;
+ if (expandVariableReferences(exprPtr, 0, &it_list_out, true) == ReturnError)
+ return ReturnError;
+ ProString it_list = it_list_out.at(0);
if (_variable.isEmpty()) {
if (it_list != statics.strever) {
evalError(fL1S("Invalid loop expression."));
@@ -826,7 +834,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop(
return ret;
}
-void QMakeEvaluator::visitProVariable(
+QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable(
ushort tok, const ProStringList &curr, const ushort *&tokPtr)
{
int sizeHint = *tokPtr++;
@@ -835,24 +843,26 @@ void QMakeEvaluator::visitProVariable(
skipExpression(tokPtr);
if (!m_cumulative || !curr.isEmpty())
evalError(fL1S("Left hand side of assignment must expand to exactly one word."));
- return;
+ return ReturnTrue;
}
const ProKey &varName = map(curr.first());
if (tok == TokReplace) { // ~=
// DEFINES ~= s/a/b/?[gqi]
- const ProStringList &varVal = expandVariableReferences(tokPtr, sizeHint, true);
+ ProStringList varVal;
+ if (expandVariableReferences(tokPtr, sizeHint, &varVal, true) == ReturnError)
+ return ReturnError;
const QString &val = varVal.at(0).toQString(m_tmp1);
if (val.length() < 4 || val.at(0) != QLatin1Char('s')) {
evalError(fL1S("The ~= operator can handle only the s/// function."));
- return;
+ return ReturnTrue;
}
QChar sep = val.at(1);
QStringList func = val.split(sep);
if (func.count() < 3 || func.count() > 4) {
evalError(fL1S("The s/// function expects 3 or 4 arguments."));
- return;
+ return ReturnTrue;
}
bool global = false, quote = false, case_sense = false;
@@ -873,7 +883,9 @@ void QMakeEvaluator::visitProVariable(
replaceInList(&valuesRef(varName), regexp, replace, global, m_tmp2);
debugMsg(2, "replaced %s with %s", dbgQStr(pattern), dbgQStr(replace));
} else {
- ProStringList varVal = expandVariableReferences(tokPtr, sizeHint);
+ ProStringList varVal;
+ if (expandVariableReferences(tokPtr, sizeHint, &varVal, false) == ReturnError)
+ return ReturnError;
switch (tok) {
default: // whatever - cannot happen
case TokAssign: // =
@@ -919,8 +931,10 @@ void QMakeEvaluator::visitProVariable(
}
#ifdef PROEVALUATOR_FULL
else if (varName == statics.strREQUIRES)
- checkRequirements(values(varName));
+ return checkRequirements(values(varName));
#endif
+
+ return ReturnTrue;
}
void QMakeEvaluator::setTemplate()
@@ -1612,18 +1626,18 @@ bool QMakeEvaluator::isActiveConfig(const QStringRef &config, bool regex)
return false;
}
-ProStringList QMakeEvaluator::expandVariableReferences(
- const ushort *&tokPtr, int sizeHint, bool joined)
+QMakeEvaluator::VisitReturn QMakeEvaluator::expandVariableReferences(
+ const ushort *&tokPtr, int sizeHint, ProStringList *ret, bool joined)
{
- ProStringList ret;
- ret.reserve(sizeHint);
+ ret->reserve(sizeHint);
forever {
- evaluateExpression(tokPtr, &ret, joined);
+ if (evaluateExpression(tokPtr, ret, joined) == ReturnError)
+ return ReturnError;
switch (*tokPtr) {
case TokValueTerminator:
case TokFuncTerminator:
tokPtr++;
- return ret;
+ return ReturnTrue;
case TokArgSeparator:
if (joined) {
tokPtr++;
@@ -1637,28 +1651,28 @@ ProStringList QMakeEvaluator::expandVariableReferences(
}
}
-QList<ProStringList> QMakeEvaluator::prepareFunctionArgs(const ushort *&tokPtr)
+QMakeEvaluator::VisitReturn QMakeEvaluator::prepareFunctionArgs(
+ const ushort *&tokPtr, QList<ProStringList> *ret)
{
- QList<ProStringList> args_list;
if (*tokPtr != TokFuncTerminator) {
for (;; tokPtr++) {
ProStringList arg;
- evaluateExpression(tokPtr, &arg, false);
- args_list << arg;
+ if (evaluateExpression(tokPtr, &arg, false) == ReturnError)
+ return ReturnError;
+ *ret << arg;
if (*tokPtr == TokFuncTerminator)
break;
Q_ASSERT(*tokPtr == TokArgSeparator);
}
}
tokPtr++;
- return args_list;
+ return ReturnTrue;
}
-ProStringList QMakeEvaluator::evaluateFunction(
- const ProFunctionDef &func, const QList<ProStringList> &argumentsList, VisitReturn *ok)
+QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFunction(
+ const ProFunctionDef &func, const QList<ProStringList> &argumentsList, ProStringList *ret)
{
VisitReturn vr;
- ProStringList ret;
if (m_valuemapStack.count() >= 100) {
evalError(fL1S("Ran into infinite recursion (depth > 100)."));
@@ -1677,25 +1691,22 @@ ProStringList QMakeEvaluator::evaluateFunction(
vr = visitProBlock(func.pro(), func.tokPtr());
if (vr == ReturnReturn)
vr = ReturnTrue;
- ret = m_returnValue;
+ if (vr == ReturnTrue)
+ *ret = m_returnValue;
m_returnValue.clear();
m_current = m_locationStack.pop();
m_valuemapStack.pop();
}
- if (ok)
- *ok = vr;
- if (vr == ReturnTrue)
- return ret;
- return ProStringList();
+ return vr;
}
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBoolFunction(
const ProFunctionDef &func, const QList<ProStringList> &argumentsList,
const ProString &function)
{
- VisitReturn vr;
- ProStringList ret = evaluateFunction(func, argumentsList, &vr);
+ ProStringList ret;
+ VisitReturn vr = evaluateFunction(func, argumentsList, &ret);
if (vr == ReturnTrue) {
if (ret.isEmpty())
return ReturnTrue;
@@ -1723,13 +1734,18 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
{
if (int func_t = statics.functions.value(func)) {
//why don't the builtin functions just use args_list? --Sam
- return evaluateBuiltinConditional(func_t, func, expandVariableReferences(tokPtr, 5, true));
+ ProStringList args;
+ if (expandVariableReferences(tokPtr, 5, &args, true) == ReturnError)
+ return ReturnError;
+ return evaluateBuiltinConditional(func_t, func, args);
}
QHash<ProKey, ProFunctionDef>::ConstIterator it =
m_functionDefs.testFunctions.constFind(func);
if (it != m_functionDefs.testFunctions.constEnd()) {
- const QList<ProStringList> args = prepareFunctionArgs(tokPtr);
+ QList<ProStringList> args;
+ if (prepareFunctionArgs(tokPtr, &args) == ReturnError)
+ return ReturnError;
traceMsg("calling %s(%s)", dbgKey(func), dbgStrListList(args));
return evaluateBoolFunction(*it, args, func);
}
@@ -1739,34 +1755,41 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
return ReturnFalse;
}
-ProStringList QMakeEvaluator::evaluateExpandFunction(
- const ProKey &func, const ushort *&tokPtr)
+QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateExpandFunction(
+ const ProKey &func, const ushort *&tokPtr, ProStringList *ret)
{
if (int func_t = statics.expands.value(func)) {
//why don't the builtin functions just use args_list? --Sam
- return evaluateBuiltinExpand(func_t, func, expandVariableReferences(tokPtr, 5, true));
+ ProStringList args;
+ if (expandVariableReferences(tokPtr, 5, &args, true) == ReturnError)
+ return ReturnError;
+ *ret = evaluateBuiltinExpand(func_t, func, args);
+ return ReturnTrue;
}
QHash<ProKey, ProFunctionDef>::ConstIterator it =
m_functionDefs.replaceFunctions.constFind(func);
if (it != m_functionDefs.replaceFunctions.constEnd()) {
- const QList<ProStringList> args = prepareFunctionArgs(tokPtr);
+ QList<ProStringList> args;
+ if (prepareFunctionArgs(tokPtr, &args) == ReturnError)
+ return ReturnError;
traceMsg("calling $$%s(%s)", dbgKey(func), dbgStrListList(args));
- return evaluateFunction(*it, args, 0);
+ return evaluateFunction(*it, args, ret);
}
skipExpression(tokPtr);
evalError(fL1S("'%1' is not a recognized replace function.").arg(func.toQString(m_tmp1)));
- return ProStringList();
+ return ReturnFalse;
}
-bool QMakeEvaluator::evaluateConditional(const QStringRef &cond, const QString &where, int line)
+QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditional(
+ const QStringRef &cond, const QString &where, int line)
{
- bool ret = false;
+ VisitReturn ret = ReturnFalse;
ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar);
if (pro->isOk()) {
m_locationStack.push(m_current);
- ret = visitProBlock(pro, pro->tokPtr()) == ReturnTrue;
+ ret = visitProBlock(pro, pro->tokPtr());
m_current = m_locationStack.pop();
}
pro->deref();
@@ -1774,28 +1797,49 @@ bool QMakeEvaluator::evaluateConditional(const QStringRef &cond, const QString &
}
#ifdef PROEVALUATOR_FULL
-void QMakeEvaluator::checkRequirements(const ProStringList &deps)
+QMakeEvaluator::VisitReturn QMakeEvaluator::checkRequirements(const ProStringList &deps)
{
ProStringList &failed = valuesRef(ProKey("QMAKE_FAILED_REQUIREMENTS"));
- for (const ProString &dep : deps)
- if (!evaluateConditional(dep.toQStringRef(), m_current.pro->fileName(), m_current.line))
+ for (const ProString &dep : deps) {
+ VisitReturn vr = evaluateConditional(dep.toQStringRef(), m_current.pro->fileName(), m_current.line);
+ if (vr == ReturnError)
+ return ReturnError;
+ if (vr != ReturnTrue)
failed << dep;
+ }
+ return ReturnTrue;
}
#endif
+static bool isFunctParam(const ProKey &variableName)
+{
+ const int len = variableName.size();
+ const QChar *data = variableName.constData();
+ for (int i = 0; i < len; i++) {
+ ushort c = data[i].unicode();
+ if (c < '0' || c > '9')
+ return false;
+ }
+ return true;
+}
+
ProValueMap *QMakeEvaluator::findValues(const ProKey &variableName, ProValueMap::Iterator *rit)
{
ProValueMapStack::Iterator vmi = m_valuemapStack.end();
- do {
+ for (bool first = true; ; first = false) {
--vmi;
ProValueMap::Iterator it = (*vmi).find(variableName);
if (it != (*vmi).end()) {
if (it->constBegin() == statics.fakeValue.constBegin())
- return 0;
+ break;
*rit = it;
return &(*vmi);
}
- } while (vmi != m_valuemapStack.begin());
+ if (vmi == m_valuemapStack.begin())
+ break;
+ if (first && isFunctParam(variableName))
+ break;
+ }
return 0;
}
@@ -1807,18 +1851,20 @@ ProStringList &QMakeEvaluator::valuesRef(const ProKey &variableName)
it->clear();
return *it;
}
- ProValueMapStack::Iterator vmi = m_valuemapStack.end();
- if (--vmi != m_valuemapStack.begin()) {
- do {
- --vmi;
- ProValueMap::ConstIterator it = (*vmi).constFind(variableName);
- if (it != (*vmi).constEnd()) {
- ProStringList &ret = m_valuemapStack.top()[variableName];
- if (it->constBegin() != statics.fakeValue.constBegin())
- ret = *it;
- return ret;
- }
- } while (vmi != m_valuemapStack.begin());
+ if (!isFunctParam(variableName)) {
+ ProValueMapStack::Iterator vmi = m_valuemapStack.end();
+ if (--vmi != m_valuemapStack.begin()) {
+ do {
+ --vmi;
+ ProValueMap::ConstIterator it = (*vmi).constFind(variableName);
+ if (it != (*vmi).constEnd()) {
+ ProStringList &ret = m_valuemapStack.top()[variableName];
+ if (it->constBegin() != statics.fakeValue.constBegin())
+ ret = *it;
+ return ret;
+ }
+ } while (vmi != m_valuemapStack.begin());
+ }
}
return m_valuemapStack.top()[variableName];
}
@@ -1826,7 +1872,7 @@ ProStringList &QMakeEvaluator::valuesRef(const ProKey &variableName)
ProStringList QMakeEvaluator::values(const ProKey &variableName) const
{
ProValueMapStack::ConstIterator vmi = m_valuemapStack.constEnd();
- do {
+ for (bool first = true; ; first = false) {
--vmi;
ProValueMap::ConstIterator it = (*vmi).constFind(variableName);
if (it != (*vmi).constEnd()) {
@@ -1834,7 +1880,11 @@ ProStringList QMakeEvaluator::values(const ProKey &variableName) const
break;
return *it;
}
- } while (vmi != m_valuemapStack.constBegin());
+ if (vmi == m_valuemapStack.constBegin())
+ break;
+ if (first && isFunctParam(variableName))
+ break;
+ }
return ProStringList();
}
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
index ab13b24645..eddabe39a0 100644
--- a/qmake/library/qmakeevaluator.h
+++ b/qmake/library/qmakeevaluator.h
@@ -148,7 +148,7 @@ public:
{ return b ? ReturnTrue : ReturnFalse; }
static ALWAYS_INLINE uint getBlockLen(const ushort *&tokPtr);
- void evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined);
+ VisitReturn evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined);
static ALWAYS_INLINE void skipStr(const ushort *&tokPtr);
static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr);
void skipExpression(const ushort *&tokPtr);
@@ -168,7 +168,7 @@ public:
VisitReturn visitProLoop(const ProKey &variable, const ushort *exprPtr,
const ushort *tokPtr);
void visitProFunctionDef(ushort tok, const ProKey &name, const ushort *tokPtr);
- void visitProVariable(ushort tok, const ProStringList &curr, const ushort *&tokPtr);
+ VisitReturn visitProVariable(ushort tok, const ProStringList &curr, const ushort *&tokPtr);
ALWAYS_INLINE const ProKey &map(const ProString &var) { return map(var.toKey()); }
const ProKey &map(const ProKey &var);
@@ -177,8 +177,7 @@ public:
void setTemplate();
ProStringList split_value_list(const QStringRef &vals, const ProFile *source = 0);
- ProStringList expandVariableReferences(const ProString &value, int *pos = 0, bool joined = false);
- ProStringList expandVariableReferences(const ushort *&tokPtr, int sizeHint = 0, bool joined = false);
+ VisitReturn expandVariableReferences(const ushort *&tokPtr, int sizeHint, ProStringList *ret, bool joined);
QString currentFileName() const;
QString currentDirectory() const;
@@ -203,22 +202,22 @@ public:
void deprecationWarning(const QString &msg) const
{ message(QMakeHandler::EvalWarnDeprecated, msg); }
- QList<ProStringList> prepareFunctionArgs(const ushort *&tokPtr);
- ProStringList evaluateFunction(const ProFunctionDef &func,
- const QList<ProStringList> &argumentsList, VisitReturn *ok);
+ VisitReturn prepareFunctionArgs(const ushort *&tokPtr, QList<ProStringList> *ret);
+ VisitReturn evaluateFunction(const ProFunctionDef &func,
+ const QList<ProStringList> &argumentsList, ProStringList *ret);
VisitReturn evaluateBoolFunction(const ProFunctionDef &func,
const QList<ProStringList> &argumentsList,
const ProString &function);
- ProStringList evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr);
+ VisitReturn evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr, ProStringList *ret);
VisitReturn evaluateConditionalFunction(const ProKey &function, const ushort *&tokPtr);
ProStringList evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args);
VisitReturn evaluateBuiltinConditional(int func_t, const ProKey &function, const ProStringList &args);
- bool evaluateConditional(const QStringRef &cond, const QString &where, int line = -1);
+ VisitReturn evaluateConditional(const QStringRef &cond, const QString &where, int line = -1);
#ifdef PROEVALUATOR_FULL
- void checkRequirements(const ProStringList &deps);
+ VisitReturn checkRequirements(const ProStringList &deps);
#endif
void updateMkspecPaths();
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp
index 90bc64bd2b..7d645625a1 100644
--- a/qmake/library/qmakeparser.cpp
+++ b/qmake/library/qmakeparser.cpp
@@ -299,27 +299,30 @@ void QMakeParser::read(ProFile *pro, const QStringRef &in, int line, SubGrammar
// Worst-case size calculations:
// - line marker adds 1 (2-nl) to 1st token of each line
// - empty assignment "A=":2 =>
- // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) + 0(1) +
+ // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) + size_hint(1) +
// TokValueTerminator(1) == 8 (9)
// - non-empty assignment "A=B C":5 =>
- // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) + 2(1) +
+ // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) + size_hint(1) +
// TokLiteral(1) + len(1) + "B"(1) +
// TokLiteral(1) + len(1) + "C"(1) + TokValueTerminator(1) == 14 (15)
// - variable expansion: "$$f":3 =>
// TokVariable(1) + hash(2) + len(1) + "f"(1) = 5
// - function expansion: "$$f()":5 =>
// TokFuncName(1) + hash(2) + len(1) + "f"(1) + TokFuncTerminator(1) = 6
+ // - test literal: "X":1 =>
+ // TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokCondition(1) = 6 (7)
// - scope: "X:":2 =>
// TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokCondition(1) +
- // TokBranch(1) + len(2) + ... + len(2) + ... == 10
- // - test: "X():":4 =>
+ // TokBranch(1) + len(2) + ... + len(2) + ... == 11 (12)
+ // - test call: "X():":4 =>
// TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokTestCall(1) + TokFuncTerminator(1) +
- // TokBranch(1) + len(2) + ... + len(2) + ... == 11
+ // TokBranch(1) + len(2) + ... + len(2) + ... == 12 (13)
// - "for(A,B):":9 =>
// TokForLoop(1) + hash(2) + len(1) + "A"(1) +
// len(2) + TokLiteral(1) + len(1) + "B"(1) + TokValueTerminator(1) +
// len(2) + ... + TokTerminator(1) == 14 (15)
- tokBuff.reserve((in.size() + 1) * 5);
+ // One extra for possibly missing trailing newline.
+ tokBuff.reserve((in.size() + 1) * 7);
ushort *tokPtr = (ushort *)tokBuff.constData(); // Current writing position
// Expression precompiler buffer.
diff --git a/qmake/project.cpp b/qmake/project.cpp
index 28a6c72a46..2f8411d52f 100644
--- a/qmake/project.cpp
+++ b/qmake/project.cpp
@@ -105,9 +105,8 @@ QStringList QMakeProject::expand(const ProKey &func, const QList<ProStringList>
QHash<ProKey, ProFunctionDef>::ConstIterator it =
m_functionDefs.replaceFunctions.constFind(func);
if (it != m_functionDefs.replaceFunctions.constEnd()) {
- QMakeProject::VisitReturn vr;
- ProStringList ret = evaluateFunction(*it, args, &vr);
- if (vr == QMakeProject::ReturnError)
+ ProStringList ret;
+ if (evaluateFunction(*it, args, &ret) == QMakeProject::ReturnError)
exit(3);
return ret.toQStringList();
}
@@ -126,7 +125,9 @@ ProString QMakeProject::expand(const QString &expr, const QString &where, int li
m_current.pro = pro;
m_current.line = 0;
const ushort *tokPtr = pro->tokPtr();
- ProStringList result = expandVariableReferences(tokPtr, 1, true);
+ ProStringList result;
+ if (expandVariableReferences(tokPtr, 1, &result, true) == ReturnError)
+ exit(3);
if (!result.isEmpty())
ret = result.at(0);
}
diff --git a/qmake/project.h b/qmake/project.h
index 4986c7c82d..d7a5852bed 100644
--- a/qmake/project.h
+++ b/qmake/project.h
@@ -55,7 +55,7 @@ public:
ProString expand(const QString &v, const QString &file, int line);
QStringList expand(const ProKey &func, const QList<ProStringList> &args);
bool test(const QString &v, const QString &file, int line)
- { m_current.clear(); return evaluateConditional(QStringRef(&v), file, line); }
+ { m_current.clear(); return evaluateConditional(QStringRef(&v), file, line) == ReturnTrue; }
bool test(const ProKey &func, const QList<ProStringList> &args);
bool isSet(const ProKey &v) const { return m_valuemapStack.first().contains(v); }