forked from qt-creator/qt-creator
optimize function scoping
previously, the entire value hash was simply pushed on a stack upon entering a custom function. the problem with that was that setting the function's argument already detached (i.e., copied) the entire hash. so instead store only actually modified values in nested scopes and let lookups cascade to parent scopes. improvement: 2% for qt, 15% for creator ...
This commit is contained in:
@@ -229,7 +229,10 @@ public:
|
|||||||
void visitProOperator(ProOperator *oper);
|
void visitProOperator(ProOperator *oper);
|
||||||
void visitProCondition(ProCondition *condition);
|
void visitProCondition(ProCondition *condition);
|
||||||
|
|
||||||
QStringList valuesDirect(const QString &variableName) const { return m_valuemap[variableName]; }
|
QHash<QString, QStringList> *findValues(const QString &variableName,
|
||||||
|
QHash<QString, QStringList>::Iterator *it);
|
||||||
|
QStringList &valuesRef(const QString &variableName);
|
||||||
|
QStringList valuesDirect(const QString &variableName) const;
|
||||||
QStringList values(const QString &variableName) const;
|
QStringList values(const QString &variableName) const;
|
||||||
QString propertyValue(const QString &val, bool complain = true) const;
|
QString propertyValue(const QString &val, bool complain = true) const;
|
||||||
|
|
||||||
@@ -286,8 +289,6 @@ public:
|
|||||||
};
|
};
|
||||||
QStack<ProLoop> m_loopStack;
|
QStack<ProLoop> m_loopStack;
|
||||||
|
|
||||||
QHash<QString, QStringList> m_valuemap; // VariableName must be us-ascii, the content however can be non-us-ascii.
|
|
||||||
QHash<const ProFile*, QHash<QString, QStringList> > m_filevaluemap; // Variables per include file
|
|
||||||
QString m_outputDir;
|
QString m_outputDir;
|
||||||
|
|
||||||
int m_listCount;
|
int m_listCount;
|
||||||
@@ -295,7 +296,8 @@ public:
|
|||||||
QString m_definingFunc;
|
QString m_definingFunc;
|
||||||
FunctionDefs m_functionDefs;
|
FunctionDefs m_functionDefs;
|
||||||
QStringList m_returnValue;
|
QStringList m_returnValue;
|
||||||
QStack<QHash<QString, QStringList> > m_valuemapStack;
|
QStack<QHash<QString, QStringList> > m_valuemapStack; // VariableName must be us-ascii, the content however can be non-us-ascii.
|
||||||
|
QHash<const ProFile*, QHash<QString, QStringList> > m_filevaluemap; // Variables per include file
|
||||||
|
|
||||||
QStringList m_addUserConfigCmdArgs;
|
QStringList m_addUserConfigCmdArgs;
|
||||||
QStringList m_removeUserConfigCmdArgs;
|
QStringList m_removeUserConfigCmdArgs;
|
||||||
@@ -361,6 +363,7 @@ static struct {
|
|||||||
QHash<QString, int> functions;
|
QHash<QString, int> functions;
|
||||||
QHash<QString, int> varList;
|
QHash<QString, int> varList;
|
||||||
QRegExp reg_variableName;
|
QRegExp reg_variableName;
|
||||||
|
QStringList fakeValue;
|
||||||
} statics;
|
} statics;
|
||||||
|
|
||||||
void ProFileEvaluator::Private::initStatics()
|
void ProFileEvaluator::Private::initStatics()
|
||||||
@@ -392,6 +395,8 @@ void ProFileEvaluator::Private::initStatics()
|
|||||||
statics.reg_variableName.setPattern(QLatin1String("\\$\\(.*\\)"));
|
statics.reg_variableName.setPattern(QLatin1String("\\$\\(.*\\)"));
|
||||||
statics.reg_variableName.setMinimal(true);
|
statics.reg_variableName.setMinimal(true);
|
||||||
|
|
||||||
|
statics.fakeValue.detach(); // It has to have a unique begin() value
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char * const name;
|
const char * const name;
|
||||||
const ExpandFunc func;
|
const ExpandFunc func;
|
||||||
@@ -495,6 +500,7 @@ ProFileEvaluator::Private::Private(ProFileEvaluator *q_, ProFileOption *option)
|
|||||||
m_skipLevel = 0;
|
m_skipLevel = 0;
|
||||||
m_definingFunc.clear();
|
m_definingFunc.clear();
|
||||||
m_listCount = 0;
|
m_listCount = 0;
|
||||||
|
m_valuemapStack.push(QHash<QString, QStringList>());
|
||||||
}
|
}
|
||||||
|
|
||||||
ProFileEvaluator::Private::~Private()
|
ProFileEvaluator::Private::~Private()
|
||||||
@@ -1077,7 +1083,7 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitProLoopIteration()
|
|||||||
|
|
||||||
if (loop.infinite) {
|
if (loop.infinite) {
|
||||||
if (!loop.variable.isEmpty())
|
if (!loop.variable.isEmpty())
|
||||||
m_valuemap[loop.variable] = QStringList(QString::number(loop.index++));
|
m_valuemapStack.top()[loop.variable] = QStringList(QString::number(loop.index++));
|
||||||
if (loop.index > 1000) {
|
if (loop.index > 1000) {
|
||||||
errorMessage(format("ran into infinite loop (> 1000 iterations)."));
|
errorMessage(format("ran into infinite loop (> 1000 iterations)."));
|
||||||
return ProItem::ReturnFalse;
|
return ProItem::ReturnFalse;
|
||||||
@@ -1089,7 +1095,7 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitProLoopIteration()
|
|||||||
return ProItem::ReturnFalse;
|
return ProItem::ReturnFalse;
|
||||||
val = loop.list.at(loop.index++);
|
val = loop.list.at(loop.index++);
|
||||||
} while (val.isEmpty()); // stupid, but qmake is like that
|
} while (val.isEmpty()); // stupid, but qmake is like that
|
||||||
m_valuemap[loop.variable] = QStringList(val);
|
m_valuemapStack.top()[loop.variable] = QStringList(val);
|
||||||
}
|
}
|
||||||
return ProItem::ReturnTrue;
|
return ProItem::ReturnTrue;
|
||||||
}
|
}
|
||||||
@@ -1097,7 +1103,7 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitProLoopIteration()
|
|||||||
void ProFileEvaluator::Private::visitProLoopCleanup()
|
void ProFileEvaluator::Private::visitProLoopCleanup()
|
||||||
{
|
{
|
||||||
ProLoop &loop = m_loopStack.top();
|
ProLoop &loop = m_loopStack.top();
|
||||||
m_valuemap[loop.variable] = loop.oldVarVal;
|
m_valuemapStack.top()[loop.variable] = loop.oldVarVal;
|
||||||
m_loopStack.pop_back();
|
m_loopStack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1138,7 +1144,7 @@ void ProFileEvaluator::Private::visitProVariable(ProVariable *var)
|
|||||||
if (!m_skipLevel || m_cumulative) {
|
if (!m_skipLevel || m_cumulative) {
|
||||||
// We could make a union of modified and unmodified values,
|
// We could make a union of modified and unmodified values,
|
||||||
// but this will break just as much as it fixes, so leave it as is.
|
// but this will break just as much as it fixes, so leave it as is.
|
||||||
replaceInList(&m_valuemap[varName], regexp, replace, global);
|
replaceInList(&valuesRef(varName), regexp, replace, global);
|
||||||
replaceInList(&m_filevaluemap[currentProFile()][varName], regexp, replace, global);
|
replaceInList(&m_filevaluemap[currentProFile()][varName], regexp, replace, global);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1150,31 +1156,31 @@ void ProFileEvaluator::Private::visitProVariable(ProVariable *var)
|
|||||||
case ProVariable::SetOperator: // =
|
case ProVariable::SetOperator: // =
|
||||||
if (!m_cumulative) {
|
if (!m_cumulative) {
|
||||||
if (!m_skipLevel) {
|
if (!m_skipLevel) {
|
||||||
m_valuemap[varName] = varVal;
|
m_valuemapStack.top()[varName] = varVal;
|
||||||
m_filevaluemap[currentProFile()][varName] = varVal;
|
m_filevaluemap[currentProFile()][varName] = varVal;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We are greedy for values.
|
// We are greedy for values.
|
||||||
m_valuemap[varName] += varVal;
|
valuesRef(varName) += varVal;
|
||||||
m_filevaluemap[currentProFile()][varName] += varVal;
|
m_filevaluemap[currentProFile()][varName] += varVal;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProVariable::UniqueAddOperator: // *=
|
case ProVariable::UniqueAddOperator: // *=
|
||||||
if (!m_skipLevel || m_cumulative) {
|
if (!m_skipLevel || m_cumulative) {
|
||||||
insertUnique(&m_valuemap[varName], varVal);
|
insertUnique(&valuesRef(varName), varVal);
|
||||||
insertUnique(&m_filevaluemap[currentProFile()][varName], varVal);
|
insertUnique(&m_filevaluemap[currentProFile()][varName], varVal);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProVariable::AddOperator: // +=
|
case ProVariable::AddOperator: // +=
|
||||||
if (!m_skipLevel || m_cumulative) {
|
if (!m_skipLevel || m_cumulative) {
|
||||||
m_valuemap[varName] += varVal;
|
valuesRef(varName) += varVal;
|
||||||
m_filevaluemap[currentProFile()][varName] += varVal;
|
m_filevaluemap[currentProFile()][varName] += varVal;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProVariable::RemoveOperator: // -=
|
case ProVariable::RemoveOperator: // -=
|
||||||
if (!m_cumulative) {
|
if (!m_cumulative) {
|
||||||
if (!m_skipLevel) {
|
if (!m_skipLevel) {
|
||||||
removeEach(&m_valuemap[varName], varVal);
|
removeEach(&valuesRef(varName), varVal);
|
||||||
removeEach(&m_filevaluemap[currentProFile()][varName], varVal);
|
removeEach(&m_filevaluemap[currentProFile()][varName], varVal);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1307,18 +1313,18 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitProFile(ProFile *pro)
|
|||||||
&m_option->base_valuemap, &m_option->base_functions);
|
&m_option->base_valuemap, &m_option->base_functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_valuemap = m_option->base_valuemap;
|
m_valuemapStack.top() = m_option->base_valuemap;
|
||||||
|
|
||||||
clearFunctions(&m_functionDefs);
|
clearFunctions(&m_functionDefs);
|
||||||
m_functionDefs = m_option->base_functions;
|
m_functionDefs = m_option->base_functions;
|
||||||
refFunctions(&m_functionDefs.testFunctions);
|
refFunctions(&m_functionDefs.testFunctions);
|
||||||
refFunctions(&m_functionDefs.replaceFunctions);
|
refFunctions(&m_functionDefs.replaceFunctions);
|
||||||
|
|
||||||
QStringList &tgt = m_valuemap[QLatin1String("TARGET")];
|
QStringList &tgt = m_valuemapStack.top()[QLatin1String("TARGET")];
|
||||||
if (tgt.isEmpty())
|
if (tgt.isEmpty())
|
||||||
tgt.append(QFileInfo(pro->fileName()).baseName());
|
tgt.append(QFileInfo(pro->fileName()).baseName());
|
||||||
|
|
||||||
QStringList &tmp = m_valuemap[QLatin1String("CONFIG")];
|
QStringList &tmp = m_valuemapStack.top()[QLatin1String("CONFIG")];
|
||||||
tmp.append(m_addUserConfigCmdArgs);
|
tmp.append(m_addUserConfigCmdArgs);
|
||||||
foreach (const QString &remove, m_removeUserConfigCmdArgs)
|
foreach (const QString &remove, m_removeUserConfigCmdArgs)
|
||||||
tmp.removeAll(remove);
|
tmp.removeAll(remove);
|
||||||
@@ -1817,7 +1823,7 @@ bool ProFileEvaluator::Private::isActiveConfig(const QString &config, bool regex
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// CONFIG variable
|
// CONFIG variable
|
||||||
foreach (const QString &configValue, m_valuemap.value(statics.strCONFIG)) {
|
foreach (const QString &configValue, valuesDirect(statics.strCONFIG)) {
|
||||||
if (re.exactMatch(configValue))
|
if (re.exactMatch(configValue))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1827,7 +1833,7 @@ bool ProFileEvaluator::Private::isActiveConfig(const QString &config, bool regex
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// CONFIG variable
|
// CONFIG variable
|
||||||
foreach (const QString &configValue, m_valuemap.value(statics.strCONFIG)) {
|
foreach (const QString &configValue, valuesDirect(statics.strCONFIG)) {
|
||||||
if (configValue == config)
|
if (configValue == config)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1855,19 +1861,19 @@ QStringList ProFileEvaluator::Private::evaluateFunction(
|
|||||||
oki = false;
|
oki = false;
|
||||||
} else {
|
} else {
|
||||||
State sts = m_sts;
|
State sts = m_sts;
|
||||||
m_valuemapStack.push(m_valuemap);
|
m_valuemapStack.push(QHash<QString, QStringList>());
|
||||||
|
|
||||||
QStringList args;
|
QStringList args;
|
||||||
for (int i = 0; i < argumentsList.count(); ++i) {
|
for (int i = 0; i < argumentsList.count(); ++i) {
|
||||||
args += argumentsList[i];
|
args += argumentsList[i];
|
||||||
m_valuemap[QString::number(i+1)] = argumentsList[i];
|
m_valuemapStack.top()[QString::number(i+1)] = argumentsList[i];
|
||||||
}
|
}
|
||||||
m_valuemap[statics.strARGS] = args;
|
m_valuemapStack.top()[statics.strARGS] = args;
|
||||||
oki = (visitProBlock(funcPtr) != ProItem::ReturnFalse); // True || Return
|
oki = (visitProBlock(funcPtr) != ProItem::ReturnFalse); // True || Return
|
||||||
ret = m_returnValue;
|
ret = m_returnValue;
|
||||||
m_returnValue.clear();
|
m_returnValue.clear();
|
||||||
|
|
||||||
m_valuemap = m_valuemapStack.pop();
|
m_valuemapStack.pop();
|
||||||
m_sts = sts;
|
m_sts = sts;
|
||||||
}
|
}
|
||||||
if (ok)
|
if (ok)
|
||||||
@@ -2080,7 +2086,7 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
|
|||||||
QStringList lst;
|
QStringList lst;
|
||||||
foreach (const QString &arg, args)
|
foreach (const QString &arg, args)
|
||||||
lst += split_value_list(arg);
|
lst += split_value_list(arg);
|
||||||
m_valuemap[tmp] = lst;
|
m_valuemapStack.top()[tmp] = lst;
|
||||||
break; }
|
break; }
|
||||||
case E_FIND:
|
case E_FIND:
|
||||||
if (args.count() != 2) {
|
if (args.count() != 2) {
|
||||||
@@ -2323,8 +2329,21 @@ ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
logMessage(format("export(variable) requires one argument."));
|
logMessage(format("export(variable) requires one argument."));
|
||||||
return ProItem::ReturnFalse;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < m_valuemapStack.size(); ++i)
|
for (int i = m_valuemapStack.size(); --i > 0; ) {
|
||||||
m_valuemapStack[i][args[0]] = m_valuemap.value(args[0]);
|
QHash<QString, QStringList>::Iterator it = m_valuemapStack[i].find(args.at(0));
|
||||||
|
if (it != m_valuemapStack.at(i).end()) {
|
||||||
|
if (it->constBegin() == statics.fakeValue.constBegin()) {
|
||||||
|
// This is stupid, but qmake doesn't propagate deletions
|
||||||
|
m_valuemapStack[0][args.at(0)] = QStringList();
|
||||||
|
} else {
|
||||||
|
m_valuemapStack[0][args.at(0)] = *it;
|
||||||
|
}
|
||||||
|
m_valuemapStack[i].erase(it);
|
||||||
|
while (--i)
|
||||||
|
m_valuemapStack[i].remove(args.at(0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return ProItem::ReturnTrue;
|
return ProItem::ReturnTrue;
|
||||||
case T_INFILE:
|
case T_INFILE:
|
||||||
if (args.count() < 2 || args.count() > 3) {
|
if (args.count() < 2 || args.count() > 3) {
|
||||||
@@ -2383,11 +2402,11 @@ ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
it_list = statics.strforever;
|
it_list = statics.strforever;
|
||||||
} else {
|
} else {
|
||||||
loop.variable = args[0];
|
loop.variable = args[0];
|
||||||
loop.oldVarVal = m_valuemap.value(loop.variable);
|
loop.oldVarVal = valuesDirect(loop.variable);
|
||||||
doVariableReplace(&args[1]);
|
doVariableReplace(&args[1]);
|
||||||
it_list = args[1];
|
it_list = args[1];
|
||||||
}
|
}
|
||||||
loop.list = m_valuemap.value(it_list);
|
loop.list = valuesDirect(it_list);
|
||||||
if (loop.list.isEmpty()) {
|
if (loop.list.isEmpty()) {
|
||||||
if (it_list == statics.strforever) {
|
if (it_list == statics.strforever) {
|
||||||
loop.infinite = true;
|
loop.infinite = true;
|
||||||
@@ -2621,10 +2640,14 @@ ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
logMessage(format("%1(variable) requires one argument.").arg(function));
|
logMessage(format("%1(variable) requires one argument.").arg(function));
|
||||||
return ProItem::ReturnFalse;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
QHash<QString, QStringList>::Iterator it = m_valuemap.find(args[0]);
|
QHash<QString, QStringList> *hsh;
|
||||||
if (it == m_valuemap.end())
|
QHash<QString, QStringList>::Iterator it;
|
||||||
|
if (!(hsh = findValues(args.at(0), &it)))
|
||||||
return ProItem::ReturnFalse;
|
return ProItem::ReturnFalse;
|
||||||
|
if (hsh == &m_valuemapStack.top())
|
||||||
it->clear();
|
it->clear();
|
||||||
|
else
|
||||||
|
m_valuemapStack.top()[args.at(0)].clear();
|
||||||
return ProItem::ReturnTrue;
|
return ProItem::ReturnTrue;
|
||||||
}
|
}
|
||||||
case T_UNSET: {
|
case T_UNSET: {
|
||||||
@@ -2634,10 +2657,16 @@ ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
logMessage(format("%1(variable) requires one argument.").arg(function));
|
logMessage(format("%1(variable) requires one argument.").arg(function));
|
||||||
return ProItem::ReturnFalse;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
QHash<QString, QStringList>::Iterator it = m_valuemap.find(args[0]);
|
QHash<QString, QStringList> *hsh;
|
||||||
if (it == m_valuemap.end())
|
QHash<QString, QStringList>::Iterator it;
|
||||||
|
if (!(hsh = findValues(args.at(0), &it)))
|
||||||
return ProItem::ReturnFalse;
|
return ProItem::ReturnFalse;
|
||||||
m_valuemap.erase(it);
|
if (m_valuemapStack.size() == 1)
|
||||||
|
hsh->erase(it);
|
||||||
|
else if (hsh == &m_valuemapStack.top())
|
||||||
|
*it = statics.fakeValue;
|
||||||
|
else
|
||||||
|
m_valuemapStack.top()[args.at(0)] = statics.fakeValue;
|
||||||
return ProItem::ReturnTrue;
|
return ProItem::ReturnTrue;
|
||||||
}
|
}
|
||||||
case T_INCLUDE: {
|
case T_INCLUDE: {
|
||||||
@@ -2744,6 +2773,50 @@ ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QHash<QString, QStringList> *ProFileEvaluator::Private::findValues(
|
||||||
|
const QString &variableName, QHash<QString, QStringList>::Iterator *rit)
|
||||||
|
{
|
||||||
|
for (int i = m_valuemapStack.size(); --i >= 0; ) {
|
||||||
|
QHash<QString, QStringList>::Iterator it = m_valuemapStack[i].find(variableName);
|
||||||
|
if (it != m_valuemapStack[i].end()) {
|
||||||
|
if (it->constBegin() == statics.fakeValue.constBegin())
|
||||||
|
return 0;
|
||||||
|
*rit = it;
|
||||||
|
return &m_valuemapStack[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList &ProFileEvaluator::Private::valuesRef(const QString &variableName)
|
||||||
|
{
|
||||||
|
QHash<QString, QStringList>::Iterator it = m_valuemapStack.top().find(variableName);
|
||||||
|
if (it != m_valuemapStack.top().end())
|
||||||
|
return *it;
|
||||||
|
for (int i = m_valuemapStack.size() - 1; --i >= 0; ) {
|
||||||
|
QHash<QString, QStringList>::ConstIterator it = m_valuemapStack.at(i).constFind(variableName);
|
||||||
|
if (it != m_valuemapStack.at(i).constEnd()) {
|
||||||
|
QStringList &ret = m_valuemapStack.top()[variableName];
|
||||||
|
ret = *it;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m_valuemapStack.top()[variableName];
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList ProFileEvaluator::Private::valuesDirect(const QString &variableName) const
|
||||||
|
{
|
||||||
|
for (int i = m_valuemapStack.size(); --i >= 0; ) {
|
||||||
|
QHash<QString, QStringList>::ConstIterator it = m_valuemapStack.at(i).constFind(variableName);
|
||||||
|
if (it != m_valuemapStack.at(i).constEnd()) {
|
||||||
|
if (it->constBegin() == statics.fakeValue.constBegin())
|
||||||
|
break;
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
|
||||||
QStringList ProFileEvaluator::Private::values(const QString &variableName) const
|
QStringList ProFileEvaluator::Private::values(const QString &variableName) const
|
||||||
{
|
{
|
||||||
QHash<QString, int>::ConstIterator vli = statics.varList.find(variableName);
|
QHash<QString, int>::ConstIterator vli = statics.varList.find(variableName);
|
||||||
@@ -2934,7 +3007,7 @@ bool ProFileEvaluator::Private::evaluateFeatureFile(
|
|||||||
|
|
||||||
cool:
|
cool:
|
||||||
// It's beyond me why qmake has this inside this if ...
|
// It's beyond me why qmake has this inside this if ...
|
||||||
QStringList &already = m_valuemap[QLatin1String("QMAKE_INTERNAL_INCLUDED_FEATURES")];
|
QStringList &already = valuesRef(QLatin1String("QMAKE_INTERNAL_INCLUDED_FEATURES"));
|
||||||
if (already.contains(fn))
|
if (already.contains(fn))
|
||||||
return true;
|
return true;
|
||||||
already.append(fn);
|
already.append(fn);
|
||||||
@@ -2968,12 +3041,12 @@ bool ProFileEvaluator::Private::evaluateFileInto(
|
|||||||
visitor.d->m_cumulative = false;
|
visitor.d->m_cumulative = false;
|
||||||
visitor.d->m_parsePreAndPostFiles = false;
|
visitor.d->m_parsePreAndPostFiles = false;
|
||||||
visitor.d->m_verbose = m_verbose;
|
visitor.d->m_verbose = m_verbose;
|
||||||
visitor.d->m_valuemap = *values;
|
visitor.d->m_valuemapStack.top() = *values;
|
||||||
if (funcs)
|
if (funcs)
|
||||||
visitor.d->m_functionDefs = *funcs;
|
visitor.d->m_functionDefs = *funcs;
|
||||||
if (!visitor.d->evaluateFile(fileName))
|
if (!visitor.d->evaluateFile(fileName))
|
||||||
return false;
|
return false;
|
||||||
*values = visitor.d->m_valuemap;
|
*values = visitor.d->m_valuemapStack.top();
|
||||||
if (funcs) {
|
if (funcs) {
|
||||||
*funcs = visitor.d->m_functionDefs;
|
*funcs = visitor.d->m_functionDefs;
|
||||||
// So they are not unref'd
|
// So they are not unref'd
|
||||||
@@ -3033,7 +3106,7 @@ ProFileEvaluator::~ProFileEvaluator()
|
|||||||
|
|
||||||
bool ProFileEvaluator::contains(const QString &variableName) const
|
bool ProFileEvaluator::contains(const QString &variableName) const
|
||||||
{
|
{
|
||||||
return d->m_valuemap.contains(variableName);
|
return d->m_valuemapStack.top().contains(variableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList ProFileEvaluator::values(const QString &variableName) const
|
QStringList ProFileEvaluator::values(const QString &variableName) const
|
||||||
|
|||||||
Reference in New Issue
Block a user