summaryrefslogtreecommitdiffstats
path: root/qmake/library/qmakeevaluator.h
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/library/qmakeevaluator.h')
-rw-r--r--qmake/library/qmakeevaluator.h309
1 files changed, 309 insertions, 0 deletions
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
new file mode 100644
index 0000000000..7c0da0c2d4
--- /dev/null
+++ b/qmake/library/qmakeevaluator.h
@@ -0,0 +1,309 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the qmake application of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMAKEEVALUATOR_H
+#define QMAKEEVALUATOR_H
+
+#if defined(PROEVALUATOR_FULL) && defined(PROEVALUATOR_THREAD_SAFE)
+# error PROEVALUATOR_FULL is incompatible with PROEVALUATOR_THREAD_SAFE due to cache() implementation
+#endif
+
+#include "qmakeparser.h"
+#include "ioutils.h"
+
+#include <qlist.h>
+#include <qlinkedlist.h>
+#include <qset.h>
+#include <qstack.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#ifndef QT_BOOTSTRAPPED
+# include <qprocess.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QMakeGlobals;
+
+class QMAKE_EXPORT QMakeHandler : public QMakeParserHandler
+{
+public:
+ enum {
+ SourceEvaluator = 0x10,
+
+ EvalWarnLanguage = SourceEvaluator | WarningMessage | WarnLanguage,
+ EvalWarnDeprecated = SourceEvaluator | WarningMessage | WarnDeprecated,
+
+ EvalError = ErrorMessage | SourceEvaluator
+ };
+
+ // error(), warning() and message() from .pro file
+ virtual void fileMessage(const QString &msg) = 0;
+
+ enum EvalFileType { EvalProjectFile, EvalIncludeFile, EvalConfigFile, EvalFeatureFile, EvalAuxFile };
+ virtual void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type) = 0;
+ virtual void doneWithEval(ProFile *parent) = 0;
+};
+
+// We use a QLinkedList based stack instead of a QVector based one (QStack), so that
+// the addresses of value maps stay constant. The qmake generators rely on that.
+class QMAKE_EXPORT ProValueMapStack : public QLinkedList<ProValueMap>
+{
+public:
+ inline void push(const ProValueMap &t) { append(t); }
+ inline ProValueMap pop() { return takeLast(); }
+ ProValueMap &top() { return last(); }
+ const ProValueMap &top() const { return last(); }
+};
+
+class QMAKE_EXPORT QMakeEvaluator
+{
+public:
+ enum LoadFlag {
+ LoadProOnly = 0,
+ LoadPreFiles = 1,
+ LoadPostFiles = 2,
+ LoadAll = LoadPreFiles|LoadPostFiles,
+ LoadSilent = 0x10
+ };
+ Q_DECLARE_FLAGS(LoadFlags, LoadFlag)
+
+ static void initStatics();
+ static void initFunctionStatics();
+ QMakeEvaluator(QMakeGlobals *option, QMakeParser *parser,
+ QMakeHandler *handler);
+ ~QMakeEvaluator();
+
+#ifdef QT_BUILD_QMAKE
+ void setExtraVars(const ProValueMap &extraVars) { m_extraVars = extraVars; }
+ void setExtraConfigs(const ProStringList &extraConfigs) { m_extraConfigs = extraConfigs; }
+#endif
+ void setOutputDir(const QString &outputDir) { m_outputDir = outputDir; }
+
+ ProStringList values(const ProKey &variableName) const;
+ ProStringList &valuesRef(const ProKey &variableName);
+ ProString first(const ProKey &variableName) const;
+ ProString propertyValue(const ProKey &val) const;
+
+ ProString dirSep() const { return m_dirSep; }
+ bool isHostBuild() const { return m_hostBuild; }
+
+ enum VisitReturn {
+ ReturnFalse,
+ ReturnTrue,
+ ReturnError,
+ ReturnBreak,
+ ReturnNext,
+ ReturnReturn
+ };
+
+ static ALWAYS_INLINE VisitReturn returnBool(bool b)
+ { return b ? ReturnTrue : ReturnFalse; }
+
+ static ALWAYS_INLINE uint getBlockLen(const ushort *&tokPtr);
+ ProString getStr(const ushort *&tokPtr);
+ ProKey getHashStr(const ushort *&tokPtr);
+ void evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined);
+ static ALWAYS_INLINE void skipStr(const ushort *&tokPtr);
+ static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr);
+ void skipExpression(const ushort *&tokPtr);
+
+ void loadDefaults();
+ bool prepareProject(const QString &inDir);
+ bool loadSpecInternal();
+ bool loadSpec();
+ void initFrom(const QMakeEvaluator &other);
+ void setupProject();
+ void evaluateCommand(const QString &cmds, const QString &where);
+ VisitReturn visitProFile(ProFile *pro, QMakeHandler::EvalFileType type,
+ LoadFlags flags);
+ VisitReturn visitProBlock(ProFile *pro, const ushort *tokPtr);
+ VisitReturn visitProBlock(const ushort *tokPtr);
+ VisitReturn visitProLoop(const ProKey &variable, const ushort *exprPtr,
+ const ushort *tokPtr);
+ void visitProFunctionDef(ushort tok, const ProKey &name, const ushort *tokPtr);
+ void visitProVariable(ushort tok, const ProStringList &curr, const ushort *&tokPtr);
+
+ ALWAYS_INLINE const ProKey &map(const ProString &var) { return map(var.toKey()); }
+ const ProKey &map(const ProKey &var);
+ ProValueMap *findValues(const ProKey &variableName, ProValueMap::Iterator *it);
+
+ void setTemplate();
+
+ ProStringList split_value_list(const QString &vals, const ProFile *source = 0);
+ ProStringList expandVariableReferences(const ProString &value, int *pos = 0, bool joined = false);
+ ProStringList expandVariableReferences(const ushort *&tokPtr, int sizeHint = 0, bool joined = false);
+
+ QString currentFileName() const;
+ QString currentDirectory() const;
+ ProFile *currentProFile() const;
+ QString resolvePath(const QString &fileName) const
+ { return QMakeInternal::IoUtils::resolvePath(currentDirectory(), fileName); }
+
+ bool evaluateFile(const QString &fileName, QMakeHandler::EvalFileType type,
+ LoadFlags flags);
+ bool evaluateFileChecked(const QString &fileName, QMakeHandler::EvalFileType type,
+ LoadFlags flags);
+ bool evaluateFeatureFile(const QString &fileName, bool silent = false);
+ bool evaluateFileInto(const QString &fileName,
+ ProValueMap *values, // output-only
+ LoadFlags flags);
+ void evaluateConfigFeatures();
+ void message(int type, const QString &msg) const;
+ void evalError(const QString &msg) const
+ { message(QMakeHandler::EvalError, msg); }
+ void languageWarning(const QString &msg) const
+ { message(QMakeHandler::EvalWarnLanguage, msg); }
+ void deprecationWarning(const QString &msg) const
+ { message(QMakeHandler::EvalWarnDeprecated, msg); }
+
+ QList<ProStringList> prepareFunctionArgs(const ushort *&tokPtr);
+ ProStringList evaluateFunction(const ProFunctionDef &func,
+ const QList<ProStringList> &argumentsList, bool *ok);
+ VisitReturn evaluateBoolFunction(const ProFunctionDef &func,
+ const QList<ProStringList> &argumentsList,
+ const ProString &function);
+
+ ProStringList evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr);
+ VisitReturn evaluateConditionalFunction(const ProKey &function, const ushort *&tokPtr);
+
+ ProStringList evaluateBuiltinExpand(const ProKey &function, const ProStringList &args);
+ VisitReturn evaluateBuiltinConditional(const ProKey &function, const ProStringList &args);
+
+ bool evaluateConditional(const QString &cond, const QString &where, int line = -1);
+#ifdef PROEVALUATOR_FULL
+ void checkRequirements(const ProStringList &deps);
+#endif
+
+ void updateMkspecPaths();
+ void updateFeaturePaths();
+
+ bool isActiveConfig(const QString &config, bool regex = false);
+
+ void populateDeps(
+ const ProStringList &deps, const ProString &prefix,
+ QHash<ProKey, QSet<ProKey> > &dependencies,
+ ProValueMap &dependees, ProStringList &rootSet) const;
+
+ VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
+ const QString &contents);
+#ifndef QT_BOOTSTRAPPED
+ void runProcess(QProcess *proc, const QString &command) const;
+#endif
+ QByteArray getCommandOutput(const QString &args) const;
+
+ static void removeEach(ProStringList *varlist, const ProStringList &value);
+
+ QMakeEvaluator *m_caller;
+ int m_loopLevel; // To report unexpected break() and next()s
+#ifdef PROEVALUATOR_CUMULATIVE
+ bool m_cumulative;
+ int m_skipLevel;
+#else
+ enum { m_cumulative = 0 };
+ enum { m_skipLevel = 0 };
+#endif
+
+#ifdef PROEVALUATOR_DEBUG
+ void debugMsgInternal(int level, const char *fmt, ...) const;
+ void traceMsgInternal(const char *fmt, ...) const;
+ static QString formatValue(const ProString &val, bool forceQuote = false);
+ static QString formatValueList(const ProStringList &vals, bool commas = false);
+ static QString formatValueListList(const QList<ProStringList> &vals);
+
+ const int m_debugLevel;
+#else
+ ALWAYS_INLINE void debugMsgInternal(int, const char *, ...) const {}
+ ALWAYS_INLINE void traceMsgInternal(const char *, ...) const {}
+
+ enum { m_debugLevel = 0 };
+#endif
+
+ struct Location {
+ Location() : pro(0), line(0) {}
+ Location(ProFile *_pro, ushort _line) : pro(_pro), line(_line) {}
+ void clear() { pro = 0; line = 0; }
+ ProFile *pro;
+ ushort line;
+ };
+
+ Location m_current; // Currently evaluated location
+ QStack<Location> m_locationStack; // All execution location changes
+ QStack<ProFile *> m_profileStack; // Includes only
+
+#ifdef QT_BUILD_QMAKE
+ ProValueMap m_extraVars;
+ ProStringList m_extraConfigs;
+#endif
+ QString m_outputDir;
+
+ int m_listCount;
+ bool m_valuemapInited;
+ bool m_hostBuild;
+ QString m_qmakespec;
+ QString m_qmakespecFull;
+ QString m_qmakespecName;
+ QString m_superfile;
+ QString m_conffile;
+ QString m_cachefile;
+ QString m_sourceRoot;
+ QString m_buildRoot;
+ QStringList m_qmakepath;
+ QStringList m_qmakefeatures;
+ QStringList m_mkspecPaths;
+ QStringList m_featureRoots;
+ ProString m_dirSep;
+ ProFunctionDefs m_functionDefs;
+ ProStringList m_returnValue;
+ ProValueMapStack m_valuemapStack; // VariableName must be us-ascii, the content however can be non-us-ascii.
+ QString m_tmp1, m_tmp2, m_tmp3, m_tmp[2]; // Temporaries for efficient toQString
+ mutable QString m_mtmp;
+
+ QMakeGlobals *m_option;
+ QMakeParser *m_parser;
+ QMakeHandler *m_handler;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeEvaluator::LoadFlags)
+
+QT_END_NAMESPACE
+
+#endif // QMAKEEVALUATOR_H