1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the qmake application of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include "project.h" |
30 | |
31 | #include "option.h" |
32 | #include <qmakeevaluator_p.h> |
33 | |
34 | #include <qdir.h> |
35 | |
36 | #include <stdio.h> |
37 | |
38 | using namespace QMakeInternal; |
39 | |
40 | QT_BEGIN_NAMESPACE |
41 | |
42 | QMakeProject::QMakeProject() |
43 | : QMakeEvaluator(Option::globals, Option::parser, Option::vfs, &Option::evalHandler) |
44 | { |
45 | } |
46 | |
47 | QMakeProject::QMakeProject(QMakeProject *p) |
48 | : QMakeEvaluator(Option::globals, Option::parser, Option::vfs, &Option::evalHandler) |
49 | { |
50 | initFrom(p); |
51 | } |
52 | |
53 | bool QMakeProject::boolRet(VisitReturn vr) |
54 | { |
55 | if (vr == ReturnError) |
56 | exit(3); |
57 | Q_ASSERT(vr == ReturnTrue || vr == ReturnFalse); |
58 | return vr != ReturnFalse; |
59 | } |
60 | |
61 | bool QMakeProject::read(const QString &project, LoadFlags what) |
62 | { |
63 | m_projectFile = project; |
64 | setOutputDir(Option::output_dir); |
65 | QString absproj = (project == QLatin1String("-" )) |
66 | ? QLatin1String("(stdin)" ) |
67 | : QDir::cleanPath(QDir(qmake_getpwd()).absoluteFilePath(project)); |
68 | m_projectDir = QFileInfo(absproj).path(); |
69 | return boolRet(evaluateFile(absproj, QMakeHandler::EvalProjectFile, what)); |
70 | } |
71 | |
72 | static ProStringList prepareBuiltinArgs(const QList<ProStringList> &args) |
73 | { |
74 | ProStringList ret; |
75 | ret.reserve(args.size()); |
76 | for (const ProStringList &arg : args) |
77 | ret << arg.join(' '); |
78 | return ret; |
79 | } |
80 | |
81 | bool QMakeProject::test(const ProKey &func, const QList<ProStringList> &args) |
82 | { |
83 | m_current.clear(); |
84 | |
85 | auto adef = statics.functions.constFind(func); |
86 | if (adef != statics.functions.constEnd()) |
87 | return boolRet(evaluateBuiltinConditional(*adef, func, prepareBuiltinArgs(args))); |
88 | |
89 | QHash<ProKey, ProFunctionDef>::ConstIterator it = |
90 | m_functionDefs.testFunctions.constFind(func); |
91 | if (it != m_functionDefs.testFunctions.constEnd()) |
92 | return boolRet(evaluateBoolFunction(*it, args, func)); |
93 | |
94 | evalError(QStringLiteral("'%1' is not a recognized test function." ) |
95 | .arg(func.toQStringView())); |
96 | return false; |
97 | } |
98 | |
99 | QStringList QMakeProject::expand(const ProKey &func, const QList<ProStringList> &args) |
100 | { |
101 | m_current.clear(); |
102 | |
103 | auto adef = statics.expands.constFind(func); |
104 | if (adef != statics.expands.constEnd()) { |
105 | ProStringList ret; |
106 | if (evaluateBuiltinExpand(*adef, func, prepareBuiltinArgs(args), ret) == ReturnError) |
107 | exit(3); |
108 | return ret.toQStringList(); |
109 | } |
110 | |
111 | QHash<ProKey, ProFunctionDef>::ConstIterator it = |
112 | m_functionDefs.replaceFunctions.constFind(func); |
113 | if (it != m_functionDefs.replaceFunctions.constEnd()) { |
114 | ProStringList ret; |
115 | if (evaluateFunction(*it, args, &ret) == QMakeProject::ReturnError) |
116 | exit(3); |
117 | return ret.toQStringList(); |
118 | } |
119 | |
120 | evalError(QStringLiteral("'%1' is not a recognized replace function." ) |
121 | .arg(func.toQStringView())); |
122 | return QStringList(); |
123 | } |
124 | |
125 | ProString QMakeProject::expand(const QString &expr, const QString &where, int line) |
126 | { |
127 | ProString ret; |
128 | ProFile *pro = m_parser->parsedProBlock(QStringView(expr), 0, where, line, |
129 | QMakeParser::ValueGrammar); |
130 | if (pro->isOk()) { |
131 | m_current.pro = pro; |
132 | m_current.line = 0; |
133 | const ushort *tokPtr = pro->tokPtr(); |
134 | ProStringList result; |
135 | if (expandVariableReferences(tokPtr, 1, &result, true) == ReturnError) |
136 | exit(3); |
137 | if (!result.isEmpty()) |
138 | ret = result.at(0); |
139 | } |
140 | pro->deref(); |
141 | return ret; |
142 | } |
143 | |
144 | bool QMakeProject::isEmpty(const ProKey &v) const |
145 | { |
146 | ProValueMap::ConstIterator it = m_valuemapStack.front().constFind(v); |
147 | return it == m_valuemapStack.front().constEnd() || it->isEmpty(); |
148 | } |
149 | |
150 | void QMakeProject::dump() const |
151 | { |
152 | QStringList out; |
153 | for (ProValueMap::ConstIterator it = m_valuemapStack.front().begin(); |
154 | it != m_valuemapStack.front().end(); ++it) { |
155 | if (!it.key().startsWith('.')) { |
156 | QString str = it.key() + " =" ; |
157 | for (const ProString &v : it.value()) |
158 | str += ' ' + formatValue(v); |
159 | out << str; |
160 | } |
161 | } |
162 | out.sort(); |
163 | for (const QString &v : qAsConst(out)) |
164 | puts(qPrintable(v)); |
165 | } |
166 | |
167 | QT_END_NAMESPACE |
168 | |