5#include <QtCore/QDebug>
6#include <QtCore/QTextStream>
86 : filterFunction(
f), filterDescription(filterDescription) {}
106 int k1 =
static_cast<int>(
p1.kind());
107 int k2 =
static_cast<int>(
p2.kind());
116 return std::get<Field>(
p1.m_data).fieldName.compare(std::get<Field>(
p2.m_data).fieldName);
118 if (std::get<Index>(
p1.m_data).indexValue < std::get<Index>(
p2.m_data).indexValue)
120 if (std::get<Index>(
p1.m_data).indexValue > std::get<Index>(
p2.m_data).indexValue)
124 return std::get<Key>(
p1.m_data).keyValue.compare(std::get<Key>(
p2.m_data).keyValue);
128 PathRoot k2 = std::get<Root>(
p2.m_data).contextKind;
133 int c = int(
k1) - int(k2);
136 return std::get<Root>(
p1.m_data).contextName.compare(std::get<Root>(
p2.m_data).contextName);
140 int c = int(std::get<Current>(
p1.m_data).contextKind)
141 - int(std::get<Current>(
p2.m_data).contextKind);
144 return std::get<Current>(
p1.m_data).contextName
145 .compare(std::get<Current>(
p2.m_data).contextName);
151 int c = std::get<Filter>(
p1.m_data).filterDescription
152 .compare(std::get<Filter>(
p2.m_data).filterDescription);
155 if (std::get<Filter>(
p1.m_data).filterDescription.startsWith(u
"<")) {
167 Q_ASSERT(
false &&
"unexpected PathComponent in PathComponent::cmp");
178 if (
i >= m_length ||
i < 0) {
179 Q_ASSERT(
false &&
"index out of bounds");
180 return emptyComponent;
182 i =
i - m_length - m_endOffset;
183 auto data = m_data.get();
185 i +=
data->components.size();
187 return std::as_const(
data)->components[
i];
190 Q_ASSERT(
false &&
"Invalid data reached while resolving a seemengly valid index in Path (inconsisten Path object)");
191 return emptyComponent;
199QQmlJS::Dom::Path::operator bool()
const
216 auto &comp = component(0);
218 return r->contextKind;
224 auto comp = component(0);
226 return c->contextKind;
233 return Path::Kind::Empty;
234 return component(0).
kind();
239 return component(0).
name();
249 return component(0).
index(defaultValue);
254 auto &comp = component(0);
256 return f->filterFunction;
268 return mid(m_length-1, 1);
276 if (
c.kind() == Kind::Field ||
c.kind() == Kind::Root ||
c.kind() == Kind::Current) {
289 return diff >= 0 && diff <
base.size();
298 return diff >= 0 && diff <
base.size() && diff +
el.
size() <
base.size();
306 const QChar dot = QChar::fromLatin1(
'.');
307 const QChar lsBrace = QChar::fromLatin1(
'[');
308 const QChar rsBrace = QChar::fromLatin1(
']');
309 const QChar dollar = QChar::fromLatin1(
'$');
310 const QChar at = QChar::fromLatin1(
'@');
312 const QChar backslash = QChar::fromLatin1(
'\\');
313 const QChar underscore = QChar::fromLatin1(
'_');
314 const QChar tilda = QChar::fromLatin1(
'~');
315 for (
int i=0;
i <
s.size(); ++
i)
316 if (
s.at(
i) == lsBrace ||
s.at(
i) ==
dot)
324 while (
i <
s.size()) {
326 while (
i <
s.size() &&
s.at(
i).isSpace())
335 while (
i <
s.size() &&
s.at(
i).isLetterOrNumber()){
340 }
else if (
c ==
at) {
342 while (
i <
s.size() &&
s.at(
i).isLetterOrNumber()){
347 }
else if (
c.isLetter()) {
348 myErrors().warning(
tr(
"Field expressions should start with a dot, even when at the start of the path %1.")
349 .
arg(
s)).handle(errorHandler);
359 while (
i <
s.size() &&
s.at(
i).isDigit())
365 myErrors().warning(
tr(
"Error extracting integer from '%1' at char %2.")
369 }
else if (
c.isLetter() ||
c == tilda ||
c == underscore) {
371 while (
i <
s.size() && (
s.at(
i).isLetterOrNumber() ||
s.at(
i) == underscore ||
s.at(
i) == tilda))
377 bool properEnd =
false;
378 while (
i <
s.size()) {
383 }
else if (
c == backslash) {
384 strVal.append(
s.mid(i0,
i - i0).toString());
387 if (
c == QChar::fromLatin1(
'n'))
388 strVal.append(QChar::fromLatin1(
'\n'));
389 else if (
c == QChar::fromLatin1(
'r'))
390 strVal.append(QChar::fromLatin1(
'\r'));
391 else if (
c == QChar::fromLatin1(
't'))
392 strVal.append(QChar::fromLatin1(
'\t'));
399 strVal.append(
s.mid(i0,
i - i0).toString());
402 myErrors().error(
tr(
"Unclosed quoted string at char %1.")
407 }
else if (
c == QChar::fromLatin1(
'*')) {
409 }
else if (
c == QChar::fromLatin1(
'?')) {
410 while (
i <
s.size() &&
s.at(
i).isSpace())
412 if (
i >=
s.size() ||
s.at(
i) != QChar::fromLatin1(
'(')) {
413 myErrors().error(
tr(
"Expected a brace in filter after the question mark (at char %1).")
418 while (
i <
s.size() &&
s.at(
i) != QChar::fromLatin1(
')')) ++
i;
419 if (
i >=
s.size() ||
s.at(
i) != QChar::fromLatin1(
')')) {
420 myErrors().error(
tr(
"Expected a closing brace in filter after the question mark (at char %1).")
426 myErrors().error(
tr(
"Filter from string not yet implemented.")).handle(errorHandler);
429 myErrors().error(
tr(
"Unexpected character '%1' after square bracket at %2.")
430 .
arg(
c).
arg(
i-1)).handle(errorHandler);
433 while (
i <
s.size() &&
s.at(
i).isSpace()) ++
i;
434 if (
i >=
s.size() ||
s.at(
i) != rsBrace) {
435 myErrors().error(
tr(
"square braces misses closing brace at char %1.")
445 while (
i <
s.size() &&
s.at(
i).isSpace()) ++
i;
449 }
else if (
s.at(
i).isLetter() ||
s.at(
i) == underscore ||
s.at(
i) == tilda) {
451 while (
i <
s.size() && (
s.at(
i).isLetterOrNumber() ||
s.at(
i) == underscore ||
s.at(
i) == tilda)) {
456 }
else if (
s.at(
i).isDigit()) {
458 while (
i <
s.size() &&
s.at(
i).isDigit()){
464 myErrors().warning(
tr(
"Error extracting integer from '%1' at char %2.")
469 myErrors().info(
tr(
"Index should use square brackets and not a dot (at char %1).")
473 }
else if (
s.at(
i) ==
dot ||
s.at(
i) == lsBrace) {
476 }
else if (
s.at(
i) ==
at) {
478 while (
i <
s.size() &&
s.at(
i).isLetterOrNumber()){
483 }
else if (
s.at(
i) == dollar) {
485 while (
i <
s.size() &&
s.at(
i).isLetterOrNumber()){
492 myErrors().error(
tr(
"Unexpected character '%1' after dot (at char %2).")
497 }
else if (
c == lsBrace) {
500 myErrors().error(
tr(
"Unexpected character '%1' after end of component (char %2).")
516 return Path(0,
components.size(), std::make_shared<PathEls::PathData>(
519 Q_ASSERT(
false &&
"Unexpected state in Path::fromString");
525 return Path(0,1,std::make_shared<PathEls::PathData>(
531 return Path(0,1,std::make_shared<PathEls::PathData>(
537 return Path(0,1,std::make_shared<PathEls::PathData>(
543 return Path(0,1,std::make_shared<PathEls::PathData>(
550 return Path(0,1,std::make_shared<PathEls::PathData>(
556 return Path(0,1,std::make_shared<PathEls::PathData>(
564 std::make_shared<PathEls::PathData>(
571 std::make_shared<PathEls::PathData>(
577 return Path(0,1,std::make_shared<PathEls::PathData>(
583 return Path(0,1,std::make_shared<PathEls::PathData>(
589 return Path(0,1,std::make_shared<PathEls::PathData>(
600 if (m_endOffset != 0)
601 return noEndOffset().
empty();
602 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
609 res.m_data->strData.append(
name);
615 if (m_endOffset != 0)
617 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
623 if (m_endOffset != 0)
624 return noEndOffset().
key(
name);
625 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
636 if (m_endOffset != 0)
637 return noEndOffset().
index(
i);
638 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
644 if (m_endOffset != 0)
645 return noEndOffset().
any();
646 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
653 res.m_data->strData.append(desc);
659 if (m_endOffset != 0)
661 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
667 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
674 res.m_data->strData.append(
s);
680 if (m_endOffset != 0)
682 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
686Path Path::path(
const Path &toAdd,
bool avoidToAddAsBase)
const
688 if (toAdd.length() == 0)
691 if (m_endOffset != 0) {
693 if (thisExtended.
length() > resLength)
694 thisExtended = thisExtended.mid(0, resLength);
696 if (added == toAdd.
mid(0, toAdd.length())) {
697 if (resLength == thisExtended.length())
700 return thisExtended.
path(toAdd.mid(added.
length(), resLength - thisExtended.length()));
703 if (!avoidToAddAsBase) {
705 if (toAddExtended.length() >= resLength) {
706 toAddExtended = toAddExtended.
mid(toAddExtended.length() - resLength, resLength);
707 if (toAddExtended.mid(0,
length()) == *
this)
708 return toAddExtended;
714 bool addHasStr =
false;
715 auto data = toAdd.m_data.get();
717 if (!
data->strData.isEmpty()) {
727 myStrs.append(
data->strData);
730 data = toAdd.m_data.get();
732 for (
int ij = 0; ij <
data->strData.size(); ++ij) {
733 bool hasAlready =
false;
734 for (
int ii = 0; ii < myStrs.size() && !hasAlready; ++ii)
737 addedStrs.append(
data->strData[ij]);
743 for (
int i = 0;
i < toAdd.length(); ++
i) {
745 QStringView compStrView = toAdd.component(
i).stringView();
746 if (!compStrView.isEmpty()) {
747 for (
int j = 0;
j < addedStrs.size(); ++
j) {
749 toAddStrs.append(addedStrs[
j]);
750 addedStrs.removeAt(
j);
756 return Path(0, m_length + toAdd.length(), std::make_shared<PathEls::PathData>(
757 toAddStrs,
components, ((m_endOffset == 0) ? m_data : noEndOffset().m_data)));
763 auto data = m_data.get();
765 newLen +=
data->components.size();
768 newLen -= m_endOffset;
769 return Path(m_endOffset, newLen, m_data);
775 return Path(0, m_length + m_endOffset, m_data);
797 const int lMin =
qMin(
p1.m_length,
p2.m_length);
798 if (
p1.m_data.get() ==
p2.m_data.get() &&
p1.m_endOffset ==
p2.m_endOffset &&
p1.m_length ==
p2.m_length)
800 for (
int i = 0;
i < lMin; ++
i) {
805 if (lMin <
p2.m_length)
807 if (
p1.m_length > lMin)
817Path Path::noEndOffset()
const
821 if (m_endOffset == 0)
824 qint16 endOffset = m_endOffset;
825 std::shared_ptr<PathEls::PathData> lastData = m_data;
826 while (lastData && endOffset >= lastData->components.size()) {
827 endOffset -= lastData->components.size();
828 lastData = lastData->parent;
831 Q_ASSERT(lastData &&
"Internal problem, reference to non existing PathData");
832 return Path(0, m_length, std::make_shared<PathEls::PathData>(
833 lastData->strData, lastData->components.mid(0, lastData->components.size() - endOffset), lastData->parent));
835 return Path(0, m_length, lastData);
840 if (m_endOffset != 0) {
841 Path newP = noEndOffset();
842 return newP.appendComponent(
c);
844 if (m_data && m_data.use_count() != 1) {
847 newP.m_data->parent = m_data;
848 newP.m_length =
static_cast<quint16>(m_length + 1);
853 : std::make_shared<PathEls::PathData>(
QStringList(),
854 QVector<PathEls::PathComponent>()));
862 my_data->components.append(
c);
866 my_data->strData.append(
c.asCurrent()->contextName.toString());
869 my_data->components.append(
c);
873 if (!
c.asFilter()->filterDescription.isEmpty()) {
874 my_data->strData.append(
c.asFilter()->filterDescription.toString());
875 my_data->components.append(
878 my_data->components.append(
c);
882 my_data->components.append(
c);
886 my_data->strData.append(
c.asRoot()->contextName.toString());
887 my_data->components.append(
PathEls::Root(my_data->strData.last()));
889 my_data->components.append(
c);
895 return Path { 0,
static_cast<quint16>(m_length + 1), my_data };
907 for (
int i = 0;
i < m_length; ++
i) {
908 auto &
c = component(
i);
909 if (!
c.hasSquareBrackets()) {
910 if (!
first || (
c.kind() != Kind::Root &&
c.kind() != Kind::Current))
929 if (m_length >
n &&
n >= 0)
930 return Path(m_endOffset, m_length -
n, m_data);
936 if (m_length >
n &&
n >= 0)
937 return Path(m_endOffset +
n, m_length -
n, m_data);
944 if (offset < 0 || offset >= m_length || length <= 0 || length > m_length)
946 int newEndOffset = m_endOffset + m_length -
offset -
length;
959 res.m_data->strData.append(
s);
967#include "moc_qqmldompath_p.cpp"
QString arg(Args &&...args) const
Represents a set of tags grouping a set of related error messages.
bool hasSquareBrackets() const
void dump(const Sink &sink, const QString &name, bool hasSquareBrackets) const
bool checkName(QStringView s) const
QStringView filterDescription
bool checkName(QStringView s) const
static int cmp(const PathComponent &p1, const PathComponent &p2)
index_type index(index_type defaultValue=-1) const
PathCurrent headCurrent() const
Path dropTail(int n=1) const
index_type headIndex(index_type defaultValue=-1) const
static Path Key(QStringView s=u"")
static int cmp(const Path &p1, const Path &p2)
static Path Root(PathRoot r)
Path key(const QString &name) const
Path field(const QString &name) const
Path appendComponent(const PathEls::PathComponent &c)
PathIterator begin() const
Path current(PathCurrent s) const
Path filter(const std::function< bool(const DomItem &)> &, const QString &) const
static ErrorGroups myErrors()
bool checkHeadName(QStringView name) const
Path operator[](int i) const
static Path Index(index_type i)
Path path(const Path &toAdd, bool avoidToAddAsBase=false) const
Path mid(int offset, int length) const
void dump(const Sink &sink) const
static Path fromString(const QString &s, const ErrorHandler &errorHandler=nullptr)
static Path Field(QStringView s=u"")
std::function< bool(const DomItem &) headFilter)() const
Path index(index_type i) const
Path dropFront(int n=1) const
static Path Current(PathCurrent c)
PathEls::PathComponent Component
PathRoot headRoot() const
constexpr qsizetype size() const noexcept
Returns the size of this string view, in UTF-16 code units (that is, surrogate pairs count as two for...
const_iterator begin() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first character in the st...
bool endsWith(QStringView s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
const_pointer constData() const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool inQString(QStringView el, const QString &base)
std::function< void(const ErrorMessage &)> ErrorHandler
Combined button and popup list for selecting options.
QList< QString > QStringList
Constructs a string list that contains the given string, str.
DBusConnection const char DBusError * error
constexpr const T & qMin(const T &a, const T &b)
GLint GLenum GLint components
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLenum GLuint GLintptr offset
GLsizei GLenum GLboolean sink
static qreal dot(const QPointF &a, const QPointF &b)
#define NewErrorGroup(name)
QLatin1StringView QLatin1String
static QString quote(const QString &str)