summaryrefslogtreecommitdiffstats
path: root/qmake/library/proitems.h
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/library/proitems.h')
-rw-r--r--qmake/library/proitems.h264
1 files changed, 216 insertions, 48 deletions
diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h
index 994bfcc75d..b712ca371b 100644
--- a/qmake/library/proitems.h
+++ b/qmake/library/proitems.h
@@ -44,14 +44,29 @@
#include "qmake_global.h"
-#include <QString>
-#include <QStringList>
-#include <QHash>
-#include <QTextStream>
+#include <qstring.h>
+#include <qvector.h>
+#include <qhash.h>
QT_BEGIN_NAMESPACE
-#if 0
+class QTextStream;
+
+#ifdef PROPARSER_THREAD_SAFE
+typedef QAtomicInt ProItemRefCount;
+#else
+class ProItemRefCount {
+public:
+ ProItemRefCount(int cnt = 0) : m_cnt(cnt) {}
+ bool ref() { return ++m_cnt != 0; }
+ bool deref() { return --m_cnt != 0; }
+ ProItemRefCount &operator=(int value) { m_cnt = value; return *this; }
+private:
+ int m_cnt;
+};
+#endif
+
+#ifndef QT_BUILD_QMAKE
# define PROITEM_EXPLICIT explicit
#else
# define PROITEM_EXPLICIT
@@ -59,27 +74,36 @@ QT_BEGIN_NAMESPACE
class ProKey;
class ProStringList;
+class ProFile;
class ProString {
public:
- ProString() {}
- ProString(const ProString &other) : m_string(other.m_string) {}
- PROITEM_EXPLICIT ProString(const QString &str) : m_string(str) {}
- PROITEM_EXPLICIT ProString(const char *str) : m_string(QLatin1String(str)) {}
- void clear() { m_string.clear(); }
-
- ProString &prepend(const ProString &other) { m_string.prepend(other.m_string); return *this; }
- ProString &append(const ProString &other) { m_string.append(other.m_string); return *this; }
- ProString &append(const QString &other) { m_string.append(other); return *this; }
- ProString &append(const char *other) { m_string.append(QLatin1String(other)); return *this; }
- ProString &append(QChar other) { m_string.append(other); return *this; }
+ ProString();
+ ProString(const ProString &other);
+ PROITEM_EXPLICIT ProString(const QString &str);
+ PROITEM_EXPLICIT ProString(const char *str);
+ ProString(const QString &str, int offset, int length);
+ void setValue(const QString &str);
+ void clear() { m_string.clear(); m_length = 0; }
+ ProString &setSource(const ProString &other) { m_file = other.m_file; return *this; }
+ ProString &setSource(const ProFile *pro) { m_file = pro; return *this; }
+ const ProFile *sourceFile() const { return m_file; }
+
+ ProString &prepend(const ProString &other);
+ ProString &append(const ProString &other, bool *pending = 0);
+ ProString &append(const QString &other) { return append(ProString(other)); }
+ ProString &append(const QLatin1String other);
+ ProString &append(const char *other) { return append(QLatin1String(other)); }
+ ProString &append(QChar other);
+ ProString &append(const ProStringList &other, bool *pending = 0, bool skipEmpty1st = false);
ProString &operator+=(const ProString &other) { return append(other); }
ProString &operator+=(const QString &other) { return append(other); }
+ ProString &operator+=(const QLatin1String other) { return append(other); }
ProString &operator+=(const char *other) { return append(other); }
ProString &operator+=(QChar other) { return append(other); }
- void chop(int n) { m_string.chop(n); }
- void chopFront(int n) { m_string.remove(0, n); }
+ void chop(int n) { Q_ASSERT(n <= m_length); m_length -= n; }
+ void chopFront(int n) { Q_ASSERT(n <= m_length); m_offset += n; m_length -= n; }
bool operator==(const ProString &other) const { return toQStringRef() == other.toQStringRef(); }
bool operator==(const QString &other) const { return toQStringRef() == other; }
@@ -90,15 +114,15 @@ public:
bool operator!=(QLatin1String other) const { return !(*this == other); }
bool operator!=(const char *other) const { return !(*this == other); }
bool isNull() const { return m_string.isNull(); }
- bool isEmpty() const { return m_string.isEmpty(); }
- int length() const { return m_string.size(); }
- int size() const { return m_string.size(); }
- QChar at(int i) const { return m_string.at(i); }
- const QChar *constData() const { return m_string.constData(); }
- ProString mid(int off, int len = -1) const { return m_string.mid(off, len); }
+ bool isEmpty() const { return !m_length; }
+ int length() const { return m_length; }
+ int size() const { return m_length; }
+ QChar at(int i) const { Q_ASSERT((uint)i < (uint)m_length); return constData()[i]; }
+ const QChar *constData() const { return m_string.constData() + m_offset; }
+ ProString mid(int off, int len = -1) const;
ProString left(int len) const { return mid(0, len); }
ProString right(int len) const { return mid(qMax(0, size() - len)); }
- ProString trimmed() const { return m_string.trimmed(); }
+ ProString trimmed() const;
int compare(const ProString &sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().compare(sub.toQStringRef(), cs); }
int compare(const QString &sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().compare(sub, cs); }
int compare(const char *sub, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return toQStringRef().compare(QLatin1String(sub), cs); }
@@ -122,12 +146,15 @@ public:
int toInt(bool *ok = 0) const { return toQString().toInt(ok); } // XXX optimize
short toShort(bool *ok = 0) const { return toQString().toShort(ok); } // XXX optimize
- ALWAYS_INLINE QStringRef toQStringRef() const { return QStringRef(&m_string, 0, m_string.length()); }
+ static uint hash(const QChar *p, int n);
+
+ ALWAYS_INLINE QStringRef toQStringRef() const { return QStringRef(&m_string, m_offset, m_length); }
ALWAYS_INLINE ProKey &toKey() { return *(ProKey *)this; }
ALWAYS_INLINE const ProKey &toKey() const { return *(const ProKey *)this; }
- QString toQString() const { return m_string; }
+ QString toQString() const;
+ QString &toQString(QString &tmp) const;
QByteArray toLatin1() const { return toQStringRef().toLatin1(); }
@@ -135,10 +162,23 @@ private:
ProString(const ProKey &other);
ProString &operator=(const ProKey &other);
+ enum OmitPreHashing { NoHash };
+ ProString(const ProString &other, OmitPreHashing);
+
+ enum DoPreHashing { DoHash };
+ ALWAYS_INLINE ProString(const QString &str, DoPreHashing);
+ ALWAYS_INLINE ProString(const char *str, DoPreHashing);
+ ALWAYS_INLINE ProString(const QString &str, int offset, int length, DoPreHashing);
+ ALWAYS_INLINE ProString(const QString &str, int offset, int length, uint hash);
+
QString m_string;
- friend uint qHash(const ProKey &str, uint seed);
+ int m_offset, m_length;
+ const ProFile *m_file;
+ mutable uint m_hash;
+ QChar *prepareExtend(int extraLen, int thisTarget, int extraTarget);
+ uint updatedHash() const;
+ friend uint qHash(const ProString &str);
friend QString operator+(const ProString &one, const ProString &two);
- friend QString &operator+=(QString &that, const ProString &other);
friend class ProKey;
};
Q_DECLARE_TYPEINFO(ProString, Q_MOVABLE_TYPE);
@@ -146,8 +186,11 @@ Q_DECLARE_TYPEINFO(ProString, Q_MOVABLE_TYPE);
class ProKey : public ProString {
public:
ALWAYS_INLINE ProKey() : ProString() {}
- explicit ProKey(const QString &str) : ProString(str) {}
- PROITEM_EXPLICIT ProKey(const char *str) : ProString(str) {}
+ explicit ProKey(const QString &str);
+ PROITEM_EXPLICIT ProKey(const char *str);
+ ProKey(const QString &str, int off, int len);
+ ProKey(const QString &str, int off, int len, uint hash);
+ void setValue(const QString &str);
#ifdef Q_CC_MSVC
// Workaround strange MSVC behaviour when exporting classes with ProKey members.
@@ -167,10 +210,8 @@ private:
};
Q_DECLARE_TYPEINFO(ProKey, Q_MOVABLE_TYPE);
-inline uint qHash(const ProKey &key, uint seed = 0)
- { return qHash(key.m_string, seed); }
-inline QString operator+(const ProString &one, const ProString &two)
- { return one.m_string + two.m_string; }
+uint qHash(const ProString &str);
+QString operator+(const ProString &one, const ProString &two);
inline QString operator+(const ProString &one, const QString &two)
{ return one + ProString(two); }
inline QString operator+(const QString &one, const ProString &two)
@@ -189,29 +230,31 @@ inline bool operator==(const QString &that, const ProString &other)
inline bool operator!=(const QString &that, const ProString &other)
{ return !(other == that); }
-inline QTextStream &operator<<(QTextStream &t, const ProString &str)
- { t << str.toQString(); return t; }
+QTextStream &operator<<(QTextStream &t, const ProString &str);
-class ProStringList : public QList<ProString> {
+class ProStringList : public QVector<ProString> {
public:
ProStringList() {}
ProStringList(const ProString &str) { *this << str; }
- explicit ProStringList(const QStringList &list) : QList<ProString>(*(const ProStringList *)&list) {}
- QStringList toQStringList() const { return *(const QStringList *)this; }
+ explicit ProStringList(const QStringList &list);
+ QStringList toQStringList() const;
ProStringList &operator<<(const ProString &str)
- { QList<ProString>::operator<<(str); return *this; }
+ { QVector<ProString>::operator<<(str); return *this; }
- QString join(const QString &sep) const { return toQStringList().join(sep); }
+ int length() const { return size(); }
- void remove(int idx) { removeAt(idx); }
+ QString join(const QString &sep) const;
- bool contains(const ProString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
- { return contains(str.toQString(), cs); }
+ void removeAll(const ProString &str);
+ void removeAll(const char *str);
+ void removeAt(int idx) { remove(idx); }
+ void removeDuplicates();
+
+ bool contains(const ProString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
- { return (*(const QStringList *)this).contains(str, cs); }
- bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
- { return (*(const QStringList *)this).contains(str, cs); }
+ { return contains(ProString(str), cs); }
+ bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
};
Q_DECLARE_TYPEINFO(ProStringList, Q_MOVABLE_TYPE);
@@ -220,6 +263,131 @@ inline ProStringList operator+(const ProStringList &one, const ProStringList &tw
typedef QHash<ProKey, ProStringList> ProValueMap;
+// These token definitions affect both ProFileEvaluator and ProWriter
+enum ProToken {
+ TokTerminator = 0, // end of stream (possibly not included in length; must be zero)
+ TokLine, // line marker:
+ // - line (1)
+ TokAssign, // variable =
+ TokAppend, // variable +=
+ TokAppendUnique, // variable *=
+ TokRemove, // variable -=
+ TokReplace, // variable ~=
+ // previous literal/expansion is a variable manipulation
+ // - value expression + TokValueTerminator
+ TokValueTerminator, // assignment value terminator
+ TokLiteral, // literal string (fully dequoted)
+ // - length (1)
+ // - string data (length; unterminated)
+ TokHashLiteral, // literal string with hash (fully dequoted)
+ // - hash (2)
+ // - length (1)
+ // - string data (length; unterminated)
+ TokVariable, // qmake variable expansion
+ // - hash (2)
+ // - name length (1)
+ // - name (name length; unterminated)
+ TokProperty, // qmake property expansion
+ // - hash (2)
+ // - name length (1)
+ // - name (name length; unterminated)
+ TokEnvVar, // environment variable expansion
+ // - name length (1)
+ // - name (name length; unterminated)
+ TokFuncName, // replace function expansion
+ // - hash (2)
+ // - name length (1)
+ // - name (name length; unterminated)
+ // - ((nested expansion + TokArgSeparator)* + nested expansion)?
+ // - TokFuncTerminator
+ TokArgSeparator, // function argument separator
+ TokFuncTerminator, // function argument list terminator
+ TokCondition, // previous literal/expansion is a conditional
+ TokTestCall, // previous literal/expansion is a test function call
+ // - ((nested expansion + TokArgSeparator)* + nested expansion)?
+ // - TokFuncTerminator
+ TokNot, // '!' operator
+ TokAnd, // ':' operator
+ TokOr, // '|' operator
+ TokBranch, // branch point:
+ // - then block length (2)
+ // - then block + TokTerminator (then block length)
+ // - else block length (2)
+ // - else block + TokTerminator (else block length)
+ TokForLoop, // for loop:
+ // - variable name: hash (2), length (1), chars (length)
+ // - expression: length (2), bytes + TokValueTerminator (length)
+ // - body length (2)
+ // - body + TokTerminator (body length)
+ TokTestDef, // test function definition:
+ TokReplaceDef, // replace function definition:
+ // - function name: hash (2), length (1), chars (length)
+ // - body length (2)
+ // - body + TokTerminator (body length)
+ TokMask = 0xff,
+ TokQuoted = 0x100, // The expression is quoted => join expanded stringlist
+ TokNewStr = 0x200 // Next stringlist element
+};
+
+class QMAKE_EXPORT ProFile
+{
+public:
+ explicit ProFile(const QString &fileName);
+ ~ProFile();
+
+ QString fileName() const { return m_fileName; }
+ QString directoryName() const { return m_directoryName; }
+ const QString &items() const { return m_proitems; }
+ QString *itemsRef() { return &m_proitems; }
+ const ushort *tokPtr() const { return (const ushort *)m_proitems.constData(); }
+
+ void ref() { m_refCount.ref(); }
+ void deref() { if (!m_refCount.deref()) delete this; }
+
+ bool isOk() const { return m_ok; }
+ void setOk(bool ok) { m_ok = ok; }
+
+ bool isHostBuild() const { return m_hostBuild; }
+ void setHostBuild(bool host_build) { m_hostBuild = host_build; }
+
+private:
+ ProItemRefCount m_refCount;
+ QString m_proitems;
+ QString m_fileName;
+ QString m_directoryName;
+ bool m_ok;
+ bool m_hostBuild;
+};
+
+class ProFunctionDef {
+public:
+ ProFunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); }
+ ProFunctionDef(const ProFunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); }
+ ~ProFunctionDef() { m_pro->deref(); }
+ ProFunctionDef &operator=(const ProFunctionDef &o)
+ {
+ if (this != &o) {
+ m_pro->deref();
+ m_pro = o.m_pro;
+ m_pro->ref();
+ m_offset = o.m_offset;
+ }
+ return *this;
+ }
+ ProFile *pro() const { return m_pro; }
+ const ushort *tokPtr() const { return m_pro->tokPtr() + m_offset; }
+private:
+ ProFile *m_pro;
+ int m_offset;
+};
+
+Q_DECLARE_TYPEINFO(ProFunctionDef, Q_MOVABLE_TYPE);
+
+struct ProFunctionDefs {
+ QHash<ProKey, ProFunctionDef> testFunctions;
+ QHash<ProKey, ProFunctionDef> replaceFunctions;
+};
+
QT_END_NAMESPACE
#endif // PROITEMS_H