5#include <QtCore/QDebug>
6#include <QtCore/QTextStream>
92 return s.startsWith(u
"?(")
108 int k1 =
static_cast<int>(
p1.kind());
109 int k2 =
static_cast<int>(
p2.kind());
118 return p1.data.field.fieldName.compare(
p2.data.field.fieldName);
120 if (
p1.data.index.indexValue <
p2.data.index.indexValue)
122 if (
p1.data.index.indexValue >
p2.data.index.indexValue)
126 return p1.data.key.keyValue.compare(
p2.data.key.keyValue);
135 int c = int(
k1) - int(k2);
138 return p1.data.root.contextName.compare(
p2.data.root.contextName);
142 int c = int(
p1.data.current.contextKind) - int(
p2.data.current.contextKind);
145 return p1.data.current.contextName.compare(
p2.data.current.contextName);
151 int c =
p1.data.filter.filterDescription.compare(
p2.data.filter.filterDescription);
154 if (
p1.data.filter.filterDescription.startsWith(u
"<")) {
166 Q_ASSERT(
false &&
"unexpected PathComponent in PathComponent::cmp");
177 if (
i >= m_length ||
i < 0) {
178 Q_ASSERT(
false &&
"index out of bounds");
179 return emptyComponent;
181 i =
i - m_length - m_endOffset;
182 auto data = m_data.get();
184 i +=
data->components.size();
186 return std::as_const(
data)->components[
i];
189 Q_ASSERT(
false &&
"Invalid data reached while resolving a seemengly valid index in Path (inconsisten Path object)");
190 return emptyComponent;
198QQmlJS::Dom::Path::operator bool()
const
215 auto &comp = component(0);
217 return r->contextKind;
223 auto comp = component(0);
225 return c->contextKind;
232 return Path::Kind::Empty;
233 return component(0).
kind();
238 return component(0).
name();
248 return component(0).
index(defaultValue);
253 auto &comp = component(0);
255 return f->filterFunction;
267 return mid(m_length-1, 1);
275 if (
c.kind() == Kind::Field ||
c.kind() == Kind::Root ||
c.kind() == Kind::Current) {
288 return diff >= 0 && diff <
base.
size();
314 for (
int i=0;
i <
s.size(); ++
i)
315 if (
s.at(
i) == lsBrace ||
s.at(
i) ==
dot)
323 while (
i <
s.size()) {
325 while (
i <
s.size() &&
s.at(
i).isSpace())
334 while (
i <
s.size() &&
s.at(
i).isLetterOrNumber()){
339 }
else if (
c ==
at) {
341 while (
i <
s.size() &&
s.at(
i).isLetterOrNumber()){
346 }
else if (
c.isLetter()) {
347 myErrors().
warning(
tr(
"Field expressions should start with a dot, even when at the start of the path %1.")
358 while (
i <
s.size() &&
s.at(
i).isDigit())
368 }
else if (
c.isLetter() ||
c == tilda ||
c == underscore) {
370 while (
i <
s.size() && (
s.at(
i).isLetterOrNumber() ||
s.at(
i) == underscore ||
s.at(
i) == tilda))
376 bool properEnd =
false;
377 while (
i <
s.size()) {
382 }
else if (
c == backslash) {
383 strVal.
append(
s.mid(i0,
i - i0).toString());
398 strVal.
append(
s.mid(i0,
i - i0).toString());
409 while (
i <
s.size() &&
s.at(
i).isSpace())
412 myErrors().
error(
tr(
"Expected a brace in filter after the question mark (at char %1).")
419 myErrors().
error(
tr(
"Expected a closing brace in filter after the question mark (at char %1).")
428 myErrors().
error(
tr(
"Unexpected character '%1' after square bracket at %2.")
432 while (
i <
s.size() &&
s.at(
i).isSpace()) ++
i;
433 if (
i >=
s.size() ||
s.at(
i) != rsBrace) {
444 while (
i <
s.size() &&
s.at(
i).isSpace()) ++
i;
448 }
else if (
s.at(
i).isLetter() ||
s.at(
i) == underscore ||
s.at(
i) == tilda) {
450 while (
i <
s.size() && (
s.at(
i).isLetterOrNumber() ||
s.at(
i) == underscore ||
s.at(
i) == tilda)) {
455 }
else if (
s.at(
i).isDigit()) {
457 while (
i <
s.size() &&
s.at(
i).isDigit()){
468 myErrors().
info(
tr(
"Index should use square brackets and not a dot (at char %1).")
472 }
else if (
s.at(
i) ==
dot ||
s.at(
i) == lsBrace) {
475 }
else if (
s.at(
i) ==
at) {
477 while (
i <
s.size() &&
s.at(
i).isLetterOrNumber()){
482 }
else if (
s.at(
i) == dollar) {
484 while (
i <
s.size() &&
s.at(
i).isLetterOrNumber()){
491 myErrors().
error(
tr(
"Unexpected character '%1' after dot (at char %2).")
496 }
else if (
c == lsBrace) {
499 myErrors().
error(
tr(
"Unexpected character '%1' after end of component (char %2).")
515 return Path(0,
components.size(), std::make_shared<PathEls::PathData>(
518 Q_ASSERT(
false &&
"Unexpected state in Path::fromString");
524 return Path(0,1,std::make_shared<PathEls::PathData>(
530 return Path(0,1,std::make_shared<PathEls::PathData>(
536 return Path(0,1,std::make_shared<PathEls::PathData>(
542 return Path(0,1,std::make_shared<PathEls::PathData>(
549 return Path(0,1,std::make_shared<PathEls::PathData>(
555 return Path(0,1,std::make_shared<PathEls::PathData>(
563 std::make_shared<PathEls::PathData>(
570 std::make_shared<PathEls::PathData>(
576 return Path(0,1,std::make_shared<PathEls::PathData>(
582 return Path(0,1,std::make_shared<PathEls::PathData>(
588 return Path(0,1,std::make_shared<PathEls::PathData>(
599 if (m_endOffset != 0)
600 return noEndOffset().
empty();
601 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
608 res.m_data->strData.append(
name);
614 if (m_endOffset != 0)
616 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
622 if (m_endOffset != 0)
623 return noEndOffset().
key(
name);
624 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
635 if (m_endOffset != 0)
636 return noEndOffset().
index(
i);
637 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
643 if (m_endOffset != 0)
644 return noEndOffset().
any();
645 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
652 res.m_data->strData.append(
desc);
658 if (m_endOffset != 0)
660 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
666 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
673 res.m_data->strData.append(
s);
679 if (m_endOffset != 0)
681 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
685Path Path::path(
Path toAdd,
bool avoidToAddAsBase)
const
690 if (m_endOffset != 0) {
692 if (thisExtended.
length() > resLength)
693 thisExtended = thisExtended.
mid(0, resLength);
695 if (added == toAdd.
mid(0, toAdd.
length())) {
696 if (resLength == thisExtended.
length())
702 if (!avoidToAddAsBase) {
704 if (toAddExtended.
length() >= resLength) {
705 toAddExtended = toAddExtended.
mid(toAddExtended.
length() - resLength, resLength);
706 if (toAddExtended.
mid(0,
length()) == *
this)
707 return toAddExtended;
713 bool addHasStr =
false;
714 auto data = toAdd.m_data.get();
716 if (!
data->strData.isEmpty()) {
726 myStrs.append(
data->strData);
729 data = toAdd.m_data.get();
731 for (
int ij = 0; ij <
data->strData.size(); ++ij) {
732 bool hasAlready =
false;
733 for (
int ii = 0; ii < myStrs.size() && !hasAlready; ++ii)
736 addedStrs.append(
data->strData[ij]);
742 for (
int i = 0;
i < toAdd.
length(); ++
i) {
746 for (
int j = 0;
j < addedStrs.size(); ++
j) {
748 toAddStrs.append(addedStrs[
j]);
749 addedStrs.removeAt(
j);
755 return Path(0, m_length + toAdd.
length(), std::make_shared<PathEls::PathData>(
756 toAddStrs,
components, ((m_endOffset == 0) ? m_data : noEndOffset().m_data)));
762 auto data = m_data.get();
764 newLen +=
data->components.size();
767 newLen -= m_endOffset;
768 return Path(m_endOffset, newLen, m_data);
774 return Path(0, m_length + m_endOffset, m_data);
796 const int lMin =
qMin(
p1.m_length,
p2.m_length);
797 if (
p1.m_data.get() ==
p2.m_data.get() &&
p1.m_endOffset ==
p2.m_endOffset &&
p1.m_length ==
p2.m_length)
799 for (
int i = 0;
i < lMin; ++
i) {
804 if (lMin <
p2.m_length)
806 if (
p1.m_length > lMin)
816Path Path::noEndOffset()
const
820 if (m_endOffset == 0)
823 qint16 endOffset = m_endOffset;
824 std::shared_ptr<PathEls::PathData> lastData = m_data;
825 while (lastData && endOffset >= lastData->components.size()) {
826 endOffset -= lastData->components.size();
827 lastData = lastData->parent;
830 Q_ASSERT(lastData &&
"Internal problem, reference to non existing PathData");
831 return Path(0, m_length, std::make_shared<PathEls::PathData>(
832 lastData->strData, lastData->components.mid(0, lastData->components.size() - endOffset), lastData->parent));
834 return Path(0, m_length, lastData);
839 if (m_endOffset != 0) {
840 Path newP = noEndOffset();
843 if (m_data && m_data.use_count() != 1) {
846 newP.m_data->parent = m_data;
847 newP.m_length =
static_cast<quint16>(m_length + 1);
852 : std::make_shared<PathEls::PathData>(
QStringList(),
861 my_data->components.append(
c);
865 my_data->strData.append(
c.asCurrent()->contextName.toString());
868 my_data->components.append(
c);
872 if (!
c.base()->asFilter()->filterDescription.isEmpty()) {
873 my_data->strData.append(
c.base()->asFilter()->filterDescription.toString());
874 my_data->components.append(
875 PathEls::Filter(
c.base()->asFilter()->filterFunction, my_data->strData.last()));
877 my_data->components.append(
c);
881 my_data->components.append(
c);
885 my_data->strData.append(
c.asRoot()->contextName.toString());
886 my_data->components.append(
PathEls::Root(my_data->strData.last()));
888 my_data->components.append(
c);
894 return Path { 0,
static_cast<quint16>(m_length + 1), my_data };
906 for (
int i = 0;
i < m_length; ++
i) {
907 auto &
c = component(
i);
908 if (!
c.hasSquareBrackets()) {
909 if (!
first || (
c.kind() != Kind::Root &&
c.kind() != Kind::Current))
928 if (m_length >
n &&
n >= 0)
929 return Path(m_endOffset, m_length -
n, m_data);
935 if (m_length >
n &&
n >= 0)
936 return Path(m_endOffset +
n, m_length -
n, m_data);
943 if (offset < 0 || offset >= m_length || length <= 0 || length > m_length)
945 int newEndOffset = m_endOffset + m_length -
offset -
length;
958 res.m_data->strData.append(
s);
966#include "moc_qqmldompath_p.cpp"
static constexpr QChar fromLatin1(char c) noexcept
Converts the Latin-1 character c to its equivalent QChar.
QString arg(Args &&...args) const
Represents a set of tags grouping a set of related error messages.
ErrorMessage info(QString message) const
ErrorMessage warning(QString message) const
ErrorMessage error(QString message) const
ErrorMessage handle(const ErrorHandler &errorHandler=nullptr)
virtual bool hasSquareBrackets() const
virtual void dump(Sink sink) const
virtual QString name() const =0
const Current * asCurrent() const override
bool checkName(QStringView s) const override
QStringView filterDescription
QString name() const override
const Filter * asFilter() const override
bool checkName(QStringView s) const
static int cmp(const PathComponent &p1, const PathComponent &p2)
QStringView stringView() const
index_type index(index_type defaultValue=-1) const
const Root * asRoot() const override
PathCurrent headCurrent() const
Path dropTail(int n=1) const
void dump(Sink sink) 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(QString name) const
Path path(Path toAdd, bool avoidToAddAsBase=false) const
Path appendComponent(const PathEls::PathComponent &c)
std::function< bool(DomItem)> headFilter() const
PathIterator begin() const
Path current(PathCurrent s) const
static ErrorGroups myErrors()
Path field(QString name) const
bool checkHeadName(QStringView name) const
Path operator[](int i) const
static Path Index(index_type i)
Path mid(int offset, int length) const
static Path fromString(QString s, ErrorHandler errorHandler=nullptr)
Path filter(std::function< bool(DomItem)>, QString) const
static Path Field(QStringView s=u"")
Path index(index_type i) const
Path dropFront(int n=1) const
static Path Current(PathCurrent c)
PathEls::PathComponent Component
PathRoot headRoot() const
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
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
const QChar * constData() const
Returns a pointer to the data stored in the QString.
qsizetype size() const
Returns the number of characters in this string.
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...
QString & append(QChar c)
std::function< void(const ErrorMessage &)> ErrorHandler
bool inQString(QStringView el, QString base)
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
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 GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
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)