From 849f1f9efda601bcfd3760256205a2014e0bc936 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 3 Sep 2012 20:57:59 +0200 Subject: [PATCH] don't allow overloading of built-in functions the functions are not versioned or scoped, so user-defined overloads would mess up qmake's own feature files. it seems safer to break user projects than to allow the user to break qmake. Change-Id: I020a2e6416bbb6e2fd2ece339629d848c00c8398 Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- qmake/library/qmakebuiltins.cpp | 14 ++------------ qmake/library/qmakeevaluator.cpp | 20 ++++++++++++++++---- qmake/library/qmakeevaluator.h | 4 ++-- qmake/project.cpp | 17 +++++++++++++++-- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index b2852657b0..5140ed57ef 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -398,13 +398,12 @@ void QMakeEvaluator::populateDeps( } ProStringList QMakeEvaluator::evaluateBuiltinExpand( - const ProKey &func, const ProStringList &args) + int func_t, const ProKey &func, const ProStringList &args) { ProStringList ret; traceMsg("calling built-in $$%s(%s)", dbgKey(func), dbgSepStrList(args)); - ExpandFunc func_t = ExpandFunc(statics.expands.value(func)); switch (func_t) { case E_BASENAME: case E_DIRNAME: @@ -1023,10 +1022,6 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0))); } break; - case E_INVALID: - evalError(fL1S("'%1' is not a recognized replace function.") - .arg(func.toQString(m_tmp1))); - break; default: evalError(fL1S("Function '%1' is not implemented.").arg(func.toQString(m_tmp1))); break; @@ -1036,11 +1031,10 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( - const ProKey &function, const ProStringList &args) + int func_t, const ProKey &function, const ProStringList &args) { traceMsg("calling built-in %s(%s)", dbgKey(function), dbgSepStrList(args)); - TestFunc func_t = (TestFunc)statics.functions.value(function); switch (func_t) { case T_DEFINED: { if (args.count() < 1 || args.count() > 2) { @@ -1634,10 +1628,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return writeFile(fL1S("cache "), fn, QIODevice::Append, varstr); } #endif - case T_INVALID: - evalError(fL1S("'%1' is not a recognized test function.") - .arg(function.toQString(m_tmp1))); - return ReturnFalse; 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 8bb4fddf19..8fad206f6a 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -1642,6 +1642,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBoolFunction( QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( const ProKey &func, const ushort *&tokPtr) { + 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)); + } + QHash::ConstIterator it = m_functionDefs.testFunctions.constFind(func); if (it != m_functionDefs.testFunctions.constEnd()) { @@ -1650,13 +1655,19 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction( return evaluateBoolFunction(*it, args, func); } - //why don't the builtin functions just use args_list? --Sam - return evaluateBuiltinConditional(func, expandVariableReferences(tokPtr, 5, true)); + skipExpression(tokPtr); + evalError(fL1S("'%1' is not a recognized test function.").arg(func.toQString(m_tmp1))); + return ReturnFalse; } ProStringList QMakeEvaluator::evaluateExpandFunction( const ProKey &func, const ushort *&tokPtr) { + 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)); + } + QHash::ConstIterator it = m_functionDefs.replaceFunctions.constFind(func); if (it != m_functionDefs.replaceFunctions.constEnd()) { @@ -1665,8 +1676,9 @@ ProStringList QMakeEvaluator::evaluateExpandFunction( return evaluateFunction(*it, args, 0); } - //why don't the builtin functions just use args_list? --Sam - return evaluateBuiltinExpand(func, expandVariableReferences(tokPtr, 5, true)); + skipExpression(tokPtr); + evalError(fL1S("'%1' is not a recognized replace function.").arg(func.toQString(m_tmp1))); + return ProStringList(); } bool QMakeEvaluator::evaluateConditional(const QString &cond, const QString &where, int line) diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 5904c08dbd..312b02c413 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -205,8 +205,8 @@ public: ProStringList evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr); VisitReturn evaluateConditionalFunction(const ProKey &function, const ushort *&tokPtr); - ProStringList evaluateBuiltinExpand(const ProKey &function, const ProStringList &args); - VisitReturn evaluateBuiltinConditional(const ProKey &function, const ProStringList &args); + 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 QString &cond, const QString &where, int line = -1); #ifdef PROEVALUATOR_FULL diff --git a/qmake/project.cpp b/qmake/project.cpp index e369ce1b42..478693f78b 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -42,11 +42,14 @@ #include "project.h" #include "option.h" +#include #include #include +using namespace QMakeInternal; + QT_BEGIN_NAMESPACE QMakeProject::QMakeProject() @@ -83,24 +86,34 @@ bool QMakeProject::test(const ProKey &func, const QList &args) { m_current.clear(); + if (int func_t = statics.functions.value(func)) + return evaluateBuiltinConditional(func_t, func, prepareBuiltinArgs(args)) == ReturnTrue; + QHash::ConstIterator it = m_functionDefs.testFunctions.constFind(func); if (it != m_functionDefs.testFunctions.constEnd()) return evaluateBoolFunction(*it, args, func) == ReturnTrue; - return evaluateBuiltinConditional(func, prepareBuiltinArgs(args)) == ReturnTrue; + evalError(QStringLiteral("'%1' is not a recognized test function.") + .arg(func.toQString(m_tmp1))); + return false; } QStringList QMakeProject::expand(const ProKey &func, const QList &args) { m_current.clear(); + if (int func_t = statics.expands.value(func)) + return evaluateBuiltinExpand(func_t, func, prepareBuiltinArgs(args)).toQStringList(); + QHash::ConstIterator it = m_functionDefs.replaceFunctions.constFind(func); if (it != m_functionDefs.replaceFunctions.constEnd()) return evaluateFunction(*it, args, 0).toQStringList(); - return evaluateBuiltinExpand(func, prepareBuiltinArgs(args)).toQStringList(); + evalError(QStringLiteral("'%1' is not a recognized replace function.") + .arg(func.toQString(m_tmp1))); + return QStringList(); } ProString QMakeProject::expand(const QString &expr, const QString &where, int line)