1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "project.h"
5
6#include "cachekeys.h"
7#include "option.h"
8#include <qmakeevaluator_p.h>
9
10#include <qdir.h>
11
12#include <stdio.h>
13
14using namespace QMakeInternal;
15
16QT_BEGIN_NAMESPACE
17
18QMakeProject::QMakeProject()
19 : QMakeEvaluator(Option::globals, Option::parser, Option::vfs, &Option::evalHandler)
20{
21}
22
23QMakeProject::QMakeProject(QMakeProject *p)
24 : QMakeEvaluator(Option::globals, Option::parser, Option::vfs, &Option::evalHandler)
25{
26 initFrom(other: p);
27}
28
29bool QMakeProject::boolRet(VisitReturn vr)
30{
31 if (vr == ReturnError) {
32 qmakeClearCaches();
33 exit(status: 3);
34 }
35 Q_ASSERT(vr == ReturnTrue || vr == ReturnFalse);
36 return vr != ReturnFalse;
37}
38
39bool QMakeProject::read(const QString &project, LoadFlags what)
40{
41 m_projectFile = project;
42 setOutputDir(Option::output_dir);
43 QString absproj = (project == QLatin1String("-"))
44 ? QLatin1String("(stdin)")
45 : QDir::cleanPath(path: QDir(qmake_getpwd()).absoluteFilePath(fileName: project));
46 m_projectDir = QFileInfo(absproj).path();
47 return boolRet(vr: evaluateFile(fileName: absproj, type: QMakeHandler::EvalProjectFile, flags: what));
48}
49
50static ProStringList prepareBuiltinArgs(const QList<ProStringList> &args)
51{
52 ProStringList ret;
53 ret.reserve(asize: args.size());
54 for (const ProStringList &arg : args)
55 ret << arg.join(sep: ' ');
56 return ret;
57}
58
59bool QMakeProject::test(const ProKey &func, const QList<ProStringList> &args)
60{
61 m_current.clear();
62
63 auto adef = statics.functions.constFind(key: func);
64 if (adef != statics.functions.constEnd())
65 return boolRet(vr: evaluateBuiltinConditional(adef: *adef, function: func, args: prepareBuiltinArgs(args)));
66
67 QHash<ProKey, ProFunctionDef>::ConstIterator it =
68 m_functionDefs.testFunctions.constFind(key: func);
69 if (it != m_functionDefs.testFunctions.constEnd())
70 return boolRet(vr: evaluateBoolFunction(func: *it, argumentsList: args, function: func));
71
72 evalError(QStringLiteral("'%1' is not a recognized test function.")
73 .arg(a: func.toQStringView()));
74 return false;
75}
76
77QStringList QMakeProject::expand(const ProKey &func, const QList<ProStringList> &args)
78{
79 m_current.clear();
80
81 auto adef = statics.expands.constFind(key: func);
82 if (adef != statics.expands.constEnd()) {
83 ProStringList ret;
84 if (evaluateBuiltinExpand(adef: *adef, function: func, args: prepareBuiltinArgs(args), ret) == ReturnError)
85 exit(status: 3);
86 return ret.toQStringList();
87 }
88
89 QHash<ProKey, ProFunctionDef>::ConstIterator it =
90 m_functionDefs.replaceFunctions.constFind(key: func);
91 if (it != m_functionDefs.replaceFunctions.constEnd()) {
92 ProStringList ret;
93 if (evaluateFunction(func: *it, argumentsList: args, ret: &ret) == QMakeProject::ReturnError)
94 exit(status: 3);
95 return ret.toQStringList();
96 }
97
98 evalError(QStringLiteral("'%1' is not a recognized replace function.")
99 .arg(a: func.toQStringView()));
100 return QStringList();
101}
102
103ProString QMakeProject::expand(const QString &expr, const QString &where, int line)
104{
105 ProString ret;
106 ProFile *pro = m_parser->parsedProBlock(contents: QStringView(expr), id: 0, name: where, line,
107 grammar: QMakeParser::ValueGrammar);
108 if (pro->isOk()) {
109 m_current.pro = pro;
110 m_current.line = 0;
111 const ushort *tokPtr = pro->tokPtr();
112 ProStringList result;
113 if (expandVariableReferences(tokPtr, sizeHint: 1, ret: &result, joined: true) == ReturnError)
114 exit(status: 3);
115 if (!result.isEmpty())
116 ret = result.at(i: 0);
117 }
118 pro->deref();
119 return ret;
120}
121
122bool QMakeProject::isEmpty(const ProKey &v) const
123{
124 ProValueMap::ConstIterator it = m_valuemapStack.front().constFind(key: v);
125 return it == m_valuemapStack.front().constEnd() || it->isEmpty();
126}
127
128void QMakeProject::dump() const
129{
130 QStringList out;
131 for (ProValueMap::ConstIterator it = m_valuemapStack.front().begin();
132 it != m_valuemapStack.front().end(); ++it) {
133 if (!it.key().startsWith(c: '.')) {
134 QString str = it.key() + " =";
135 for (const ProString &v : it.value())
136 str += ' ' + formatValue(val: v);
137 out << str;
138 }
139 }
140 out.sort();
141 for (const QString &v : std::as_const(t&: out))
142 puts(qPrintable(v));
143}
144
145QT_END_NAMESPACE
146

source code of qtbase/qmake/project.cpp