aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2021-07-09 11:22:22 +0200
committerEike Ziller <eike.ziller@qt.io>2021-07-09 12:05:20 +0000
commitc3e413a8643857111ea80747605ba2cf5c2e328b (patch)
tree2926147acd8969f7a211f7a64593a48ad031130d
parent0568be071d5523478775019c9dd28d5a081efa74 (diff)
proparser: Update ProItems to state in Qt 6.2
Except for our Qt 5 workarounds with toStringView, qHash return value, and ProStringList which must be an explicit QVector for Qt 5. Most importantly that pulls in a change to ProString::toQString(QString &tmp) const from 76004502baa118016c8e0f32895af7a822f1ba37 in qtbase, which replaces a setRawData call which otherwise leads to severe issues when built with Qt 6. Fixes: QTCREATORBUG-25574 Change-Id: I488b4e0b63becc59a4ea34aace5c249921fa1a60 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--src/shared/proparser/proitems.cpp18
-rw-r--r--src/shared/proparser/proitems.h94
2 files changed, 85 insertions, 27 deletions
diff --git a/src/shared/proparser/proitems.cpp b/src/shared/proparser/proitems.cpp
index f689c41923..1f4a436115 100644
--- a/src/shared/proparser/proitems.cpp
+++ b/src/shared/proparser/proitems.cpp
@@ -25,6 +25,7 @@
#include "proitems.h"
+#include <qdebug.h>
#include <qfileinfo.h>
#include <qset.h>
#include <qstringlist.h>
@@ -50,6 +51,11 @@ ProString::ProString() :
{
}
+ProString::ProString(const ProString &other) :
+ m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(other.m_hash)
+{
+}
+
ProString::ProString(const ProString &other, OmitPreHashing) :
m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(0x80000000)
{
@@ -72,13 +78,13 @@ ProString::ProString(Utils::StringView str) :
}
ProString::ProString(const char *str, DoPreHashing) :
- m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0)
+ m_string(QString::fromLatin1(str)), m_offset(0), m_length(int(qstrlen(str))), m_file(0)
{
updatedHash();
}
ProString::ProString(const char *str) :
- m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0), m_hash(0x80000000)
+ m_string(QString::fromLatin1(str)), m_offset(0), m_length(int(qstrlen(str))), m_file(0), m_hash(0x80000000)
{
}
@@ -148,7 +154,8 @@ QString ProString::toQString() const
QString &ProString::toQString(QString &tmp) const
{
- return tmp.setRawData(m_string.constData() + m_offset, m_length);
+ tmp = m_string.mid(m_offset, m_length);
+ return tmp;
}
ProString &ProString::prepend(const ProString &other)
@@ -493,4 +500,9 @@ ProKey ProFile::getHashStr(const ushort *&tPtr)
return ret;
}
+QDebug operator<<(QDebug debug, const ProString &str)
+{
+ return debug << str.toQString();
+}
+
QT_END_NAMESPACE
diff --git a/src/shared/proparser/proitems.h b/src/shared/proparser/proitems.h
index 3e0686fe13..9d851a9d57 100644
--- a/src/shared/proparser/proitems.h
+++ b/src/shared/proparser/proitems.h
@@ -64,6 +64,8 @@ class ProFile;
class ProString {
public:
ProString();
+ ProString(const ProString &other);
+ ProString &operator=(const ProString &) = default;
template<typename A, typename B>
ProString &operator=(const QStringBuilder<A, B> &str)
{ return *this = QString(str); }
@@ -74,7 +76,6 @@ public:
ProString(const QStringBuilder<A, B> &str)
: ProString(QString(str))
{}
-
ProString(const QString &str, int offset, int length);
void setValue(const QString &str);
void clear() { m_string.clear(); m_length = 0; }
@@ -83,14 +84,14 @@ public:
int sourceFile() const { return m_file; }
ProString &prepend(const ProString &other);
- ProString &append(const ProString &other, bool *pending = 0);
+ ProString &append(const ProString &other, bool *pending = nullptr);
ProString &append(const QString &other) { return append(ProString(other)); }
template<typename A, typename B>
ProString &append(const QStringBuilder<A, B> &other) { return append(QString(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 &append(const ProStringList &other, bool *pending = nullptr, bool skipEmpty1st = false);
ProString &operator+=(const ProString &other) { return append(other); }
ProString &operator+=(const QString &other) { return append(other); }
template<typename A, typename B>
@@ -146,9 +147,9 @@ public:
bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; }
bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; }
bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; }
- int toLongLong(bool *ok = 0, int base = 10) const { return toStringView().toLongLong(ok, base); }
- int toInt(bool *ok = 0, int base = 10) const { return toStringView().toInt(ok, base); }
- short toShort(bool *ok = 0, int base = 10) const { return toStringView().toShort(ok, base); }
+ qlonglong toLongLong(bool *ok = nullptr, int base = 10) const { return toStringView().toLongLong(ok, base); }
+ int toInt(bool *ok = nullptr, int base = 10) const { return toStringView().toInt(ok, base); }
+ short toShort(bool *ok = nullptr, int base = 10) const { return toStringView().toShort(ok, base); }
uint hash() const { return m_hash; }
static uint hash(const QChar *p, int n);
@@ -185,7 +186,8 @@ private:
friend QString operator+(const ProString &one, const ProString &two);
friend class ProKey;
};
-Q_DECLARE_TYPEINFO(ProString, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(ProString, Q_RELOCATABLE_TYPE);
+
class ProKey : public ProString {
public:
@@ -195,7 +197,6 @@ public:
ProKey(const QStringBuilder<A, B> &str)
: ProString(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);
@@ -217,7 +218,7 @@ public:
private:
ProKey(const ProString &other);
};
-Q_DECLARE_TYPEINFO(ProKey, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(ProKey, Q_RELOCATABLE_TYPE);
template <> struct QConcatenable<ProString> : private QAbstractConcatenable
{
@@ -228,6 +229,8 @@ template <> struct QConcatenable<ProString> : private QAbstractConcatenable
static inline void appendTo(const ProString &a, QChar *&out)
{
const auto n = a.size();
+ if (!n)
+ return;
memcpy(out, a.toStringView().data(), sizeof(QChar) * n);
out += n;
}
@@ -242,6 +245,8 @@ template <> struct QConcatenable<ProKey> : private QAbstractConcatenable
static inline void appendTo(const ProKey &a, QChar *&out)
{
const auto n = a.size();
+ if (!n)
+ return;
memcpy(out, a.toStringView().data(), sizeof(QChar) * n);
out += n;
}
@@ -257,6 +262,54 @@ QTextStream &operator<<(QTextStream &t, const ProString &str);
template<typename A, typename B>
QTextStream &operator<<(QTextStream &t, const QStringBuilder<A, B> &str) { return t << QString(str); }
+// This class manages read-only access to a ProString via a raw data QString
+// temporary, ensuring that the latter is accessed exclusively.
+class ProStringRoUser
+{
+public:
+ ProStringRoUser(QString &rs)
+ {
+ m_rs = &rs;
+ }
+ ProStringRoUser(const ProString &ps, QString &rs)
+ : ProStringRoUser(rs)
+ {
+ ps.toQString(rs);
+ }
+ // No destructor, as a RAII pattern cannot be used: references to the
+ // temporary string can legitimately outlive instances of this class
+ // (if they are held by Qt, e.g. in QRegExp).
+ QString &set(const ProString &ps) { return ps.toQString(*m_rs); }
+ QString &str() { return *m_rs; }
+
+protected:
+ QString *m_rs;
+};
+
+// This class manages read-write access to a ProString via a raw data QString
+// temporary, ensuring that the latter is accessed exclusively, and that raw
+// data does not leak outside its source's refcounting.
+class ProStringRwUser : public ProStringRoUser
+{
+public:
+ ProStringRwUser(QString &rs)
+ : ProStringRoUser(rs), m_ps(nullptr) {}
+ ProStringRwUser(const ProString &ps, QString &rs)
+ : ProStringRoUser(ps, rs), m_ps(&ps) {}
+ QString &set(const ProString &ps) { m_ps = &ps; return ProStringRoUser::set(ps); }
+ ProString extract(const QString &s) const
+ { return s.isSharedWith(*m_rs) ? *m_ps : ProString(s).setSource(*m_ps); }
+ ProString extract(const QString &s, const ProStringRwUser &other) const
+ {
+ if (other.m_ps && s.isSharedWith(*other.m_rs))
+ return *other.m_ps;
+ return extract(s);
+ }
+
+private:
+ const ProString *m_ps;
+};
+
class ProStringList : public QVector<ProString> {
public:
ProStringList() {}
@@ -290,21 +343,12 @@ public:
{ return contains(ProString(str), cs); }
bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
};
-Q_DECLARE_TYPEINFO(ProStringList, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(ProStringList, Q_RELOCATABLE_TYPE);
inline ProStringList operator+(const ProStringList &one, const ProStringList &two)
{ ProStringList ret = one; ret += two; return ret; }
-typedef QHash<ProKey, ProStringList> ProValueMap;
-
-// For std::list (sic!)
-#ifdef Q_CC_MSVC
-inline bool operator<(const ProValueMap &, const ProValueMap &)
-{
- Q_ASSERT(false);
- return false;
-}
-#endif
+typedef QMap<ProKey, ProStringList> ProValueMap;
// These token definitions affect both ProFileEvaluator and ProWriter
enum ProToken {
@@ -419,7 +463,7 @@ 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(ProFunctionDef &&other) Q_DECL_NOTHROW
+ ProFunctionDef(ProFunctionDef &&other) noexcept
: m_pro(other.m_pro), m_offset(other.m_offset) { other.m_pro = nullptr; }
~ProFunctionDef() { if (m_pro) m_pro->deref(); }
ProFunctionDef &operator=(const ProFunctionDef &o)
@@ -433,13 +477,13 @@ public:
}
return *this;
}
- ProFunctionDef &operator=(ProFunctionDef &&other) Q_DECL_NOTHROW
+ ProFunctionDef &operator=(ProFunctionDef &&other) noexcept
{
ProFunctionDef moved(std::move(other));
swap(moved);
return *this;
}
- void swap(ProFunctionDef &other) Q_DECL_NOTHROW
+ void swap(ProFunctionDef &other) noexcept
{
qSwap(m_pro, other.m_pro);
qSwap(m_offset, other.m_offset);
@@ -452,11 +496,13 @@ private:
int m_offset;
};
-Q_DECLARE_TYPEINFO(ProFunctionDef, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(ProFunctionDef, Q_RELOCATABLE_TYPE);
struct ProFunctionDefs {
QHash<ProKey, ProFunctionDef> testFunctions;
QHash<ProKey, ProFunctionDef> replaceFunctions;
};
+QDebug operator<<(QDebug debug, const ProString &str);
+
QT_END_NAMESPACE