// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "project.h" #include "cachekeys.h" #include "option.h" #include #include #include using namespace QMakeInternal; QT_BEGIN_NAMESPACE QMakeProject::QMakeProject() : QMakeEvaluator(Option::globals, Option::parser, Option::vfs, &Option::evalHandler) { } QMakeProject::QMakeProject(QMakeProject *p) : QMakeEvaluator(Option::globals, Option::parser, Option::vfs, &Option::evalHandler) { initFrom(p); } bool QMakeProject::boolRet(VisitReturn vr) { if (vr == ReturnError) { qmakeClearCaches(); exit(3); } Q_ASSERT(vr == ReturnTrue || vr == ReturnFalse); return vr != ReturnFalse; } bool QMakeProject::read(const QString &project, LoadFlags what) { m_projectFile = project; setOutputDir(Option::output_dir); QString absproj = (project == QLatin1String("-")) ? QLatin1String("(stdin)") : QDir::cleanPath(QDir(qmake_getpwd()).absoluteFilePath(project)); m_projectDir = QFileInfo(absproj).path(); return boolRet(evaluateFile(absproj, QMakeHandler::EvalProjectFile, what)); } static ProStringList prepareBuiltinArgs(const QList &args) { ProStringList ret; ret.reserve(args.size()); for (const ProStringList &arg : args) ret << arg.join(' '); return ret; } bool QMakeProject::test(const ProKey &func, const QList &args) { m_current.clear(); auto adef = statics.functions.constFind(func); if (adef != statics.functions.constEnd()) return boolRet(evaluateBuiltinConditional(*adef, func, prepareBuiltinArgs(args))); QHash::ConstIterator it = m_functionDefs.testFunctions.constFind(func); if (it != m_functionDefs.testFunctions.constEnd()) return boolRet(evaluateBoolFunction(*it, args, func)); evalError(QStringLiteral("'%1' is not a recognized test function.") .arg(func.toQStringView())); return false; } QStringList QMakeProject::expand(const ProKey &func, const QList &args) { m_current.clear(); auto adef = statics.expands.constFind(func); if (adef != statics.expands.constEnd()) { ProStringList ret; if (evaluateBuiltinExpand(*adef, func, prepareBuiltinArgs(args), ret) == ReturnError) exit(3); return ret.toQStringList(); } QHash::ConstIterator it = m_functionDefs.replaceFunctions.constFind(func); if (it != m_functionDefs.replaceFunctions.constEnd()) { ProStringList ret; if (evaluateFunction(*it, args, &ret) == QMakeProject::ReturnError) exit(3); return ret.toQStringList(); } evalError(QStringLiteral("'%1' is not a recognized replace function.") .arg(func.toQStringView())); return QStringList(); } ProString QMakeProject::expand(const QString &expr, const QString &where, int line) { ProString ret; ProFile *pro = m_parser->parsedProBlock(QStringView(expr), 0, where, line, QMakeParser::ValueGrammar); if (pro->isOk()) { m_current.pro = pro; m_current.line = 0; const ushort *tokPtr = pro->tokPtr(); ProStringList result; if (expandVariableReferences(tokPtr, 1, &result, true) == ReturnError) exit(3); if (!result.isEmpty()) ret = result.at(0); } pro->deref(); return ret; } bool QMakeProject::isEmpty(const ProKey &v) const { ProValueMap::ConstIterator it = m_valuemapStack.front().constFind(v); return it == m_valuemapStack.front().constEnd() || it->isEmpty(); } void QMakeProject::dump() const { QStringList out; for (ProValueMap::ConstIterator it = m_valuemapStack.front().begin(); it != m_valuemapStack.front().end(); ++it) { if (!it.key().startsWith('.')) { QString str = it.key() + " ="; for (const ProString &v : it.value()) str += ' ' + formatValue(v); out << str; } } out.sort(); for (const QString &v : qAsConst(out)) puts(qPrintable(v)); } QT_END_NAMESPACE