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
49QT_BEGIN_NAMESPACE
50
51#ifdef PROPARSER_THREAD_SAFE
52typedef QAtomicInt ProItemRefCount;
53#else
54class ProItemRefCount {
55public:
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; }
60private:
61 int m_cnt;
62};
63#endif
64
65namespace ProStringConstants {
66enum OmitPreHashing { NoHash };
67}
68
69class ProStringList;
70class ProFile;
71
72class ProString {
73public:
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
111private:
112 QString m_string;
113 int m_offset, m_length;
114 const ProFile *m_file;
115 mutable uint m_hash;
116 QChar *prepareAppend(int extraLen);
117 uint updatedHash() const;
118 friend uint qHash(const ProString &str);
119 friend QString operator+(const ProString &one, const ProString &two);
120};
121Q_DECLARE_TYPEINFO(ProString, Q_MOVABLE_TYPE);
122
123uint qHash(const ProString &str);
124QString operator+(const ProString &one, const ProString &two);
125inline QString operator+(const ProString &one, const QString &two)
126 { return one + ProString(two, ProStringConstants::NoHash); }
127inline QString operator+(const QString &one, const ProString &two)
128 { return ProString(one, ProStringConstants::NoHash) + two; }
129
130class ProStringList : public QVector<ProString> {
131public:
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
139enum 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
203class PROPARSER_EXPORT ProFile
204{
205public:
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
221private:
222 ProItemRefCount m_refCount;
223 QString m_proitems;
224 QString m_fileName;
225 QString m_directoryName;
226 bool m_ok;
227};
228
229QT_END_NAMESPACE
230
231#endif // PROITEMS_H
232