1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the qmake application of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
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 Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
42
#ifndef QMAKEEVALUATOR_H
43
#define QMAKEEVALUATOR_H
45
#if defined(PROEVALUATOR_FULL) && defined(PROEVALUATOR_THREAD_SAFE)
46
# error PROEVALUATOR_FULL is incompatible with PROEVALUATOR_THREAD_SAFE due to cache() implementation
49
#include "qmakeparser.h"
53
#include <qlinkedlist.h>
57
#include <qstringlist.h>
58
#ifndef QT_BOOTSTRAPPED
59
# include <qprocess.h>
66
class QMAKE_EXPORT QMakeHandler : public QMakeParserHandler
70
SourceEvaluator = 0x10,
72
EvalWarnLanguage = SourceEvaluator | WarningMessage | WarnLanguage,
73
EvalWarnDeprecated = SourceEvaluator | WarningMessage | WarnDeprecated,
75
EvalError = ErrorMessage | SourceEvaluator
78
// error(), warning() and message() from .pro file
79
virtual void fileMessage(const QString &msg) = 0;
81
enum EvalFileType { EvalProjectFile, EvalIncludeFile, EvalConfigFile, EvalFeatureFile, EvalAuxFile };
82
virtual void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type) = 0;
83
virtual void doneWithEval(ProFile *parent) = 0;
86
// We use a QLinkedList based stack instead of a QVector based one (QStack), so that
87
// the addresses of value maps stay constant. The qmake generators rely on that.
88
class QMAKE_EXPORT ProValueMapStack : public QLinkedList<ProValueMap>
91
inline void push(const ProValueMap &t) { append(t); }
92
inline ProValueMap pop() { return takeLast(); }
93
ProValueMap &top() { return last(); }
94
const ProValueMap &top() const { return last(); }
97
class QMAKE_EXPORT QMakeEvaluator
104
LoadAll = LoadPreFiles|LoadPostFiles,
107
Q_DECLARE_FLAGS(LoadFlags, LoadFlag)
109
static void initStatics();
110
static void initFunctionStatics();
111
QMakeEvaluator(QMakeGlobals *option, QMakeParser *parser,
112
QMakeHandler *handler);
115
#ifdef QT_BUILD_QMAKE
116
void setExtraVars(const ProValueMap &extraVars) { m_extraVars = extraVars; }
117
void setExtraConfigs(const ProStringList &extraConfigs) { m_extraConfigs = extraConfigs; }
119
void setOutputDir(const QString &outputDir) { m_outputDir = outputDir; }
121
ProStringList values(const ProKey &variableName) const;
122
ProStringList &valuesRef(const ProKey &variableName);
123
ProString first(const ProKey &variableName) const;
124
ProString propertyValue(const ProKey &val) const;
126
ProString dirSep() const { return m_dirSep; }
127
bool isHostBuild() const { return m_hostBuild; }
138
static ALWAYS_INLINE VisitReturn returnBool(bool b)
139
{ return b ? ReturnTrue : ReturnFalse; }
141
static ALWAYS_INLINE uint getBlockLen(const ushort *&tokPtr);
142
ProString getStr(const ushort *&tokPtr);
143
ProKey getHashStr(const ushort *&tokPtr);
144
void evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined);
145
static ALWAYS_INLINE void skipStr(const ushort *&tokPtr);
146
static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr);
147
void skipExpression(const ushort *&tokPtr);
150
bool prepareProject(const QString &inDir);
151
bool loadSpecInternal();
153
void initFrom(const QMakeEvaluator &other);
155
void evaluateCommand(const QString &cmds, const QString &where);
156
VisitReturn visitProFile(ProFile *pro, QMakeHandler::EvalFileType type,
158
VisitReturn visitProBlock(ProFile *pro, const ushort *tokPtr);
159
VisitReturn visitProBlock(const ushort *tokPtr);
160
VisitReturn visitProLoop(const ProKey &variable, const ushort *exprPtr,
161
const ushort *tokPtr);
162
void visitProFunctionDef(ushort tok, const ProKey &name, const ushort *tokPtr);
163
void visitProVariable(ushort tok, const ProStringList &curr, const ushort *&tokPtr);
165
ALWAYS_INLINE const ProKey &map(const ProString &var) { return map(var.toKey()); }
166
const ProKey &map(const ProKey &var);
167
ProValueMap *findValues(const ProKey &variableName, ProValueMap::Iterator *it);
171
ProStringList split_value_list(const QString &vals, const ProFile *source = 0);
172
ProStringList expandVariableReferences(const ProString &value, int *pos = 0, bool joined = false);
173
ProStringList expandVariableReferences(const ushort *&tokPtr, int sizeHint = 0, bool joined = false);
175
QString currentFileName() const;
176
QString currentDirectory() const;
177
ProFile *currentProFile() const;
178
QString resolvePath(const QString &fileName) const
179
{ return QMakeInternal::IoUtils::resolvePath(currentDirectory(), fileName); }
181
VisitReturn evaluateFile(const QString &fileName, QMakeHandler::EvalFileType type,
183
VisitReturn evaluateFileChecked(const QString &fileName, QMakeHandler::EvalFileType type,
185
VisitReturn evaluateFeatureFile(const QString &fileName, bool silent = false);
186
VisitReturn evaluateFileInto(const QString &fileName,
187
ProValueMap *values, // output-only
189
VisitReturn evaluateConfigFeatures();
190
void message(int type, const QString &msg) const;
191
void evalError(const QString &msg) const
192
{ message(QMakeHandler::EvalError, msg); }
193
void languageWarning(const QString &msg) const
194
{ message(QMakeHandler::EvalWarnLanguage, msg); }
195
void deprecationWarning(const QString &msg) const
196
{ message(QMakeHandler::EvalWarnDeprecated, msg); }
198
QList<ProStringList> prepareFunctionArgs(const ushort *&tokPtr);
199
ProStringList evaluateFunction(const ProFunctionDef &func,
200
const QList<ProStringList> &argumentsList, VisitReturn *ok);
201
VisitReturn evaluateBoolFunction(const ProFunctionDef &func,
202
const QList<ProStringList> &argumentsList,
203
const ProString &function);
205
ProStringList evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr);
206
VisitReturn evaluateConditionalFunction(const ProKey &function, const ushort *&tokPtr);
208
ProStringList evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args);
209
VisitReturn evaluateBuiltinConditional(int func_t, const ProKey &function, const ProStringList &args);
211
bool evaluateConditional(const QString &cond, const QString &where, int line = -1);
212
#ifdef PROEVALUATOR_FULL
213
void checkRequirements(const ProStringList &deps);
216
void updateMkspecPaths();
217
void updateFeaturePaths();
219
bool isActiveConfig(const QString &config, bool regex = false);
222
const ProStringList &deps, const ProString &prefix,
223
QHash<ProKey, QSet<ProKey> > &dependencies,
224
ProValueMap &dependees, ProStringList &rootSet) const;
226
VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
227
const QString &contents);
228
#ifndef QT_BOOTSTRAPPED
229
void runProcess(QProcess *proc, const QString &command) const;
231
QByteArray getCommandOutput(const QString &args) const;
233
static void removeEach(ProStringList *varlist, const ProStringList &value);
235
QMakeEvaluator *m_caller;
236
#ifdef PROEVALUATOR_CUMULATIVE
240
enum { m_cumulative = 0 };
241
enum { m_skipLevel = 0 };
244
#ifdef PROEVALUATOR_DEBUG
245
void debugMsgInternal(int level, const char *fmt, ...) const;
246
void traceMsgInternal(const char *fmt, ...) const;
247
static QString formatValue(const ProString &val, bool forceQuote = false);
248
static QString formatValueList(const ProStringList &vals, bool commas = false);
249
static QString formatValueListList(const QList<ProStringList> &vals);
251
const int m_debugLevel;
253
ALWAYS_INLINE void debugMsgInternal(int, const char *, ...) const {}
254
ALWAYS_INLINE void traceMsgInternal(const char *, ...) const {}
256
enum { m_debugLevel = 0 };
260
Location() : pro(0), line(0) {}
261
Location(ProFile *_pro, ushort _line) : pro(_pro), line(_line) {}
262
void clear() { pro = 0; line = 0; }
267
Location m_current; // Currently evaluated location
268
QStack<Location> m_locationStack; // All execution location changes
269
QStack<ProFile *> m_profileStack; // Includes only
271
#ifdef QT_BUILD_QMAKE
272
ProValueMap m_extraVars;
273
ProStringList m_extraConfigs;
278
bool m_valuemapInited;
281
QString m_qmakespecName;
285
QString m_sourceRoot;
287
QStringList m_qmakepath;
288
QStringList m_qmakefeatures;
289
QStringList m_mkspecPaths;
290
QStringList m_featureRoots;
292
ProFunctionDefs m_functionDefs;
293
ProStringList m_returnValue;
294
ProValueMapStack m_valuemapStack; // VariableName must be us-ascii, the content however can be non-us-ascii.
295
QString m_tmp1, m_tmp2, m_tmp3, m_tmp[2]; // Temporaries for efficient toQString
296
mutable QString m_mtmp;
298
QMakeGlobals *m_option;
299
QMakeParser *m_parser;
300
QMakeHandler *m_handler;
303
Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeEvaluator::LoadFlags)
307
#endif // QMAKEEVALUATOR_H