source: trunk/src/corelib/xml/qxmlstream.g@ 1036

Last change on this file since 1036 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 55.4 KB
Line 
1----------------------------------------------------------------------------
2--
3-- Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4-- All rights reserved.
5-- Contact: Nokia Corporation ([email protected])
6--
7-- This file is part of the QtCore module of the Qt Toolkit.
8--
9-- $QT_BEGIN_LICENSE:LGPL$
10-- Commercial Usage
11-- Licensees holding valid Qt Commercial licenses may use this file in
12-- accordance with the Qt Commercial License Agreement provided with the
13-- Software or, alternatively, in accordance with the terms contained in
14-- a written agreement between you and Nokia.
15--
16-- GNU Lesser General Public License Usage
17-- Alternatively, this file may be used under the terms of the GNU Lesser
18-- General Public License version 2.1 as published by the Free Software
19-- Foundation and appearing in the file LICENSE.LGPL included in the
20-- packaging of this file. Please review the following information to
21-- ensure the GNU Lesser General Public License version 2.1 requirements
22-- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23--
24-- In addition, as a special exception, Nokia gives you certain additional
25-- rights. These rights are described in the Nokia Qt LGPL Exception
26-- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27--
28-- GNU General Public License Usage
29-- Alternatively, this file may be used under the terms of the GNU
30-- General Public License version 3.0 as published by the Free Software
31-- Foundation and appearing in the file LICENSE.GPL included in the
32-- packaging of this file. Please review the following information to
33-- ensure the GNU General Public License version 3.0 requirements will be
34-- met: http://www.gnu.org/copyleft/gpl.html.
35--
36-- If you have questions regarding the use of this file, please contact
37-- Nokia at [email protected].
38-- $QT_END_LICENSE$
39--
40----------------------------------------------------------------------------
41
42%parser QXmlStreamReader_Table
43
44%merged_output qxmlstream_p.h
45
46%token NOTOKEN
47%token SPACE " "
48%token LANGLE "<"
49%token RANGLE ">"
50%token AMPERSAND "&"
51%token HASH "#"
52%token QUOTE "\'"
53%token DBLQUOTE "\""
54%token LBRACK "["
55%token RBRACK "]"
56%token LPAREN "("
57%token RPAREN ")"
58%token PIPE "|"
59%token EQ "="
60%token PERCENT "%"
61%token SLASH "/"
62%token COLON ":"
63%token SEMICOLON ";"
64%token COMMA ","
65%token DASH "-"
66%token PLUS "+"
67%token STAR "*"
68%token DOT "."
69%token QUESTIONMARK "?"
70%token BANG "!"
71%token LETTER "[a-zA-Z]"
72%token DIGIT "[0-9]"
73
74-- after langle_bang
75%token CDATA_START "[CDATA["
76%token DOCTYPE "DOCTYPE"
77%token ELEMENT "ELEMENT"
78%token ATTLIST "ATTLIST"
79%token ENTITY "ENTITY"
80%token NOTATION "NOTATION"
81
82-- entity decl
83%token SYSTEM "SYSTEM"
84%token PUBLIC "PUBLIC"
85%token NDATA "NDATA"
86
87-- default decl
88%token REQUIRED "REQUIRED"
89%token IMPLIED "IMPLIED"
90%token FIXED "FIXED"
91
92-- conent spec
93%token EMPTY "EMPTY"
94%token ANY "ANY"
95%token PCDATA "PCDATA"
96
97-- error
98%token ERROR
99
100-- entities
101%token PARSE_ENTITY
102%token ENTITY_DONE
103%token UNRESOLVED_ENTITY
104
105-- att type
106%token CDATA "CDATA"
107%token ID "ID"
108%token IDREF "IDREF"
109%token IDREFS "IDREFS"
110%token ENTITY "ENTITY"
111%token ENTITIES "ENTITIES"
112%token NMTOKEN "NMTOKEN"
113%token NMTOKENS "NMTOKENS"
114
115-- xml declaration
116%token XML "<?xml"
117%token VERSION "version"
118
119%nonassoc SHIFT_THERE
120%nonassoc AMPERSAND
121 BANG
122 COLON
123 COMMA
124 DASH
125 DBLQUOTE
126 DIGIT
127 DOT
128 ENTITY_DONE
129 EQ
130 HASH
131 LBRACK
132 LETTER
133 LPAREN
134 PERCENT
135 PIPE
136 PLUS
137 QUESTIONMARK
138 QUOTE
139 RANGLE
140 RBRACK
141 RPAREN
142 SEMICOLON
143 SLASH
144 SPACE
145 STAR
146
147%start document
148
149/.
150template <typename T> class QXmlStreamSimpleStack {
151 T *data;
152 int tos, cap;
153public:
154 inline QXmlStreamSimpleStack():data(0), tos(-1), cap(0){}
155 inline ~QXmlStreamSimpleStack(){ if (data) qFree(data); }
156
157 inline void reserve(int extraCapacity) {
158 if (tos + extraCapacity + 1 > cap) {
159 cap = qMax(tos + extraCapacity + 1, cap << 1 );
160 data = reinterpret_cast<T *>(qRealloc(data, cap * sizeof(T)));
161 Q_CHECK_PTR(data);
162 }
163 }
164
165 inline T &push() { reserve(1); return data[++tos]; }
166 inline T &rawPush() { return data[++tos]; }
167 inline const T &top() const { return data[tos]; }
168 inline T &top() { return data[tos]; }
169 inline T &pop() { return data[tos--]; }
170 inline T &operator[](int index) { return data[index]; }
171 inline const T &at(int index) const { return data[index]; }
172 inline int size() const { return tos + 1; }
173 inline void resize(int s) { tos = s - 1; }
174 inline bool isEmpty() const { return tos < 0; }
175 inline void clear() { tos = -1; }
176};
177
178
179class QXmlStream
180{
181 Q_DECLARE_TR_FUNCTIONS(QXmlStream)
182};
183
184class QXmlStreamPrivateTagStack {
185public:
186 struct NamespaceDeclaration
187 {
188 QStringRef prefix;
189 QStringRef namespaceUri;
190 };
191
192 struct Tag
193 {
194 QStringRef name;
195 QStringRef qualifiedName;
196 NamespaceDeclaration namespaceDeclaration;
197 int tagStackStringStorageSize;
198 int namespaceDeclarationsSize;
199 };
200
201
202 QXmlStreamPrivateTagStack();
203 QXmlStreamSimpleStack<NamespaceDeclaration> namespaceDeclarations;
204 QString tagStackStringStorage;
205 int tagStackStringStorageSize;
206 bool tagsDone;
207
208 inline QStringRef addToStringStorage(const QStringRef &s) {
209 int pos = tagStackStringStorageSize;
210 int sz = s.size();
211 if (pos != tagStackStringStorage.size())
212 tagStackStringStorage.resize(pos);
213 tagStackStringStorage.insert(pos, s.unicode(), sz);
214 tagStackStringStorageSize += sz;
215 return QStringRef(&tagStackStringStorage, pos, sz);
216 }
217 inline QStringRef addToStringStorage(const QString &s) {
218 int pos = tagStackStringStorageSize;
219 int sz = s.size();
220 if (pos != tagStackStringStorage.size())
221 tagStackStringStorage.resize(pos);
222 tagStackStringStorage.insert(pos, s.unicode(), sz);
223 tagStackStringStorageSize += sz;
224 return QStringRef(&tagStackStringStorage, pos, sz);
225 }
226
227 QXmlStreamSimpleStack<Tag> tagStack;
228
229
230 inline Tag &tagStack_pop() {
231 Tag& tag = tagStack.pop();
232 tagStackStringStorageSize = tag.tagStackStringStorageSize;
233 namespaceDeclarations.resize(tag.namespaceDeclarationsSize);
234 tagsDone = tagStack.isEmpty();
235 return tag;
236 }
237 inline Tag &tagStack_push() {
238 Tag &tag = tagStack.push();
239 tag.tagStackStringStorageSize = tagStackStringStorageSize;
240 tag.namespaceDeclarationsSize = namespaceDeclarations.size();
241 return tag;
242 }
243};
244
245
246class QXmlStreamEntityResolver;
247#ifndef QT_NO_XMLSTREAMREADER
248class QXmlStreamReaderPrivate : public QXmlStreamReader_Table, public QXmlStreamPrivateTagStack{
249 QXmlStreamReader *q_ptr;
250 Q_DECLARE_PUBLIC(QXmlStreamReader)
251public:
252 QXmlStreamReaderPrivate(QXmlStreamReader *q);
253 ~QXmlStreamReaderPrivate();
254 void init();
255
256 QByteArray rawReadBuffer;
257 QByteArray dataBuffer;
258 uchar firstByte;
259 qint64 nbytesread;
260 QString readBuffer;
261 int readBufferPos;
262 QXmlStreamSimpleStack<uint> putStack;
263 struct Entity {
264 Entity(const QString& str = QString())
265 :value(str), external(false), unparsed(false), literal(false),
266 hasBeenParsed(false), isCurrentlyReferenced(false){}
267 static inline Entity createLiteral(const QString &entity)
268 { Entity result(entity); result.literal = result.hasBeenParsed = true; return result; }
269 QString value;
270 uint external : 1;
271 uint unparsed : 1;
272 uint literal : 1;
273 uint hasBeenParsed : 1;
274 uint isCurrentlyReferenced : 1;
275 };
276 QHash<QString, Entity> entityHash;
277 QHash<QString, Entity> parameterEntityHash;
278 QXmlStreamSimpleStack<Entity *>entityReferenceStack;
279 inline bool referenceEntity(Entity &entity) {
280 if (entity.isCurrentlyReferenced) {
281 raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
282 return false;
283 }
284 entity.isCurrentlyReferenced = true;
285 entityReferenceStack.push() = &entity;
286 injectToken(ENTITY_DONE);
287 return true;
288 }
289
290
291 QIODevice *device;
292 bool deleteDevice;
293#ifndef QT_NO_TEXTCODEC
294 QTextCodec *codec;
295 QTextDecoder *decoder;
296#endif
297 bool atEnd;
298
299 /*!
300 \sa setType()
301 */
302 QXmlStreamReader::TokenType type;
303 QXmlStreamReader::Error error;
304 QString errorString;
305 QString unresolvedEntity;
306
307 qint64 lineNumber, lastLineStart, characterOffset;
308
309
310 void write(const QString &);
311 void write(const char *);
312
313
314 QXmlStreamAttributes attributes;
315 QStringRef namespaceForPrefix(const QStringRef &prefix);
316 void resolveTag();
317 void resolvePublicNamespaces();
318 void resolveDtd();
319 uint resolveCharRef(int symbolIndex);
320 bool checkStartDocument();
321 void startDocument();
322 void parseError();
323 void checkPublicLiteral(const QStringRef &publicId);
324
325 bool scanDtd;
326 QStringRef lastAttributeValue;
327 bool lastAttributeIsCData;
328 struct DtdAttribute {
329 QStringRef tagName;
330 QStringRef attributeQualifiedName;
331 QStringRef attributePrefix;
332 QStringRef attributeName;
333 QStringRef defaultValue;
334 bool isCDATA;
335 bool isNamespaceAttribute;
336 };
337 QXmlStreamSimpleStack<DtdAttribute> dtdAttributes;
338 struct NotationDeclaration {
339 QStringRef name;
340 QStringRef publicId;
341 QStringRef systemId;
342 };
343 QXmlStreamSimpleStack<NotationDeclaration> notationDeclarations;
344 QXmlStreamNotationDeclarations publicNotationDeclarations;
345 QXmlStreamNamespaceDeclarations publicNamespaceDeclarations;
346
347 struct EntityDeclaration {
348 QStringRef name;
349 QStringRef notationName;
350 QStringRef publicId;
351 QStringRef systemId;
352 QStringRef value;
353 bool parameter;
354 bool external;
355 inline void clear() {
356 name.clear();
357 notationName.clear();
358 publicId.clear();
359 systemId.clear();
360 value.clear();
361 parameter = external = false;
362 }
363 };
364 QXmlStreamSimpleStack<EntityDeclaration> entityDeclarations;
365 QXmlStreamEntityDeclarations publicEntityDeclarations;
366
367 QStringRef text;
368
369 QStringRef prefix, namespaceUri, qualifiedName, name;
370 QStringRef processingInstructionTarget, processingInstructionData;
371 QStringRef dtdName, dtdPublicId, dtdSystemId;
372 QStringRef documentVersion, documentEncoding;
373 uint isEmptyElement : 1;
374 uint isWhitespace : 1;
375 uint isCDATA : 1;
376 uint standalone : 1;
377 uint hasCheckedStartDocument : 1;
378 uint normalizeLiterals : 1;
379 uint hasSeenTag : 1;
380 uint inParseEntity : 1;
381 uint referenceToUnparsedEntityDetected : 1;
382 uint referenceToParameterEntityDetected : 1;
383 uint hasExternalDtdSubset : 1;
384 uint lockEncoding : 1;
385 uint namespaceProcessing : 1;
386
387 int resumeReduction;
388 void resume(int rule);
389
390 inline bool entitiesMustBeDeclared() const {
391 return (!inParseEntity
392 && (standalone
393 || (!referenceToUnparsedEntityDetected
394 && !referenceToParameterEntityDetected // Errata 13 as of 2006-04-25
395 && !hasExternalDtdSubset)));
396 }
397
398 // qlalr parser
399 int tos;
400 int stack_size;
401 struct Value {
402 int pos;
403 int len;
404 int prefix;
405 ushort c;
406 };
407
408 Value *sym_stack;
409 int *state_stack;
410 inline void reallocateStack();
411 inline Value &sym(int index) const
412 { return sym_stack[tos + index - 1]; }
413 QString textBuffer;
414 inline void clearTextBuffer() {
415 if (!scanDtd) {
416 textBuffer.resize(0);
417 textBuffer.reserve(256);
418 }
419 }
420 struct Attribute {
421 Value key;
422 Value value;
423 };
424 QXmlStreamSimpleStack<Attribute> attributeStack;
425
426 inline QStringRef symString(int index) {
427 const Value &symbol = sym(index);
428 return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
429 }
430 inline QStringRef symName(int index) {
431 const Value &symbol = sym(index);
432 return QStringRef(&textBuffer, symbol.pos, symbol.len);
433 }
434 inline QStringRef symString(int index, int offset) {
435 const Value &symbol = sym(index);
436 return QStringRef(&textBuffer, symbol.pos + symbol.prefix + offset, symbol.len - symbol.prefix - offset);
437 }
438 inline QStringRef symPrefix(int index) {
439 const Value &symbol = sym(index);
440 if (symbol.prefix)
441 return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
442 return QStringRef();
443 }
444 inline QStringRef symString(const Value &symbol) {
445 return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
446 }
447 inline QStringRef symName(const Value &symbol) {
448 return QStringRef(&textBuffer, symbol.pos, symbol.len);
449 }
450 inline QStringRef symPrefix(const Value &symbol) {
451 if (symbol.prefix)
452 return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
453 return QStringRef();
454 }
455
456 inline void clearSym() { Value &val = sym(1); val.pos = textBuffer.size(); val.len = 0; }
457
458
459 short token;
460 ushort token_char;
461
462 uint filterCarriageReturn();
463 inline uint getChar();
464 inline uint peekChar();
465 inline void putChar(uint c) { putStack.push() = c; }
466 inline void putChar(QChar c) { putStack.push() = c.unicode(); }
467 void putString(const QString &s, int from = 0);
468 void putStringLiteral(const QString &s);
469 void putReplacement(const QString &s);
470 void putReplacementInAttributeValue(const QString &s);
471 ushort getChar_helper();
472
473 bool scanUntil(const char *str, short tokenToInject = -1);
474 bool scanString(const char *str, short tokenToInject, bool requireSpace = true);
475 inline void injectToken(ushort tokenToInject) {
476 putChar(int(tokenToInject) << 16);
477 }
478
479 QString resolveUndeclaredEntity(const QString &name);
480 void parseEntity(const QString &value);
481 QXmlStreamReaderPrivate *entityParser;
482
483 bool scanAfterLangleBang();
484 bool scanPublicOrSystem();
485 bool scanNData();
486 bool scanAfterDefaultDecl();
487 bool scanAttType();
488
489
490 // scan optimization functions. Not strictly necessary but LALR is
491 // not very well suited for scanning fast
492 int fastScanLiteralContent();
493 int fastScanSpace();
494 int fastScanContentCharList();
495 int fastScanName(int *prefix = 0);
496 inline int fastScanNMTOKEN();
497
498
499 bool parse();
500 inline void consumeRule(int);
501
502 void raiseError(QXmlStreamReader::Error error, const QString& message = QString());
503 void raiseWellFormedError(const QString &message);
504
505 QXmlStreamEntityResolver *entityResolver;
506
507private:
508 /*! \internal
509 Never assign to variable type directly. Instead use this function.
510
511 This prevents errors from being ignored.
512 */
513 inline void setType(const QXmlStreamReader::TokenType t)
514 {
515 if(type != QXmlStreamReader::Invalid)
516 type = t;
517 }
518};
519
520bool QXmlStreamReaderPrivate::parse()
521{
522 // cleanup currently reported token
523
524 switch (type) {
525 case QXmlStreamReader::StartElement:
526 name.clear();
527 prefix.clear();
528 qualifiedName.clear();
529 namespaceUri.clear();
530 if (publicNamespaceDeclarations.size())
531 publicNamespaceDeclarations.clear();
532 if (attributes.size())
533 attributes.resize(0);
534 if (isEmptyElement) {
535 setType(QXmlStreamReader::EndElement);
536 Tag &tag = tagStack_pop();
537 namespaceUri = tag.namespaceDeclaration.namespaceUri;
538 name = tag.name;
539 qualifiedName = tag.qualifiedName;
540 isEmptyElement = false;
541 return true;
542 }
543 clearTextBuffer();
544 break;
545 case QXmlStreamReader::EndElement:
546 name.clear();
547 prefix.clear();
548 qualifiedName.clear();
549 namespaceUri.clear();
550 clearTextBuffer();
551 break;
552 case QXmlStreamReader::DTD:
553 publicNotationDeclarations.clear();
554 publicEntityDeclarations.clear();
555 dtdName.clear();
556 dtdPublicId.clear();
557 dtdSystemId.clear();
558 // fall through
559 case QXmlStreamReader::Comment:
560 case QXmlStreamReader::Characters:
561 isCDATA = false;
562 isWhitespace = true;
563 text.clear();
564 clearTextBuffer();
565 break;
566 case QXmlStreamReader::EntityReference:
567 text.clear();
568 name.clear();
569 clearTextBuffer();
570 break;
571 case QXmlStreamReader::ProcessingInstruction:
572 processingInstructionTarget.clear();
573 processingInstructionData.clear();
574 clearTextBuffer();
575 break;
576 case QXmlStreamReader::NoToken:
577 case QXmlStreamReader::Invalid:
578 break;
579 case QXmlStreamReader::StartDocument:
580 lockEncoding = true;
581 documentVersion.clear();
582 documentEncoding.clear();
583#ifndef QT_NO_TEXTCODEC
584 if(decoder->hasFailure()) {
585 raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
586 readBuffer.clear();
587 return false;
588 }
589#endif
590 // fall through
591 default:
592 clearTextBuffer();
593 ;
594 }
595
596 setType(QXmlStreamReader::NoToken);
597
598
599 // the main parse loop
600 int act, r;
601
602 if (resumeReduction) {
603 act = state_stack[tos-1];
604 r = resumeReduction;
605 resumeReduction = 0;
606 goto ResumeReduction;
607 }
608
609 act = state_stack[tos];
610
611 forever {
612 if (token == -1 && - TERMINAL_COUNT != action_index[act]) {
613 uint cu = getChar();
614 token = NOTOKEN;
615 token_char = cu;
616 if (cu & 0xff0000) {
617 token = cu >> 16;
618 } else switch (token_char) {
619 case 0xfffe:
620 case 0xffff:
621 token = ERROR;
622 break;
623 case '\r':
624 token = SPACE;
625 if (cu == '\r') {
626 if ((token_char = filterCarriageReturn())) {
627 ++lineNumber;
628 lastLineStart = characterOffset + readBufferPos;
629 break;
630 }
631 } else {
632 break;
633 }
634 // fall through
635 case '\0': {
636 token = EOF_SYMBOL;
637 if (!tagsDone && !inParseEntity) {
638 int a = t_action(act, token);
639 if (a < 0) {
640 raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
641 return false;
642 }
643 }
644
645 } break;
646 case '\n':
647 ++lineNumber;
648 lastLineStart = characterOffset + readBufferPos;
649 case ' ':
650 case '\t':
651 token = SPACE;
652 break;
653 case '&':
654 token = AMPERSAND;
655 break;
656 case '#':
657 token = HASH;
658 break;
659 case '\'':
660 token = QUOTE;
661 break;
662 case '\"':
663 token = DBLQUOTE;
664 break;
665 case '<':
666 token = LANGLE;
667 break;
668 case '>':
669 token = RANGLE;
670 break;
671 case '[':
672 token = LBRACK;
673 break;
674 case ']':
675 token = RBRACK;
676 break;
677 case '(':
678 token = LPAREN;
679 break;
680 case ')':
681 token = RPAREN;
682 break;
683 case '|':
684 token = PIPE;
685 break;
686 case '=':
687 token = EQ;
688 break;
689 case '%':
690 token = PERCENT;
691 break;
692 case '/':
693 token = SLASH;
694 break;
695 case ':':
696 token = COLON;
697 break;
698 case ';':
699 token = SEMICOLON;
700 break;
701 case ',':
702 token = COMMA;
703 break;
704 case '-':
705 token = DASH;
706 break;
707 case '+':
708 token = PLUS;
709 break;
710 case '*':
711 token = STAR;
712 break;
713 case '.':
714 token = DOT;
715 break;
716 case '?':
717 token = QUESTIONMARK;
718 break;
719 case '!':
720 token = BANG;
721 break;
722 case '0':
723 case '1':
724 case '2':
725 case '3':
726 case '4':
727 case '5':
728 case '6':
729 case '7':
730 case '8':
731 case '9':
732 token = DIGIT;
733 break;
734 default:
735 if (cu < 0x20)
736 token = NOTOKEN;
737 else
738 token = LETTER;
739 break;
740 }
741 }
742
743 act = t_action (act, token);
744 if (act == ACCEPT_STATE) {
745 // reset the parser in case someone resumes (process instructions can follow a valid document)
746 tos = 0;
747 state_stack[tos++] = 0;
748 state_stack[tos] = 0;
749 return true;
750 } else if (act > 0) {
751 if (++tos == stack_size-1)
752 reallocateStack();
753
754 Value &val = sym_stack[tos];
755 val.c = token_char;
756 val.pos = textBuffer.size();
757 val.prefix = 0;
758 val.len = 1;
759 if (token_char)
760 textBuffer += QChar(token_char);
761
762 state_stack[tos] = act;
763 token = -1;
764
765
766 } else if (act < 0) {
767 r = - act - 1;
768
769#if defined (QLALR_DEBUG)
770 int ridx = rule_index[r];
771 printf ("%3d) %s ::=", r + 1, spell[rule_info[ridx]]);
772 ++ridx;
773 for (int i = ridx; i < ridx + rhs[r]; ++i) {
774 int symbol = rule_info[i];
775 if (const char *name = spell[symbol])
776 printf (" %s", name);
777 else
778 printf (" #%d", symbol);
779 }
780 printf ("\n");
781#endif
782
783 tos -= rhs[r];
784 act = state_stack[tos++];
785 ResumeReduction:
786 switch (r) {
787./
788
789document ::= PARSE_ENTITY content;
790/.
791 case $rule_number:
792 setType(QXmlStreamReader::EndDocument);
793 break;
794./
795
796document ::= prolog;
797/.
798 case $rule_number:
799 if (type != QXmlStreamReader::Invalid) {
800 if (hasSeenTag || inParseEntity) {
801 setType(QXmlStreamReader::EndDocument);
802 } else {
803 raiseError(QXmlStreamReader::NotWellFormedError, QXmlStream::tr("Start tag expected."));
804 // reset the parser
805 tos = 0;
806 state_stack[tos++] = 0;
807 state_stack[tos] = 0;
808 return false;
809 }
810 }
811 break;
812./
813
814
815prolog ::= prolog stag content etag;
816prolog ::= prolog empty_element_tag;
817prolog ::= prolog comment;
818prolog ::= prolog xml_decl;
819prolog ::= prolog processing_instruction;
820prolog ::= prolog doctype_decl;
821prolog ::= prolog SPACE;
822prolog ::=;
823
824entity_done ::= ENTITY_DONE;
825/.
826 case $rule_number:
827 entityReferenceStack.pop()->isCurrentlyReferenced = false;
828 clearSym();
829 break;
830./
831
832
833xml_decl_start ::= XML;
834/.
835 case $rule_number:
836 if (!scanString(spell[VERSION], VERSION, false) && atEnd) {
837 resume($rule_number);
838 return false;
839 }
840 break;
841./
842
843xml_decl ::= xml_decl_start VERSION space_opt EQ space_opt literal attribute_list_opt QUESTIONMARK RANGLE;
844/.
845 case $rule_number:
846 setType(QXmlStreamReader::StartDocument);
847 documentVersion = symString(6);
848 startDocument();
849 break;
850./
851
852external_id ::= SYSTEM literal;
853/.
854 case $rule_number:
855 hasExternalDtdSubset = true;
856 dtdSystemId = symString(2);
857 break;
858./
859external_id ::= PUBLIC public_literal space literal;
860/.
861 case $rule_number:
862 checkPublicLiteral(symString(2));
863 dtdPublicId = symString(2);
864 dtdSystemId = symString(4);
865 hasExternalDtdSubset = true;
866 break;
867./
868external_id ::=;
869
870doctype_decl_start ::= langle_bang DOCTYPE qname space;
871/.
872 case $rule_number:
873 if (!scanPublicOrSystem() && atEnd) {
874 resume($rule_number);
875 return false;
876 }
877 dtdName = symString(3);
878 break;
879./
880
881doctype_decl ::= langle_bang DOCTYPE qname RANGLE;
882/.
883 case $rule_number:./
884doctype_decl ::= langle_bang DOCTYPE qname markup space_opt RANGLE;
885/.
886 case $rule_number:
887 dtdName = symString(3);
888 // fall through
889./
890doctype_decl ::= doctype_decl_start external_id space_opt markup space_opt RANGLE;
891/.
892 case $rule_number:./
893doctype_decl ::= doctype_decl_start external_id space_opt RANGLE;
894/.
895 case $rule_number:
896 setType(QXmlStreamReader::DTD);
897 text = &textBuffer;
898 break;
899./
900
901markup_start ::= LBRACK;
902/.
903 case $rule_number:
904 scanDtd = true;
905 break;
906./
907
908markup ::= markup_start markup_list RBRACK;
909/.
910 case $rule_number:
911 scanDtd = false;
912 break;
913./
914
915
916markup_list ::= markup_decl | space | pereference;
917markup_list ::= markup_list markup_decl | markup_list space | markup_list pereference;
918markup_list ::=;
919
920markup_decl ::= element_decl | attlist_decl | entity_decl | entity_done | notation_decl | processing_instruction | comment;
921
922
923element_decl_start ::= langle_bang ELEMENT qname space;
924/.
925 case $rule_number:
926 if (!scanString(spell[EMPTY], EMPTY, false)
927 && !scanString(spell[ANY], ANY, false)
928 && atEnd) {
929 resume($rule_number);
930 return false;
931 }
932 break;
933./
934
935element_decl ::= element_decl_start content_spec space_opt RANGLE;
936
937
938content_spec ::= EMPTY | ANY | mixed | children;
939
940pcdata_start ::= HASH;
941/.
942 case $rule_number:
943 if (!scanString(spell[PCDATA], PCDATA, false) && atEnd) {
944 resume($rule_number);
945 return false;
946 }
947 break;
948./
949
950pcdata ::= pcdata_start PCDATA;
951
952questionmark_or_star_or_plus_opt ::= QUESTIONMARK | STAR | PLUS;
953questionmark_or_star_or_plus_opt ::=;
954
955cp ::= qname questionmark_or_star_or_plus_opt | choice_or_seq questionmark_or_star_or_plus_opt;
956
957cp_pipe_or_comma_list ::= cp space_opt;
958cp_pipe_or_comma_list ::= cp space_opt PIPE space_opt cp_pipe_list space_opt;
959cp_pipe_or_comma_list ::= cp space_opt COMMA space_opt cp_comma_list space_opt;
960cp_pipe_list ::= cp | cp_pipe_list space_opt PIPE space_opt cp;
961cp_comma_list ::= cp | cp_comma_list space_opt COMMA space_opt cp;
962
963
964name_pipe_list ::= PIPE space_opt qname;
965name_pipe_list ::= name_pipe_list space_opt PIPE space_opt qname;
966
967star_opt ::= | STAR;
968
969mixed ::= LPAREN space_opt pcdata space_opt RPAREN star_opt;
970mixed ::= LPAREN space_opt pcdata space_opt name_pipe_list space_opt RPAREN STAR;
971
972choice_or_seq ::= LPAREN space_opt cp_pipe_or_comma_list RPAREN;
973
974children ::= choice_or_seq questionmark_or_star_or_plus_opt;
975
976
977nmtoken_pipe_list ::= nmtoken;
978nmtoken_pipe_list ::= nmtoken_pipe_list space_opt PIPE space_opt nmtoken;
979
980
981att_type ::= CDATA;
982/.
983 case $rule_number: {
984 lastAttributeIsCData = true;
985 } break;
986./
987att_type ::= ID | IDREF | IDREFS | ENTITY | ENTITIES | NMTOKEN | NMTOKENS;
988att_type ::= LPAREN space_opt nmtoken_pipe_list space_opt RPAREN space;
989att_type ::= NOTATION LPAREN space_opt nmtoken_pipe_list space_opt RPAREN space;
990
991
992default_declhash ::= HASH;
993/.
994 case $rule_number:
995 if (!scanAfterDefaultDecl() && atEnd) {
996 resume($rule_number);
997 return false;
998 }
999 break;
1000./
1001
1002default_decl ::= default_declhash REQUIRED;
1003default_decl ::= default_declhash IMPLIED;
1004default_decl ::= attribute_value;
1005default_decl ::= default_declhash FIXED space attribute_value;
1006attdef_start ::= space qname space;
1007/.
1008 case $rule_number:
1009 sym(1) = sym(2);
1010 lastAttributeValue.clear();
1011 lastAttributeIsCData = false;
1012 if (!scanAttType() && atEnd) {
1013 resume($rule_number);
1014 return false;
1015 }
1016 break;
1017./
1018
1019attdef ::= attdef_start att_type default_decl;
1020/.
1021 case $rule_number: {
1022 DtdAttribute &dtdAttribute = dtdAttributes.push();
1023 dtdAttribute.tagName.clear();
1024 dtdAttribute.isCDATA = lastAttributeIsCData;
1025 dtdAttribute.attributePrefix = addToStringStorage(symPrefix(1));
1026 dtdAttribute.attributeName = addToStringStorage(symString(1));
1027 dtdAttribute.attributeQualifiedName = addToStringStorage(symName(1));
1028 dtdAttribute.isNamespaceAttribute = (dtdAttribute.attributePrefix == QLatin1String("xmlns")
1029 || (dtdAttribute.attributePrefix.isEmpty()
1030 && dtdAttribute.attributeName == QLatin1String("xmlns")));
1031 if (lastAttributeValue.isNull()) {
1032 dtdAttribute.defaultValue.clear();
1033 } else {
1034 if (dtdAttribute.isCDATA)
1035 dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue);
1036 else
1037 dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue.toString().simplified());
1038
1039 }
1040 } break;
1041./
1042
1043attdef_list ::= attdef;
1044attdef_list ::= attdef_list attdef;
1045
1046attlist_decl ::= langle_bang ATTLIST qname space_opt RANGLE;
1047attlist_decl ::= langle_bang ATTLIST qname attdef_list space_opt RANGLE;
1048/.
1049 case $rule_number: {
1050 if (referenceToUnparsedEntityDetected && !standalone)
1051 break;
1052 int n = dtdAttributes.size();
1053 QStringRef tagName = addToStringStorage(symName(3));
1054 while (n--) {
1055 DtdAttribute &dtdAttribute = dtdAttributes[n];
1056 if (!dtdAttribute.tagName.isNull())
1057 break;
1058 dtdAttribute.tagName = tagName;
1059 for (int i = 0; i < n; ++i) {
1060 if ((dtdAttributes[i].tagName.isNull() || dtdAttributes[i].tagName == tagName)
1061 && dtdAttributes[i].attributeQualifiedName == dtdAttribute.attributeQualifiedName) {
1062 dtdAttribute.attributeQualifiedName.clear(); // redefined, delete it
1063 break;
1064 }
1065 }
1066 }
1067 } break;
1068./
1069
1070entity_decl_start ::= langle_bang ENTITY name space;
1071/.
1072 case $rule_number: {
1073 if (!scanPublicOrSystem() && atEnd) {
1074 resume($rule_number);
1075 return false;
1076 }
1077 EntityDeclaration &entityDeclaration = entityDeclarations.push();
1078 entityDeclaration.clear();
1079 entityDeclaration.name = symString(3);
1080 } break;
1081./
1082
1083entity_decl_start ::= langle_bang ENTITY PERCENT space name space;
1084/.
1085 case $rule_number: {
1086 if (!scanPublicOrSystem() && atEnd) {
1087 resume($rule_number);
1088 return false;
1089 }
1090 EntityDeclaration &entityDeclaration = entityDeclarations.push();
1091 entityDeclaration.clear();
1092 entityDeclaration.name = symString(5);
1093 entityDeclaration.parameter = true;
1094 } break;
1095./
1096
1097entity_decl_external ::= entity_decl_start SYSTEM literal;
1098/.
1099 case $rule_number: {
1100 if (!scanNData() && atEnd) {
1101 resume($rule_number);
1102 return false;
1103 }
1104 EntityDeclaration &entityDeclaration = entityDeclarations.top();
1105 entityDeclaration.systemId = symString(3);
1106 entityDeclaration.external = true;
1107 } break;
1108./
1109
1110entity_decl_external ::= entity_decl_start PUBLIC public_literal space literal;
1111/.
1112 case $rule_number: {
1113 if (!scanNData() && atEnd) {
1114 resume($rule_number);
1115 return false;
1116 }
1117 EntityDeclaration &entityDeclaration = entityDeclarations.top();
1118 checkPublicLiteral((entityDeclaration.publicId = symString(3)));
1119 entityDeclaration.systemId = symString(5);
1120 entityDeclaration.external = true;
1121 } break;
1122./
1123
1124entity_decl ::= entity_decl_external NDATA name space_opt RANGLE;
1125/.
1126 case $rule_number: {
1127 EntityDeclaration &entityDeclaration = entityDeclarations.top();
1128 entityDeclaration.notationName = symString(3);
1129 if (entityDeclaration.parameter)
1130 raiseWellFormedError(QXmlStream::tr("NDATA in parameter entity declaration."));
1131 }
1132 //fall through
1133./
1134
1135entity_decl ::= entity_decl_external space_opt RANGLE;
1136/.
1137 case $rule_number:./
1138
1139entity_decl ::= entity_decl_start entity_value space_opt RANGLE;
1140/.
1141 case $rule_number: {
1142 if (referenceToUnparsedEntityDetected && !standalone) {
1143 entityDeclarations.pop();
1144 break;
1145 }
1146 EntityDeclaration &entityDeclaration = entityDeclarations.top();
1147 if (!entityDeclaration.external)
1148 entityDeclaration.value = symString(2);
1149 QString entityName = entityDeclaration.name.toString();
1150 QHash<QString, Entity> &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
1151 if (!hash.contains(entityName)) {
1152 Entity entity(entityDeclaration.value.toString());
1153 entity.unparsed = (!entityDeclaration.notationName.isNull());
1154 entity.external = entityDeclaration.external;
1155 hash.insert(entityName, entity);
1156 }
1157 } break;
1158./
1159
1160
1161processing_instruction ::= LANGLE QUESTIONMARK name space;
1162/.
1163 case $rule_number: {
1164 setType(QXmlStreamReader::ProcessingInstruction);
1165 int pos = sym(4).pos + sym(4).len;
1166 processingInstructionTarget = symString(3);
1167 if (scanUntil("?>")) {
1168 processingInstructionData = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
1169 const QString piTarget(processingInstructionTarget.toString());
1170 if (!piTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
1171 raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document."));
1172 }
1173 else if(!QXmlUtils::isNCName(piTarget))
1174 raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.").arg(piTarget));
1175 } else if (type != QXmlStreamReader::Invalid){
1176 resume($rule_number);
1177 return false;
1178 }
1179 } break;
1180./
1181
1182processing_instruction ::= LANGLE QUESTIONMARK name QUESTIONMARK RANGLE;
1183/.
1184 case $rule_number:
1185 setType(QXmlStreamReader::ProcessingInstruction);
1186 processingInstructionTarget = symString(3);
1187 if (!processingInstructionTarget.toString().compare(QLatin1String("xml"), Qt::CaseInsensitive))
1188 raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name."));
1189 break;
1190./
1191
1192
1193langle_bang ::= LANGLE BANG;
1194/.
1195 case $rule_number:
1196 if (!scanAfterLangleBang() && atEnd) {
1197 resume($rule_number);
1198 return false;
1199 }
1200 break;
1201./
1202
1203comment_start ::= langle_bang DASH DASH;
1204/.
1205 case $rule_number:
1206 if (!scanUntil("--")) {
1207 resume($rule_number);
1208 return false;
1209 }
1210 break;
1211./
1212
1213comment ::= comment_start RANGLE;
1214/.
1215 case $rule_number: {
1216 setType(QXmlStreamReader::Comment);
1217 int pos = sym(1).pos + 4;
1218 text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
1219 } break;
1220./
1221
1222
1223cdata ::= langle_bang CDATA_START;
1224/.
1225 case $rule_number: {
1226 setType(QXmlStreamReader::Characters);
1227 isCDATA = true;
1228 isWhitespace = false;
1229 int pos = sym(2).pos;
1230 if (scanUntil("]]>", -1)) {
1231 text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
1232 } else {
1233 resume($rule_number);
1234 return false;
1235 }
1236 } break;
1237./
1238
1239notation_decl_start ::= langle_bang NOTATION name space;
1240/.
1241 case $rule_number: {
1242 if (!scanPublicOrSystem() && atEnd) {
1243 resume($rule_number);
1244 return false;
1245 }
1246 NotationDeclaration &notationDeclaration = notationDeclarations.push();
1247 notationDeclaration.name = symString(3);
1248 } break;
1249./
1250
1251notation_decl ::= notation_decl_start SYSTEM literal space_opt RANGLE;
1252/.
1253 case $rule_number: {
1254 NotationDeclaration &notationDeclaration = notationDeclarations.top();
1255 notationDeclaration.systemId = symString(3);
1256 notationDeclaration.publicId.clear();
1257 } break;
1258./
1259
1260notation_decl ::= notation_decl_start PUBLIC public_literal space_opt RANGLE;
1261/.
1262 case $rule_number: {
1263 NotationDeclaration &notationDeclaration = notationDeclarations.top();
1264 notationDeclaration.systemId.clear();
1265 checkPublicLiteral((notationDeclaration.publicId = symString(3)));
1266 } break;
1267./
1268
1269notation_decl ::= notation_decl_start PUBLIC public_literal space literal space_opt RANGLE;
1270/.
1271 case $rule_number: {
1272 NotationDeclaration &notationDeclaration = notationDeclarations.top();
1273 checkPublicLiteral((notationDeclaration.publicId = symString(3)));
1274 notationDeclaration.systemId = symString(5);
1275 } break;
1276./
1277
1278
1279
1280content_char ::= RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | PERCENT | SLASH | COLON | SEMICOLON | COMMA | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG | QUOTE | DBLQUOTE | LETTER | DIGIT;
1281
1282scan_content_char ::= content_char;
1283/.
1284 case $rule_number:
1285 isWhitespace = false;
1286 // fall through
1287./
1288
1289scan_content_char ::= SPACE;
1290/.
1291 case $rule_number:
1292 sym(1).len += fastScanContentCharList();
1293 if (atEnd && !inParseEntity) {
1294 resume($rule_number);
1295 return false;
1296 }
1297 break;
1298./
1299
1300content_char_list ::= content_char_list char_ref;
1301content_char_list ::= content_char_list entity_ref;
1302content_char_list ::= content_char_list entity_done;
1303content_char_list ::= content_char_list scan_content_char;
1304content_char_list ::= char_ref;
1305content_char_list ::= entity_ref;
1306content_char_list ::= entity_done;
1307content_char_list ::= scan_content_char;
1308
1309
1310character_content ::= content_char_list %prec SHIFT_THERE;
1311/.
1312 case $rule_number:
1313 if (!textBuffer.isEmpty()) {
1314 setType(QXmlStreamReader::Characters);
1315 text = &textBuffer;
1316 }
1317 break;
1318./
1319
1320literal ::= QUOTE QUOTE;
1321/.
1322 case $rule_number:./
1323literal ::= DBLQUOTE DBLQUOTE;
1324/.
1325 case $rule_number:
1326 clearSym();
1327 break;
1328./
1329literal ::= QUOTE literal_content_with_dblquote QUOTE;
1330/.
1331 case $rule_number:./
1332literal ::= DBLQUOTE literal_content_with_quote DBLQUOTE;
1333/.
1334 case $rule_number:
1335 sym(1) = sym(2);
1336 break;
1337./
1338
1339literal_content_with_dblquote ::= literal_content_with_dblquote literal_content;
1340/.
1341 case $rule_number:./
1342literal_content_with_quote ::= literal_content_with_quote literal_content;
1343/.
1344 case $rule_number:./
1345literal_content_with_dblquote ::= literal_content_with_dblquote DBLQUOTE;
1346/.
1347 case $rule_number:./
1348literal_content_with_quote ::= literal_content_with_quote QUOTE;
1349/.
1350 case $rule_number:
1351 sym(1).len += sym(2).len;
1352 break;
1353./
1354literal_content_with_dblquote ::= literal_content;
1355literal_content_with_quote ::= literal_content;
1356literal_content_with_dblquote ::= DBLQUOTE;
1357literal_content_with_quote ::= QUOTE;
1358
1359literal_content_start ::= LETTER | DIGIT | RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | PERCENT | SLASH | COLON | SEMICOLON | COMMA | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG;
1360
1361literal_content_start ::= SPACE;
1362/.
1363 case $rule_number:
1364 if (normalizeLiterals)
1365 textBuffer.data()[textBuffer.size()-1] = QLatin1Char(' ');
1366 break;
1367./
1368
1369literal_content ::= literal_content_start;
1370/.
1371 case $rule_number:
1372 sym(1).len += fastScanLiteralContent();
1373 if (atEnd) {
1374 resume($rule_number);
1375 return false;
1376 }
1377 break;
1378./
1379
1380
1381public_literal ::= literal;
1382/.
1383 case $rule_number: {
1384 if (!QXmlUtils::isPublicID(symString(1).toString())) {
1385 raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1).toString()));
1386 resume($rule_number);
1387 return false;
1388 }
1389 } break;
1390./
1391
1392entity_value ::= QUOTE QUOTE;
1393/.
1394 case $rule_number:./
1395entity_value ::= DBLQUOTE DBLQUOTE;
1396/.
1397 case $rule_number:
1398 clearSym();
1399 break;
1400./
1401
1402entity_value ::= QUOTE entity_value_content_with_dblquote QUOTE;
1403/.
1404 case $rule_number:./
1405entity_value ::= DBLQUOTE entity_value_content_with_quote DBLQUOTE;
1406/.
1407 case $rule_number:
1408 sym(1) = sym(2);
1409 break;
1410./
1411
1412entity_value_content_with_dblquote ::= entity_value_content_with_dblquote entity_value_content;
1413/.
1414 case $rule_number:./
1415entity_value_content_with_quote ::= entity_value_content_with_quote entity_value_content;
1416/.
1417 case $rule_number:./
1418entity_value_content_with_dblquote ::= entity_value_content_with_dblquote DBLQUOTE;
1419/.
1420 case $rule_number:./
1421entity_value_content_with_quote ::= entity_value_content_with_quote QUOTE;
1422/.
1423 case $rule_number:
1424 sym(1).len += sym(2).len;
1425 break;
1426./
1427entity_value_content_with_dblquote ::= entity_value_content;
1428entity_value_content_with_quote ::= entity_value_content;
1429entity_value_content_with_dblquote ::= DBLQUOTE;
1430entity_value_content_with_quote ::= QUOTE;
1431
1432entity_value_content ::= LETTER | DIGIT | LANGLE | RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | SLASH | COLON | SEMICOLON | COMMA | SPACE | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG;
1433entity_value_content ::= char_ref | entity_ref_in_entity_value | entity_done;
1434
1435
1436attribute_value ::= QUOTE QUOTE;
1437/.
1438 case $rule_number:./
1439attribute_value ::= DBLQUOTE DBLQUOTE;
1440/.
1441 case $rule_number:
1442 clearSym();
1443 break;
1444./
1445attribute_value ::= QUOTE attribute_value_content_with_dblquote QUOTE;
1446/.
1447 case $rule_number:./
1448attribute_value ::= DBLQUOTE attribute_value_content_with_quote DBLQUOTE;
1449/.
1450 case $rule_number:
1451 sym(1) = sym(2);
1452 lastAttributeValue = symString(1);
1453 break;
1454./
1455
1456attribute_value_content_with_dblquote ::= attribute_value_content_with_dblquote attribute_value_content;
1457/.
1458 case $rule_number:./
1459attribute_value_content_with_quote ::= attribute_value_content_with_quote attribute_value_content;
1460/.
1461 case $rule_number:./
1462attribute_value_content_with_dblquote ::= attribute_value_content_with_dblquote DBLQUOTE;
1463/.
1464 case $rule_number:./
1465attribute_value_content_with_quote ::= attribute_value_content_with_quote QUOTE;
1466/.
1467 case $rule_number:
1468 sym(1).len += sym(2).len;
1469 break;
1470./
1471attribute_value_content_with_dblquote ::= attribute_value_content | DBLQUOTE;
1472attribute_value_content_with_quote ::= attribute_value_content | QUOTE;
1473
1474attribute_value_content ::= literal_content | char_ref | entity_ref_in_attribute_value | entity_done;
1475
1476attribute ::= qname space_opt EQ space_opt attribute_value;
1477/.
1478 case $rule_number: {
1479 QStringRef prefix = symPrefix(1);
1480 if (prefix.isEmpty() && symString(1) == QLatin1String("xmlns") && namespaceProcessing) {
1481 NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
1482 namespaceDeclaration.prefix.clear();
1483
1484 const QStringRef ns(symString(5));
1485 if(ns == QLatin1String("http://www.w3.org/2000/xmlns/") ||
1486 ns == QLatin1String("http://www.w3.org/XML/1998/namespace"))
1487 raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
1488 else
1489 namespaceDeclaration.namespaceUri = addToStringStorage(ns);
1490 } else {
1491 Attribute &attribute = attributeStack.push();
1492 attribute.key = sym(1);
1493 attribute.value = sym(5);
1494
1495 QStringRef attributeQualifiedName = symName(1);
1496 bool normalize = false;
1497 for (int a = 0; a < dtdAttributes.size(); ++a) {
1498 DtdAttribute &dtdAttribute = dtdAttributes[a];
1499 if (!dtdAttribute.isCDATA
1500 && dtdAttribute.tagName == qualifiedName
1501 && dtdAttribute.attributeQualifiedName == attributeQualifiedName
1502 ) {
1503 normalize = true;
1504 break;
1505 }
1506 }
1507 if (normalize) {
1508 // normalize attribute value (simplify and trim)
1509 int pos = textBuffer.size();
1510 int n = 0;
1511 bool wasSpace = true;
1512 for (int i = 0; i < attribute.value.len; ++i) {
1513 QChar c = textBuffer.at(attribute.value.pos + i);
1514 if (c.unicode() == ' ') {
1515 if (wasSpace)
1516 continue;
1517 wasSpace = true;
1518 } else {
1519 wasSpace = false;
1520 }
1521 textBuffer += textBuffer.at(attribute.value.pos + i);
1522 ++n;
1523 }
1524 if (wasSpace)
1525 while (n && textBuffer.at(pos + n - 1).unicode() == ' ')
1526 --n;
1527 attribute.value.pos = pos;
1528 attribute.value.len = n;
1529 }
1530 if (prefix == QLatin1String("xmlns") && namespaceProcessing) {
1531 NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
1532 QStringRef namespacePrefix = symString(attribute.key);
1533 QStringRef namespaceUri = symString(attribute.value);
1534 attributeStack.pop();
1535 if (((namespacePrefix == QLatin1String("xml"))
1536 ^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace")))
1537 || namespaceUri == QLatin1String("http://www.w3.org/2000/xmlns/")
1538 || namespaceUri.isEmpty()
1539 || namespacePrefix == QLatin1String("xmlns"))
1540 raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
1541
1542 namespaceDeclaration.prefix = addToStringStorage(namespacePrefix);
1543 namespaceDeclaration.namespaceUri = addToStringStorage(namespaceUri);
1544 }
1545 }
1546 } break;
1547./
1548
1549
1550
1551attribute_list_opt ::= | space | space attribute_list space_opt;
1552attribute_list ::= attribute | attribute_list space attribute;
1553
1554stag_start ::= LANGLE qname;
1555/.
1556 case $rule_number: {
1557 normalizeLiterals = true;
1558 Tag &tag = tagStack_push();
1559 prefix = tag.namespaceDeclaration.prefix = addToStringStorage(symPrefix(2));
1560 name = tag.name = addToStringStorage(symString(2));
1561 qualifiedName = tag.qualifiedName = addToStringStorage(symName(2));
1562 if ((!prefix.isEmpty() && !QXmlUtils::isNCName(prefix)) || !QXmlUtils::isNCName(name))
1563 raiseWellFormedError(QXmlStream::tr("Invalid XML name."));
1564 } break;
1565./
1566
1567
1568empty_element_tag ::= stag_start attribute_list_opt SLASH RANGLE;
1569/.
1570 case $rule_number:
1571 isEmptyElement = true;
1572 // fall through
1573./
1574
1575
1576stag ::= stag_start attribute_list_opt RANGLE;
1577/.
1578 case $rule_number:
1579 setType(QXmlStreamReader::StartElement);
1580 resolveTag();
1581 if (tagStack.size() == 1 && hasSeenTag && !inParseEntity)
1582 raiseWellFormedError(QXmlStream::tr("Extra content at end of document."));
1583 hasSeenTag = true;
1584 break;
1585./
1586
1587
1588etag ::= LANGLE SLASH qname space_opt RANGLE;
1589/.
1590 case $rule_number: {
1591 setType(QXmlStreamReader::EndElement);
1592 Tag &tag = tagStack_pop();
1593
1594 namespaceUri = tag.namespaceDeclaration.namespaceUri;
1595 name = tag.name;
1596 qualifiedName = tag.qualifiedName;
1597 if (qualifiedName != symName(3))
1598 raiseWellFormedError(QXmlStream::tr("Opening and ending tag mismatch."));
1599 } break;
1600./
1601
1602
1603unresolved_entity ::= UNRESOLVED_ENTITY;
1604/.
1605 case $rule_number:
1606 if (entitiesMustBeDeclared()) {
1607 raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(unresolvedEntity));
1608 break;
1609 }
1610 setType(QXmlStreamReader::EntityReference);
1611 name = &unresolvedEntity;
1612 break;
1613./
1614
1615entity_ref ::= AMPERSAND name SEMICOLON;
1616/.
1617 case $rule_number: {
1618 sym(1).len += sym(2).len + 1;
1619 QString reference = symString(2).toString();
1620 if (entityHash.contains(reference)) {
1621 Entity &entity = entityHash[reference];
1622 if (entity.unparsed) {
1623 raiseWellFormedError(QXmlStream::tr("Reference to unparsed entity '%1'.").arg(reference));
1624 } else {
1625 if (!entity.hasBeenParsed) {
1626 parseEntity(entity.value);
1627 entity.hasBeenParsed = true;
1628 }
1629 if (entity.literal)
1630 putStringLiteral(entity.value);
1631 else if (referenceEntity(entity))
1632 putReplacement(entity.value);
1633 textBuffer.chop(2 + sym(2).len);
1634 clearSym();
1635 }
1636 break;
1637 }
1638
1639 if (entityResolver) {
1640 QString replacementText = resolveUndeclaredEntity(reference);
1641 if (!replacementText.isNull()) {
1642 putReplacement(replacementText);
1643 textBuffer.chop(2 + sym(2).len);
1644 clearSym();
1645 break;
1646 }
1647 }
1648
1649 injectToken(UNRESOLVED_ENTITY);
1650 unresolvedEntity = symString(2).toString();
1651 textBuffer.chop(2 + sym(2).len);
1652 clearSym();
1653
1654 } break;
1655./
1656
1657pereference ::= PERCENT name SEMICOLON;
1658/.
1659 case $rule_number: {
1660 sym(1).len += sym(2).len + 1;
1661 QString reference = symString(2).toString();
1662 if (parameterEntityHash.contains(reference)) {
1663 referenceToParameterEntityDetected = true;
1664 Entity &entity = parameterEntityHash[reference];
1665 if (entity.unparsed || entity.external) {
1666 referenceToUnparsedEntityDetected = true;
1667 } else {
1668 if (referenceEntity(entity))
1669 putString(entity.value);
1670 textBuffer.chop(2 + sym(2).len);
1671 clearSym();
1672 }
1673 } else if (entitiesMustBeDeclared()) {
1674 raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(symString(2).toString()));
1675 }
1676 } break;
1677./
1678
1679
1680
1681entity_ref_in_entity_value ::= AMPERSAND name SEMICOLON;
1682/.
1683 case $rule_number:
1684 sym(1).len += sym(2).len + 1;
1685 break;
1686./
1687
1688entity_ref_in_attribute_value ::= AMPERSAND name SEMICOLON;
1689/.
1690 case $rule_number: {
1691 sym(1).len += sym(2).len + 1;
1692 QString reference = symString(2).toString();
1693 if (entityHash.contains(reference)) {
1694 Entity &entity = entityHash[reference];
1695 if (entity.unparsed || entity.value.isNull()) {
1696 raiseWellFormedError(QXmlStream::tr("Reference to external entity '%1' in attribute value.").arg(reference));
1697 break;
1698 }
1699 if (!entity.hasBeenParsed) {
1700 parseEntity(entity.value);
1701 entity.hasBeenParsed = true;
1702 }
1703 if (entity.literal)
1704 putStringLiteral(entity.value);
1705 else if (referenceEntity(entity))
1706 putReplacementInAttributeValue(entity.value);
1707 textBuffer.chop(2 + sym(2).len);
1708 clearSym();
1709 break;
1710 }
1711
1712 if (entityResolver) {
1713 QString replacementText = resolveUndeclaredEntity(reference);
1714 if (!replacementText.isNull()) {
1715 putReplacement(replacementText);
1716 textBuffer.chop(2 + sym(2).len);
1717 clearSym();
1718 break;
1719 }
1720 }
1721 if (entitiesMustBeDeclared()) {
1722 raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(reference));
1723 }
1724 } break;
1725./
1726
1727char_ref ::= AMPERSAND HASH char_ref_value SEMICOLON;
1728/.
1729 case $rule_number: {
1730 if (uint s = resolveCharRef(3)) {
1731 if (s >= 0xffff)
1732 putStringLiteral(QString::fromUcs4(&s, 1));
1733 else
1734 putChar((LETTER << 16) | s);
1735
1736 textBuffer.chop(3 + sym(3).len);
1737 clearSym();
1738 } else {
1739 raiseWellFormedError(QXmlStream::tr("Invalid character reference."));
1740 }
1741 } break;
1742./
1743
1744
1745char_ref_value ::= LETTER | DIGIT;
1746char_ref_value ::= char_ref_value LETTER;
1747/.
1748 case $rule_number:./
1749char_ref_value ::= char_ref_value DIGIT;
1750/.
1751 case $rule_number:
1752 sym(1).len += sym(2).len;
1753 break;
1754./
1755
1756
1757content ::= content character_content;
1758content ::= content stag content etag;
1759content ::= content empty_element_tag;
1760content ::= content comment;
1761content ::= content cdata;
1762content ::= content xml_decl;
1763content ::= content processing_instruction;
1764content ::= content doctype_decl;
1765content ::= content unresolved_entity;
1766content ::= ;
1767
1768
1769space ::= SPACE;
1770/.
1771 case $rule_number:
1772 sym(1).len += fastScanSpace();
1773 if (atEnd) {
1774 resume($rule_number);
1775 return false;
1776 }
1777 break;
1778./
1779
1780
1781space_opt ::=;
1782space_opt ::= space;
1783
1784qname ::= LETTER;
1785/.
1786 case $rule_number: {
1787 sym(1).len += fastScanName(&sym(1).prefix);
1788 if (atEnd) {
1789 resume($rule_number);
1790 return false;
1791 }
1792 } break;
1793./
1794
1795name ::= LETTER;
1796/.
1797 case $rule_number:
1798 sym(1).len += fastScanName();
1799 if (atEnd) {
1800 resume($rule_number);
1801 return false;
1802 }
1803 break;
1804./
1805
1806nmtoken ::= LETTER;
1807/.
1808 case $rule_number:./
1809nmtoken ::= DIGIT;
1810/.
1811 case $rule_number:./
1812nmtoken ::= DOT;
1813/.
1814 case $rule_number:./
1815nmtoken ::= DASH;
1816/.
1817 case $rule_number:./
1818nmtoken ::= COLON;
1819/.
1820 case $rule_number:
1821 sym(1).len += fastScanNMTOKEN();
1822 if (atEnd) {
1823 resume($rule_number);
1824 return false;
1825 }
1826
1827 break;
1828./
1829
1830
1831/.
1832 default:
1833 ;
1834 } // switch
1835 act = state_stack[tos] = nt_action (act, lhs[r] - TERMINAL_COUNT);
1836 if (type != QXmlStreamReader::NoToken)
1837 return true;
1838 } else {
1839 parseError();
1840 break;
1841 }
1842 }
1843 return false;
1844}
1845#endif //QT_NO_XMLSTREAMREADER.xml
1846
1847./
Note: See TracBrowser for help on using the repository browser.