summaryrefslogtreecommitdiffstats
path: root/src/corelib/serialization/qxmlstream.g
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/serialization/qxmlstream.g')
-rw-r--r--src/corelib/serialization/qxmlstream.g1852
1 files changed, 1852 insertions, 0 deletions
diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g
new file mode 100644
index 0000000000..fd69a6e4af
--- /dev/null
+++ b/src/corelib/serialization/qxmlstream.g
@@ -0,0 +1,1852 @@
+----------------------------------------------------------------------------
+--
+-- Copyright (C) 2016 The Qt Company Ltd.
+-- Contact: https://www.qt.io/licensing/
+--
+-- This file is part of the QtCore module of the Qt Toolkit.
+--
+-- $QT_BEGIN_LICENSE:LGPL$
+-- Commercial License Usage
+-- Licensees holding valid commercial Qt licenses may use this file in
+-- accordance with the commercial license agreement provided with the
+-- Software or, alternatively, in accordance with the terms contained in
+-- a written agreement between you and The Qt Company. For licensing terms
+-- and conditions see https://www.qt.io/terms-conditions. For further
+-- information use the contact form at https://www.qt.io/contact-us.
+--
+-- GNU Lesser General Public License Usage
+-- Alternatively, this file may be used under the terms of the GNU Lesser
+-- General Public License version 3 as published by the Free Software
+-- Foundation and appearing in the file LICENSE.LGPL3 included in the
+-- packaging of this file. Please review the following information to
+-- ensure the GNU Lesser General Public License version 3 requirements
+-- will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+--
+-- GNU General Public License Usage
+-- Alternatively, this file may be used under the terms of the GNU
+-- General Public License version 2.0 or (at your option) the GNU General
+-- Public license version 3 or any later version approved by the KDE Free
+-- Qt Foundation. The licenses are as published by the Free Software
+-- Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+-- included in the packaging of this file. Please review the following
+-- information to ensure the GNU General Public License requirements will
+-- be met: https://www.gnu.org/licenses/gpl-2.0.html and
+-- https://www.gnu.org/licenses/gpl-3.0.html.
+--
+-- $QT_END_LICENSE$
+--
+----------------------------------------------------------------------------
+
+%parser QXmlStreamReader_Table
+
+%merged_output qxmlstream_p.h
+
+%token NOTOKEN
+%token SPACE " "
+%token LANGLE "<"
+%token RANGLE ">"
+%token AMPERSAND "&"
+%token HASH "#"
+%token QUOTE "\'"
+%token DBLQUOTE "\""
+%token LBRACK "["
+%token RBRACK "]"
+%token LPAREN "("
+%token RPAREN ")"
+%token PIPE "|"
+%token EQ "="
+%token PERCENT "%"
+%token SLASH "/"
+%token COLON ":"
+%token SEMICOLON ";"
+%token COMMA ","
+%token DASH "-"
+%token PLUS "+"
+%token STAR "*"
+%token DOT "."
+%token QUESTIONMARK "?"
+%token BANG "!"
+%token LETTER "[a-zA-Z]"
+%token DIGIT "[0-9]"
+
+-- after langle_bang
+%token CDATA_START "[CDATA["
+%token DOCTYPE "DOCTYPE"
+%token ELEMENT "ELEMENT"
+%token ATTLIST "ATTLIST"
+%token ENTITY "ENTITY"
+%token NOTATION "NOTATION"
+
+-- entity decl
+%token SYSTEM "SYSTEM"
+%token PUBLIC "PUBLIC"
+%token NDATA "NDATA"
+
+-- default decl
+%token REQUIRED "REQUIRED"
+%token IMPLIED "IMPLIED"
+%token FIXED "FIXED"
+
+-- conent spec
+%token EMPTY "EMPTY"
+%token ANY "ANY"
+%token PCDATA "PCDATA"
+
+-- error
+%token ERROR
+
+-- entities
+%token PARSE_ENTITY
+%token ENTITY_DONE
+%token UNRESOLVED_ENTITY
+
+-- att type
+%token CDATA "CDATA"
+%token ID "ID"
+%token IDREF "IDREF"
+%token IDREFS "IDREFS"
+%token ENTITY "ENTITY"
+%token ENTITIES "ENTITIES"
+%token NMTOKEN "NMTOKEN"
+%token NMTOKENS "NMTOKENS"
+
+-- xml declaration
+%token XML "<?xml"
+%token VERSION "version"
+
+%nonassoc SHIFT_THERE
+%nonassoc AMPERSAND
+ BANG
+ COLON
+ COMMA
+ DASH
+ DBLQUOTE
+ DIGIT
+ DOT
+ ENTITY_DONE
+ EQ
+ HASH
+ LBRACK
+ LETTER
+ LPAREN
+ PERCENT
+ PIPE
+ PLUS
+ QUESTIONMARK
+ QUOTE
+ RANGLE
+ RBRACK
+ RPAREN
+ SEMICOLON
+ SLASH
+ SPACE
+ STAR
+
+%start document
+
+/.
+template <typename T> class QXmlStreamSimpleStack {
+ T *data;
+ int tos, cap;
+public:
+ inline QXmlStreamSimpleStack():data(0), tos(-1), cap(0){}
+ inline ~QXmlStreamSimpleStack(){ if (data) free(data); }
+
+ inline void reserve(int extraCapacity) {
+ if (tos + extraCapacity + 1 > cap) {
+ cap = qMax(tos + extraCapacity + 1, cap << 1 );
+ data = reinterpret_cast<T *>(realloc(data, cap * sizeof(T)));
+ Q_CHECK_PTR(data);
+ }
+ }
+
+ inline T &push() { reserve(1); return data[++tos]; }
+ inline T &rawPush() { return data[++tos]; }
+ inline const T &top() const { return data[tos]; }
+ inline T &top() { return data[tos]; }
+ inline T &pop() { return data[tos--]; }
+ inline T &operator[](int index) { return data[index]; }
+ inline const T &at(int index) const { return data[index]; }
+ inline int size() const { return tos + 1; }
+ inline void resize(int s) { tos = s - 1; }
+ inline bool isEmpty() const { return tos < 0; }
+ inline void clear() { tos = -1; }
+};
+
+
+class QXmlStream
+{
+ Q_DECLARE_TR_FUNCTIONS(QXmlStream)
+};
+
+class QXmlStreamPrivateTagStack {
+public:
+ struct NamespaceDeclaration
+ {
+ QStringRef prefix;
+ QStringRef namespaceUri;
+ };
+
+ struct Tag
+ {
+ QStringRef name;
+ QStringRef qualifiedName;
+ NamespaceDeclaration namespaceDeclaration;
+ int tagStackStringStorageSize;
+ int namespaceDeclarationsSize;
+ };
+
+
+ QXmlStreamPrivateTagStack();
+ QXmlStreamSimpleStack<NamespaceDeclaration> namespaceDeclarations;
+ QString tagStackStringStorage;
+ int tagStackStringStorageSize;
+ int initialTagStackStringStorageSize;
+ bool tagsDone;
+
+ inline QStringRef addToStringStorage(const QStringRef &s) {
+ return addToStringStorage(qToStringViewIgnoringNull(s));
+ }
+ inline QStringRef addToStringStorage(const QString &s) {
+ return addToStringStorage(qToStringViewIgnoringNull(s));
+ }
+ QStringRef addToStringStorage(QStringView s)
+ {
+ int pos = tagStackStringStorageSize;
+ int sz = s.size();
+ if (pos != tagStackStringStorage.size())
+ tagStackStringStorage.resize(pos);
+ tagStackStringStorage.append(s.data(), sz);
+ tagStackStringStorageSize += sz;
+ return QStringRef(&tagStackStringStorage, pos, sz);
+ }
+
+ QXmlStreamSimpleStack<Tag> tagStack;
+
+
+ inline Tag &tagStack_pop() {
+ Tag& tag = tagStack.pop();
+ tagStackStringStorageSize = tag.tagStackStringStorageSize;
+ namespaceDeclarations.resize(tag.namespaceDeclarationsSize);
+ tagsDone = tagStack.isEmpty();
+ return tag;
+ }
+ inline Tag &tagStack_push() {
+ Tag &tag = tagStack.push();
+ tag.tagStackStringStorageSize = tagStackStringStorageSize;
+ tag.namespaceDeclarationsSize = namespaceDeclarations.size();
+ return tag;
+ }
+};
+
+
+class QXmlStreamEntityResolver;
+#ifndef QT_NO_XMLSTREAMREADER
+class QXmlStreamReaderPrivate : public QXmlStreamReader_Table, public QXmlStreamPrivateTagStack{
+ QXmlStreamReader *q_ptr;
+ Q_DECLARE_PUBLIC(QXmlStreamReader)
+public:
+ QXmlStreamReaderPrivate(QXmlStreamReader *q);
+ ~QXmlStreamReaderPrivate();
+ void init();
+
+ QByteArray rawReadBuffer;
+ QByteArray dataBuffer;
+ uchar firstByte;
+ qint64 nbytesread;
+ QString readBuffer;
+ int readBufferPos;
+ QXmlStreamSimpleStack<uint> putStack;
+ struct Entity {
+ Entity() = default;
+ Entity(const QString &name, const QString &value)
+ : name(name), value(value), external(false), unparsed(false), literal(false),
+ hasBeenParsed(false), isCurrentlyReferenced(false){}
+ static inline Entity createLiteral(QLatin1String name, QLatin1String value)
+ { Entity result(name, value); result.literal = result.hasBeenParsed = true; return result; }
+ QString name, value;
+ uint external : 1;
+ uint unparsed : 1;
+ uint literal : 1;
+ uint hasBeenParsed : 1;
+ uint isCurrentlyReferenced : 1;
+ };
+ // these hash tables use a QStringView as a key to avoid creating QStrings
+ // just for lookup. The keys are usually views into Entity::name and thus
+ // are guaranteed to have the same lifetime as the referenced data:
+ QHash<QStringView, Entity> entityHash;
+ QHash<QStringView, Entity> parameterEntityHash;
+ QXmlStreamSimpleStack<Entity *>entityReferenceStack;
+ inline bool referenceEntity(Entity &entity) {
+ if (entity.isCurrentlyReferenced) {
+ raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
+ return false;
+ }
+ entity.isCurrentlyReferenced = true;
+ entityReferenceStack.push() = &entity;
+ injectToken(ENTITY_DONE);
+ return true;
+ }
+
+
+ QIODevice *device;
+ bool deleteDevice;
+#ifndef QT_NO_TEXTCODEC
+ QTextCodec *codec;
+ QTextDecoder *decoder;
+#endif
+ bool atEnd;
+
+ /*!
+ \sa setType()
+ */
+ QXmlStreamReader::TokenType type;
+ QXmlStreamReader::Error error;
+ QString errorString;
+ QString unresolvedEntity;
+
+ qint64 lineNumber, lastLineStart, characterOffset;
+
+
+ void write(const QString &);
+ void write(const char *);
+
+
+ QXmlStreamAttributes attributes;
+ QStringRef namespaceForPrefix(const QStringRef &prefix);
+ void resolveTag();
+ void resolvePublicNamespaces();
+ void resolveDtd();
+ uint resolveCharRef(int symbolIndex);
+ bool checkStartDocument();
+ void startDocument();
+ void parseError();
+ void checkPublicLiteral(const QStringRef &publicId);
+
+ bool scanDtd;
+ QStringRef lastAttributeValue;
+ bool lastAttributeIsCData;
+ struct DtdAttribute {
+ QStringRef tagName;
+ QStringRef attributeQualifiedName;
+ QStringRef attributePrefix;
+ QStringRef attributeName;
+ QStringRef defaultValue;
+ bool isCDATA;
+ bool isNamespaceAttribute;
+ };
+ QXmlStreamSimpleStack<DtdAttribute> dtdAttributes;
+ struct NotationDeclaration {
+ QStringRef name;
+ QStringRef publicId;
+ QStringRef systemId;
+ };
+ QXmlStreamSimpleStack<NotationDeclaration> notationDeclarations;
+ QXmlStreamNotationDeclarations publicNotationDeclarations;
+ QXmlStreamNamespaceDeclarations publicNamespaceDeclarations;
+
+ struct EntityDeclaration {
+ QStringRef name;
+ QStringRef notationName;
+ QStringRef publicId;
+ QStringRef systemId;
+ QStringRef value;
+ bool parameter;
+ bool external;
+ inline void clear() {
+ name.clear();
+ notationName.clear();
+ publicId.clear();
+ systemId.clear();
+ value.clear();
+ parameter = external = false;
+ }
+ };
+ QXmlStreamSimpleStack<EntityDeclaration> entityDeclarations;
+ QXmlStreamEntityDeclarations publicEntityDeclarations;
+
+ QStringRef text;
+
+ QStringRef prefix, namespaceUri, qualifiedName, name;
+ QStringRef processingInstructionTarget, processingInstructionData;
+ QStringRef dtdName, dtdPublicId, dtdSystemId;
+ QStringRef documentVersion, documentEncoding;
+ uint isEmptyElement : 1;
+ uint isWhitespace : 1;
+ uint isCDATA : 1;
+ uint standalone : 1;
+ uint hasCheckedStartDocument : 1;
+ uint normalizeLiterals : 1;
+ uint hasSeenTag : 1;
+ uint inParseEntity : 1;
+ uint referenceToUnparsedEntityDetected : 1;
+ uint referenceToParameterEntityDetected : 1;
+ uint hasExternalDtdSubset : 1;
+ uint lockEncoding : 1;
+ uint namespaceProcessing : 1;
+
+ int resumeReduction;
+ void resume(int rule);
+
+ inline bool entitiesMustBeDeclared() const {
+ return (!inParseEntity
+ && (standalone
+ || (!referenceToUnparsedEntityDetected
+ && !referenceToParameterEntityDetected // Errata 13 as of 2006-04-25
+ && !hasExternalDtdSubset)));
+ }
+
+ // qlalr parser
+ int tos;
+ int stack_size;
+ struct Value {
+ int pos;
+ int len;
+ int prefix;
+ ushort c;
+ };
+
+ Value *sym_stack;
+ int *state_stack;
+ inline void reallocateStack();
+ inline Value &sym(int index) const
+ { return sym_stack[tos + index - 1]; }
+ QString textBuffer;
+ inline void clearTextBuffer() {
+ if (!scanDtd) {
+ textBuffer.resize(0);
+ textBuffer.reserve(256);
+ }
+ }
+ struct Attribute {
+ Value key;
+ Value value;
+ };
+ QXmlStreamSimpleStack<Attribute> attributeStack;
+
+ inline QStringRef symString(int index) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
+ }
+ QStringView symView(int index) const
+ {
+ const Value &symbol = sym(index);
+ return QStringView(textBuffer.data() + symbol.pos, symbol.len).mid(symbol.prefix);
+ }
+ inline QStringRef symName(int index) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos, symbol.len);
+ }
+ inline QStringRef symString(int index, int offset) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix + offset, symbol.len - symbol.prefix - offset);
+ }
+ inline QStringRef symPrefix(int index) {
+ const Value &symbol = sym(index);
+ if (symbol.prefix)
+ return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
+ return QStringRef();
+ }
+ inline QStringRef symString(const Value &symbol) {
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
+ }
+ inline QStringRef symName(const Value &symbol) {
+ return QStringRef(&textBuffer, symbol.pos, symbol.len);
+ }
+ inline QStringRef symPrefix(const Value &symbol) {
+ if (symbol.prefix)
+ return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
+ return QStringRef();
+ }
+
+ inline void clearSym() { Value &val = sym(1); val.pos = textBuffer.size(); val.len = 0; }
+
+
+ short token;
+ uint token_char;
+
+ uint filterCarriageReturn();
+ inline uint getChar();
+ inline uint peekChar();
+ inline void putChar(uint c) { putStack.push() = c; }
+ inline void putChar(QChar c) { putStack.push() = c.unicode(); }
+ void putString(const QString &s, int from = 0);
+ void putStringLiteral(const QString &s);
+ void putReplacement(const QString &s);
+ void putReplacementInAttributeValue(const QString &s);
+ uint getChar_helper();
+
+ bool scanUntil(const char *str, short tokenToInject = -1);
+ bool scanString(const char *str, short tokenToInject, bool requireSpace = true);
+ inline void injectToken(ushort tokenToInject) {
+ putChar(int(tokenToInject) << 16);
+ }
+
+ QString resolveUndeclaredEntity(const QString &name);
+ void parseEntity(const QString &value);
+ QXmlStreamReaderPrivate *entityParser;
+
+ bool scanAfterLangleBang();
+ bool scanPublicOrSystem();
+ bool scanNData();
+ bool scanAfterDefaultDecl();
+ bool scanAttType();
+
+
+ // scan optimization functions. Not strictly necessary but LALR is
+ // not very well suited for scanning fast
+ int fastScanLiteralContent();
+ int fastScanSpace();
+ int fastScanContentCharList();
+ int fastScanName(int *prefix = 0);
+ inline int fastScanNMTOKEN();
+
+
+ bool parse();
+ inline void consumeRule(int);
+
+ void raiseError(QXmlStreamReader::Error error, const QString& message = QString());
+ void raiseWellFormedError(const QString &message);
+
+ QXmlStreamEntityResolver *entityResolver;
+
+private:
+ /*! \internal
+ Never assign to variable type directly. Instead use this function.
+
+ This prevents errors from being ignored.
+ */
+ inline void setType(const QXmlStreamReader::TokenType t)
+ {
+ if(type != QXmlStreamReader::Invalid)
+ type = t;
+ }
+};
+
+bool QXmlStreamReaderPrivate::parse()
+{
+ // cleanup currently reported token
+
+ switch (type) {
+ case QXmlStreamReader::StartElement:
+ name.clear();
+ prefix.clear();
+ qualifiedName.clear();
+ namespaceUri.clear();
+ publicNamespaceDeclarations.clear();
+ attributes.clear();
+ if (isEmptyElement) {
+ setType(QXmlStreamReader::EndElement);
+ Tag &tag = tagStack_pop();
+ namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ name = tag.name;
+ qualifiedName = tag.qualifiedName;
+ isEmptyElement = false;
+ return true;
+ }
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::EndElement:
+ name.clear();
+ prefix.clear();
+ qualifiedName.clear();
+ namespaceUri.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::DTD:
+ publicNotationDeclarations.clear();
+ publicEntityDeclarations.clear();
+ dtdName.clear();
+ dtdPublicId.clear();
+ dtdSystemId.clear();
+ Q_FALLTHROUGH();
+ case QXmlStreamReader::Comment:
+ case QXmlStreamReader::Characters:
+ isCDATA = false;
+ isWhitespace = true;
+ text.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::EntityReference:
+ text.clear();
+ name.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::ProcessingInstruction:
+ processingInstructionTarget.clear();
+ processingInstructionData.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::NoToken:
+ case QXmlStreamReader::Invalid:
+ break;
+ case QXmlStreamReader::StartDocument:
+ lockEncoding = true;
+ documentVersion.clear();
+ documentEncoding.clear();
+#ifndef QT_NO_TEXTCODEC
+ if (decoder && decoder->hasFailure()) {
+ raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
+ readBuffer.clear();
+ return false;
+ }
+#endif
+ Q_FALLTHROUGH();
+ default:
+ clearTextBuffer();
+ ;
+ }
+
+ setType(QXmlStreamReader::NoToken);
+
+
+ // the main parse loop
+ int act, r;
+
+ if (resumeReduction) {
+ act = state_stack[tos-1];
+ r = resumeReduction;
+ resumeReduction = 0;
+ goto ResumeReduction;
+ }
+
+ act = state_stack[tos];
+
+ forever {
+ if (token == -1 && - TERMINAL_COUNT != action_index[act]) {
+ uint cu = getChar();
+ token = NOTOKEN;
+ token_char = cu == ~0U ? cu : ushort(cu);
+ if ((cu != ~0U) && (cu & 0xff0000)) {
+ token = cu >> 16;
+ } else switch (token_char) {
+ case 0xfffe:
+ case 0xffff:
+ token = ERROR;
+ break;
+ case '\r':
+ token = SPACE;
+ if (cu == '\r') {
+ if ((token_char = filterCarriageReturn())) {
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ break;
+ }
+ } else {
+ break;
+ }
+ Q_FALLTHROUGH();
+ case ~0U: {
+ token = EOF_SYMBOL;
+ if (!tagsDone && !inParseEntity) {
+ int a = t_action(act, token);
+ if (a < 0) {
+ raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
+ return false;
+ }
+ }
+
+ } break;
+ case '\n':
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ Q_FALLTHROUGH();
+ case ' ':
+ case '\t':
+ token = SPACE;
+ break;
+ case '&':
+ token = AMPERSAND;
+ break;
+ case '#':
+ token = HASH;
+ break;
+ case '\'':
+ token = QUOTE;
+ break;
+ case '\"':
+ token = DBLQUOTE;
+ break;
+ case '<':
+ token = LANGLE;
+ break;
+ case '>':
+ token = RANGLE;
+ break;
+ case '[':
+ token = LBRACK;
+ break;
+ case ']':
+ token = RBRACK;
+ break;
+ case '(':
+ token = LPAREN;
+ break;
+ case ')':
+ token = RPAREN;
+ break;
+ case '|':
+ token = PIPE;
+ break;
+ case '=':
+ token = EQ;
+ break;
+ case '%':
+ token = PERCENT;
+ break;
+ case '/':
+ token = SLASH;
+ break;
+ case ':':
+ token = COLON;
+ break;
+ case ';':
+ token = SEMICOLON;
+ break;
+ case ',':
+ token = COMMA;
+ break;
+ case '-':
+ token = DASH;
+ break;
+ case '+':
+ token = PLUS;
+ break;
+ case '*':
+ token = STAR;
+ break;
+ case '.':
+ token = DOT;
+ break;
+ case '?':
+ token = QUESTIONMARK;
+ break;
+ case '!':
+ token = BANG;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ token = DIGIT;
+ break;
+ default:
+ if (cu < 0x20)
+ token = NOTOKEN;
+ else
+ token = LETTER;
+ break;
+ }
+ }
+
+ act = t_action (act, token);
+ if (act == ACCEPT_STATE) {
+ // reset the parser in case someone resumes (process instructions can follow a valid document)
+ tos = 0;
+ state_stack[tos++] = 0;
+ state_stack[tos] = 0;
+ return true;
+ } else if (act > 0) {
+ if (++tos == stack_size-1)
+ reallocateStack();
+
+ Value &val = sym_stack[tos];
+ val.c = token_char;
+ val.pos = textBuffer.size();
+ val.prefix = 0;
+ val.len = 1;
+ if (token_char)
+ textBuffer += QChar(token_char);
+
+ state_stack[tos] = act;
+ token = -1;
+
+
+ } else if (act < 0) {
+ r = - act - 1;
+
+#if defined (QLALR_DEBUG)
+ int ridx = rule_index[r];
+ printf ("%3d) %s ::=", r + 1, spell[rule_info[ridx]]);
+ ++ridx;
+ for (int i = ridx; i < ridx + rhs[r]; ++i) {
+ int symbol = rule_info[i];
+ if (const char *name = spell[symbol])
+ printf (" %s", name);
+ else
+ printf (" #%d", symbol);
+ }
+ printf ("\n");
+#endif
+
+ tos -= rhs[r];
+ act = state_stack[tos++];
+ ResumeReduction:
+ switch (r) {
+./
+
+document ::= PARSE_ENTITY content;
+/.
+ case $rule_number:
+ setType(QXmlStreamReader::EndDocument);
+ break;
+./
+
+document ::= prolog;
+/.
+ case $rule_number:
+ if (type != QXmlStreamReader::Invalid) {
+ if (hasSeenTag || inParseEntity) {
+ setType(QXmlStreamReader::EndDocument);
+ } else {
+ raiseError(QXmlStreamReader::NotWellFormedError, QXmlStream::tr("Start tag expected."));
+ // reset the parser
+ tos = 0;
+ state_stack[tos++] = 0;
+ state_stack[tos] = 0;
+ return false;
+ }
+ }
+ break;
+./
+
+
+prolog ::= prolog stag content etag;
+prolog ::= prolog empty_element_tag;
+prolog ::= prolog comment;
+prolog ::= prolog xml_decl;
+prolog ::= prolog processing_instruction;
+prolog ::= prolog doctype_decl;
+prolog ::= prolog SPACE;
+prolog ::=;
+
+entity_done ::= ENTITY_DONE;
+/.
+ case $rule_number:
+ entityReferenceStack.pop()->isCurrentlyReferenced = false;
+ clearSym();
+ break;
+./
+
+
+xml_decl_start ::= XML;
+/.
+ case $rule_number:
+ if (!scanString(spell[VERSION], VERSION, false) && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+xml_decl ::= xml_decl_start VERSION space_opt EQ space_opt literal attribute_list_opt QUESTIONMARK RANGLE;
+/.
+ case $rule_number:
+ setType(QXmlStreamReader::StartDocument);
+ documentVersion = symString(6);
+ startDocument();
+ break;
+./
+
+external_id ::= SYSTEM literal;
+/.
+ case $rule_number:
+ hasExternalDtdSubset = true;
+ dtdSystemId = symString(2);
+ break;
+./
+external_id ::= PUBLIC public_literal space literal;
+/.
+ case $rule_number:
+ checkPublicLiteral(symString(2));
+ dtdPublicId = symString(2);
+ dtdSystemId = symString(4);
+ hasExternalDtdSubset = true;
+ break;
+./
+external_id ::=;
+
+doctype_decl_start ::= langle_bang DOCTYPE qname space;
+/.
+ case $rule_number:
+ if (!scanPublicOrSystem() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ dtdName = symString(3);
+ break;
+./
+
+doctype_decl ::= langle_bang DOCTYPE qname RANGLE;
+/.
+ case $rule_number:./
+doctype_decl ::= langle_bang DOCTYPE qname markup space_opt RANGLE;
+/.
+ case $rule_number:
+ dtdName = symString(3);
+ // fall through
+./
+doctype_decl ::= doctype_decl_start external_id space_opt markup space_opt RANGLE;
+/.
+ case $rule_number:./
+doctype_decl ::= doctype_decl_start external_id space_opt RANGLE;
+/.
+ case $rule_number:
+ setType(QXmlStreamReader::DTD);
+ text = &textBuffer;
+ break;
+./
+
+markup_start ::= LBRACK;
+/.
+ case $rule_number:
+ scanDtd = true;
+ break;
+./
+
+markup ::= markup_start markup_list RBRACK;
+/.
+ case $rule_number:
+ scanDtd = false;
+ break;
+./
+
+
+markup_list ::= markup_decl | space | pereference;
+markup_list ::= markup_list markup_decl | markup_list space | markup_list pereference;
+markup_list ::=;
+
+markup_decl ::= element_decl | attlist_decl | entity_decl | entity_done | notation_decl | processing_instruction | comment;
+
+
+element_decl_start ::= langle_bang ELEMENT qname space;
+/.
+ case $rule_number:
+ if (!scanString(spell[EMPTY], EMPTY, false)
+ && !scanString(spell[ANY], ANY, false)
+ && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+element_decl ::= element_decl_start content_spec space_opt RANGLE;
+
+
+content_spec ::= EMPTY | ANY | mixed | children;
+
+pcdata_start ::= HASH;
+/.
+ case $rule_number:
+ if (!scanString(spell[PCDATA], PCDATA, false) && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+pcdata ::= pcdata_start PCDATA;
+
+questionmark_or_star_or_plus_opt ::= QUESTIONMARK | STAR | PLUS;
+questionmark_or_star_or_plus_opt ::=;
+
+cp ::= qname questionmark_or_star_or_plus_opt | choice_or_seq questionmark_or_star_or_plus_opt;
+
+cp_pipe_or_comma_list ::= cp space_opt;
+cp_pipe_or_comma_list ::= cp space_opt PIPE space_opt cp_pipe_list space_opt;
+cp_pipe_or_comma_list ::= cp space_opt COMMA space_opt cp_comma_list space_opt;
+cp_pipe_list ::= cp | cp_pipe_list space_opt PIPE space_opt cp;
+cp_comma_list ::= cp | cp_comma_list space_opt COMMA space_opt cp;
+
+
+name_pipe_list ::= PIPE space_opt qname;
+name_pipe_list ::= name_pipe_list space_opt PIPE space_opt qname;
+
+star_opt ::= | STAR;
+
+mixed ::= LPAREN space_opt pcdata space_opt RPAREN star_opt;
+mixed ::= LPAREN space_opt pcdata space_opt name_pipe_list space_opt RPAREN STAR;
+
+choice_or_seq ::= LPAREN space_opt cp_pipe_or_comma_list RPAREN;
+
+children ::= choice_or_seq questionmark_or_star_or_plus_opt;
+
+
+nmtoken_pipe_list ::= nmtoken;
+nmtoken_pipe_list ::= nmtoken_pipe_list space_opt PIPE space_opt nmtoken;
+
+
+att_type ::= CDATA;
+/.
+ case $rule_number: {
+ lastAttributeIsCData = true;
+ } break;
+./
+att_type ::= ID | IDREF | IDREFS | ENTITY | ENTITIES | NMTOKEN | NMTOKENS;
+att_type ::= LPAREN space_opt nmtoken_pipe_list space_opt RPAREN space;
+att_type ::= NOTATION LPAREN space_opt nmtoken_pipe_list space_opt RPAREN space;
+
+
+default_declhash ::= HASH;
+/.
+ case $rule_number:
+ if (!scanAfterDefaultDecl() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+default_decl ::= default_declhash REQUIRED;
+default_decl ::= default_declhash IMPLIED;
+default_decl ::= attribute_value;
+default_decl ::= default_declhash FIXED space attribute_value;
+attdef_start ::= space qname space;
+/.
+ case $rule_number:
+ sym(1) = sym(2);
+ lastAttributeValue.clear();
+ lastAttributeIsCData = false;
+ if (!scanAttType() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+attdef ::= attdef_start att_type default_decl;
+/.
+ case $rule_number: {
+ DtdAttribute &dtdAttribute = dtdAttributes.push();
+ dtdAttribute.tagName.clear();
+ dtdAttribute.isCDATA = lastAttributeIsCData;
+ dtdAttribute.attributePrefix = addToStringStorage(symPrefix(1));
+ dtdAttribute.attributeName = addToStringStorage(symString(1));
+ dtdAttribute.attributeQualifiedName = addToStringStorage(symName(1));
+ dtdAttribute.isNamespaceAttribute = (dtdAttribute.attributePrefix == QLatin1String("xmlns")
+ || (dtdAttribute.attributePrefix.isEmpty()
+ && dtdAttribute.attributeName == QLatin1String("xmlns")));
+ if (lastAttributeValue.isNull()) {
+ dtdAttribute.defaultValue.clear();
+ } else {
+ if (dtdAttribute.isCDATA)
+ dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue);
+ else
+ dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue.toString().simplified());
+
+ }
+ } break;
+./
+
+attdef_list ::= attdef;
+attdef_list ::= attdef_list attdef;
+
+attlist_decl ::= langle_bang ATTLIST qname space_opt RANGLE;
+attlist_decl ::= langle_bang ATTLIST qname attdef_list space_opt RANGLE;
+/.
+ case $rule_number: {
+ if (referenceToUnparsedEntityDetected && !standalone)
+ break;
+ int n = dtdAttributes.size();
+ QStringRef tagName = addToStringStorage(symName(3));
+ while (n--) {
+ DtdAttribute &dtdAttribute = dtdAttributes[n];
+ if (!dtdAttribute.tagName.isNull())
+ break;
+ dtdAttribute.tagName = tagName;
+ for (int i = 0; i < n; ++i) {
+ if ((dtdAttributes[i].tagName.isNull() || dtdAttributes[i].tagName == tagName)
+ && dtdAttributes[i].attributeQualifiedName == dtdAttribute.attributeQualifiedName) {
+ dtdAttribute.attributeQualifiedName.clear(); // redefined, delete it
+ break;
+ }
+ }
+ }
+ } break;
+./
+
+entity_decl_start ::= langle_bang ENTITY name space;
+/.
+ case $rule_number: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.push();
+ entityDeclaration.clear();
+ entityDeclaration.name = symString(3);
+ } break;
+./
+
+entity_decl_start ::= langle_bang ENTITY PERCENT space name space;
+/.
+ case $rule_number: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.push();
+ entityDeclaration.clear();
+ entityDeclaration.name = symString(5);
+ entityDeclaration.parameter = true;
+ } break;
+./
+
+entity_decl_external ::= entity_decl_start SYSTEM literal;
+/.
+ case $rule_number: {
+ if (!scanNData() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ entityDeclaration.systemId = symString(3);
+ entityDeclaration.external = true;
+ } break;
+./
+
+entity_decl_external ::= entity_decl_start PUBLIC public_literal space literal;
+/.
+ case $rule_number: {
+ if (!scanNData() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ checkPublicLiteral((entityDeclaration.publicId = symString(3)));
+ entityDeclaration.systemId = symString(5);
+ entityDeclaration.external = true;
+ } break;
+./
+
+entity_decl ::= entity_decl_external NDATA name space_opt RANGLE;
+/.
+ case $rule_number: {
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ entityDeclaration.notationName = symString(3);
+ if (entityDeclaration.parameter)
+ raiseWellFormedError(QXmlStream::tr("NDATA in parameter entity declaration."));
+ }
+ Q_FALLTHROUGH();
+./
+
+entity_decl ::= entity_decl_external space_opt RANGLE;
+/.
+ case $rule_number:./
+
+entity_decl ::= entity_decl_start entity_value space_opt RANGLE;
+/.
+ case $rule_number: {
+ if (referenceToUnparsedEntityDetected && !standalone) {
+ entityDeclarations.pop();
+ break;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ if (!entityDeclaration.external)
+ entityDeclaration.value = symString(2);
+ auto &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
+ if (!hash.contains(qToStringViewIgnoringNull(entityDeclaration.name))) {
+ Entity entity(entityDeclaration.name.toString(),
+ entityDeclaration.value.toString());
+ entity.unparsed = (!entityDeclaration.notationName.isNull());
+ entity.external = entityDeclaration.external;
+ hash.insert(qToStringViewIgnoringNull(entity.name), entity);
+ }
+ } break;
+./
+
+
+processing_instruction ::= LANGLE QUESTIONMARK name space;
+/.
+ case $rule_number: {
+ setType(QXmlStreamReader::ProcessingInstruction);
+ int pos = sym(4).pos + sym(4).len;
+ processingInstructionTarget = symString(3);
+ if (scanUntil("?>")) {
+ processingInstructionData = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
+ if (!processingInstructionTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
+ raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document."));
+ }
+ else if (!QXmlUtils::isNCName(processingInstructionTarget))
+ raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.")
+ .arg(processingInstructionTarget));
+ } else if (type != QXmlStreamReader::Invalid){
+ resume($rule_number);
+ return false;
+ }
+ } break;
+./
+
+processing_instruction ::= LANGLE QUESTIONMARK name QUESTIONMARK RANGLE;
+/.
+ case $rule_number:
+ setType(QXmlStreamReader::ProcessingInstruction);
+ processingInstructionTarget = symString(3);
+ if (!processingInstructionTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive))
+ raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name."));
+ break;
+./
+
+
+langle_bang ::= LANGLE BANG;
+/.
+ case $rule_number:
+ if (!scanAfterLangleBang() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+comment_start ::= langle_bang DASH DASH;
+/.
+ case $rule_number:
+ if (!scanUntil("--")) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+comment ::= comment_start RANGLE;
+/.
+ case $rule_number: {
+ setType(QXmlStreamReader::Comment);
+ int pos = sym(1).pos + 4;
+ text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
+ } break;
+./
+
+
+cdata ::= langle_bang CDATA_START;
+/.
+ case $rule_number: {
+ setType(QXmlStreamReader::Characters);
+ isCDATA = true;
+ isWhitespace = false;
+ int pos = sym(2).pos;
+ if (scanUntil("]]>", -1)) {
+ text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
+ } else {
+ resume($rule_number);
+ return false;
+ }
+ } break;
+./
+
+notation_decl_start ::= langle_bang NOTATION name space;
+/.
+ case $rule_number: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ NotationDeclaration &notationDeclaration = notationDeclarations.push();
+ notationDeclaration.name = symString(3);
+ } break;
+./
+
+notation_decl ::= notation_decl_start SYSTEM literal space_opt RANGLE;
+/.
+ case $rule_number: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ notationDeclaration.systemId = symString(3);
+ notationDeclaration.publicId.clear();
+ } break;
+./
+
+notation_decl ::= notation_decl_start PUBLIC public_literal space_opt RANGLE;
+/.
+ case $rule_number: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ notationDeclaration.systemId.clear();
+ checkPublicLiteral((notationDeclaration.publicId = symString(3)));
+ } break;
+./
+
+notation_decl ::= notation_decl_start PUBLIC public_literal space literal space_opt RANGLE;
+/.
+ case $rule_number: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ checkPublicLiteral((notationDeclaration.publicId = symString(3)));
+ notationDeclaration.systemId = symString(5);
+ } break;
+./
+
+
+
+content_char ::= RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | PERCENT | SLASH | COLON | SEMICOLON | COMMA | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG | QUOTE | DBLQUOTE | LETTER | DIGIT;
+
+scan_content_char ::= content_char;
+/.
+ case $rule_number:
+ isWhitespace = false;
+ Q_FALLTHROUGH();
+./
+
+scan_content_char ::= SPACE;
+/.
+ case $rule_number:
+ sym(1).len += fastScanContentCharList();
+ if (atEnd && !inParseEntity) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+content_char_list ::= content_char_list char_ref;
+content_char_list ::= content_char_list entity_ref;
+content_char_list ::= content_char_list entity_done;
+content_char_list ::= content_char_list scan_content_char;
+content_char_list ::= char_ref;
+content_char_list ::= entity_ref;
+content_char_list ::= entity_done;
+content_char_list ::= scan_content_char;
+
+
+character_content ::= content_char_list %prec SHIFT_THERE;
+/.
+ case $rule_number:
+ if (!textBuffer.isEmpty()) {
+ setType(QXmlStreamReader::Characters);
+ text = &textBuffer;
+ }
+ break;
+./
+
+literal ::= QUOTE QUOTE;
+/.
+ case $rule_number:./
+literal ::= DBLQUOTE DBLQUOTE;
+/.
+ case $rule_number:
+ clearSym();
+ break;
+./
+literal ::= QUOTE literal_content_with_dblquote QUOTE;
+/.
+ case $rule_number:./
+literal ::= DBLQUOTE literal_content_with_quote DBLQUOTE;
+/.
+ case $rule_number:
+ sym(1) = sym(2);
+ break;
+./
+
+literal_content_with_dblquote ::= literal_content_with_dblquote literal_content;
+/.
+ case $rule_number:./
+literal_content_with_quote ::= literal_content_with_quote literal_content;
+/.
+ case $rule_number:./
+literal_content_with_dblquote ::= literal_content_with_dblquote DBLQUOTE;
+/.
+ case $rule_number:./
+literal_content_with_quote ::= literal_content_with_quote QUOTE;
+/.
+ case $rule_number:
+ sym(1).len += sym(2).len;
+ break;
+./
+literal_content_with_dblquote ::= literal_content;
+literal_content_with_quote ::= literal_content;
+literal_content_with_dblquote ::= DBLQUOTE;
+literal_content_with_quote ::= QUOTE;
+
+literal_content_start ::= LETTER | DIGIT | RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | PERCENT | SLASH | COLON | SEMICOLON | COMMA | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG;
+
+literal_content_start ::= SPACE;
+/.
+ case $rule_number:
+ if (normalizeLiterals)
+ textBuffer.data()[textBuffer.size()-1] = QLatin1Char(' ');
+ break;
+./
+
+literal_content ::= literal_content_start;
+/.
+ case $rule_number:
+ sym(1).len += fastScanLiteralContent();
+ if (atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+
+public_literal ::= literal;
+/.
+ case $rule_number: {
+ if (!QXmlUtils::isPublicID(symString(1))) {
+ raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1)));
+ resume($rule_number);
+ return false;
+ }
+ } break;
+./
+
+entity_value ::= QUOTE QUOTE;
+/.
+ case $rule_number:./
+entity_value ::= DBLQUOTE DBLQUOTE;
+/.
+ case $rule_number:
+ clearSym();
+ break;
+./
+
+entity_value ::= QUOTE entity_value_content_with_dblquote QUOTE;
+/.
+ case $rule_number:./
+entity_value ::= DBLQUOTE entity_value_content_with_quote DBLQUOTE;
+/.
+ case $rule_number:
+ sym(1) = sym(2);
+ break;
+./
+
+entity_value_content_with_dblquote ::= entity_value_content_with_dblquote entity_value_content;
+/.
+ case $rule_number:./
+entity_value_content_with_quote ::= entity_value_content_with_quote entity_value_content;
+/.
+ case $rule_number:./
+entity_value_content_with_dblquote ::= entity_value_content_with_dblquote DBLQUOTE;
+/.
+ case $rule_number:./
+entity_value_content_with_quote ::= entity_value_content_with_quote QUOTE;
+/.
+ case $rule_number:
+ sym(1).len += sym(2).len;
+ break;
+./
+entity_value_content_with_dblquote ::= entity_value_content;
+entity_value_content_with_quote ::= entity_value_content;
+entity_value_content_with_dblquote ::= DBLQUOTE;
+entity_value_content_with_quote ::= QUOTE;
+
+entity_value_content ::= LETTER | DIGIT | LANGLE | RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | SLASH | COLON | SEMICOLON | COMMA | SPACE | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG;
+entity_value_content ::= char_ref | entity_ref_in_entity_value | entity_done;
+
+
+attribute_value ::= QUOTE QUOTE;
+/.
+ case $rule_number:./
+attribute_value ::= DBLQUOTE DBLQUOTE;
+/.
+ case $rule_number:
+ clearSym();
+ break;
+./
+attribute_value ::= QUOTE attribute_value_content_with_dblquote QUOTE;
+/.
+ case $rule_number:./
+attribute_value ::= DBLQUOTE attribute_value_content_with_quote DBLQUOTE;
+/.
+ case $rule_number:
+ sym(1) = sym(2);
+ lastAttributeValue = symString(1);
+ break;
+./
+
+attribute_value_content_with_dblquote ::= attribute_value_content_with_dblquote attribute_value_content;
+/.
+ case $rule_number:./
+attribute_value_content_with_quote ::= attribute_value_content_with_quote attribute_value_content;
+/.
+ case $rule_number:./
+attribute_value_content_with_dblquote ::= attribute_value_content_with_dblquote DBLQUOTE;
+/.
+ case $rule_number:./
+attribute_value_content_with_quote ::= attribute_value_content_with_quote QUOTE;
+/.
+ case $rule_number:
+ sym(1).len += sym(2).len;
+ break;
+./
+attribute_value_content_with_dblquote ::= attribute_value_content | DBLQUOTE;
+attribute_value_content_with_quote ::= attribute_value_content | QUOTE;
+
+attribute_value_content ::= literal_content | char_ref | entity_ref_in_attribute_value | entity_done;
+
+attribute ::= qname space_opt EQ space_opt attribute_value;
+/.
+ case $rule_number: {
+ QStringRef prefix = symPrefix(1);
+ if (prefix.isEmpty() && symString(1) == QLatin1String("xmlns") && namespaceProcessing) {
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ namespaceDeclaration.prefix.clear();
+
+ const QStringRef ns(symString(5));
+ if(ns == QLatin1String("http://www.w3.org/2000/xmlns/") ||
+ ns == QLatin1String("http://www.w3.org/XML/1998/namespace"))
+ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+ else
+ namespaceDeclaration.namespaceUri = addToStringStorage(ns);
+ } else {
+ Attribute &attribute = attributeStack.push();
+ attribute.key = sym(1);
+ attribute.value = sym(5);
+
+ QStringRef attributeQualifiedName = symName(1);
+ bool normalize = false;
+ for (int a = 0; a < dtdAttributes.size(); ++a) {
+ DtdAttribute &dtdAttribute = dtdAttributes[a];
+ if (!dtdAttribute.isCDATA
+ && dtdAttribute.tagName == qualifiedName
+ && dtdAttribute.attributeQualifiedName == attributeQualifiedName
+ ) {
+ normalize = true;
+ break;
+ }
+ }
+ if (normalize) {
+ // normalize attribute value (simplify and trim)
+ int pos = textBuffer.size();
+ int n = 0;
+ bool wasSpace = true;
+ for (int i = 0; i < attribute.value.len; ++i) {
+ QChar c = textBuffer.at(attribute.value.pos + i);
+ if (c.unicode() == ' ') {
+ if (wasSpace)
+ continue;
+ wasSpace = true;
+ } else {
+ wasSpace = false;
+ }
+ textBuffer += textBuffer.at(attribute.value.pos + i);
+ ++n;
+ }
+ if (wasSpace)
+ while (n && textBuffer.at(pos + n - 1).unicode() == ' ')
+ --n;
+ attribute.value.pos = pos;
+ attribute.value.len = n;
+ }
+ if (prefix == QLatin1String("xmlns") && namespaceProcessing) {
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ QStringRef namespacePrefix = symString(attribute.key);
+ QStringRef namespaceUri = symString(attribute.value);
+ attributeStack.pop();
+ if (((namespacePrefix == QLatin1String("xml"))
+ ^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace")))
+ || namespaceUri == QLatin1String("http://www.w3.org/2000/xmlns/")
+ || namespaceUri.isEmpty()
+ || namespacePrefix == QLatin1String("xmlns"))
+ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+
+ namespaceDeclaration.prefix = addToStringStorage(namespacePrefix);
+ namespaceDeclaration.namespaceUri = addToStringStorage(namespaceUri);
+ }
+ }
+ } break;
+./
+
+
+
+attribute_list_opt ::= | space | space attribute_list space_opt;
+attribute_list ::= attribute | attribute_list space attribute;
+
+stag_start ::= LANGLE qname;
+/.
+ case $rule_number: {
+ normalizeLiterals = true;
+ Tag &tag = tagStack_push();
+ prefix = tag.namespaceDeclaration.prefix = addToStringStorage(symPrefix(2));
+ name = tag.name = addToStringStorage(symString(2));
+ qualifiedName = tag.qualifiedName = addToStringStorage(symName(2));
+ if ((!prefix.isEmpty() && !QXmlUtils::isNCName(prefix)) || !QXmlUtils::isNCName(name))
+ raiseWellFormedError(QXmlStream::tr("Invalid XML name."));
+ } break;
+./
+
+
+empty_element_tag ::= stag_start attribute_list_opt SLASH RANGLE;
+/.
+ case $rule_number:
+ isEmptyElement = true;
+ Q_FALLTHROUGH();
+./
+
+
+stag ::= stag_start attribute_list_opt RANGLE;
+/.
+ case $rule_number:
+ setType(QXmlStreamReader::StartElement);
+ resolveTag();
+ if (tagStack.size() == 1 && hasSeenTag && !inParseEntity)
+ raiseWellFormedError(QXmlStream::tr("Extra content at end of document."));
+ hasSeenTag = true;
+ break;
+./
+
+
+etag ::= LANGLE SLASH qname space_opt RANGLE;
+/.
+ case $rule_number: {
+ setType(QXmlStreamReader::EndElement);
+ Tag &tag = tagStack_pop();
+
+ namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ name = tag.name;
+ qualifiedName = tag.qualifiedName;
+ if (qualifiedName != symName(3))
+ raiseWellFormedError(QXmlStream::tr("Opening and ending tag mismatch."));
+ } break;
+./
+
+
+unresolved_entity ::= UNRESOLVED_ENTITY;
+/.
+ case $rule_number:
+ if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(unresolvedEntity));
+ break;
+ }
+ setType(QXmlStreamReader::EntityReference);
+ name = &unresolvedEntity;
+ break;
+./
+
+entity_ref ::= AMPERSAND name SEMICOLON;
+/.
+ case $rule_number: {
+ sym(1).len += sym(2).len + 1;
+ QStringView reference = symView(2);
+ if (entityHash.contains(reference)) {
+ Entity &entity = entityHash[reference];
+ if (entity.unparsed) {
+ raiseWellFormedError(QXmlStream::tr("Reference to unparsed entity '%1'.").arg(reference));
+ } else {
+ if (!entity.hasBeenParsed) {
+ parseEntity(entity.value);
+ entity.hasBeenParsed = true;
+ }
+ if (entity.literal)
+ putStringLiteral(entity.value);
+ else if (referenceEntity(entity))
+ putReplacement(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ }
+ break;
+ }
+
+ if (entityResolver) {
+ QString replacementText = resolveUndeclaredEntity(reference.toString());
+ if (!replacementText.isNull()) {
+ putReplacement(replacementText);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+ }
+
+ injectToken(UNRESOLVED_ENTITY);
+ unresolvedEntity = symString(2).toString();
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+
+ } break;
+./
+
+pereference ::= PERCENT name SEMICOLON;
+/.
+ case $rule_number: {
+ sym(1).len += sym(2).len + 1;
+ QStringView reference = symView(2);
+ if (parameterEntityHash.contains(reference)) {
+ referenceToParameterEntityDetected = true;
+ Entity &entity = parameterEntityHash[reference];
+ if (entity.unparsed || entity.external) {
+ referenceToUnparsedEntityDetected = true;
+ } else {
+ if (referenceEntity(entity))
+ putString(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ }
+ } else if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(symString(2)));
+ }
+ } break;
+./
+
+
+
+entity_ref_in_entity_value ::= AMPERSAND name SEMICOLON;
+/.
+ case $rule_number:
+ sym(1).len += sym(2).len + 1;
+ break;
+./
+
+entity_ref_in_attribute_value ::= AMPERSAND name SEMICOLON;
+/.
+ case $rule_number: {
+ sym(1).len += sym(2).len + 1;
+ QStringView reference = symView(2);
+ if (entityHash.contains(reference)) {
+ Entity &entity = entityHash[reference];
+ if (entity.unparsed || entity.value.isNull()) {
+ raiseWellFormedError(QXmlStream::tr("Reference to external entity '%1' in attribute value.").arg(reference));
+ break;
+ }
+ if (!entity.hasBeenParsed) {
+ parseEntity(entity.value);
+ entity.hasBeenParsed = true;
+ }
+ if (entity.literal)
+ putStringLiteral(entity.value);
+ else if (referenceEntity(entity))
+ putReplacementInAttributeValue(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+
+ if (entityResolver) {
+ QString replacementText = resolveUndeclaredEntity(reference.toString());
+ if (!replacementText.isNull()) {
+ putReplacement(replacementText);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+ }
+ if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(reference));
+ }
+ } break;
+./
+
+char_ref ::= AMPERSAND HASH char_ref_value SEMICOLON;
+/.
+ case $rule_number: {
+ if (uint s = resolveCharRef(3)) {
+ if (s >= 0xffff)
+ putStringLiteral(QString::fromUcs4(&s, 1));
+ else
+ putChar((LETTER << 16) | s);
+
+ textBuffer.chop(3 + sym(3).len);
+ clearSym();
+ } else {
+ raiseWellFormedError(QXmlStream::tr("Invalid character reference."));
+ }
+ } break;
+./
+
+
+char_ref_value ::= LETTER | DIGIT;
+char_ref_value ::= char_ref_value LETTER;
+/.
+ case $rule_number:./
+char_ref_value ::= char_ref_value DIGIT;
+/.
+ case $rule_number:
+ sym(1).len += sym(2).len;
+ break;
+./
+
+
+content ::= content character_content;
+content ::= content stag content etag;
+content ::= content empty_element_tag;
+content ::= content comment;
+content ::= content cdata;
+content ::= content xml_decl;
+content ::= content processing_instruction;
+content ::= content doctype_decl;
+content ::= content unresolved_entity;
+content ::= ;
+
+
+space ::= SPACE;
+/.
+ case $rule_number:
+ sym(1).len += fastScanSpace();
+ if (atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+
+space_opt ::=;
+space_opt ::= space;
+
+qname ::= LETTER;
+/.
+ case $rule_number: {
+ sym(1).len += fastScanName(&sym(1).prefix);
+ if (atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ } break;
+./
+
+name ::= LETTER;
+/.
+ case $rule_number:
+ sym(1).len += fastScanName();
+ if (atEnd) {
+ resume($rule_number);
+ return false;
+ }
+ break;
+./
+
+nmtoken ::= LETTER;
+/.
+ case $rule_number:./
+nmtoken ::= DIGIT;
+/.
+ case $rule_number:./
+nmtoken ::= DOT;
+/.
+ case $rule_number:./
+nmtoken ::= DASH;
+/.
+ case $rule_number:./
+nmtoken ::= COLON;
+/.
+ case $rule_number:
+ sym(1).len += fastScanNMTOKEN();
+ if (atEnd) {
+ resume($rule_number);
+ return false;
+ }
+
+ break;
+./
+
+
+/.
+ default:
+ ;
+ } // switch
+ act = state_stack[tos] = nt_action (act, lhs[r] - TERMINAL_COUNT);
+ if (type != QXmlStreamReader::NoToken)
+ return true;
+ } else {
+ parseError();
+ break;
+ }
+ }
+ return false;
+}
+#endif //QT_NO_XMLSTREAMREADER.xml
+
+./