Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmldompath.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#include "qqmldomitem_p.h"
5#include <QtCore/QDebug>
6#include <QtCore/QTextStream>
7#include <QtCore/QChar>
8
9#include <cstdint>
10
12namespace QQmlJS {
13namespace Dom {
14class ErrorMessage;
15
16namespace PathEls {
17
77void Base::dump(Sink sink) const {
79 sink(u"[");
80 sink(name());
82 sink(u"]");
83}
84
85Filter::Filter(function<bool(DomItem)> f, QStringView filterDescription): filterFunction(f), filterDescription(filterDescription) {}
86
88 return QLatin1String("?(%1)").arg(filterDescription); }
89
91{
92 return s.startsWith(u"?(")
93 && s.mid(2, s.size()-3) == filterDescription
94 && s.endsWith(u")");
95}
96
97enum class ParserState{
98 Start,
100 End
101};
102
104}
105
107{
108 int k1 = static_cast<int>(p1.kind());
109 int k2 = static_cast<int>(p2.kind());
110 if (k1 < k2)
111 return -1;
112 if (k1 > k2)
113 return 1;
114 switch (p1.kind()) {
115 case Kind::Empty:
116 return 0;
117 case Kind::Field:
118 return p1.data.field.fieldName.compare(p2.data.field.fieldName);
119 case Kind::Index:
120 if (p1.data.index.indexValue < p2.data.index.indexValue)
121 return -1;
122 if (p1.data.index.indexValue > p2.data.index.indexValue)
123 return 1;
124 return 0;
125 case Kind::Key:
126 return p1.data.key.keyValue.compare(p2.data.key.keyValue);
127 case Kind::Root:
128 {
129 PathRoot k1 = p1.data.root.contextKind;
130 PathRoot k2 = p2.data.root.contextKind;
133 if (k2 == PathRoot::Env || k2 == PathRoot::Universe)
134 k2 = PathRoot::Top;
135 int c = int(k1) - int(k2);
136 if (c != 0)
137 return c;
138 return p1.data.root.contextName.compare(p2.data.root.contextName);
139 }
140 case Kind::Current:
141 {
142 int c = int(p1.data.current.contextKind) - int(p2.data.current.contextKind);
143 if (c != 0)
144 return c;
145 return p1.data.current.contextName.compare(p2.data.current.contextName);
146 }
147 case Kind::Any:
148 return 0;
149 case Kind::Filter:
150 {
151 int c = p1.data.filter.filterDescription.compare(p2.data.filter.filterDescription);
152 if (c != 0)
153 return c;
154 if (p1.data.filter.filterDescription.startsWith(u"<")) {
155 // assuming non comparable native code (target comparison is not portable)
156 auto pp1 = &p1;
157 auto pp2 = &p2;
158 if (pp1 < pp2)
159 return -1;
160 if (pp1 > pp2)
161 return 1;
162 }
163 return 0;
164 }
165 }
166 Q_ASSERT(false && "unexpected PathComponent in PathComponent::cmp");
167 return 0;
168}
169
170} // namespace PathEls
171
172const PathEls::PathComponent &Path::component(int i) const
173{
174 static Component emptyComponent;
175 if (i < 0)
176 i += m_length;
177 if (i >= m_length || i < 0) {
178 Q_ASSERT(false && "index out of bounds");
179 return emptyComponent;
180 }
181 i = i - m_length - m_endOffset;
182 auto data = m_data.get();
183 while (data) {
184 i += data->components.size();
185 if (i >= 0)
186 return std::as_const(data)->components[i];
187 data = data->parent.get();
188 }
189 Q_ASSERT(false && "Invalid data reached while resolving a seemengly valid index in Path (inconsisten Path object)");
190 return emptyComponent;
191}
192
194{
195 return mid(i,1);
196}
197
198QQmlJS::Dom::Path::operator bool() const
199{
200 return length() != 0;
201}
202
204{
205 return PathIterator{*this};
206}
207
209{
210 return PathIterator();
211}
212
214{
215 auto &comp = component(0);
216 if (PathEls::Root const * r = comp.base()->asRoot())
217 return r->contextKind;
218 return PathRoot::Other;
219}
220
222{
223 auto comp = component(0);
224 if (PathEls::Current const * c = comp.base()->asCurrent())
225 return c->contextKind;
226 return PathCurrent::Other;
227}
228
230{
231 if (m_length == 0)
232 return Path::Kind::Empty;
233 return component(0).kind();
234}
235
237{
238 return component(0).name();
239}
240
242{
243 return component(0).checkName(name);
244}
245
247{
248 return component(0).index(defaultValue);
249}
250
252{
253 auto &comp = component(0);
254 if (PathEls::Filter const * f = comp.base()->asFilter()) {
255 return f->filterFunction;
256 }
257 return {};
258}
259
261{
262 return mid(0,1);
263}
264
266{
267 return mid(m_length-1, 1);
268}
269
271{
272 int i = length();
273 while (i>0) {
274 const PathEls::PathComponent &c=component(--i);
275 if (c.kind() == Kind::Field || c.kind() == Kind::Root || c.kind() == Kind::Current) {
276 return Source{mid(0, i), mid(i)};
277 }
278 }
279 return Source{Path(), *this};
280}
281
283{
286 return false;
287 ptrdiff_t diff = base.constData() - el.begin();
288 return diff >= 0 && diff < base.size();
289}
290
292{
295 return false;
296 ptrdiff_t diff = base.constData() - el.constData();
297 return diff >= 0 && diff < base.size() && diff + el.size() < base.size();
298}
299
301{
302 if (s.isEmpty())
303 return Path();
304 int len=1;
305 const QChar dot = QChar::fromLatin1('.');
306 const QChar lsBrace = QChar::fromLatin1('[');
307 const QChar rsBrace = QChar::fromLatin1(']');
308 const QChar dollar = QChar::fromLatin1('$');
309 const QChar at = QChar::fromLatin1('@');
310 const QChar quote = QChar::fromLatin1('"');
311 const QChar backslash = QChar::fromLatin1('\\');
312 const QChar underscore = QChar::fromLatin1('_');
313 const QChar tilda = QChar::fromLatin1('~');
314 for (int i=0; i < s.size(); ++i)
315 if (s.at(i) == lsBrace || s.at(i) == dot)
316 ++len;
318 components.reserve(len);
319 int i = 0;
320 int i0 = 0;
322 QStringList strVals;
323 while (i < s.size()) {
324 // skip space
325 while (i < s.size() && s.at(i).isSpace())
326 ++i;
327 if (i >= s.size())
328 break;
329 QChar c = s.at(i++);
330 switch (state) {
332 if (c == dollar) {
333 i0 = i;
334 while (i < s.size() && s.at(i).isLetterOrNumber()){
335 ++i;
336 }
337 components.append(Component(PathEls::Root(s.mid(i0,i-i0))));
339 } else if (c == at) {
340 i0 = i;
341 while (i < s.size() && s.at(i).isLetterOrNumber()){
342 ++i;
343 }
344 components.append(Component(PathEls::Current(s.mid(i0,i-i0))));
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.")
348 .arg(s)).handle(errorHandler);
349 return Path();
350 } else {
351 --i;
353 }
354 break;
356 if (c.isDigit()) {
357 i0 = i-1;
358 while (i < s.size() && s.at(i).isDigit())
359 ++i;
360 bool ok;
361 components.append(Component(static_cast<index_type>(s.mid(i0,i-i0).toString()
362 .toLongLong(&ok))));
363 if (!ok) {
364 myErrors().warning(tr("Error extracting integer from '%1' at char %2.")
365 .arg(s.mid(i0,i-i0))
366 .arg(QString::number(i0))).handle(errorHandler);
367 }
368 } else if (c.isLetter() || c == tilda || c == underscore) {
369 i0 = i-1;
370 while (i < s.size() && (s.at(i).isLetterOrNumber() || s.at(i) == underscore || s.at(i) == tilda))
371 ++i;
372 components.append(Component(PathEls::Key(s.mid(i0, i - i0).toString())));
373 } else if (c == quote) {
374 i0 = i;
375 QString strVal;
376 bool properEnd = false;
377 while (i < s.size()) {
378 c = s.at(i);
379 if (c == quote) {
380 properEnd = true;
381 break;
382 } else if (c == backslash) {
383 strVal.append(s.mid(i0, i - i0).toString());
384 c = s.at(++i);
385 i0 = i + 1;
386 if (c == QChar::fromLatin1('n'))
387 strVal.append(QChar::fromLatin1('\n'));
388 else if (c == QChar::fromLatin1('r'))
389 strVal.append(QChar::fromLatin1('\r'));
390 else if (c == QChar::fromLatin1('t'))
391 strVal.append(QChar::fromLatin1('\t'));
392 else
393 strVal.append(c);
394 }
395 ++i;
396 }
397 if (properEnd) {
398 strVal.append(s.mid(i0, i - i0).toString());
399 ++i;
400 } else {
401 myErrors().error(tr("Unclosed quoted string at char %1.")
402 .arg(QString::number(i - 1))).handle(errorHandler);
403 return Path();
404 }
405 components.append(PathEls::Key(strVal));
406 } else if (c == QChar::fromLatin1('*')) {
408 } else if (c == QChar::fromLatin1('?')) {
409 while (i < s.size() && s.at(i).isSpace())
410 ++i;
411 if (i >= s.size() || s.at(i) != QChar::fromLatin1('(')) {
412 myErrors().error(tr("Expected a brace in filter after the question mark (at char %1).")
413 .arg(QString::number(i))).handle(errorHandler);
414 return Path();
415 }
416 i0 = ++i;
417 while (i < s.size() && s.at(i) != QChar::fromLatin1(')')) ++i; // check matching braces when skipping??
418 if (i >= s.size() || s.at(i) != QChar::fromLatin1(')')) {
419 myErrors().error(tr("Expected a closing brace in filter after the question mark (at char %1).")
420 .arg(QString::number(i))).handle(errorHandler);
421 return Path();
422 }
423 //auto filterDesc = s.mid(i0,i-i0);
424 ++i;
425 myErrors().error(tr("Filter from string not yet implemented.")).handle(errorHandler);
426 return Path();
427 } else {
428 myErrors().error(tr("Unexpected character '%1' after square bracket at %2.")
429 .arg(c).arg(i-1)).handle(errorHandler);
430 return Path();
431 }
432 while (i < s.size() && s.at(i).isSpace()) ++i;
433 if (i >= s.size() || s.at(i) != rsBrace) {
434 myErrors().error(tr("square braces misses closing brace at char %1.")
435 .arg(QString::number(i))).handle(errorHandler);
436 return Path();
437 } else {
438 ++i;
439 }
441 break;
443 if (c == dot) {
444 while (i < s.size() && s.at(i).isSpace()) ++i;
445 if (i == s.size()) {
446 components.append(Component());
448 } else if (s.at(i).isLetter() || s.at(i) == underscore || s.at(i) == tilda) {
449 i0 = i;
450 while (i < s.size() && (s.at(i).isLetterOrNumber() || s.at(i) == underscore || s.at(i) == tilda)) {
451 ++i;
452 }
453 components.append(Component(PathEls::Field(s.mid(i0,i-i0))));
455 } else if (s.at(i).isDigit()) {
456 i0 = i;
457 while (i < s.size() && s.at(i).isDigit()){
458 ++i;
459 }
460 bool ok;
461 components.append(Component(static_cast<index_type>(s.mid(i0,i-i0).toString().toLongLong(&ok))));
462 if (!ok) {
463 myErrors().warning(tr("Error extracting integer from '%1' at char %2.")
464 .arg(s.mid(i0,i-i0))
465 .arg(QString::number(i0))).handle(errorHandler);
466 return Path();
467 } else {
468 myErrors().info(tr("Index should use square brackets and not a dot (at char %1).")
469 .arg(QString::number(i0))).handle(errorHandler);
470 }
472 } else if (s.at(i) == dot || s.at(i) == lsBrace) {
473 components.append(Component());
475 } else if (s.at(i) == at) {
476 i0 = ++i;
477 while (i < s.size() && s.at(i).isLetterOrNumber()){
478 ++i;
479 }
480 components.append(Component(PathEls::Current(s.mid(i0,i-i0))));
482 } else if (s.at(i) == dollar) {
483 i0 = ++i;
484 while (i < s.size() && s.at(i).isLetterOrNumber()){
485 ++i;
486 }
487 components.append(Component(PathEls::Root(s.mid(i0,i-i0))));
489 } else {
490 c=s.at(i);
491 myErrors().error(tr("Unexpected character '%1' after dot (at char %2).")
492 .arg(QStringView(&c,1))
493 .arg(QString::number(i-1))).handle(errorHandler);
494 return Path();
495 }
496 } else if (c == lsBrace) {
498 } else {
499 myErrors().error(tr("Unexpected character '%1' after end of component (char %2).")
500 .arg(QStringView(&c,1))
501 .arg(QString::number(i-1))).handle(errorHandler);
502 return Path();
503 }
504 break;
505 }
506 }
507 switch (state) {
509 return Path();
511 errorHandler(myErrors().error(tr("unclosed square brace at end.")));
512
513 return Path();
515 return Path(0, components.size(), std::make_shared<PathEls::PathData>(
516 strVals, components));
517 }
518 Q_ASSERT(false && "Unexpected state in Path::fromString");
519 return Path();
520}
521
523{
524 return Path(0,1,std::make_shared<PathEls::PathData>(
526}
527
529{
530 return Path(0,1,std::make_shared<PathEls::PathData>(
532}
533
535{
536 return Path(0,1,std::make_shared<PathEls::PathData>(
538}
539
541{
542 return Path(0,1,std::make_shared<PathEls::PathData>(
544}
545
546
548{
549 return Path(0,1,std::make_shared<PathEls::PathData>(
551}
552
554{
555 return Path(0,1,std::make_shared<PathEls::PathData>(
557}
558
560{
561 return Path(
562 0, 1,
563 std::make_shared<PathEls::PathData>(
565}
566
568{
569 return Path(0, 1,
570 std::make_shared<PathEls::PathData>(
572}
573
575{
576 return Path(0,1,std::make_shared<PathEls::PathData>(
578}
579
581{
582 return Path(0,1,std::make_shared<PathEls::PathData>(
584}
585
587{
588 return Path(0,1,std::make_shared<PathEls::PathData>(
590}
591
593{
594 return Path();
595}
596
598{
599 if (m_endOffset != 0)
600 return noEndOffset().empty();
601 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
602 QStringList(), QVector<Component>(1,Component()), m_data));
603}
604
606{
607 auto res = field(QStringView(name));
608 res.m_data->strData.append(name);
609 return res;
610}
611
613{
614 if (m_endOffset != 0)
615 return noEndOffset().field(name);
616 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
618}
619
621{
622 if (m_endOffset != 0)
623 return noEndOffset().key(name);
624 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
626}
627
629{
630 return key(name.toString());
631}
632
634{
635 if (m_endOffset != 0)
636 return noEndOffset().index(i);
637 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
638 QStringList(), QVector<Component>(1,Component(i)), m_data));
639}
640
642{
643 if (m_endOffset != 0)
644 return noEndOffset().any();
645 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
647}
648
649Path Path::filter(function<bool (DomItem)> filterF, QString desc) const
650{
651 auto res = filter(filterF, QStringView(desc));
652 res.m_data->strData.append(desc);
653 return res;
654}
655
656Path Path::filter(function<bool (DomItem)> filter, QStringView desc) const
657{
658 if (m_endOffset != 0)
659 return noEndOffset().filter(filter, desc);
660 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
661 QStringList(), QVector<Component>(1,Component(PathEls::Filter(filter, desc))), m_data));
662}
663
665{
666 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
668}
669
671{
672 auto res = current(QStringView(s));
673 res.m_data->strData.append(s);
674 return res;
675}
676
678{
679 if (m_endOffset != 0)
680 return noEndOffset().current(s);
681 return Path(0,m_length+1,std::make_shared<PathEls::PathData>(
683}
684
685Path Path::path(Path toAdd, bool avoidToAddAsBase) const
686{
687 if (toAdd.length() == 0)
688 return *this;
689 int resLength = length() + toAdd.length();
690 if (m_endOffset != 0) {
691 Path thisExtended = this->expandBack();
692 if (thisExtended.length() > resLength)
693 thisExtended = thisExtended.mid(0, resLength);
694 Path added = thisExtended.mid(length(), thisExtended.length() - length());
695 if (added == toAdd.mid(0, toAdd.length())) {
696 if (resLength == thisExtended.length())
697 return thisExtended;
698 else
699 return thisExtended.path(toAdd.mid(added.length(), resLength - thisExtended.length()));
700 }
701 }
702 if (!avoidToAddAsBase) {
703 Path toAddExtended = toAdd.expandFront();
704 if (toAddExtended.length() >= resLength) {
705 toAddExtended = toAddExtended.mid(toAddExtended.length() - resLength, resLength);
706 if (toAddExtended.mid(0,length()) == *this)
707 return toAddExtended;
708 }
709 }
711 components.reserve(toAdd.length());
712 QStringList addedStrs;
713 bool addHasStr = false;
714 auto data = toAdd.m_data.get();
715 while (data) {
716 if (!data->strData.isEmpty()) {
717 addHasStr = true;
718 break;
719 }
720 data = data->parent.get();
721 }
722 if (addHasStr) {
723 QStringList myStrs;
724 data = m_data.get();
725 while (data) {
726 myStrs.append(data->strData);
727 data = data->parent.get();
728 }
729 data = toAdd.m_data.get();
730 while (data) {
731 for (int ij = 0; ij < data->strData.size(); ++ij) {
732 bool hasAlready = false;
733 for (int ii = 0; ii < myStrs.size() && !hasAlready; ++ii)
734 hasAlready = inQString(data->strData[ij], myStrs[ii]);
735 if (!hasAlready)
736 addedStrs.append(data->strData[ij]);
737 }
738 data = data->parent.get();
739 }
740 }
741 QStringList toAddStrs;
742 for (int i = 0; i < toAdd.length(); ++i) {
743 components.append(toAdd.component(i));
744 QStringView compStrView = toAdd.component(i).stringView();
745 if (!compStrView.isEmpty()) {
746 for (int j = 0; j < addedStrs.size(); ++j) {
747 if (inQString(compStrView, addedStrs[j])) {
748 toAddStrs.append(addedStrs[j]);
749 addedStrs.removeAt(j);
750 break;
751 }
752 }
753 }
754 }
755 return Path(0, m_length + toAdd.length(), std::make_shared<PathEls::PathData>(
756 toAddStrs, components, ((m_endOffset == 0) ? m_data : noEndOffset().m_data)));
757}
758
760{
761 int newLen = 0;
762 auto data = m_data.get();
763 while (data) {
764 newLen += data->components.size();
765 data = data->parent.get();
766 }
767 newLen -= m_endOffset;
768 return Path(m_endOffset, newLen, m_data);
769}
770
772{
773 if (m_endOffset > 0)
774 return Path(0, m_length + m_endOffset, m_data);
775 return *this;
776}
777
779{
780 if (m_length > 0)
781 m_length -= 1;
782 return *this;
783}
784
786{
787 Path res = *this;
788 if (m_length > 0)
789 m_length -= 1;
790 return res;
791}
792
793int Path::cmp(const Path &p1, const Path &p2)
794{
795 // lexicographic ordering
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)
798 return 0;
799 for (int i = 0; i < lMin; ++i) {
800 int c = Component::cmp(p1.component(i), p2.component(i));
801 if (c != 0)
802 return c;
803 }
804 if (lMin < p2.m_length)
805 return -1;
806 if (p1.m_length > lMin)
807 return 1;
808 return 0;
809}
810
811Path::Path(quint16 endOffset, quint16 length, std::shared_ptr<PathEls::PathData> data)
812 :m_endOffset(endOffset), m_length(length), m_data(data)
813{
814}
815
816Path Path::noEndOffset() const
817{
818 if (m_length == 0)
819 return Path();
820 if (m_endOffset == 0)
821 return *this;
822 // peel back
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;
828 }
829 if (endOffset > 0) {
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));
833 }
834 return Path(0, m_length, lastData);
835}
836
838{
839 if (m_endOffset != 0) {
840 Path newP = noEndOffset();
841 return newP.appendComponent(c);
842 }
843 if (m_data && m_data.use_count() != 1) {
844 // create a new path (otherwise paths linking to this will change)
845 Path newP(c);
846 newP.m_data->parent = m_data;
847 newP.m_length = static_cast<quint16>(m_length + 1);
848 return newP;
849 }
850 auto my_data =
851 (m_data ? m_data
852 : std::make_shared<PathEls::PathData>(QStringList(),
854 switch (c.kind()) {
858 // no string
860 // string assumed to stay valid (Fields::...)
861 my_data->components.append(c);
862 break;
864 if (c.asCurrent()->contextKind == PathCurrent::Other) {
865 my_data->strData.append(c.asCurrent()->contextName.toString());
866 my_data->components.append(PathEls::Current(my_data->strData.last()));
867 } else {
868 my_data->components.append(c);
869 }
870 break;
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()));
876 } else {
877 my_data->components.append(c);
878 }
879 break;
881 my_data->components.append(c);
882 break;
884 if (c.asRoot()->contextKind == PathRoot::Other) {
885 my_data->strData.append(c.asRoot()->contextName.toString());
886 my_data->components.append(PathEls::Root(my_data->strData.last()));
887 } else {
888 my_data->components.append(c);
889 }
890 break;
891 }
892 if (m_data)
893 m_endOffset = 1;
894 return Path { 0, static_cast<quint16>(m_length + 1), my_data };
895}
896
898{
899 static ErrorGroups res = {{NewErrorGroup("PathParsing")}};
900 return res;
901}
902
904{
905 bool first = true;
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))
910 sink(u".");
911 }
912 c.dump(sink);
913 first = false;
914 }
915}
916
918{
919 QString res;
921 dump([&stream](QStringView str){ stream << str; });
922 stream.flush();
923 return res;
924}
925
927{
928 if (m_length > n && n >= 0)
929 return Path(m_endOffset, m_length - n, m_data);
930 return Path();
931}
932
934{
935 if (m_length > n && n >= 0)
936 return Path(m_endOffset + n, m_length - n, m_data);
937 return Path();
938}
939
941{
942 length = qMin(m_length - offset, length);
943 if (offset < 0 || offset >= m_length || length <= 0 || length > m_length)
944 return Path();
945 int newEndOffset = m_endOffset + m_length - offset - length;
946 return Path(newEndOffset, length, m_data);
947}
948
950{
951 return mid(offset, m_length - offset);
952}
953
955{
956 Path res = fromString(QStringView(s), errorHandler);
957 if (res.m_data)
958 res.m_data->strData.append(s);
959 return res;
960}
961
962} // end namespace Dom
963} // end namespace QQmlJS
965
966#include "moc_qqmldompath_p.cpp"
NSData * m_data
\inmodule QtCore
Definition qchar.h:48
static constexpr QChar fromLatin1(char c) noexcept
Converts the Latin-1 character c to its equivalent QChar.
Definition qchar.h:461
QString arg(Args &&...args) const
Definition qlist.h:74
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
QString name() const override
const Filter * asFilter() const override
bool checkName(QStringView s) const
static int cmp(const PathComponent &p1, const PathComponent &p2)
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 expandBack() const
Path path(Path toAdd, bool avoidToAddAsBase=false) const
QString headName() const
Path appendComponent(const PathEls::PathComponent &c)
std::function< bool(DomItem)> headFilter() const
Source split() 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 empty() const
Path head() const
Path mid(int offset, int length) const
Path expandFront() const
Path last() const
Kind headKind() const
static Path Empty()
static Path fromString(QString s, ErrorHandler errorHandler=nullptr)
Path filter(std::function< bool(DomItem)>, QString) const
QString toString() const
static Path Field(QStringView s=u"")
PathIterator end() const
Path index(index_type i) const
Path dropFront(int n=1) const
static Path Current(PathCurrent c)
PathEls::PathComponent Component
PathRoot headRoot() const
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:76
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
Definition qstring.h:127
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition qstring.h:1101
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1079
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:7822
QString & append(QChar c)
Definition qstring.cpp:3227
\inmodule QtCore
QString str
[2]
QPixmap p2
QPixmap p1
[0]
else opt state
[0]
std::function< void(const ErrorMessage &)> ErrorHandler
qint64 index_type
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
EGLStreamKHR stream
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLuint64 key
GLint GLenum GLint components
GLboolean r
[2]
GLenum GLuint GLenum GLsizei length
GLfloat GLfloat f
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLuint name
GLint first
GLfloat n
GLuint res
const GLubyte * c
GLenum GLsizei len
GLsizei GLenum GLboolean sink
GLdouble s
[6]
Definition qopenglext.h:235
static qreal dot(const QPointF &a, const QPointF &b)
#define NewErrorGroup(name)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int(*) void arg)
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define k1
#define tr(X)
@ desc
short qint16
Definition qtypes.h:42
unsigned short quint16
Definition qtypes.h:43
size_t quintptr
Definition qtypes.h:72
static QString quote(const QString &str)
QAction * at
QStringView el