~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to qmake/library/qmakeparser.h

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the qmake application of the Qt Toolkit.
 
7
**
 
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.
 
16
**
 
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.
 
24
**
 
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.
 
28
**
 
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.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#ifndef QMAKEPARSER_H
 
43
#define QMAKEPARSER_H
 
44
 
 
45
#include "qmake_global.h"
 
46
#include "proitems.h"
 
47
 
 
48
#include <qhash.h>
 
49
#include <qstack.h>
 
50
#ifdef PROPARSER_THREAD_SAFE
 
51
# include <qmutex.h>
 
52
# include <qwaitcondition.h>
 
53
#endif
 
54
 
 
55
QT_BEGIN_NAMESPACE
 
56
class QMAKE_EXPORT QMakeParserHandler
 
57
{
 
58
public:
 
59
    enum {
 
60
        CategoryMask = 0xf00,
 
61
        WarningMessage = 0x000,
 
62
        ErrorMessage = 0x100,
 
63
 
 
64
        SourceMask = 0xf0,
 
65
        SourceParser = 0,
 
66
 
 
67
        CodeMask = 0xf,
 
68
        WarnLanguage = 0,
 
69
        WarnDeprecated,
 
70
 
 
71
        ParserWarnLanguage = SourceParser | WarningMessage | WarnLanguage,
 
72
        ParserWarnDeprecated = SourceParser | WarningMessage | WarnDeprecated,
 
73
 
 
74
        ParserIoError = ErrorMessage | SourceParser,
 
75
        ParserError
 
76
    };
 
77
    virtual void message(int type, const QString &msg,
 
78
                         const QString &fileName = QString(), int lineNo = 0) = 0;
 
79
};
 
80
 
 
81
class ProFileCache;
 
82
 
 
83
class QMAKE_EXPORT QMakeParser
 
84
{
 
85
public:
 
86
    // Call this from a concurrency-free context
 
87
    static void initialize();
 
88
 
 
89
    QMakeParser(ProFileCache *cache, QMakeParserHandler *handler);
 
90
 
 
91
    enum SubGrammar { FullGrammar, TestGrammar, ValueGrammar };
 
92
    // fileName is expected to be absolute and cleanPath()ed.
 
93
    ProFile *parsedProFile(const QString &fileName, bool cache = false);
 
94
    ProFile *parsedProBlock(const QString &contents, const QString &name, int line = 0,
 
95
                            SubGrammar grammar = FullGrammar);
 
96
 
 
97
    void discardFileFromCache(const QString &fileName);
 
98
 
 
99
private:
 
100
    enum ScopeNesting {
 
101
        NestNone = 0,
 
102
        NestLoop = 1,
 
103
        NestFunction = 2
 
104
    };
 
105
 
 
106
    struct BlockScope {
 
107
        BlockScope() : start(0), braceLevel(0), special(false), inBranch(false), nest(NestNone) {}
 
108
        BlockScope(const BlockScope &other) { *this = other; }
 
109
        ushort *start; // Where this block started; store length here
 
110
        int braceLevel; // Nesting of braces in scope
 
111
        bool special; // Single-line conditionals inside loops, etc. cannot have else branches
 
112
        bool inBranch; // The 'else' branch of the previous TokBranch is still open
 
113
        uchar nest; // Into what control structures we are nested
 
114
    };
 
115
 
 
116
    enum ScopeState {
 
117
        StNew,  // Fresh scope
 
118
        StCtrl, // Control statement (for or else) met on current line
 
119
        StCond  // Conditionals met on current line
 
120
    };
 
121
 
 
122
    enum Context { CtxTest, CtxValue, CtxPureValue, CtxArgs };
 
123
    struct ParseCtx {
 
124
        int parens; // Nesting of non-functional parentheses
 
125
        int argc; // Number of arguments in current function call
 
126
        int wordCount; // Number of words in current expression
 
127
        Context context;
 
128
        ushort quote; // Enclosing quote type
 
129
        ushort terminator; // '}' if replace function call is braced, ':' if test function
 
130
    };
 
131
 
 
132
    bool read(ProFile *pro);
 
133
    bool read(ProFile *pro, const QString &content, int line, SubGrammar grammar);
 
134
 
 
135
    ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok);
 
136
    ALWAYS_INLINE void putBlockLen(ushort *&tokPtr, uint len);
 
137
    ALWAYS_INLINE void putBlock(ushort *&tokPtr, const ushort *buf, uint len);
 
138
    void putHashStr(ushort *&pTokPtr, const ushort *buf, uint len);
 
139
    void finalizeHashStr(ushort *buf, uint len);
 
140
    void putLineMarker(ushort *&tokPtr);
 
141
    ALWAYS_INLINE bool resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort **ptr,
 
142
                                       ushort **buf, QString *xprBuff,
 
143
                                       ushort **tokPtr, QString *tokBuff,
 
144
                                       const ushort *cur, const QString &in);
 
145
    void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
 
146
    void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
 
147
    void finalizeTest(ushort *&tokPtr);
 
148
    void bogusTest(ushort *&tokPtr);
 
149
    void enterScope(ushort *&tokPtr, bool special, ScopeState state);
 
150
    void leaveScope(ushort *&tokPtr);
 
151
    void flushCond(ushort *&tokPtr);
 
152
    void flushScopes(ushort *&tokPtr);
 
153
 
 
154
    void message(int type, const QString &msg) const;
 
155
    void parseError(const QString &msg) const
 
156
            { message(QMakeParserHandler::ParserError, msg); }
 
157
    void languageWarning(const QString &msg) const
 
158
            { message(QMakeParserHandler::ParserWarnLanguage, msg); }
 
159
    void deprecationWarning(const QString &msg) const
 
160
            { message(QMakeParserHandler::ParserWarnDeprecated, msg); }
 
161
 
 
162
    // Current location
 
163
    ProFile *m_proFile;
 
164
    int m_lineNo;
 
165
 
 
166
    QStack<BlockScope> m_blockstack;
 
167
    ScopeState m_state;
 
168
    int m_markLine; // Put marker for this line
 
169
    bool m_inError; // Current line had a parsing error; suppress followup error messages
 
170
    bool m_canElse; // Conditionals met on previous line, but no scope was opened
 
171
    bool m_invert; // Pending conditional is negated
 
172
    enum { NoOperator, AndOperator, OrOperator } m_operator; // Pending conditional is ORed/ANDed
 
173
 
 
174
    QString m_tmp; // Temporary for efficient toQString
 
175
 
 
176
    ProFileCache *m_cache;
 
177
    QMakeParserHandler *m_handler;
 
178
 
 
179
    // This doesn't help gcc 3.3 ...
 
180
    template<typename T> friend class QTypeInfo;
 
181
 
 
182
    friend class ProFileCache;
 
183
};
 
184
 
 
185
class QMAKE_EXPORT ProFileCache
 
186
{
 
187
public:
 
188
    ProFileCache() {}
 
189
    ~ProFileCache();
 
190
 
 
191
    void discardFile(const QString &fileName);
 
192
    void discardFiles(const QString &prefix);
 
193
 
 
194
private:
 
195
    struct Entry {
 
196
        ProFile *pro;
 
197
#ifdef PROPARSER_THREAD_SAFE
 
198
        struct Locker {
 
199
            Locker() : waiters(0), done(false) {}
 
200
            QWaitCondition cond;
 
201
            int waiters;
 
202
            bool done;
 
203
        };
 
204
        Locker *locker;
 
205
#endif
 
206
    };
 
207
 
 
208
    QHash<QString, Entry> parsed_files;
 
209
#ifdef PROPARSER_THREAD_SAFE
 
210
    QMutex mutex;
 
211
#endif
 
212
 
 
213
    friend class QMakeParser;
 
214
};
 
215
 
 
216
#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
 
217
Q_DECLARE_TYPEINFO(QMakeParser::BlockScope, Q_MOVABLE_TYPE);
 
218
Q_DECLARE_TYPEINFO(QMakeParser::Context, Q_PRIMITIVE_TYPE);
 
219
#endif
 
220
 
 
221
QT_END_NAMESPACE
 
222
 
 
223
#endif // PROFILEPARSER_H