---------------------------------------------------------------------------- | |
-- | |
-- Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | |
-- All rights reserved. | |
-- Contact: Nokia Corporation (qt-info@nokia.com) | |
-- | |
-- This file is part of the QtCore module of the Qt Toolkit. | |
-- | |
-- $QT_BEGIN_LICENSE:LGPL$ | |
-- GNU Lesser General Public License Usage | |
-- This file may be used under the terms of the GNU Lesser General Public | |
-- License version 2.1 as published by the Free Software Foundation and | |
-- appearing in the file LICENSE.LGPL included in the packaging of this | |
-- file. Please review the following information to ensure the GNU Lesser | |
-- General Public License version 2.1 requirements will be met: | |
-- http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
-- | |
-- In addition, as a special exception, Nokia gives you certain additional | |
-- rights. These rights are described in the Nokia Qt LGPL Exception | |
-- version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | |
-- | |
-- GNU General Public License Usage | |
-- Alternatively, this file may be used under the terms of the GNU General | |
-- Public License version 3.0 as published by the Free Software Foundation | |
-- and appearing in the file LICENSE.GPL included in the packaging of this | |
-- file. Please review the following information to ensure the GNU General | |
-- Public License version 3.0 requirements will be met: | |
-- http://www.gnu.org/copyleft/gpl.html. | |
-- | |
-- Other Usage | |
-- Alternatively, this file may be used in accordance with the terms and | |
-- conditions contained in a signed written agreement between you and Nokia. | |
-- | |
-- | |
-- | |
-- | |
-- | |
-- $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) qFree(data); } | |
inline void reserve(int extraCapacity) { | |
if (tos + extraCapacity + 1 > cap) { | |
cap = qMax(tos + extraCapacity + 1, cap << 1 ); | |
data = reinterpret_cast<T *>(qRealloc(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; | |
bool tagsDone; | |
inline QStringRef addToStringStorage(const QStringRef &s) { | |
int pos = tagStackStringStorageSize; | |
int sz = s.size(); | |
if (pos != tagStackStringStorage.size()) | |
tagStackStringStorage.resize(pos); | |
tagStackStringStorage.insert(pos, s.unicode(), sz); | |
tagStackStringStorageSize += sz; | |
return QStringRef(&tagStackStringStorage, pos, sz); | |
} | |
inline QStringRef addToStringStorage(const QString &s) { | |
int pos = tagStackStringStorageSize; | |
int sz = s.size(); | |
if (pos != tagStackStringStorage.size()) | |
tagStackStringStorage.resize(pos); | |
tagStackStringStorage.insert(pos, s.unicode(), 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(const QString& str = QString()) | |
:value(str), external(false), unparsed(false), literal(false), | |
hasBeenParsed(false), isCurrentlyReferenced(false){} | |
static inline Entity createLiteral(const QString &entity) | |
{ Entity result(entity); result.literal = result.hasBeenParsed = true; return result; } | |
QString value; | |
uint external : 1; | |
uint unparsed : 1; | |
uint literal : 1; | |
uint hasBeenParsed : 1; | |
uint isCurrentlyReferenced : 1; | |
}; | |
QHash<QString, Entity> entityHash; | |
QHash<QString, 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); | |
} | |
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; | |
ushort 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); | |
ushort 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(); | |
if (publicNamespaceDeclarations.size()) | |
publicNamespaceDeclarations.clear(); | |
if (attributes.size()) | |
attributes.resize(0); | |
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(); | |
// fall through | |
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->hasFailure()) { | |
raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content.")); | |
readBuffer.clear(); | |
return false; | |
} | |
#endif | |
// fall through | |
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; | |
if (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; | |
} | |
// fall through | |
case '\0': { | |
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; | |
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.")); | |
} | |
//fall through | |
./ | |
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); | |
QString entityName = entityDeclaration.name.toString(); | |
QHash<QString, Entity> &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash; | |
if (!hash.contains(entityName)) { | |
Entity entity(entityDeclaration.value.toString()); | |
entity.unparsed = (!entityDeclaration.notationName.isNull()); | |
entity.external = entityDeclaration.external; | |
hash.insert(entityName, 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); | |
const QString piTarget(processingInstructionTarget.toString()); | |
if (!piTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive)) { | |
raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document.")); | |
} | |
else if(!QXmlUtils::isNCName(piTarget)) | |
raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.").arg(piTarget)); | |
} 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.toString().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 ¬ationDeclaration = notationDeclarations.push(); | |
notationDeclaration.name = symString(3); | |
} break; | |
./ | |
notation_decl ::= notation_decl_start SYSTEM literal space_opt RANGLE; | |
/. | |
case $rule_number: { | |
NotationDeclaration ¬ationDeclaration = 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 ¬ationDeclaration = 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 ¬ationDeclaration = 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; | |
// fall through | |
./ | |
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).toString())) { | |
raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1).toString())); | |
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; | |
// fall through | |
./ | |
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; | |
QString reference = symString(2).toString(); | |
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); | |
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; | |
QString reference = symString(2).toString(); | |
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).toString())); | |
} | |
} 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; | |
QString reference = symString(2).toString(); | |
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); | |
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 | |
./ |