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 Qt Linguist 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 "profileevaluator.h"
30
31#include "qmakeglobals.h"
32#include "ioutils.h"
33#include "qmakevfs.h"
34
35#include <QDir>
36
37using namespace QMakeInternal;
38
39QT_BEGIN_NAMESPACE
40
41void ProFileEvaluator::initialize()
42{
43 QMakeEvaluator::initStatics();
44}
45
46ProFileEvaluator::ProFileEvaluator(ProFileGlobals *option, QMakeParser *parser, QMakeVfs *vfs,
47 QMakeHandler *handler)
48 : d(new QMakeEvaluator(option, parser, vfs, handler))
49{
50}
51
52ProFileEvaluator::~ProFileEvaluator()
53{
54 delete d;
55}
56
57bool ProFileEvaluator::contains(const QString &variableName) const
58{
59 return d->m_valuemapStack.top().contains(akey: ProKey(variableName));
60}
61
62QString ProFileEvaluator::value(const QString &variable) const
63{
64 const QStringList &vals = values(variableName: variable);
65 if (!vals.isEmpty())
66 return vals.first();
67
68 return QString();
69}
70
71QStringList ProFileEvaluator::values(const QString &variableName) const
72{
73 const ProStringList &values = d->values(variableName: ProKey(variableName));
74 QStringList ret;
75 ret.reserve(alloc: values.size());
76 foreach (const ProString &str, values)
77 ret << d->m_option->expandEnvVars(str: str.toQString());
78 return ret;
79}
80
81QStringList ProFileEvaluator::values(const QString &variableName, const ProFile *pro) const
82{
83 // It makes no sense to put any kind of magic into expanding these
84 const ProStringList &values = d->m_valuemapStack.front().value(akey: ProKey(variableName));
85 QStringList ret;
86 ret.reserve(alloc: values.size());
87 foreach (const ProString &str, values)
88 if (str.sourceFile() == pro->id())
89 ret << d->m_option->expandEnvVars(str: str.toQString());
90 return ret;
91}
92
93QString ProFileEvaluator::sysrootify(const QString &path, const QString &baseDir) const
94{
95 ProFileGlobals *option = static_cast<ProFileGlobals *>(d->m_option);
96#ifdef Q_OS_WIN
97 Qt::CaseSensitivity cs = Qt::CaseInsensitive;
98#else
99 Qt::CaseSensitivity cs = Qt::CaseSensitive;
100#endif
101 const bool isHostSystemPath =
102 option->sysroot.isEmpty() || path.startsWith(s: option->sysroot, cs)
103 || path.startsWith(s: baseDir, cs) || path.startsWith(s: d->m_outputDir, cs);
104
105 return isHostSystemPath ? path : option->sysroot + path;
106}
107
108QStringList ProFileEvaluator::absolutePathValues(
109 const QString &variable, const QString &baseDirectory) const
110{
111 QStringList result;
112 foreach (const QString &el, values(variable)) {
113 QString absEl = IoUtils::isAbsolutePath(fileName: el)
114 ? sysrootify(path: el, baseDir: baseDirectory) : IoUtils::resolvePath(baseDir: baseDirectory, fileName: el);
115 if (IoUtils::fileType(fileName: absEl) == IoUtils::FileIsDir)
116 result << QDir::cleanPath(path: absEl);
117 }
118 return result;
119}
120
121QStringList ProFileEvaluator::absoluteFileValues(
122 const QString &variable, const QString &baseDirectory, const QStringList &searchDirs,
123 const ProFile *pro) const
124{
125 QStringList result;
126 foreach (const QString &el, pro ? values(variable, pro) : values(variable)) {
127 QString absEl;
128 if (IoUtils::isAbsolutePath(fileName: el)) {
129 const QString elWithSysroot = QDir::cleanPath(path: sysrootify(path: el, baseDir: baseDirectory));
130 if (d->m_vfs->exists(fn: elWithSysroot, flags: QMakeVfs::VfsCumulative)) {
131 result << elWithSysroot;
132 goto next;
133 }
134 absEl = elWithSysroot;
135 } else {
136 foreach (const QString &dir, searchDirs) {
137 QString fn = QDir::cleanPath(path: dir + QLatin1Char('/') + el);
138 if (d->m_vfs->exists(fn, flags: QMakeVfs::VfsCumulative)) {
139 result << fn;
140 goto next;
141 }
142 }
143 if (baseDirectory.isEmpty())
144 goto next;
145 absEl = QDir::cleanPath(path: baseDirectory + QLatin1Char('/') + el);
146 }
147 {
148 int nameOff = absEl.lastIndexOf(c: QLatin1Char('/'));
149 QString absDir = d->m_tmp1.setRawData(unicode: absEl.constData(), size: nameOff);
150 // NOTE: This does not support virtual files. That shouldn't be a problem,
151 // because no sane project would add generated files by wildcard.
152 if (IoUtils::fileType(fileName: absDir) == IoUtils::FileIsDir) {
153 QString wildcard = d->m_tmp2.setRawData(unicode: absEl.constData() + nameOff + 1,
154 size: absEl.length() - nameOff - 1);
155 if (wildcard.contains(c: QLatin1Char('*')) || wildcard.contains(c: QLatin1Char('?'))) {
156 wildcard.detach(); // Keep m_tmp out of QRegExp's cache
157 QDir theDir(absDir);
158 foreach (const QString &fn, theDir.entryList(QStringList(wildcard)))
159 if (fn != QLatin1String(".") && fn != QLatin1String(".."))
160 result << absDir + QLatin1Char('/') + fn;
161 } // else if (acceptMissing)
162 }
163 }
164 next: ;
165 }
166 return result;
167}
168
169ProFileEvaluator::TemplateType ProFileEvaluator::templateType() const
170{
171 const ProStringList &templ = d->values(variableName: ProKey("TEMPLATE"));
172 if (templ.count() >= 1) {
173 const QString &t = templ.at(i: 0).toQString();
174 if (!t.compare(other: QLatin1String("app"), cs: Qt::CaseInsensitive))
175 return TT_Application;
176 if (!t.compare(other: QLatin1String("lib"), cs: Qt::CaseInsensitive))
177 return TT_Library;
178 if (!t.compare(other: QLatin1String("script"), cs: Qt::CaseInsensitive))
179 return TT_Script;
180 if (!t.compare(other: QLatin1String("aux"), cs: Qt::CaseInsensitive))
181 return TT_Aux;
182 if (!t.compare(other: QLatin1String("subdirs"), cs: Qt::CaseInsensitive))
183 return TT_Subdirs;
184 }
185 return TT_Unknown;
186}
187
188bool ProFileEvaluator::loadNamedSpec(const QString &specDir, bool hostSpec)
189{
190 d->m_qmakespec = specDir;
191 d->m_hostBuild = hostSpec;
192
193 d->updateMkspecPaths();
194 return d->loadSpecInternal();
195}
196
197bool ProFileEvaluator::accept(ProFile *pro, QMakeEvaluator::LoadFlags flags)
198{
199 return d->visitProFile(pro, type: QMakeHandler::EvalProjectFile, flags) == QMakeEvaluator::ReturnTrue;
200}
201
202QString ProFileEvaluator::propertyValue(const QString &name) const
203{
204 return d->m_option->propertyValue(name: ProKey(name)).toQString();
205}
206
207QString ProFileEvaluator::resolvedMkSpec() const
208{
209 return d->m_qmakespec;
210}
211
212#ifdef PROEVALUATOR_CUMULATIVE
213void ProFileEvaluator::setCumulative(bool on)
214{
215 d->m_cumulative = on;
216}
217#endif
218
219void ProFileEvaluator::setExtraVars(const QHash<QString, QStringList> &extraVars)
220{
221 ProValueMap map;
222 QHash<QString, QStringList>::const_iterator it = extraVars.constBegin();
223 QHash<QString, QStringList>::const_iterator end = extraVars.constEnd();
224 for ( ; it != end; ++it)
225 map.insert(akey: ProKey(it.key()), avalue: ProStringList(it.value()));
226 d->setExtraVars(map);
227}
228
229void ProFileEvaluator::setExtraConfigs(const QStringList &extraConfigs)
230{
231 d->setExtraConfigs(ProStringList(extraConfigs));
232}
233
234void ProFileEvaluator::setOutputDir(const QString &dir)
235{
236 d->m_outputDir = dir;
237}
238
239QT_END_NAMESPACE
240

source code of qttools/src/linguist/shared/profileevaluator.cpp