fix build

This commit is contained in:
Martin Rotter 2024-04-15 10:14:27 +02:00
parent 2d1e85b8b0
commit 9e2a370e0c
2 changed files with 187 additions and 3 deletions

View File

@ -3,8 +3,8 @@
#include "3rd-party/qdatetimeparser/qdatetimeparser.h" #include "3rd-party/qdatetimeparser/qdatetimeparser.h"
#include "private/qstringiterator_p.h" // #include "private/qstringiterator_p.h"
#include "private/qtenvironmentvariables_p.h" // #include "private/qtenvironmentvariables_p.h"
#include <QDebug> #include <QDebug>
#include <QTimeZone> #include <QTimeZone>
@ -354,6 +354,184 @@ int QDateTimeParser::sectionPos(const SectionNode& sn) const {
Helper function for parseSection. Helper function for parseSection.
*/ */
class QStringIterator {
QString::const_iterator i, pos, e;
static_assert((std::is_same<QString::const_iterator, const QChar*>::value));
static bool less(const QChar* lhs, const QChar* rhs) noexcept {
return std::less{}(lhs, rhs);
}
public:
explicit QStringIterator(QStringView string, qsizetype idx = 0)
: i(string.begin()), pos(i + idx), e(string.end()) {}
inline explicit QStringIterator(const QChar* begin, const QChar* end) : i(begin), pos(begin), e(end) {}
explicit QStringIterator(const QChar* begin, qsizetype idx, const QChar* end)
: i(begin), pos(begin + idx), e(end) {}
inline QString::const_iterator position() const {
return pos;
}
qsizetype index() const {
return pos - i;
}
inline void setPosition(QString::const_iterator position) {
Q_ASSERT_X(!less(position, i) && !less(e, position), Q_FUNC_INFO, "position out of bounds");
pos = position;
}
// forward iteration
inline bool hasNext() const {
return less(pos, e);
}
inline void advance() {
Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
if (Q_UNLIKELY((pos++)->isHighSurrogate())) {
if (Q_LIKELY(pos != e && pos->isLowSurrogate()))
++pos;
}
}
inline void advanceUnchecked() {
Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
if (Q_UNLIKELY((pos++)->isHighSurrogate())) {
Q_ASSERT(hasNext() && pos->isLowSurrogate());
++pos;
}
}
inline char32_t peekNextUnchecked() const {
Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
if (Q_UNLIKELY(pos->isHighSurrogate())) {
Q_ASSERT(less(pos + 1, e) && pos[1].isLowSurrogate());
return QChar::surrogateToUcs4(pos[0], pos[1]);
}
return pos->unicode();
}
inline char32_t peekNext(char32_t invalidAs = QChar::ReplacementCharacter) const {
Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
if (Q_UNLIKELY(pos->isSurrogate())) {
if (Q_LIKELY(pos->isHighSurrogate())) {
const QChar* low = pos + 1;
if (Q_LIKELY(low != e && low->isLowSurrogate()))
return QChar::surrogateToUcs4(*pos, *low);
}
return invalidAs;
}
return pos->unicode();
}
inline char32_t nextUnchecked() {
Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
const QChar cur = *pos++;
if (Q_UNLIKELY(cur.isHighSurrogate())) {
Q_ASSERT(hasNext() && pos->isLowSurrogate());
return QChar::surrogateToUcs4(cur, *pos++);
}
return cur.unicode();
}
inline char32_t next(char32_t invalidAs = QChar::ReplacementCharacter) {
Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
const QChar uc = *pos++;
if (Q_UNLIKELY(uc.isSurrogate())) {
if (Q_LIKELY(uc.isHighSurrogate() && hasNext() && pos->isLowSurrogate()))
return QChar::surrogateToUcs4(uc, *pos++);
return invalidAs;
}
return uc.unicode();
}
// backwards iteration
inline bool hasPrevious() const {
return less(i, pos);
}
inline void recede() {
Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
if (Q_UNLIKELY((--pos)->isLowSurrogate())) {
const QChar* high = pos - 1;
if (Q_LIKELY(high != i - 1 && high->isHighSurrogate()))
--pos;
}
}
inline void recedeUnchecked() {
Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
if (Q_UNLIKELY((--pos)->isLowSurrogate())) {
Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
--pos;
}
}
inline char32_t peekPreviousUnchecked() const {
Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
if (Q_UNLIKELY(pos[-1].isLowSurrogate())) {
Q_ASSERT(less(i + 1, pos) && pos[-2].isHighSurrogate());
return QChar::surrogateToUcs4(pos[-2], pos[-1]);
}
return pos[-1].unicode();
}
inline char32_t peekPrevious(char32_t invalidAs = QChar::ReplacementCharacter) const {
Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
if (Q_UNLIKELY(pos[-1].isSurrogate())) {
if (Q_LIKELY(pos[-1].isLowSurrogate())) {
const QChar* high = pos - 2;
if (Q_LIKELY(high != i - 1 && high->isHighSurrogate()))
return QChar::surrogateToUcs4(*high, pos[-1]);
}
return invalidAs;
}
return pos[-1].unicode();
}
inline char32_t previousUnchecked() {
Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
const QChar cur = *--pos;
if (Q_UNLIKELY(cur.isLowSurrogate())) {
Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
return QChar::surrogateToUcs4(*--pos, cur);
}
return cur.unicode();
}
inline char32_t previous(char32_t invalidAs = QChar::ReplacementCharacter) {
Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
const QChar uc = *--pos;
if (Q_UNLIKELY(uc.isSurrogate())) {
if (Q_LIKELY(uc.isLowSurrogate() && hasPrevious() && pos[-1].isHighSurrogate()))
return QChar::surrogateToUcs4(*--pos, uc);
return invalidAs;
}
return uc.unicode();
}
};
static qsizetype digitCount(QStringView str) { static qsizetype digitCount(QStringView str) {
qsizetype digits = 0; qsizetype digits = 0;
for (QStringIterator it(str); it.hasNext();) { for (QStringIterator it(str); it.hasNext();) {
@ -1187,12 +1365,14 @@ static QTime actualTime(QDateTimeParser::Sections known,
\internal \internal
*/ */
static int startsWithLocalTimeZone(QStringView name, const QDateTime& when) { static int startsWithLocalTimeZone(QStringView name, const QDateTime& when) {
/*
// On MS-Win, at least when system zone is UTC, the tzname[]s may be empty. // On MS-Win, at least when system zone is UTC, the tzname[]s may be empty.
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
const QString zone(qTzName(i)); const QString zone(qTzName(i));
if (!zone.isEmpty() && name.startsWith(zone)) if (!zone.isEmpty() && name.startsWith(zone))
return zone.size(); return zone.size();
} }
*/
// Mimic what QLocale::toString() would have used, to ensure round-trips work: // Mimic what QLocale::toString() would have used, to ensure round-trips work:
const QString local = QDateTime(when.date(), when.time()).timeZoneAbbreviation(); const QString local = QDateTime(when.date(), when.time()).timeZoneAbbreviation();
if (name.startsWith(local)) if (name.startsWith(local))

View File

@ -90,7 +90,7 @@ QDateTime TextFactory::parseDateTime(const QString& date_time, QString* used_dt_
QDateTime dt; QDateTime dt;
QTime time_zone_offset; QTime time_zone_offset;
const QLocale locale(QLocale::Language::C); // const QLocale locale(QLocale::Language::C);
bool positive_time_zone_offset = false; bool positive_time_zone_offset = false;
static QStringList date_patterns = dateTimePatterns(); static QStringList date_patterns = dateTimePatterns();
QStringList timezone_offset_patterns; QStringList timezone_offset_patterns;
@ -115,6 +115,10 @@ QDateTime TextFactory::parseDateTime(const QString& date_time, QString* used_dt_
dt = locale.toDateTime(input_date_chopped, pattern); dt = locale.toDateTime(input_date_chopped, pattern);
#endif #endif
*/ */
// NOTE: We use QDateTimeParser class extracted/modified from Qt sources to allow
// matching only prefixes of input date strings.
//
// Built-in parser only matches if the WHOLE input strings matches.
QDateTimeParser par(QMetaType::QDateTime, QDateTimeParser::FromString, QCalendar()); QDateTimeParser par(QMetaType::QDateTime, QDateTimeParser::FromString, QCalendar());
par.setDefaultLocale(QLocale::c()); par.setDefaultLocale(QLocale::c());
par.parseFormat(pattern); par.parseFormat(pattern);