summaryrefslogtreecommitdiffstats
path: root/qmake/library
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-12-16 15:21:35 +0100
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2016-12-16 16:38:33 +0100
commitb13150336174083962d90922761fd96f07e173b4 (patch)
tree1655e9009efba21b008d7d2f810aacbde3e2c2d8 /qmake/library
parentff19ebcc2d9c9668af24fe8add9f70c160776367 (diff)
parent9bfe3ab71e5291445e66be96d6cd1f63934a2d83 (diff)
Merge remote-tracking branch 'origin/5.8' into dev
Conflicts: configure configure.pri examples/widgets/painting/fontsampler/mainwindow.cpp examples/widgets/painting/fontsampler/mainwindow.h mkspecs/features/moc.prf src/corelib/global/qglobal.h src/gui/text/qtextdocument.cpp Change-Id: Ica65512e00871695190a14ccea5c275b0165f787
Diffstat (limited to 'qmake/library')
-rw-r--r--qmake/library/proitems.h3
-rw-r--r--qmake/library/qmakebuiltins.cpp21
-rw-r--r--qmake/library/qmakeevaluator.cpp21
-rw-r--r--qmake/library/qmakeevaluator.h2
-rw-r--r--qmake/library/qmakeglobals.h1
-rw-r--r--qmake/library/qmakeparser.cpp26
6 files changed, 64 insertions, 10 deletions
diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h
index 05d9e8da28..c81e205699 100644
--- a/qmake/library/proitems.h
+++ b/qmake/library/proitems.h
@@ -329,6 +329,9 @@ enum ProToken {
// - function name: hash (2), length (1), chars (length)
// - body length (2)
// - body + TokTerminator (body length)
+ TokBypassNesting, // escape from function local variable scopes:
+ // - block length (2)
+ // - block + TokTerminator (block length)
TokMask = 0xff,
TokQuoted = 0x100, // The expression is quoted => join expanded stringlist
TokNewStr = 0x200 // Next stringlist element
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index 02c910fe46..b30373b596 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -101,7 +101,7 @@ enum TestFunc {
T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
T_DEFINED, T_DISCARD_FROM, T_CONTAINS, T_INFILE,
T_COUNT, T_ISEMPTY, T_PARSE_JSON, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF,
- T_MKPATH, T_WRITE_FILE, T_TOUCH, T_CACHE
+ T_MKPATH, T_WRITE_FILE, T_TOUCH, T_CACHE, T_RELOAD_PROPERTIES
};
void QMakeEvaluator::initFunctionStatics()
@@ -200,6 +200,7 @@ void QMakeEvaluator::initFunctionStatics()
{ "write_file", T_WRITE_FILE },
{ "touch", T_TOUCH },
{ "cache", T_CACHE },
+ { "reload_properties", T_RELOAD_PROPERTIES },
};
statics.functions.reserve((int)(sizeof(testInits)/sizeof(testInits[0])));
for (unsigned i = 0; i < sizeof(testInits)/sizeof(testInits[0]); ++i)
@@ -560,11 +561,9 @@ void QMakeEvaluator::populateDeps(
}
}
-ProStringList QMakeEvaluator::evaluateBuiltinExpand(
- int func_t, const ProKey &func, const ProStringList &args)
+QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
+ int func_t, const ProKey &func, const ProStringList &args, ProStringList &ret)
{
- ProStringList ret;
-
traceMsg("calling built-in $$%s(%s)", dbgKey(func), dbgSepStrList(args));
switch (func_t) {
@@ -1110,6 +1109,11 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
if (qfile.open(stdin, QIODevice::ReadOnly)) {
QTextStream t(&qfile);
const QString &line = t.readLine();
+ if (t.atEnd()) {
+ fputs("\n", stderr);
+ evalError(fL1S("Unexpected EOF."));
+ return ReturnError;
+ }
ret = split_value_list(QStringRef(&line));
}
}
@@ -1279,7 +1283,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
break;
}
- return ret;
+ return ReturnTrue;
}
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
@@ -2012,6 +2016,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
return writeFile(fL1S("cache "), fn, QIODevice::Append, false, varstr);
}
+ case T_RELOAD_PROPERTIES:
+#ifdef QT_BUILD_QMAKE
+ m_option->reloadProperties();
+#endif
+ return ReturnTrue;
default:
evalError(fL1S("Function '%1' is not implemented.").arg(function.toQString(m_tmp1)));
return ReturnFalse;
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index fd24cf209d..767528eb57 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -594,6 +594,24 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
tokPtr += blockLen;
okey = true, or_op = false; // force next evaluation
break;
+ case TokBypassNesting:
+ blockLen = getBlockLen(tokPtr);
+ if ((m_cumulative || okey != or_op) && blockLen) {
+ ProValueMapStack savedValuemapStack = m_valuemapStack;
+ m_valuemapStack.clear();
+ m_valuemapStack.append(savedValuemapStack.takeFirst());
+ traceMsg("visiting nesting-bypassing block");
+ ret = visitProBlock(tokPtr);
+ traceMsg("visited nesting-bypassing block");
+ savedValuemapStack.prepend(m_valuemapStack.first());
+ m_valuemapStack = savedValuemapStack;
+ } else {
+ traceMsg("skipped nesting-bypassing block");
+ ret = ReturnTrue;
+ }
+ tokPtr += blockLen;
+ okey = true, or_op = false; // force next evaluation
+ break;
case TokTestDef:
case TokReplaceDef:
if (m_cumulative || okey != or_op) {
@@ -1761,8 +1779,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateExpandFunction(
ProStringList args;
if (expandVariableReferences(tokPtr, 5, &args, true) == ReturnError)
return ReturnError;
- *ret = evaluateBuiltinExpand(func_t, func, args);
- return ReturnTrue;
+ return evaluateBuiltinExpand(func_t, func, args, *ret);
}
QHash<ProKey, ProFunctionDef>::ConstIterator it =
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
index 3f2a22c567..544c257f07 100644
--- a/qmake/library/qmakeevaluator.h
+++ b/qmake/library/qmakeevaluator.h
@@ -212,7 +212,7 @@ public:
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 evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args, ProStringList &ret);
VisitReturn evaluateBuiltinConditional(int func_t, const ProKey &function, const ProStringList &args);
VisitReturn evaluateConditional(const QStringRef &cond, const QString &where, int line = -1);
diff --git a/qmake/library/qmakeglobals.h b/qmake/library/qmakeglobals.h
index 96c39fa168..1bb8632883 100644
--- a/qmake/library/qmakeglobals.h
+++ b/qmake/library/qmakeglobals.h
@@ -125,6 +125,7 @@ public:
void setDirectories(const QString &input_dir, const QString &output_dir);
#ifdef QT_BUILD_QMAKE
void setQMakeProperty(QMakeProperty *prop) { property = prop; }
+ void reloadProperties() { property->reload(); }
ProString propertyValue(const ProKey &name) const { return property->value(name); }
#else
# ifdef PROEVALUATOR_INIT_PROPS
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp
index 56b217dfbb..78350c76c4 100644
--- a/qmake/library/qmakeparser.cpp
+++ b/qmake/library/qmakeparser.cpp
@@ -118,6 +118,7 @@ static struct {
QString strfor;
QString strdefineTest;
QString strdefineReplace;
+ QString strbypassNesting;
QString stroption;
QString strreturn;
QString strnext;
@@ -141,6 +142,7 @@ void QMakeParser::initialize()
statics.strfor = QLatin1String("for");
statics.strdefineTest = QLatin1String("defineTest");
statics.strdefineReplace = QLatin1String("defineReplace");
+ statics.strbypassNesting = QLatin1String("bypassNesting");
statics.stroption = QLatin1String("option");
statics.strreturn = QLatin1String("return");
statics.strnext = QLatin1String("next");
@@ -1157,6 +1159,25 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
}
parseError(fL1S("%1(function) requires one literal argument.").arg(*defName));
return;
+ } else if (m_tmp == statics.strbypassNesting) {
+ if (*uce != TokFuncTerminator) {
+ bogusTest(tokPtr, fL1S("%1() requires zero arguments.").arg(m_tmp));
+ return;
+ }
+ if (!(m_blockstack.top().nest & NestFunction)) {
+ bogusTest(tokPtr, fL1S("Unexpected %1().").arg(m_tmp));
+ return;
+ }
+ if (m_invert) {
+ bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp));
+ return;
+ }
+ flushScopes(tokPtr);
+ putLineMarker(tokPtr);
+ putOperator(tokPtr);
+ putTok(tokPtr, TokBypassNesting);
+ enterScope(tokPtr, true, StCtrl);
+ return;
} else if (m_tmp == statics.strreturn) {
if (m_blockstack.top().nest & NestFunction) {
if (argc > 1) {
@@ -1425,7 +1446,7 @@ static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outS
"TokReturn", "TokBreak", "TokNext",
"TokNot", "TokAnd", "TokOr",
"TokBranch", "TokForLoop",
- "TokTestDef", "TokReplaceDef"
+ "TokTestDef", "TokReplaceDef", "TokBypassNesting"
};
while (offset != limit) {
@@ -1509,6 +1530,9 @@ static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outS
if (ok)
ok = getSubBlock(tokens, limit, offset, outStr, indent, "body");
break;
+ case TokBypassNesting:
+ ok = getSubBlock(tokens, limit, offset, outStr, indent, "block");
+ break;
default:
Q_ASSERT(!"unhandled token");
}