1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the Qt Linguist 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 PROITEMS_H |
43 | #define PROITEMS_H |
44 | |
45 | #include "proparser_global.h" |
46 | #include <QtCore/QString> |
47 | #include <QtCore/QVector> |
48 | |
49 | QT_BEGIN_NAMESPACE |
50 | |
51 | #ifdef PROPARSER_THREAD_SAFE |
52 | typedef QAtomicInt ProItemRefCount; |
53 | #else |
54 | class ProItemRefCount { |
55 | public: |
56 | ProItemRefCount(int cnt = 0) : m_cnt(cnt) {} |
57 | bool ref() { return ++m_cnt != 0; } |
58 | bool deref() { return --m_cnt != 0; } |
59 | ProItemRefCount &operator=(int value) { m_cnt = value; return *this; } |
60 | private: |
61 | int m_cnt; |
62 | }; |
63 | #endif |
64 | |
65 | namespace ProStringConstants { |
66 | enum OmitPreHashing { NoHash }; |
67 | } |
68 | |
69 | class ProStringList; |
70 | class ProFile; |
71 | |
72 | class ProString { |
73 | public: |
74 | ProString(); |
75 | ProString(const ProString &other); |
76 | ProString(const ProString &other, ProStringConstants::OmitPreHashing); |
77 | explicit ProString(const QString &str); |
78 | ProString(const QString &str, ProStringConstants::OmitPreHashing); |
79 | explicit ProString(const char *str); |
80 | ProString(const char *str, ProStringConstants::OmitPreHashing); |
81 | ProString(const QString &str, int offset, int length); |
82 | ProString(const QString &str, int offset, int length, uint hash); |
83 | ProString(const QString &str, int offset, int length, ProStringConstants::OmitPreHashing); |
84 | void setValue(const QString &str); |
85 | void setValue(const QString &str, ProStringConstants::OmitPreHashing); |
86 | ProString &setSource(const ProString &other) { m_file = other.m_file; return *this; } |
87 | ProString &setSource(const ProFile *pro) { m_file = pro; return *this; } |
88 | const ProFile *sourceFile() const { return m_file; } |
89 | QString toQString() const; |
90 | QString &toQString(QString &tmp) const; |
91 | ProString &operator+=(const ProString &other); |
92 | ProString &append(const ProString &other, bool *pending = 0); |
93 | ProString &append(const ProStringList &other, bool *pending = 0, bool skipEmpty1st = false); |
94 | bool operator==(const ProString &other) const; |
95 | bool operator==(const QString &other) const; |
96 | bool operator==(const QLatin1String &other) const; |
97 | bool operator!=(const ProString &other) const { return !(*this == other); } |
98 | bool operator!=(const QString &other) const { return !(*this == other); } |
99 | bool operator!=(const QLatin1String &other) const { return !(*this == other); } |
100 | bool isEmpty() const { return !m_length; } |
101 | int size() const { return m_length; } |
102 | const QChar *constData() const { return m_string.constData() + m_offset; } |
103 | ProString mid(int off, int len = -1) const; |
104 | ProString left(int len) const { return mid(0, len); } |
105 | ProString right(int len) const { return mid(qMax(0, size() - len)); } |
106 | ProString trimmed() const; |
107 | void clear() { m_string.clear(); m_length = 0; } |
108 | |
109 | static uint hash(const QChar *p, int n); |
110 | |
111 | private: |
112 | QString m_string; |
113 | int m_offset, m_length; |
114 | const ProFile *m_file; |
115 | mutable uint m_hash; |
116 | QChar *prepareAppend(int ); |
117 | uint updatedHash() const; |
118 | friend uint qHash(const ProString &str); |
119 | friend QString operator+(const ProString &one, const ProString &two); |
120 | }; |
121 | Q_DECLARE_TYPEINFO(ProString, Q_MOVABLE_TYPE); |
122 | |
123 | uint qHash(const ProString &str); |
124 | QString operator+(const ProString &one, const ProString &two); |
125 | inline QString operator+(const ProString &one, const QString &two) |
126 | { return one + ProString(two, ProStringConstants::NoHash); } |
127 | inline QString operator+(const QString &one, const ProString &two) |
128 | { return ProString(one, ProStringConstants::NoHash) + two; } |
129 | |
130 | class ProStringList : public QVector<ProString> { |
131 | public: |
132 | ProStringList() {} |
133 | ProStringList(const ProString &str) { *this << str; } |
134 | QString join(const QString &sep) const; |
135 | void removeDuplicates(); |
136 | }; |
137 | |
138 | // These token definitions affect both ProFileEvaluator and ProWriter |
139 | enum ProToken { |
140 | TokTerminator = 0, // end of stream (possibly not included in length; must be zero) |
141 | TokLine, // line marker: |
142 | // - line (1) |
143 | TokAssign, // variable = |
144 | TokAppend, // variable += |
145 | TokAppendUnique, // variable *= |
146 | TokRemove, // variable -= |
147 | TokReplace, // variable ~= |
148 | // previous literal/expansion is a variable manipulation |
149 | // - value expression + TokValueTerminator |
150 | TokValueTerminator, // assignment value terminator |
151 | TokLiteral, // literal string (fully dequoted) |
152 | // - length (1) |
153 | // - string data (length; unterminated) |
154 | TokHashLiteral, // literal string with hash (fully dequoted) |
155 | // - hash (2) |
156 | // - length (1) |
157 | // - string data (length; unterminated) |
158 | TokVariable, // qmake variable expansion |
159 | // - hash (2) |
160 | // - name length (1) |
161 | // - name (name length; unterminated) |
162 | TokProperty, // qmake property expansion |
163 | // - name length (1) |
164 | // - name (name length; unterminated) |
165 | TokEnvVar, // environment variable expansion |
166 | // - name length (1) |
167 | // - name (name length; unterminated) |
168 | TokFuncName, // replace function expansion |
169 | // - hash (2) |
170 | // - name length (1) |
171 | // - name (name length; unterminated) |
172 | // - ((nested expansion + TokArgSeparator)* + nested expansion)? |
173 | // - TokFuncTerminator |
174 | TokArgSeparator, // function argument separator |
175 | TokFuncTerminator, // function argument list terminator |
176 | TokCondition, // previous literal/expansion is a conditional |
177 | TokTestCall, // previous literal/expansion is a test function call |
178 | // - ((nested expansion + TokArgSeparator)* + nested expansion)? |
179 | // - TokFuncTerminator |
180 | TokNot, // '!' operator |
181 | TokAnd, // ':' operator |
182 | TokOr, // '|' operator |
183 | TokBranch, // branch point: |
184 | // - then block length (2) |
185 | // - then block + TokTerminator (then block length) |
186 | // - else block length (2) |
187 | // - else block + TokTerminator (else block length) |
188 | TokForLoop, // for loop: |
189 | // - variable name: hash (2), length (1), chars (length) |
190 | // - expression: length (2), bytes + TokValueTerminator (length) |
191 | // - body length (2) |
192 | // - body + TokTerminator (body length) |
193 | TokTestDef, // test function definition: |
194 | TokReplaceDef, // replace function definition: |
195 | // - function name: hash (2), length (1), chars (length) |
196 | // - body length (2) |
197 | // - body + TokTerminator (body length) |
198 | TokMask = 0xff, |
199 | TokQuoted = 0x100, // The expression is quoted => join expanded stringlist |
200 | TokNewStr = 0x200 // Next stringlist element |
201 | }; |
202 | |
203 | class PROPARSER_EXPORT ProFile |
204 | { |
205 | public: |
206 | explicit ProFile(const QString &fileName); |
207 | ~ProFile(); |
208 | |
209 | QString fileName() const { return m_fileName; } |
210 | QString directoryName() const { return m_directoryName; } |
211 | const QString &items() const { return m_proitems; } |
212 | QString *itemsRef() { return &m_proitems; } |
213 | const ushort *tokPtr() const { return (const ushort *)m_proitems.constData(); } |
214 | |
215 | void ref() { m_refCount.ref(); } |
216 | void deref() { if (!m_refCount.deref()) delete this; } |
217 | |
218 | bool isOk() const { return m_ok; } |
219 | void setOk(bool ok) { m_ok = ok; } |
220 | |
221 | private: |
222 | ProItemRefCount m_refCount; |
223 | QString m_proitems; |
224 | QString m_fileName; |
225 | QString m_directoryName; |
226 | bool m_ok; |
227 | }; |
228 | |
229 | QT_END_NAMESPACE |
230 | |
231 | #endif // PROITEMS_H |
232 | |