diff options
Diffstat (limited to 'qmake/library/proitems.h')
-rw-r--r-- | qmake/library/proitems.h | 264 |
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 |