1/****************************************************************************
2**
3** Copyright (C) 2020 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40
41//
42// W A R N I N G
43// -------------
44//
45// This file is not part of the Qt API. It exists purely as an
46// implementation detail. This header file may change from version to
47// version without notice, or even be removed.
48//
49// We mean it.
50//
51
52//
53// W A R N I N G
54// -------------
55//
56// This file is automatically generated from qxmlstream.g.
57// Changes should be made to that file, not here. Any change to this file will
58// be lost!
59//
60// To regenerate this file, run:
61// qlalr --no-debug --no-lines --qt qxmlstream.g
62//
63
64#include <QtCore/private/qglobal_p.h>
65#include <qxmlstream.h>
66#include "qxmlstream_p.h"
67#include "qxmlutils_p.h"
68#include <qstringconverter.h>
69
70#include <memory>
71
72#ifndef QXMLSTREAMPARSER_P_H
73#define QXMLSTREAMPARSER_P_H
74
75QT_BEGIN_NAMESPACE
76
77#ifndef QT_NO_XMLSTREAMREADER
78
79bool QXmlStreamReaderPrivate::parse()
80{
81 // cleanup currently reported token
82
83 switch (type) {
84 case QXmlStreamReader::StartElement:
85 name.clear();
86 prefix.clear();
87 qualifiedName.clear();
88 namespaceUri.clear();
89 publicNamespaceDeclarations.clear();
90 attributes.clear();
91 if (isEmptyElement) {
92 setType(QXmlStreamReader::EndElement);
93 Tag tag = tagStack_pop();
94 namespaceUri = tag.namespaceDeclaration.namespaceUri;
95 name = tag.name;
96 qualifiedName = tag.qualifiedName;
97 isEmptyElement = false;
98 return true;
99 }
100 clearTextBuffer();
101 break;
102 case QXmlStreamReader::EndElement:
103 name.clear();
104 prefix.clear();
105 qualifiedName.clear();
106 namespaceUri.clear();
107 clearTextBuffer();
108 break;
109 case QXmlStreamReader::DTD:
110 publicNotationDeclarations.clear();
111 publicEntityDeclarations.clear();
112 dtdName.clear();
113 dtdPublicId.clear();
114 dtdSystemId.clear();
115 Q_FALLTHROUGH();
116 case QXmlStreamReader::Comment:
117 case QXmlStreamReader::Characters:
118 isCDATA = false;
119 isWhitespace = true;
120 text.clear();
121 clearTextBuffer();
122 break;
123 case QXmlStreamReader::EntityReference:
124 text.clear();
125 name.clear();
126 clearTextBuffer();
127 break;
128 case QXmlStreamReader::ProcessingInstruction:
129 processingInstructionTarget.clear();
130 processingInstructionData.clear();
131 clearTextBuffer();
132 break;
133 case QXmlStreamReader::NoToken:
134 case QXmlStreamReader::Invalid:
135 break;
136 case QXmlStreamReader::StartDocument:
137 lockEncoding = true;
138 documentVersion.clear();
139 documentEncoding.clear();
140 if (decoder.isValid() && decoder.hasError()) {
141 raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
142 readBuffer.clear();
143 return false;
144 }
145 Q_FALLTHROUGH();
146 default:
147 clearTextBuffer();
148 ;
149 }
150
151 setType(QXmlStreamReader::NoToken);
152
153
154 // the main parse loop
155 int act, r;
156
157 if (resumeReduction) {
158 act = state_stack[tos-1];
159 r = resumeReduction;
160 resumeReduction = 0;
161 goto ResumeReduction;
162 }
163
164 act = state_stack[tos];
165
166 forever {
167 if (token == -1 && - TERMINAL_COUNT != action_index[act]) {
168 uint cu = getChar();
169 token = NOTOKEN;
170 token_char = cu == ~0U ? cu : ushort(cu);
171 if ((cu != ~0U) && (cu & 0xff0000)) {
172 token = cu >> 16;
173 } else switch (token_char) {
174 case 0xfffe:
175 case 0xffff:
176 token = ERROR;
177 break;
178 case '\r':
179 token = SPACE;
180 if (cu == '\r') {
181 if ((token_char = filterCarriageReturn())) {
182 ++lineNumber;
183 lastLineStart = characterOffset + readBufferPos;
184 break;
185 }
186 } else {
187 break;
188 }
189 Q_FALLTHROUGH();
190 case ~0U: {
191 token = EOF_SYMBOL;
192 if (!tagsDone && !inParseEntity) {
193 int a = t_action(act, token);
194 if (a < 0) {
195 raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
196 return false;
197 }
198 }
199
200 } break;
201 case '\n':
202 ++lineNumber;
203 lastLineStart = characterOffset + readBufferPos;
204 Q_FALLTHROUGH();
205 case ' ':
206 case '\t':
207 token = SPACE;
208 break;
209 case '&':
210 token = AMPERSAND;
211 break;
212 case '#':
213 token = HASH;
214 break;
215 case '\'':
216 token = QUOTE;
217 break;
218 case '\"':
219 token = DBLQUOTE;
220 break;
221 case '<':
222 token = LANGLE;
223 break;
224 case '>':
225 token = RANGLE;
226 break;
227 case '[':
228 token = LBRACK;
229 break;
230 case ']':
231 token = RBRACK;
232 break;
233 case '(':
234 token = LPAREN;
235 break;
236 case ')':
237 token = RPAREN;
238 break;
239 case '|':
240 token = PIPE;
241 break;
242 case '=':
243 token = EQ;
244 break;
245 case '%':
246 token = PERCENT;
247 break;
248 case '/':
249 token = SLASH;
250 break;
251 case ':':
252 token = COLON;
253 break;
254 case ';':
255 token = SEMICOLON;
256 break;
257 case ',':
258 token = COMMA;
259 break;
260 case '-':
261 token = DASH;
262 break;
263 case '+':
264 token = PLUS;
265 break;
266 case '*':
267 token = STAR;
268 break;
269 case '.':
270 token = DOT;
271 break;
272 case '?':
273 token = QUESTIONMARK;
274 break;
275 case '!':
276 token = BANG;
277 break;
278 case '0':
279 case '1':
280 case '2':
281 case '3':
282 case '4':
283 case '5':
284 case '6':
285 case '7':
286 case '8':
287 case '9':
288 token = DIGIT;
289 break;
290 default:
291 if (cu < 0x20)
292 token = NOTOKEN;
293 else
294 token = LETTER;
295 break;
296 }
297 }
298
299 act = t_action (act, token);
300 if (act == ACCEPT_STATE) {
301 // reset the parser in case someone resumes (process instructions can follow a valid document)
302 tos = 0;
303 state_stack[tos++] = 0;
304 state_stack[tos] = 0;
305 return true;
306 } else if (act > 0) {
307 if (++tos >= stack_size-1)
308 reallocateStack();
309
310 Value &val = sym_stack[tos];
311 val.c = token_char;
312 val.pos = textBuffer.size();
313 val.prefix = 0;
314 val.len = 1;
315 if (token_char)
316 textBuffer += QChar(token_char);
317
318 state_stack[tos] = act;
319 token = -1;
320
321
322 } else if (act < 0) {
323 r = - act - 1;
324
325#if defined (QLALR_DEBUG)
326 int ridx = rule_index[r];
327 printf ("%3d) %s ::=", r + 1, spell[rule_info[ridx]]);
328 ++ridx;
329 for (int i = ridx; i < ridx + rhs[r]; ++i) {
330 int symbol = rule_info[i];
331 if (const char *name = spell[symbol])
332 printf (" %s", name);
333 else
334 printf (" #%d", symbol);
335 }
336 printf ("\n");
337#endif
338
339 tos -= rhs[r];
340 act = state_stack[tos++];
341 ResumeReduction:
342 switch (r) {
343
344 case 0:
345 setType(QXmlStreamReader::EndDocument);
346 break;
347
348 case 1:
349 if (type != QXmlStreamReader::Invalid) {
350 if (hasSeenTag || inParseEntity) {
351 setType(QXmlStreamReader::EndDocument);
352 } else {
353 raiseError(QXmlStreamReader::NotWellFormedError, QXmlStream::tr("Start tag expected."));
354 // reset the parser
355 tos = 0;
356 state_stack[tos++] = 0;
357 state_stack[tos] = 0;
358 return false;
359 }
360 }
361 break;
362
363 case 10:
364 entityReferenceStack.pop()->isCurrentlyReferenced = false;
365 if (entityReferenceStack.isEmpty())
366 entityLength = 0;
367 clearSym();
368 break;
369
370 case 11:
371 if (!scanString(spell[VERSION], VERSION, false) && atEnd) {
372 resume(11);
373 return false;
374 }
375 break;
376
377 case 12:
378 setType(QXmlStreamReader::StartDocument);
379 documentVersion = symString(6);
380 startDocument();
381 break;
382
383 case 13:
384 hasExternalDtdSubset = true;
385 dtdSystemId = symString(2);
386 break;
387
388 case 14:
389 checkPublicLiteral(symString(2));
390 dtdPublicId = symString(2);
391 dtdSystemId = symString(4);
392 hasExternalDtdSubset = true;
393 break;
394
395 case 16:
396 if (!scanPublicOrSystem() && atEnd) {
397 resume(16);
398 return false;
399 }
400 dtdName = symString(3);
401 break;
402
403 case 17:
404 case 18:
405 dtdName = symString(3);
406 Q_FALLTHROUGH();
407
408 case 19:
409 case 20:
410 setType(QXmlStreamReader::DTD);
411 text = &textBuffer;
412 break;
413
414 case 21:
415 scanDtd = true;
416 break;
417
418 case 22:
419 scanDtd = false;
420 break;
421
422 case 37:
423 if (!scanString(spell[EMPTY], EMPTY, false)
424 && !scanString(spell[ANY], ANY, false)
425 && atEnd) {
426 resume(37);
427 return false;
428 }
429 break;
430
431 case 43:
432 if (!scanString(spell[PCDATA], PCDATA, false) && atEnd) {
433 resume(43);
434 return false;
435 }
436 break;
437
438 case 68: {
439 lastAttributeIsCData = true;
440 } break;
441
442 case 78:
443 if (!scanAfterDefaultDecl() && atEnd) {
444 resume(78);
445 return false;
446 }
447 break;
448
449 case 83:
450 sym(1) = sym(2);
451 lastAttributeValue.clear();
452 lastAttributeIsCData = false;
453 if (!scanAttType() && atEnd) {
454 resume(83);
455 return false;
456 }
457 break;
458
459 case 84: {
460 DtdAttribute &dtdAttribute = dtdAttributes.push();
461 dtdAttribute.tagName.clear();
462 dtdAttribute.isCDATA = lastAttributeIsCData;
463 dtdAttribute.attributePrefix = addToStringStorage(symPrefix(1));
464 dtdAttribute.attributeName = addToStringStorage(symString(1));
465 dtdAttribute.attributeQualifiedName = addToStringStorage(symName(1));
466 dtdAttribute.isNamespaceAttribute = (dtdAttribute.attributePrefix == QLatin1String("xmlns")
467 || (dtdAttribute.attributePrefix.isEmpty()
468 && dtdAttribute.attributeName == QLatin1String("xmlns")));
469 if (lastAttributeValue.isNull()) {
470 dtdAttribute.defaultValue.clear();
471 } else {
472 if (dtdAttribute.isCDATA)
473 dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue);
474 else
475 dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue.toString().simplified());
476
477 }
478 } break;
479
480 case 88: {
481 if (referenceToUnparsedEntityDetected && !standalone)
482 break;
483 int n = dtdAttributes.size();
484 XmlStringRef tagName = addToStringStorage(symName(3));
485 while (n--) {
486 DtdAttribute &dtdAttribute = dtdAttributes[n];
487 if (!dtdAttribute.tagName.isNull())
488 break;
489 dtdAttribute.tagName = tagName;
490 for (int i = 0; i < n; ++i) {
491 if ((dtdAttributes[i].tagName.isNull() || dtdAttributes[i].tagName == tagName)
492 && dtdAttributes[i].attributeQualifiedName == dtdAttribute.attributeQualifiedName) {
493 dtdAttribute.attributeQualifiedName.clear(); // redefined, delete it
494 break;
495 }
496 }
497 }
498 } break;
499
500 case 89: {
501 if (!scanPublicOrSystem() && atEnd) {
502 resume(89);
503 return false;
504 }
505 EntityDeclaration &entityDeclaration = entityDeclarations.push();
506 entityDeclaration.clear();
507 entityDeclaration.name = symString(3);
508 } break;
509
510 case 90: {
511 if (!scanPublicOrSystem() && atEnd) {
512 resume(90);
513 return false;
514 }
515 EntityDeclaration &entityDeclaration = entityDeclarations.push();
516 entityDeclaration.clear();
517 entityDeclaration.name = symString(5);
518 entityDeclaration.parameter = true;
519 } break;
520
521 case 91: {
522 if (!scanNData() && atEnd) {
523 resume(91);
524 return false;
525 }
526 EntityDeclaration &entityDeclaration = entityDeclarations.top();
527 entityDeclaration.systemId = symString(3);
528 entityDeclaration.external = true;
529 } break;
530
531 case 92: {
532 if (!scanNData() && atEnd) {
533 resume(92);
534 return false;
535 }
536 EntityDeclaration &entityDeclaration = entityDeclarations.top();
537 checkPublicLiteral((entityDeclaration.publicId = symString(3)));
538 entityDeclaration.systemId = symString(5);
539 entityDeclaration.external = true;
540 } break;
541
542 case 93: {
543 EntityDeclaration &entityDeclaration = entityDeclarations.top();
544 entityDeclaration.notationName = symString(3);
545 if (entityDeclaration.parameter)
546 raiseWellFormedError(QXmlStream::tr("NDATA in parameter entity declaration."));
547 }
548 Q_FALLTHROUGH();
549
550 case 94:
551 case 95: {
552 if (referenceToUnparsedEntityDetected && !standalone) {
553 entityDeclarations.pop();
554 break;
555 }
556 EntityDeclaration &entityDeclaration = entityDeclarations.top();
557 if (!entityDeclaration.external)
558 entityDeclaration.value = symString(2);
559 auto &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
560 if (!hash.contains(entityDeclaration.name)) {
561 Entity entity(entityDeclaration.name.toString(),
562 entityDeclaration.value.toString());
563 entity.unparsed = (!entityDeclaration.notationName.isNull());
564 entity.external = entityDeclaration.external;
565 hash.insert(qToStringViewIgnoringNull(entity.name), entity);
566 }
567 } break;
568
569 case 96: {
570 setType(QXmlStreamReader::ProcessingInstruction);
571 int pos = sym(4).pos + sym(4).len;
572 processingInstructionTarget = symString(3);
573 if (scanUntil("?>")) {
574 processingInstructionData = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
575 if (!processingInstructionTarget.view().compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
576 raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document."));
577 }
578 else if (!QXmlUtils::isNCName(processingInstructionTarget))
579 raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.")
580 .arg(processingInstructionTarget));
581 } else if (type != QXmlStreamReader::Invalid){
582 resume(96);
583 return false;
584 }
585 } break;
586
587 case 97:
588 setType(QXmlStreamReader::ProcessingInstruction);
589 processingInstructionTarget = symString(3);
590 if (!processingInstructionTarget.view().compare(QLatin1String("xml"), Qt::CaseInsensitive))
591 raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name."));
592 break;
593
594 case 98:
595 if (!scanAfterLangleBang() && atEnd) {
596 resume(98);
597 return false;
598 }
599 break;
600
601 case 99:
602 if (!scanUntil("--")) {
603 resume(99);
604 return false;
605 }
606 break;
607
608 case 100: {
609 setType(QXmlStreamReader::Comment);
610 int pos = sym(1).pos + 4;
611 text = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
612 } break;
613
614 case 101: {
615 setType(QXmlStreamReader::Characters);
616 isCDATA = true;
617 isWhitespace = false;
618 int pos = sym(2).pos;
619 if (scanUntil("]]>", -1)) {
620 text = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
621 } else {
622 resume(101);
623 return false;
624 }
625 } break;
626
627 case 102: {
628 if (!scanPublicOrSystem() && atEnd) {
629 resume(102);
630 return false;
631 }
632 NotationDeclaration &notationDeclaration = notationDeclarations.push();
633 notationDeclaration.name = symString(3);
634 } break;
635
636 case 103: {
637 NotationDeclaration &notationDeclaration = notationDeclarations.top();
638 notationDeclaration.systemId = symString(3);
639 notationDeclaration.publicId.clear();
640 } break;
641
642 case 104: {
643 NotationDeclaration &notationDeclaration = notationDeclarations.top();
644 notationDeclaration.systemId.clear();
645 checkPublicLiteral((notationDeclaration.publicId = symString(3)));
646 } break;
647
648 case 105: {
649 NotationDeclaration &notationDeclaration = notationDeclarations.top();
650 checkPublicLiteral((notationDeclaration.publicId = symString(3)));
651 notationDeclaration.systemId = symString(5);
652 } break;
653
654 case 129:
655 isWhitespace = false;
656 Q_FALLTHROUGH();
657
658 case 130:
659 sym(1).len += fastScanContentCharList();
660 if (atEnd && !inParseEntity) {
661 resume(130);
662 return false;
663 }
664 break;
665
666 case 139:
667 if (!textBuffer.isEmpty()) {
668 setType(QXmlStreamReader::Characters);
669 text = &textBuffer;
670 }
671 break;
672
673 case 140:
674 case 141:
675 clearSym();
676 break;
677
678 case 142:
679 case 143:
680 sym(1) = sym(2);
681 break;
682
683 case 144:
684 case 145:
685 case 146:
686 case 147:
687 sym(1).len += sym(2).len;
688 break;
689
690 case 173:
691 if (normalizeLiterals)
692 textBuffer.data()[textBuffer.size()-1] = QLatin1Char(' ');
693 break;
694
695 case 174:
696 sym(1).len += fastScanLiteralContent();
697 if (atEnd) {
698 resume(174);
699 return false;
700 }
701 break;
702
703 case 175: {
704 if (!QXmlUtils::isPublicID(symString(1))) {
705 raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1)));
706 resume(175);
707 return false;
708 }
709 } break;
710
711 case 176:
712 case 177:
713 clearSym();
714 break;
715
716 case 178:
717 case 179:
718 sym(1) = sym(2);
719 break;
720
721 case 180:
722 case 181:
723 case 182:
724 case 183:
725 sym(1).len += sym(2).len;
726 break;
727
728 case 213:
729 case 214:
730 clearSym();
731 break;
732
733 case 215:
734 case 216:
735 sym(1) = sym(2);
736 lastAttributeValue = symString(1);
737 break;
738
739 case 217:
740 case 218:
741 case 219:
742 case 220:
743 sym(1).len += sym(2).len;
744 break;
745
746 case 229: {
747 XmlStringRef prefix = symPrefix(1);
748 if (prefix.isEmpty() && symString(1) == QLatin1String("xmlns") && namespaceProcessing) {
749 NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
750 namespaceDeclaration.prefix.clear();
751
752 const XmlStringRef ns(symString(5));
753 if (ns.view() == QLatin1String("http://www.w3.org/2000/xmlns/") ||
754 ns.view() == QLatin1String("http://www.w3.org/XML/1998/namespace"))
755 raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
756 else
757 namespaceDeclaration.namespaceUri = addToStringStorage(ns);
758 } else {
759 Attribute &attribute = attributeStack.push();
760 attribute.key = sym(1);
761 attribute.value = sym(5);
762
763 XmlStringRef attributeQualifiedName = symName(1);
764 bool normalize = false;
765 for (int a = 0; a < dtdAttributes.size(); ++a) {
766 DtdAttribute &dtdAttribute = dtdAttributes[a];
767 if (!dtdAttribute.isCDATA
768 && dtdAttribute.tagName == qualifiedName
769 && dtdAttribute.attributeQualifiedName == attributeQualifiedName
770 ) {
771 normalize = true;
772 break;
773 }
774 }
775 if (normalize) {
776 // normalize attribute value (simplify and trim)
777 int pos = textBuffer.size();
778 int n = 0;
779 bool wasSpace = true;
780 for (int i = 0; i < attribute.value.len; ++i) {
781 QChar c = textBuffer.at(attribute.value.pos + i);
782 if (c.unicode() == ' ') {
783 if (wasSpace)
784 continue;
785 wasSpace = true;
786 } else {
787 wasSpace = false;
788 }
789 textBuffer += textBuffer.at(attribute.value.pos + i);
790 ++n;
791 }
792 if (wasSpace)
793 while (n && textBuffer.at(pos + n - 1).unicode() == ' ')
794 --n;
795 attribute.value.pos = pos;
796 attribute.value.len = n;
797 }
798 if (prefix == QLatin1String("xmlns") && namespaceProcessing) {
799 NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
800 XmlStringRef namespacePrefix = symString(attribute.key);
801 XmlStringRef namespaceUri = symString(attribute.value);
802 attributeStack.pop();
803 if (((namespacePrefix == QLatin1String("xml"))
804 ^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace")))
805 || namespaceUri == QLatin1String("http://www.w3.org/2000/xmlns/")
806 || namespaceUri.isEmpty()
807 || namespacePrefix == QLatin1String("xmlns"))
808 raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
809
810 namespaceDeclaration.prefix = addToStringStorage(namespacePrefix);
811 namespaceDeclaration.namespaceUri = addToStringStorage(namespaceUri);
812 }
813 }
814 } break;
815
816 case 235: {
817 normalizeLiterals = true;
818 Tag &tag = tagStack_push();
819 prefix = tag.namespaceDeclaration.prefix = addToStringStorage(symPrefix(2));
820 name = tag.name = addToStringStorage(symString(2));
821 qualifiedName = tag.qualifiedName = addToStringStorage(symName(2));
822 if ((!prefix.isEmpty() && !QXmlUtils::isNCName(prefix)) || !QXmlUtils::isNCName(name))
823 raiseWellFormedError(QXmlStream::tr("Invalid XML name."));
824 } break;
825
826 case 236:
827 isEmptyElement = true;
828 Q_FALLTHROUGH();
829
830 case 237:
831 setType(QXmlStreamReader::StartElement);
832 resolveTag();
833 if (tagStack.size() == 1 && hasSeenTag && !inParseEntity)
834 raiseWellFormedError(QXmlStream::tr("Extra content at end of document."));
835 hasSeenTag = true;
836 break;
837
838 case 238: {
839 setType(QXmlStreamReader::EndElement);
840 Tag tag = tagStack_pop();
841
842 namespaceUri = tag.namespaceDeclaration.namespaceUri;
843 name = tag.name;
844 qualifiedName = tag.qualifiedName;
845 if (qualifiedName != symName(3))
846 raiseWellFormedError(QXmlStream::tr("Opening and ending tag mismatch."));
847 } break;
848
849 case 239:
850 if (entitiesMustBeDeclared()) {
851 raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(unresolvedEntity));
852 break;
853 }
854 setType(QXmlStreamReader::EntityReference);
855 name = &unresolvedEntity;
856 break;
857
858 case 240: {
859 sym(1).len += sym(2).len + 1;
860 QStringView reference = symView(2);
861 if (const auto it = entityHash.find(reference); it != entityHash.end()) {
862 Entity &entity = *it;
863 if (entity.unparsed) {
864 raiseWellFormedError(QXmlStream::tr("Reference to unparsed entity '%1'.").arg(reference));
865 } else {
866 if (!entity.hasBeenParsed) {
867 parseEntity(entity.value);
868 entity.hasBeenParsed = true;
869 }
870 if (entity.literal)
871 putStringLiteral(entity.value);
872 else if (referenceEntity(entity))
873 putReplacement(entity.value);
874 textBuffer.chop(2 + sym(2).len);
875 clearSym();
876 }
877 break;
878 }
879
880 if (entityResolver) {
881 QString replacementText = resolveUndeclaredEntity(reference.toString());
882 if (!replacementText.isNull()) {
883 putReplacement(replacementText);
884 textBuffer.chop(2 + sym(2).len);
885 clearSym();
886 break;
887 }
888 }
889
890 injectToken(UNRESOLVED_ENTITY);
891 unresolvedEntity = symString(2).toString();
892 textBuffer.chop(2 + sym(2).len);
893 clearSym();
894
895 } break;
896
897 case 241: {
898 sym(1).len += sym(2).len + 1;
899 QStringView reference = symView(2);
900 if (const auto it = parameterEntityHash.find(reference); it != parameterEntityHash.end()) {
901 referenceToParameterEntityDetected = true;
902 Entity &entity = *it;
903 if (entity.unparsed || entity.external) {
904 referenceToUnparsedEntityDetected = true;
905 } else {
906 if (referenceEntity(entity))
907 putString(entity.value);
908 textBuffer.chop(2 + sym(2).len);
909 clearSym();
910 }
911 } else if (entitiesMustBeDeclared()) {
912 raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(symString(2)));
913 }
914 } break;
915
916 case 242:
917 sym(1).len += sym(2).len + 1;
918 break;
919
920 case 243: {
921 sym(1).len += sym(2).len + 1;
922 QStringView reference = symView(2);
923 if (const auto it = entityHash.find(reference); it != entityHash.end()) {
924 Entity &entity = *it;
925 if (entity.unparsed || entity.value.isNull()) {
926 raiseWellFormedError(QXmlStream::tr("Reference to external entity '%1' in attribute value.").arg(reference));
927 break;
928 }
929 if (!entity.hasBeenParsed) {
930 parseEntity(entity.value);
931 entity.hasBeenParsed = true;
932 }
933 if (entity.literal)
934 putStringLiteral(entity.value);
935 else if (referenceEntity(entity))
936 putReplacementInAttributeValue(entity.value);
937 textBuffer.chop(2 + sym(2).len);
938 clearSym();
939 break;
940 }
941
942 if (entityResolver) {
943 QString replacementText = resolveUndeclaredEntity(reference.toString());
944 if (!replacementText.isNull()) {
945 putReplacement(replacementText);
946 textBuffer.chop(2 + sym(2).len);
947 clearSym();
948 break;
949 }
950 }
951 if (entitiesMustBeDeclared()) {
952 raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(reference));
953 }
954 } break;
955
956 case 244: {
957 if (char32_t s = resolveCharRef(3)) {
958 putStringLiteral(QChar::fromUcs4(s));
959 textBuffer.chop(3 + sym(3).len);
960 clearSym();
961 } else {
962 raiseWellFormedError(QXmlStream::tr("Invalid character reference."));
963 }
964 } break;
965
966 case 247:
967 case 248:
968 sym(1).len += sym(2).len;
969 break;
970
971 case 259:
972 sym(1).len += fastScanSpace();
973 if (atEnd) {
974 resume(259);
975 return false;
976 }
977 break;
978
979 case 262: {
980 sym(1).len += fastScanName(&sym(1).prefix);
981 if (atEnd) {
982 resume(262);
983 return false;
984 }
985 } break;
986
987 case 263:
988 sym(1).len += fastScanName();
989 if (atEnd) {
990 resume(263);
991 return false;
992 }
993 break;
994
995 case 264:
996 case 265:
997 case 266:
998 case 267:
999 case 268:
1000 sym(1).len += fastScanNMTOKEN();
1001 if (atEnd) {
1002 resume(268);
1003 return false;
1004 }
1005
1006 break;
1007
1008 default:
1009 ;
1010 } // switch
1011 act = state_stack[tos] = nt_action (act, lhs[r] - TERMINAL_COUNT);
1012 if (type != QXmlStreamReader::NoToken)
1013 return true;
1014 } else {
1015 parseError();
1016 break;
1017 }
1018 }
1019 return false;
1020}
1021
1022#endif
1023
1024QT_END_NAMESPACE
1025
1026#endif
1027
1028