diff options
author | Dimitri van Heesch <doxygen@gmail.com> | 2020-12-11 19:39:33 (GMT) |
---|---|---|
committer | Dimitri van Heesch <doxygen@gmail.com> | 2020-12-11 19:39:33 (GMT) |
commit | 6a9921990a399ae0298b75f8d0fb1f6b6987e4ef (patch) | |
tree | e5262d5cf44fc18af9176eece0b3bcd35f96f7f3 | |
parent | 979ea243de83a693e0d9da545ee4cbe7db9521ee (diff) | |
parent | 9ebfb15e1ec786a0dd2ebd14fe23d8d0d29f951e (diff) | |
download | Doxygen-6a9921990a399ae0298b75f8d0fb1f6b6987e4ef.zip Doxygen-6a9921990a399ae0298b75f8d0fb1f6b6987e4ef.tar.gz Doxygen-6a9921990a399ae0298b75f8d0fb1f6b6987e4ef.tar.bz2 |
Merge branch 'xmlparser'
-rw-r--r-- | qtools/CMakeLists.txt | 1 | ||||
-rw-r--r-- | qtools/qtools.pro.in | 88 | ||||
-rw-r--r-- | qtools/qxml.cpp | 6061 | ||||
-rw-r--r-- | qtools/qxml.h | 671 | ||||
-rw-r--r-- | src/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/layout.cpp | 1773 | ||||
-rw-r--r-- | src/layout.h | 61 | ||||
-rw-r--r-- | src/tagreader.cpp | 549 | ||||
-rw-r--r-- | src/xml.h | 74 | ||||
-rw-r--r-- | src/xml.l | 484 |
10 files changed, 1735 insertions, 8030 deletions
diff --git a/qtools/CMakeLists.txt b/qtools/CMakeLists.txt index d49ca47..aca6694 100644 --- a/qtools/CMakeLists.txt +++ b/qtools/CMakeLists.txt @@ -21,7 +21,6 @@ qtextstream.cpp qtextcodec.cpp qstringlist.cpp qcstringlist.cpp -qxml.cpp qmap.cpp qutfcodec.cpp ) diff --git a/qtools/qtools.pro.in b/qtools/qtools.pro.in deleted file mode 100644 index 21d26cc..0000000 --- a/qtools/qtools.pro.in +++ /dev/null @@ -1,88 +0,0 @@ -TEMPLATE = lib -CONFIG = warn_on staticlib $extraopts -HEADERS = qarray.h \ - qbuffer.h \ - qcache.h \ - qgcache.h \ - qcollection.h \ - qconfig.h \ - qcstring.h \ - qdatastream.h \ - qdatetime.h \ - qdict.h \ - qdir.h \ - qfeatures.h \ - qfile.h \ - qfiledefs_p.h \ - qfileinfo.h \ - qgarray.h \ - qfeatures.h \ - qgdict.h \ - qgeneric.h \ - qglist.h \ - qglobal.h \ - qgstring.h \ - qgvector.h \ - qintdict.h \ - qiodevice.h \ - qinternallist.h \ - qptrdict.h \ - qqueue.h \ - qregexp.h \ - qshared.h \ - qsortedlist.h \ - qstack.h \ - qstring.h \ - qstringlist.h \ - qstrlist.h \ - qstrvec.h \ - qtextstream.h \ - qtl.h \ - qvaluelist.h \ - qvector.h \ - qxml.h \ - qvaluestack.h \ - qmap.h \ - qmodules.h \ - qutfcodec.h - -SOURCES = qbuffer.cpp \ - qcollection.cpp \ - qcstring.cpp \ - qdatastream.cpp \ - qdatetime.cpp \ - qdir.cpp \ - qfile.cpp \ - qfileinfo.cpp \ - qgarray.cpp \ - qgcache.cpp \ - qgdict.cpp \ - qglist.cpp \ - qglobal.cpp \ - qgstring.cpp \ - qgvector.cpp \ - qiodevice.cpp \ - qregexp.cpp \ - qstring.cpp \ - qtextstream.cpp \ - qtextcodec.cpp \ - qstringlist.cpp \ - qxml.cpp \ - qmap.cpp \ - qutfcodec.cpp - -unix:SOURCES += qfile_unix.cpp \ - qdir_unix.cpp \ - qfileinfo_unix.cpp - -win32:SOURCES += qfile_win32.cpp \ - qdir_win32.cpp \ - qfileinfo_win32.cpp - -INCLUDEPATH = . -#TMAKE_CXXFLAGS += -DQT_NO_CODECS -DQT_LITE_UNICODE -TMAKE_CXXFLAGS += -DQT_LITE_UNICODE -win32:TMAKE_CXXFLAGS += -DQT_NODLL -win32-g++:TMAKE_CXXFLAGS += -D__CYGWIN__ -DALL_STATIC -OBJECTS_DIR = ../objects/qtools -DESTDIR = ../lib diff --git a/qtools/qxml.cpp b/qtools/qxml.cpp deleted file mode 100644 index b7a68fc..0000000 --- a/qtools/qxml.cpp +++ /dev/null @@ -1,6061 +0,0 @@ -/**************************************************************************** -** -** -** Implementation of QXmlSimpleReader and related classes. -** -** Created : 000518 -** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the XML module of the Qt GUI Toolkit. -** -** This file may be distributed under the terms of the Q Public License -** as defined by Trolltech AS of Norway and appearing in the file -** LICENSE.QPL included in the packaging of this file. -** -** This file may be distributed and/or modified under the terms of the -** GNU General Public License version 2 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. -** -** Licensees holding valid Qt Enterprise Edition licenses may use this -** file in accordance with the Qt Commercial License Agreement provided -** with the Software. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for -** information about Qt Commercial License Agreements. -** See http://www.trolltech.com/qpl/ for QPL licensing information. -** See http://www.trolltech.com/gpl/ for GPL licensing information. -** -** Contact info@trolltech.com if any conditions of this licensing are -** not clear to you. -** -**********************************************************************/ - -#define QT_XML_CPP -#include "qxml.h" -#include "qtextcodec.h" -#include "qbuffer.h" - -#ifndef QT_NO_XML -// NOT REVISED - -// Error strings for the XML reader -#define XMLERR_OK "no error occurred" -#define XMLERR_TAGMISMATCH "tag mismatch" -#define XMLERR_UNEXPECTEDEOF "unexpected end of file" -#define XMLERR_FINISHEDPARSINGWHILENOTEOF "parsing is finished but end of file is not reached" -#define XMLERR_LETTEREXPECTED "letter is expected" -#define XMLERR_ERRORPARSINGELEMENT "error while parsing element" -#define XMLERR_ERRORPARSINGPROLOG "error while parsing prolog" -#define XMLERR_ERRORPARSINGMAINELEMENT "error while parsing main element" -#define XMLERR_ERRORPARSINGCONTENT "error while parsing content" -#define XMLERR_ERRORPARSINGNAME "error while parsing name" -#define XMLERR_ERRORPARSINGNMTOKEN "error while parsing Nmtoken" -#define XMLERR_ERRORPARSINGATTRIBUTE "error while parsing attribute" -#define XMLERR_ERRORPARSINGMISC "error while parsing misc" -#define XMLERR_ERRORPARSINGCHOICE "error while parsing choice or seq" -#define XMLERR_ERRORBYCONSUMER "error triggered by consumer" -#define XMLERR_UNEXPECTEDCHARACTER "unexpected character" -#define XMLERR_EQUALSIGNEXPECTED "expected '=' but not found" -#define XMLERR_QUOTATIONEXPECTED "expected \" or ' but not found" -#define XMLERR_ERRORPARSINGREFERENCE "error while parsing reference" -#define XMLERR_ERRORPARSINGPI "error while parsing processing instruction" -#define XMLERR_ERRORPARSINGATTLISTDECL "error while parsing attribute list declaration" -#define XMLERR_ERRORPARSINGATTTYPE "error while parsing attribute type declaration" -#define XMLERR_ERRORPARSINGATTVALUE "error while parsing attribute value declaration" -#define XMLERR_ERRORPARSINGELEMENTDECL "error while parsing element declaration" -#define XMLERR_ERRORPARSINGENTITYDECL "error while parsing entity declaration" -#define XMLERR_ERRORPARSINGNOTATIONDECL "error while parsing notation declaration" -#define XMLERR_ERRORPARSINGEXTERNALID "error while parsing external id" -#define XMLERR_ERRORPARSINGCOMMENT "error while parsing comment" -#define XMLERR_ERRORPARSINGENTITYVALUE "error while parsing entity value declaration" -#define XMLERR_CDSECTHEADEREXPECTED "expected the header for a cdata section" -#define XMLERR_MORETHANONEDOCTYPE "more than one document type definition" -#define XMLERR_ERRORPARSINGDOCTYPE "error while parsing document type definition" -#define XMLERR_INVALIDNAMEFORPI "invalid name for processing instruction" -#define XMLERR_VERSIONEXPECTED "version expected while reading the XML declaration" -#define XMLERR_EDECLORSDDECLEXPECTED "EDecl or SDDecl expected while reading the XML declaration" -#define XMLERR_SDDECLEXPECTED "SDDecl expected while reading the XML declaration" -#define XMLERR_WRONGVALUEFORSDECL "wrong value for standalone declaration" -#define XMLERR_UNPARSEDENTITYREFERENCE "unparsed entity reference in wrong context" -#define XMLERR_INTERNALGENERALENTITYINDTD "internal general entity reference not allowed in DTD" -#define XMLERR_EXTERNALGENERALENTITYINDTD "external parsed general entity reference not allowed in DTD" -#define XMLERR_EXTERNALGENERALENTITYINAV "external parsed general entity reference not allowed in attribute value" - - -// the constants for the lookup table -static const signed char cltWS = 0; // white space -static const signed char cltPer = 1; // % -static const signed char cltAmp = 2; // & -static const signed char cltGt = 3; // > -static const signed char cltLt = 4; // < -static const signed char cltSlash = 5; // / -static const signed char cltQm = 6; // ? -static const signed char cltEm = 7; // ! -static const signed char cltDash = 8; // - -static const signed char cltCB = 9; // ] -static const signed char cltOB = 10; // [ -static const signed char cltEq = 11; // = -static const signed char cltDq = 12; // " -static const signed char cltSq = 13; // ' -static const signed char cltUnknown = 14; - -// character lookup table -static const signed char charLookupTable[256]={ - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x00 - 0x07 - cltUnknown, // 0x08 - cltWS, // 0x09 \t - cltWS, // 0x0A \n - cltUnknown, // 0x0B - cltUnknown, // 0x0C - cltWS, // 0x0D \r - cltUnknown, // 0x0E - cltUnknown, // 0x0F - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x17 - 0x16 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x18 - 0x1F - cltWS, // 0x20 Space - cltEm, // 0x21 ! - cltDq, // 0x22 " - cltUnknown, // 0x23 - cltUnknown, // 0x24 - cltPer, // 0x25 % - cltAmp, // 0x26 & - cltSq, // 0x27 ' - cltUnknown, // 0x28 - cltUnknown, // 0x29 - cltUnknown, // 0x2A - cltUnknown, // 0x2B - cltUnknown, // 0x2C - cltDash, // 0x2D - - cltUnknown, // 0x2E - cltSlash, // 0x2F / - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x30 - 0x37 - cltUnknown, // 0x38 - cltUnknown, // 0x39 - cltUnknown, // 0x3A - cltUnknown, // 0x3B - cltLt, // 0x3C < - cltEq, // 0x3D = - cltGt, // 0x3E > - cltQm, // 0x3F ? - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x40 - 0x47 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x48 - 0x4F - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x50 - 0x57 - cltUnknown, // 0x58 - cltUnknown, // 0x59 - cltUnknown, // 0x5A - cltOB, // 0x5B [ - cltUnknown, // 0x5C - cltCB, // 0x5D ] - cltUnknown, // 0x5E - cltUnknown, // 0x5F - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x60 - 0x67 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x68 - 0x6F - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x70 - 0x77 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x78 - 0x7F - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x80 - 0x87 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x88 - 0x8F - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x90 - 0x97 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x98 - 0x9F - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA0 - 0xA7 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA8 - 0xAF - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB0 - 0xB7 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB8 - 0xBF - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC0 - 0xC7 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC8 - 0xCF - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD0 - 0xD7 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD8 - 0xDF - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE0 - 0xE7 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE8 - 0xEF - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xF0 - 0xF7 - cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown // 0xF8 - 0xFF -}; - - -class QXmlNamespaceSupportPrivate -{ -}; -class QXmlAttributesPrivate -{ -}; -class QXmlInputSourcePrivate -{ -}; -class QXmlParseExceptionPrivate -{ -}; -class QXmlLocatorPrivate -{ -}; -class QXmlDefaultHandlerPrivate -{ -}; - -#if defined(Q_FULL_TEMPLATE_INSTANTIATION) -bool operator==( const QMap<QString, QString>, const QMap<QString, QString> ) -{ - return FALSE; -} -#endif - -/*! - \class QXmlParseException qxml.h - \brief The QXmlParseException class is used to report errors with the - QXmlErrorHandler interface. - - \module XML - - \sa QXmlErrorHandler -*/ -/*! - \fn QXmlParseException::QXmlParseException( const QString& name, int c, int l, const QString& p, const QString& s ) - - Constructs a parse exception with the error string \a name in the column - \a c and line \a l for the public identifier \a p and the system identifier - \a s. -*/ -/*! - Returns the error message. -*/ -QString QXmlParseException::message() const -{ - return msg; -} -/*! - Returns the column number the error occurred. -*/ -int QXmlParseException::columnNumber() const -{ - return column; -} -/*! - Returns the line number the error occurred. -*/ -int QXmlParseException::lineNumber() const -{ - return line; -} -/*! - Returns the public identifier the error occurred. -*/ -QString QXmlParseException::publicId() const -{ - return pub; -} -/*! - Returns the system identifier the error occurred. -*/ -QString QXmlParseException::systemId() const -{ - return sys; -} - - -/*! - \class QXmlLocator qxml.h - \brief The QXmlLocator class provides the XML handler classes with - information about the actual parsing position. - - \module XML - - The reader reports a QXmlLocator to the content handler before he starts to - parse the document. This is done with the - QXmlContentHandler::setDocumentLocator() function. The handler classes can - now use this locator to get the actual position the reader is at. -*/ -/*! - \fn QXmlLocator::QXmlLocator( QXmlSimpleReader* parent ) - - Constructor. -*/ -/*! - \fn QXmlLocator::~QXmlLocator() - - Destructor. -*/ -/*! - Gets the column number (starting with 1) or -1 if there is no column number - available. -*/ -int QXmlLocator::columnNumber() -{ - return ( reader->columnNr == -1 ? -1 : reader->columnNr + 1 ); -} -/*! - Gets the line number (starting with 1) or -1 if there is no line number - available. -*/ -int QXmlLocator::lineNumber() -{ - return ( reader->lineNr == -1 ? -1 : reader->lineNr + 1 ); -} - - -/********************************************* - * - * QXmlNamespaceSupport - * - *********************************************/ - -/*! - \class QXmlNamespaceSupport qxml.h - \brief The QXmlNamespaceSupport class is a helper class for XML readers which - want to include namespace support. - - \module XML - - It provides some functions that makes it easy to handle namespaces. Its main - use is for subclasses of QXmlReader which want to provide namespace - support. - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. -*/ - -/*! - Constructs a QXmlNamespaceSupport. -*/ -QXmlNamespaceSupport::QXmlNamespaceSupport() -{ - reset(); -} - -/*! - Destructs a QXmlNamespaceSupport. -*/ -QXmlNamespaceSupport::~QXmlNamespaceSupport() -{ -} - -/*! - This function declares a prefix in the current namespace context; the prefix - will remain in force until this context is popped, unless it is shadowed in a - descendant context. - - Note that there is an asymmetry in this library: while prefix() will not - return the default "" prefix, even if you have declared one; to check for a - default prefix, you have to look it up explicitly using uri(). This - asymmetry exists to make it easier to look up prefixes for attribute names, - where the default prefix is not allowed. -*/ -void QXmlNamespaceSupport::setPrefix( const QString& pre, const QString& uri ) -{ - if( pre.isNull() ) { - ns.insert( "", uri ); - } else { - ns.insert( pre, uri ); - } -} - -/*! - Returns one of the prefixes mapped to a namespace URI. - - If more than one prefix is currently mapped to the same URI, this function - will make an arbitrary selection; if you want all of the prefixes, use the - prefixes() function instead. - - Note: this will never return the empty (default) prefix; to check for a - default prefix, use the uri() function with an argument of "". -*/ -QString QXmlNamespaceSupport::prefix( const QString& uri ) const -{ - QMap<QString, QString>::ConstIterator itc, it = ns.begin(); - while ( (itc=it) != ns.end() ) { - ++it; - if ( itc.data() == uri && !itc.key().isEmpty() ) - return itc.key(); - } - return ""; -} - -/*! - Looks up a prefix in the current context and returns the currently-mapped - namespace URI. Use the empty string ("") for the default namespace. -*/ -QString QXmlNamespaceSupport::uri( const QString& prefix ) const -{ - const QString& returi = ns[ prefix ]; - return returi; -} - -/*! - Splits the name at the ':' and returns the prefix and the local name. -*/ -void QXmlNamespaceSupport::splitName( const QString& qname, - QString& prefix, QString& localname ) const -{ - uint pos; - // search the ':' - for( pos=0; pos<qname.length(); pos++ ) { - if ( qname.at(pos) == ':' ) - break; - } - // and split - prefix = qname.left( pos ); - localname = qname.mid( pos+1 ); -} - -/*! - Processes a raw XML 1.0 name in the current context by removing the prefix - and looking it up among the prefixes currently declared. - - First parameter is the raw XML 1.0 name to be processed. The second parameter - is a flag whether the name is the name of an attribute (TRUE) or not (FALSE). - - The return values will be stored in the last two parameters as follows: - <ul> - <li> The namespace URI, or an empty string if none is in use. - <li> The local name (without prefix). - </ul> - - If the raw name has a prefix that has not been declared, then the return - value will be empty. - - Note that attribute names are processed differently than element names: an - unprefixed element name will received the default namespace (if any), while - an unprefixed element name will not -*/ -void QXmlNamespaceSupport::processName( const QString& qname, - bool isAttribute, - QString& nsuri, QString& localname ) const -{ - uint pos; - // search the ':' - for( pos=0; pos<qname.length(); pos++ ) { - if ( qname.at(pos) == ':' ) - break; - } - if ( pos < qname.length() ) { - // there was a ':' - nsuri = uri( qname.left( pos ) ); - localname = qname.mid( pos+1 ); - } else { - // there was no ':' - if ( isAttribute ) { - nsuri = ""; // attributes don't take default namespace - } else { - nsuri = uri( "" ); // get default namespace - } - localname = qname; - } -} - -/*! - Returns an enumeration of all prefixes currently declared. - - Note: if there is a default prefix, it will not be returned in this - enumeration; check for the default prefix using uri() with an argument - of "". -*/ -QStringList QXmlNamespaceSupport::prefixes() const -{ - QStringList list; - - QMap<QString, QString>::ConstIterator itc, it = ns.begin(); - while ( (itc=it) != ns.end() ) { - ++it; - if ( !itc.key().isEmpty() ) - list.append( itc.key() ); - } - return list; -} - -/*! - Returns a list of all prefixes currently declared for a URI. - - The xml: prefix will be included. If you want only one prefix that's - mapped to the namespace URI, and you don't care which one you get, use the - prefix() function instead. - - Note: the empty (default) prefix is never included in this enumeration; to - check for the presence of a default namespace, use uri() with an - argument of "". -*/ -QStringList QXmlNamespaceSupport::prefixes( const QString& uri ) const -{ - QStringList list; - - QMap<QString, QString>::ConstIterator itc, it = ns.begin(); - while ( (itc=it) != ns.end() ) { - ++it; - if ( itc.data() == uri && !itc.key().isEmpty() ) - list.append( itc.key() ); - } - return list; -} - -/*! - Starts a new namespace context. - - Normally, you should push a new context at the beginning of each XML element: - the new context will automatically inherit the declarations of its parent - context, but it will also keep track of which declarations were made within - this context. -*/ -void QXmlNamespaceSupport::pushContext() -{ - nsStack.push( ns ); -} - -/*! - Reverts to the previous namespace context. - - Normally, you should pop the context at the end of each XML element. After - popping the context, all namespace prefix mappings that were previously in - force are restored. -*/ -void QXmlNamespaceSupport::popContext() -{ - if( !nsStack.isEmpty() ) - ns = nsStack.pop(); -} - -/*! - Resets this namespace support object for reuse. -*/ -void QXmlNamespaceSupport::reset() -{ - nsStack.clear(); - ns.clear(); - ns.insert( "xml", "http://www.w3.org/XML/1998/namespace" ); // the XML namespace -} - - - -/********************************************* - * - * QXmlAttributes - * - *********************************************/ - -/*! - \class QXmlAttributes qxml.h - \brief The QXmlAttributes class provides XML attributes. - - \module XML - - If attributes are reported by QXmlContentHandler::startElement() this - class is used to pass the attribute values. It provides you with different - functions to access the attribute names and values. -*/ -/*! - \fn QXmlAttributes::QXmlAttributes() - - Constructs an empty attribute list. -*/ -/*! - \fn QXmlAttributes::~QXmlAttributes() - - Destructs attributes. -*/ - -/*! - Look up the index of an attribute by an XML 1.0 qualified name. - - Returns the index of the attribute (starting with 0) or -1 if it wasn't - found. - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. -*/ -int QXmlAttributes::index( const QString& qName ) const -{ - return qnameList.findIndex( qName ); -} - -/*! - Looks up the index of an attribute by a namespace name. - - \a uri specifies the namespace URI, or the empty string if the name has no - namespace URI. \a localPart specifies the attribute's local name. - - Returns the index of the attribute (starting with 0) or -1 if it wasn't - found. - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. -*/ -int QXmlAttributes::index( const QString& uri, const QString& localPart ) const -{ - uint count = uriList.count(); - for ( uint i=0; i<count; i++ ) { - if ( uriList[i] == uri && localnameList[i] == localPart ) - return i; - } - return -1; -} - -/*! - Returns the number of attributes in the list. -*/ -int QXmlAttributes::length() const -{ - return valueList.count(); -} - -/*! - Looks up an attribute's local name by index (starting with 0). - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. -*/ -QString QXmlAttributes::localName( int index ) const -{ - return localnameList[index]; -} - -/*! - Looks up an attribute's XML 1.0 qualified name by index (starting with 0). - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. -*/ -QString QXmlAttributes::qName( int index ) const -{ - return qnameList[index]; -} - -/*! - Looks up an attribute's namespace URI by index (starting with 0). - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. -*/ -QString QXmlAttributes::uri( int index ) const -{ - return uriList[index]; -} - -/*! - Looks up an attribute's type by index (starting with 0). - - At the moment only 'CDATA' is returned. -*/ -QString QXmlAttributes::type( int ) const -{ - return "CDATA"; -} - -/*! - Looks up an attribute's type by XML 1.0 qualified name. - - At the moment only 'CDATA' is returned. -*/ -QString QXmlAttributes::type( const QString& ) const -{ - return "CDATA"; -} - -/*! - Looks up an attribute's type by namespace name. - - The first parameter specifies the namespace URI, or the empty string if - the name has no namespace URI. The second parameter specifies the - attribute's local name. - - At the moment only 'CDATA' is returned. -*/ -QString QXmlAttributes::type( const QString&, const QString& ) const -{ - return "CDATA"; -} - -/*! - Looks up an attribute's value by index (starting with 0). -*/ -QString QXmlAttributes::value( int index ) const -{ - return valueList[index]; -} - -/*! - Looks up an attribute's value by XML 1.0 qualified name. - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. -*/ -QString QXmlAttributes::value( const QString& qName ) const -{ - int i = index( qName ); - if ( i == -1 ) - return QString::null; - return valueList[ i ]; -} - -/*! - Looks up an attribute's value by namespace name. - - \a uri specifies the namespace URI, or the empty string if the name has no - namespace URI. \a localName specifies the attribute's local name. - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. -*/ -QString QXmlAttributes::value( const QString& uri, const QString& localName ) const -{ - int i = index( uri, localName ); - if ( i == -1 ) - return QString::null; - return valueList[ i ]; -} - - -/********************************************* - * - * QXmlInputSource - * - *********************************************/ - -/*! - \class QXmlInputSource qxml.h - \brief The QXmlInputSource class is the source where XML data is read from. - - \module XML - - All subclasses of QXmlReader read the input from this class. -*/ - -/*! - Returns all the data this input source contains. -*/ -const QString& QXmlInputSource::data() const -{ - return input; -} - -/*! - Constructs a input source which contains no data. -*/ -QXmlInputSource::QXmlInputSource( ) -{ - input = ""; -} - -/*! - Constructs a input source and get the data from the text stream. -*/ -QXmlInputSource::QXmlInputSource( QTextStream& stream ) -{ - QByteArray rawData; - if ( stream.device()->isDirectAccess() ) { - rawData = stream.device()->readAll(); - } else { - int nread = 0; - const int bufsize = 512; - while ( !stream.device()->atEnd() ) { - rawData.resize( nread + bufsize ); - nread += stream.device()->readBlock( rawData.data()+nread, bufsize ); - } - rawData.resize( nread ); - } - readInput( rawData ); -} - -/*! - Constructs a input source and get the data from a file. If the file cannot be - read the input source is empty. -*/ -QXmlInputSource::QXmlInputSource( QFile& file ) -{ - if ( !file.open(IO_ReadOnly) ) { - input = ""; - return; - } - QByteArray rawData = file.readAll(); - readInput( rawData ); - file.close(); -} - -/*! - Destructor. -*/ -QXmlInputSource::~QXmlInputSource() -{ -} - -/*! - Sets the data of the input source to \a dat. -*/ -void QXmlInputSource::setData( const QString& dat ) -{ - input = dat; -} - -/*! - Read the XML file from the byte array; try to recognize the encoding. -*/ -// ### The input source should not do the encoding detection! -void QXmlInputSource::readInput( QByteArray& rawData ) -{ - QBuffer buf( rawData ); - buf.open( IO_ReadOnly ); - QTextStream *stream = new QTextStream( &buf ); - QChar tmp; - // assume UTF8 or UTF16 at first - stream->setEncoding( QTextStream::UnicodeUTF8 ); - input = ""; - // read the first 5 characters - for ( int i=0; i<5; i++ ) { - *stream >> tmp; - input += tmp; - } - // starts the document with an XML declaration? - if ( input == "<?xml" ) { - // read the whole XML declaration - do { - *stream >> tmp; - input += tmp; - } while( tmp != '>' ); - // and try to find out if there is an encoding - int pos = input.find( "encoding" ); - if ( pos != -1 ) { - QString encoding; - do { - pos++; - if ( pos > (int)input.length() ) - goto finished; - } while( input[pos] != '"' && input[pos] != '\'' ); - pos++; - while( input[pos] != '"' && input[pos] != '\'' ) { - encoding += input[pos]; - pos++; - if ( pos > (int)input.length() ) - goto finished; - } - delete stream; - stream = new QTextStream( &buf ); - stream->setCodec( QTextCodec::codecForName( encoding.utf8() ) ); - buf.reset(); - input = ""; - } - } -finished: - input += stream->read(); - delete stream; - buf.close(); -} - - -/********************************************* - * - * QXmlDefaultHandler - * - *********************************************/ - -/*! - \class QXmlContentHandler qxml.h - \brief The QXmlContentHandler class provides an interface to report logical - content of XML data. - - \module XML - - If the application needs to be informed of basic parsing events, it - implements this interface and sets it with QXmlReader::setContentHandler(). - The reader reports basic document-related events like the start and end of - elements and character data through this interface. - - The order of events in this interface is very important, and mirrors the - order of information in the document itself. For example, all of an element's - content (character data, processing instructions, and/or subelements) will - appear, in order, between the startElement() event and the corresponding - endElement() event. - - The class QXmlDefaultHandler gives a default implementation for this - interface; subclassing from this class is very convenient if you want only be - informed of some parsing events. - - See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>. - - \sa QXmlDTDHandler QXmlDeclHandler QXmlEntityResolver QXmlErrorHandler - QXmlLexicalHandler -*/ -/*! - \fn void QXmlContentHandler::setDocumentLocator( QXmlLocator* locator ) - - The reader calls this function before he starts parsing the document. The - argument \a locator is a pointer to a QXmlLocator which allows the - application to get the actual position of the parsing in the document. - - Do not destroy the \a locator; it is destroyed when the reader is destroyed - (do not use the \a locator after the reader got destroyed). -*/ -/*! - \fn bool QXmlContentHandler::startDocument() - - The reader calls this function when he starts parsing the document. - The reader will call this function only once before any other functions in - this class or in the QXmlDTDHandler class are called (except - QXmlContentHandler::setDocumentLocator()). - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. - - \sa endDocument() -*/ -/*! - \fn bool QXmlContentHandler::endDocument() - - The reader calls this function after he has finished the parsing. It - is only called once. It is the last function of all handler functions that is - called. It is called after the reader has read all input or has abandoned - parsing because of a fatal error. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. - - \sa startDocument() -*/ -/*! - \fn bool QXmlContentHandler::startPrefixMapping( const QString& prefix, const QString& uri ) - - The reader calls this function to signal the begin of a prefix-URI - namespace mapping scope. This information is not necessary for normal - namespace processing since the reader automatically replaces prefixes for - element and attribute names. - - Note that startPrefixMapping and endPrefixMapping calls are not guaranteed to - be properly nested relative to each-other: all startPrefixMapping events will - occur before the corresponding startElement event, and all endPrefixMapping - events will occur after the corresponding endElement event, but their order - is not otherwise guaranteed. - - The argument \a prefix is the namespace prefix being declared and the - argument \a uri is the namespace URI the prefix is mapped to. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. - - \sa endPrefixMapping() -*/ -/*! - \fn bool QXmlContentHandler::endPrefixMapping( const QString& prefix ) - - The reader calls this function to signal the end of a prefix mapping. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. - - \sa startPrefixMapping() -*/ -/*! - \fn bool QXmlContentHandler::startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts ) - - The reader calls this function when he has parsed a start element tag. - - There will be a corresponding endElement() call when the corresponding end - element tag was read. The startElement() and endElement() calls are always - nested correctly. Empty element tags (e.g. <a/>) are reported by - startElement() directly followed by a call to endElement(). - - The attribute list provided will contain only attributes with explicit - values. The attribute list will contain attributes used for namespace - declaration (i.e. attributes starting with xmlns) only if the - namespace-prefix property of the reader is TRUE. - - The argument \a uri is the namespace URI, or the empty string if the element - has no namespace URI or if namespace processing is not being performed, \a - localName is the local name (without prefix), or the empty string if - namespace processing is not being performed, \a qName is the qualified name - (with prefix), or the empty string if qualified names are not available and - \a atts are the attributes attached to the element. If there are no - attributes, \a atts is an empty attributes object - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. - - \sa endElement() -*/ -/*! - \fn bool QXmlContentHandler::endElement( const QString& namespaceURI, const QString& localName, const QString& qName ) - - The reader calls this function when he has parsed an end element tag. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. - - See also the <a href="xml-sax.html#namespaces">namespace description</a>. - - \sa startElement() -*/ -/*! - \fn bool QXmlContentHandler::characters( const QString& ch ) - - The reader calls this function when he has parsed a chunk of character - data (either normal character data or character data inside a CDATA section; - if you have to distinguish between those two types you have to use - QXmlLexicalHandler::startCDATA() and QXmlLexicalHandler::endCDATA() in - addition). - - Some readers will report whitespace in element content using the - ignorableWhitespace() function rather than this one (QXmlSimpleReader will - do it not though). - - A reader is allowed to report the character data of an element in more than - one chunk; e.g. a reader might want to report "a &lt; b" in three - characters() events ("a ", "<" and " b"). - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn bool QXmlContentHandler::ignorableWhitespace( const QString& ch ) - - Some readers may use this function to report each chunk of whitespace in - element content (QXmlSimpleReader does not though). - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn bool QXmlContentHandler::processingInstruction( const QString& target, const QString& data ) - - The reader calls this function when he has parsed a processing - instruction. - - \a target is the target name of the processing instruction and \a data is the - data of the processing instruction. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn bool QXmlContentHandler::skippedEntity( const QString& name ) - - Some readers may skip entities if they have not seen the declarations (e.g. - because they are in an external DTD). If they do so they will report it by - calling this function. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn QString QXmlContentHandler::errorString() - - The reader calls this function to get an error string if any of the handler - functions returns FALSE to him. -*/ - - -/*! - \class QXmlErrorHandler qxml.h - \brief The QXmlErrorHandler class provides an interface to report errors in - XML data. - - \module XML - - If the application is interested in reporting errors to the user or any other - customized error handling, you should subclass this class. - - You can set the error handler with QXmlReader::setErrorHandler(). - - See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>. - - \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver - QXmlLexicalHandler -*/ -/*! - \fn bool QXmlErrorHandler::warning( const QXmlParseException& exception ) - - A reader might use this function to report a warning. Warnings are conditions - that are not errors or fatal errors as defined by the XML 1.0 specification. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn bool QXmlErrorHandler::error( const QXmlParseException& exception ) - - A reader might use this function to report a recoverable error. A recoverable - error corresponds to the definition of "error" in section 1.2 of the XML 1.0 - specification. - - The reader must continue to provide normal parsing events after invoking this - function. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn bool QXmlErrorHandler::fatalError( const QXmlParseException& exception ) - - A reader must use this function to report a non-recoverable error. - - If this function returns TRUE the reader might try to go on parsing and - reporting further errors; but no regular parsing events are reported. -*/ -/*! - \fn QString QXmlErrorHandler::errorString() - - The reader calls this function to get an error string if any of the handler - functions returns FALSE to him. -*/ - - -/*! - \class QXmlDTDHandler qxml.h - \brief The QXmlDTDHandler class provides an interface to report DTD content - of XML data. - - \module XML - - If an application needs information about notations and unparsed entities, - then the application implements this interface and registers an instance with - QXmlReader::setDTDHandler(). - - Note that this interface includes only those DTD events that the XML - recommendation requires processors to report: notation and unparsed entity - declarations. - - See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>. - - \sa QXmlDeclHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler - QXmlLexicalHandler -*/ -/*! - \fn bool QXmlDTDHandler::notationDecl( const QString& name, const QString& publicId, const QString& systemId ) - - The reader calls this function when he has parsed a notation - declaration. - - The argument \a name is the notation name, \a publicId is the notations's - public identifier and \a systemId is the notations's system identifier. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn bool QXmlDTDHandler::unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName ) - - The reader calls this function when he finds an unparsed entity declaration. - - The argument \a name is the unparsed entity's name, \a publicId is the - entity's public identifier, \a systemId is the entity's system identifier and - \a notation is the name of the associated notation. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn QString QXmlDTDHandler::errorString() - - The reader calls this function to get an error string if any of the handler - functions returns FALSE to him. -*/ - - -/*! - \class QXmlEntityResolver qxml.h - \brief The QXmlEntityResolver class provides an interface to resolve extern - entities contained in XML data. - - \module XML - - If an application needs to implement customized handling for external - entities, it must implement this interface and register it with - QXmlReader::setEntityResolver(). - - See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>. - - \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlErrorHandler - QXmlLexicalHandler -*/ -/*! - \fn bool QXmlEntityResolver::resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret ) - - The reader will call this function before he opens any external entity, - except the top-level document entity. The application may request the reader - to resolve the entity itself (\a ret is 0) or to use an entirely different - input source (\a ret points to the input source). - - The reader will delete the input source \a ret when he no longer needs it. So - you should allocate it on the heap with \c new. - - The argument \a publicId is the public identifier of the external entity, \a - systemId is the system identifier of the external entity and \a ret is the - return value of this function: if it is 0 the reader should resolve the - entity itself, if it is non-zero it must point to an input source which the - reader will use instead. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn QString QXmlEntityResolver::errorString() - - The reader calls this function to get an error string if any of the handler - functions returns FALSE to him. -*/ - - -/*! - \class QXmlLexicalHandler qxml.h - \brief The QXmlLexicalHandler class provides an interface to report lexical - content of XML data. - - \module XML - - The events in the lexical handler apply to the entire document, not just to - the document element, and all lexical handler events appear between the - content handler's startDocument and endDocument events. - - You can set the lexical handler with QXmlReader::setLexicalHandler(). - - This interface is designed after the SAX2 extension LexicalHandler. The - functions startEntity() and endEntity() are not included though. - - See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>. - - \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver - QXmlErrorHandler -*/ -/*! - \fn bool QXmlLexicalHandler::startDTD( const QString& name, const QString& publicId, const QString& systemId ) - - The reader calls this function to report the start of a DTD declaration, if - any. - - All declarations reported through QXmlDTDHandler or QXmlDeclHandler appear - between the startDTD() and endDTD() calls. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. - - \sa endDTD() -*/ -/*! - \fn bool QXmlLexicalHandler::endDTD() - - The reader calls this function to report the end of a DTD declaration, if - any. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. - - \sa startDTD() -*/ -/*! - \fn bool QXmlLexicalHandler::startCDATA() - - The reader calls this function to report the start of a CDATA section. The - content of the CDATA section will be reported through the regular - QXmlContentHandler::characters(). This function is intended only to report - the boundary. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. - - \sa endCDATA() -*/ -/*! - \fn bool QXmlLexicalHandler::endCDATA() - - The reader calls this function to report the end of a CDATA section. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. - - \sa startCDATA() -*/ -/*! - \fn bool QXmlLexicalHandler::comment( const QString& ch ) - - The reader calls this function to report an XML comment anywhere in the - document. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn QString QXmlLexicalHandler::errorString() - - The reader calls this function to get an error string if any of the handler - functions returns FALSE to him. -*/ - - -/*! - \class QXmlDeclHandler qxml.h - \brief The QXmlDeclHandler class provides an interface to report declaration - content of XML data. - - \module XML - - You can set the declaration handler with QXmlReader::setDeclHandler(). - - This interface is designed after the SAX2 extension DeclHandler. - - See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>. - - \sa QXmlDTDHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler - QXmlLexicalHandler -*/ -/*! - \fn bool QXmlDeclHandler::attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value ) - - The reader calls this function to report an attribute type declaration. Only - the effective (first) declaration for an attribute will be reported. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn bool QXmlDeclHandler::internalEntityDecl( const QString& name, const QString& value ) - - The reader calls this function to report an internal entity declaration. Only - the effective (first) declaration will be reported. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn bool QXmlDeclHandler::externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId ) - - The reader calls this function to report a parsed external entity - declaration. Only the effective (first) declaration for each entity will be - reported. - - If this function returns FALSE the reader will stop parsing and will report - an error. The reader will use the function errorString() to get the error - message that will be used for reporting the error. -*/ -/*! - \fn QString QXmlDeclHandler::errorString() - - The reader calls this function to get an error string if any of the handler - functions returns FALSE to him. -*/ - - -/*! - \class QXmlDefaultHandler qxml.h - \brief The QXmlDefaultHandler class provides a default implementation of all - XML handler classes. - - \module XML - - Very often you are only interested in parts of the things that that the - reader reports to you. This class simply implements a default behaviour of - the handler classes (most of the time: do nothing). Normally this is the - class you subclass for implementing your customized handler. - - See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>. - - \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver - QXmlErrorHandler QXmlLexicalHandler -*/ -/*! - \fn QXmlDefaultHandler::QXmlDefaultHandler() - - Constructor. -*/ -/*! - \fn QXmlDefaultHandler::~QXmlDefaultHandler() - - Destructor. -*/ - -/*! - Does nothing. -*/ -void QXmlDefaultHandler::setDocumentLocator( QXmlLocator* ) -{ -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::startDocument() -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::endDocument() -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::startPrefixMapping( const QString&, const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::endPrefixMapping( const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::startElement( const QString&, const QString&, - const QString&, const QXmlAttributes& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::endElement( const QString&, const QString&, - const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::characters( const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::ignorableWhitespace( const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::processingInstruction( const QString&, - const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::skippedEntity( const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::warning( const QXmlParseException& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::error( const QXmlParseException& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::fatalError( const QXmlParseException& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::notationDecl( const QString&, const QString&, - const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::unparsedEntityDecl( const QString&, const QString&, - const QString&, const QString& ) -{ - return TRUE; -} - -/*! - Always sets \a ret to 0, so that the reader will use the system identifier - provided in the XML document. -*/ -bool QXmlDefaultHandler::resolveEntity( const QString&, const QString&, - QXmlInputSource* &ret ) -{ - ret = 0; - return TRUE; -} - -/*! - Returns the default error string. -*/ -QString QXmlDefaultHandler::errorString() -{ - return QString( XMLERR_ERRORBYCONSUMER ); -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::startDTD( const QString&, const QString&, const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::endDTD() -{ - return TRUE; -} - -#if 0 -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::startEntity( const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::endEntity( const QString& ) -{ - return TRUE; -} -#endif - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::startCDATA() -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::endCDATA() -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::comment( const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::attributeDecl( const QString&, const QString&, const QString&, const QString&, const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::internalEntityDecl( const QString&, const QString& ) -{ - return TRUE; -} - -/*! - Does nothing. -*/ -bool QXmlDefaultHandler::externalEntityDecl( const QString&, const QString&, const QString& ) -{ - return TRUE; -} - - -/********************************************* - * - * QXmlSimpleReaderPrivate - * - *********************************************/ - -class QXmlSimpleReaderPrivate -{ -private: - // constructor - QXmlSimpleReaderPrivate() - { } - - - // used for entity declarations - struct ExternParameterEntity - { - ExternParameterEntity( ) {} - ExternParameterEntity( const QString &p, const QString &s ) - : publicId(p), systemId(s) {} - QString publicId; - QString systemId; - }; - struct ExternEntity - { - ExternEntity( ) {} - ExternEntity( const QString &p, const QString &s, const QString &n ) - : publicId(p), systemId(s), notation(n) {} - QString publicId; - QString systemId; - QString notation; - }; - QMap<QString,ExternParameterEntity> externParameterEntities; - QMap<QString,QString> parameterEntities; - QMap<QString,ExternEntity> externEntities; - QMap<QString,QString> entities; - - // used for standalone declaration - enum Standalone { Yes, No, Unknown }; - - QString doctype; // only used for the doctype - QString xmlVersion; // only used to store the version information - QString encoding; // only used to store the encoding - Standalone standalone; // used to store the value of the standalone declaration - - QString publicId; // used by parseExternalID() to store the public ID - QString systemId; // used by parseExternalID() to store the system ID - QString attDeclEName; // use by parseAttlistDecl() - QString attDeclAName; // use by parseAttlistDecl() - - // flags for some features support - bool useNamespaces; - bool useNamespacePrefixes; - bool reportWhitespaceCharData; - - // used to build the attribute list - QXmlAttributes attList; - - // helper classes - QXmlLocator *locator; - QXmlNamespaceSupport namespaceSupport; - - // error string - QString error; - - // friend declarations - friend class QXmlSimpleReader; -}; - - -/********************************************* - * - * QXmlSimpleReader - * - *********************************************/ - -/*! - \class QXmlReader qxml.h - \brief The QXmlReader class provides an interface for XML readers (i.e. - parsers). - - \module XML - - This abstract class describes an interface for all XML readers in Qt. At the - moment there is only one implementation of a reader included in the XML - module of Qt (QXmlSimpleReader). In future releases there might be more - readers with different properties available (e.g. a validating parser). - - The design of the XML classes follow the - <a href="http://www.megginson.com/SAX/">SAX2 java interface</a>. - It was adopted to fit into the Qt naming conventions; so it should be very - easy for anybody who has worked with SAX2 to get started with the Qt XML - classes. - - All readers use the class QXmlInputSource to read the input document from. - Since you are normally interested in certain contents of the XML document, - the reader reports those contents through special handler classes - (QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver, - QXmlErrorHandler and QXmlLexicalHandler). - - You have to subclass these classes. Since the handler classes describe only - interfaces you must implement all functions; there is a class - (QXmlDefaultHandler) to make this easier; it implements a default behaviour - (do nothing) for all functions. - - For getting started see also the - <a href="xml-sax.html#quickStart">Quick start</a>. - - \sa QXmlSimpleReader -*/ -/*! - \fn bool QXmlReader::feature( const QString& name, bool *ok ) const - - If the reader has the feature \a name, this function returns the value of the - feature. - - If the reader has not the feature \a name, the return value may be anything. - - If \a ok is not 0, then \a ok is set to TRUE if the reader has the feature - \a name, otherwise \a ok is set to FALSE. - - \sa setFeature() hasFeature() -*/ -/*! - \fn void QXmlReader::setFeature( const QString& name, bool value ) - - Sets the feature \a name to \a value. If the reader has not the feature \a - name, this value is ignored. - - \sa feature() hasFeature() -*/ -/*! - \fn bool QXmlReader::hasFeature( const QString& name ) const - - Returns \c TRUE if the reader has the feature \a name, otherwise FALSE. - - \sa feature() setFeature() -*/ -/*! - \fn void* QXmlReader::property( const QString& name, bool *ok ) const - - If the reader has the property \a name, this function returns the value of - the property. - - If the reader has not the property \a name, the return value is 0. - - If \a ok is not 0, then \a ok is set to TRUE if the reader has the property - \a name, otherwise \a ok is set to FALSE. - - \sa setProperty() hasProperty() -*/ -/*! - \fn void QXmlReader::setProperty( const QString& name, void* value ) - - Sets the property \a name to \a value. If the reader has not the property \a - name, this value is ignored. - - \sa property() hasProperty() -*/ -/*! - \fn bool QXmlReader::hasProperty( const QString& name ) const - - Returns TRUE if the reader has the property \a name, otherwise FALSE. - - \sa property() setProperty() -*/ -/*! - \fn void QXmlReader::setEntityResolver( QXmlEntityResolver* handler ) - - Sets the entity resolver to \a handler. - - \sa entityResolver() -*/ -/*! - \fn QXmlEntityResolver* QXmlReader::entityResolver() const - - Returns the entity resolver or 0 if none was set. - - \sa setEntityResolver() -*/ -/*! - \fn void QXmlReader::setDTDHandler( QXmlDTDHandler* handler ) - - Sets the DTD handler to \a handler. - - \sa DTDHandler() -*/ -/*! - \fn QXmlDTDHandler* QXmlReader::DTDHandler() const - - Returns the DTD handler or 0 if none was set. - - \sa setDTDHandler() -*/ -/*! - \fn void QXmlReader::setContentHandler( QXmlContentHandler* handler ) - - Sets the content handler to \a handler. - - \sa contentHandler() -*/ -/*! - \fn QXmlContentHandler* QXmlReader::contentHandler() const - - Returns the content handler or 0 if none was set. - - \sa setContentHandler() -*/ -/*! - \fn void QXmlReader::setErrorHandler( QXmlErrorHandler* handler ) - - Sets the error handler to \a handler. - - \sa errorHandler() -*/ -/*! - \fn QXmlErrorHandler* QXmlReader::errorHandler() const - - Returns the error handler or 0 if none was set - - \sa setErrorHandler() -*/ -/*! - \fn void QXmlReader::setLexicalHandler( QXmlLexicalHandler* handler ) - - Sets the lexical handler to \a handler. - - \sa lexicalHandler() -*/ -/*! - \fn QXmlLexicalHandler* QXmlReader::lexicalHandler() const - - Returns the lexical handler or 0 if none was set. - - \sa setLexicalHandler() -*/ -/*! - \fn void QXmlReader::setDeclHandler( QXmlDeclHandler* handler ) - - Sets the declaration handler to \a handler. - - \sa declHandler() -*/ -/*! - \fn QXmlDeclHandler* QXmlReader::declHandler() const - - Returns the declaration handler or 0 if none was set. - - \sa setDeclHandler() -*/ -/*! - \fn bool QXmlReader::parse( const QXmlInputSource& input ) - - Parses the XML document \a input. Returns TRUE if the parsing was successful, - otherwise FALSE. -*/ -/*! - \fn bool QXmlReader::parse( const QString& systemId ) - - Parses the XML document at the location \a systemId. Returns TRUE if the - parsing was successful, otherwise FALSE. -*/ - - -/*! - \class QXmlSimpleReader qxml.h - \brief The QXmlSimpleReader class provides an implementation of a simple XML - reader (i.e. parser). - - \module XML - - This XML reader is sufficient for simple parsing tasks. Here is a short list - of the properties of this reader: - <ul> - <li> well-formed parser - <li> does not parse any external entities - <li> can do namespace processing - </ul> - - For getting started see also the - <a href="xml-sax.html#quickStart">Quick start</a>. -*/ - -//guaranteed not to be a character -const QChar QXmlSimpleReader::QEOF = QChar((ushort)0xffff); - -/*! - Constructs a simple XML reader. -*/ -QXmlSimpleReader::QXmlSimpleReader() -{ - d = new QXmlSimpleReaderPrivate(); - d->locator = new QXmlLocator( this ); - - entityRes = 0; - dtdHnd = 0; - contentHnd = 0; - errorHnd = 0; - lexicalHnd = 0; - declHnd = 0; - - // default feature settings - d->useNamespaces = TRUE; - d->useNamespacePrefixes = FALSE; - d->reportWhitespaceCharData = TRUE; -} - -/*! - Destroys a simple XML reader. -*/ -QXmlSimpleReader::~QXmlSimpleReader() -{ - delete d->locator; - delete d; -} - -/*! - Gets the state of a feature. - - \sa setFeature() hasFeature() -*/ -bool QXmlSimpleReader::feature( const QString& name, bool *ok ) const -{ - if ( ok != 0 ) - *ok = TRUE; - if ( name == "http://xml.org/sax/features/namespaces" ) { - return d->useNamespaces; - } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) { - return d->useNamespacePrefixes; - } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) { - return d->reportWhitespaceCharData; - } else { - qWarning( "Unknown feature %s", name.ascii() ); - if ( ok != 0 ) - *ok = FALSE; - } - return FALSE; -} - -/*! - Sets the state of a feature. - - Supported features are: - <ul> - <li> http://xml.org/sax/features/namespaces: - if this feature is TRUE, namespace processing is performed - <li> http://xml.org/sax/features/namespace-prefixes: - if this feature is TRUE, the original prefixed names and attributes - used for namespace declarations are reported - <li> http://trolltech.com/xml/features/report-whitespace-only-CharData: - if this feature is TRUE, CharData that consists only of whitespace (and - no other characters) is not reported via - QXmlContentHandler::characters() - </ul> - - \sa feature() hasFeature() -*/ -void QXmlSimpleReader::setFeature( const QString& name, bool value ) -{ - if ( name == "http://xml.org/sax/features/namespaces" ) { - d->useNamespaces = value; - } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) { - d->useNamespacePrefixes = value; - } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) { - d->reportWhitespaceCharData = value; - } else { - qWarning( "Unknown feature %s", name.ascii() ); - } -} - -/*! - Returns TRUE if the class has a feature named \a feature, otherwise FALSE. - - \sa setFeature() feature() -*/ -bool QXmlSimpleReader::hasFeature( const QString& name ) const -{ - if ( name == "http://xml.org/sax/features/namespaces" || - name == "http://xml.org/sax/features/namespace-prefixes" || - name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) { - return TRUE; - } else { - return FALSE; - } -} - -/*! - Returns 0 since this class does not support any properties. -*/ -void* QXmlSimpleReader::property( const QString&, bool *ok ) const -{ - if ( ok != 0 ) - *ok = FALSE; - return 0; -} - -/*! - Does nothing since this class does not support any properties. -*/ -void QXmlSimpleReader::setProperty( const QString&, void* ) -{ -} - -/*! - Returns FALSE since this class does not support any properties. -*/ -bool QXmlSimpleReader::hasProperty( const QString& ) const -{ - return FALSE; -} - -/*! \reimp */ -void QXmlSimpleReader::setEntityResolver( QXmlEntityResolver* handler ) -{ entityRes = handler; } - -/*! \reimp */ -QXmlEntityResolver* QXmlSimpleReader::entityResolver() const -{ return entityRes; } - -/*! \reimp */ -void QXmlSimpleReader::setDTDHandler( QXmlDTDHandler* handler ) -{ dtdHnd = handler; } - -/*! \reimp */ -QXmlDTDHandler* QXmlSimpleReader::DTDHandler() const -{ return dtdHnd; } - -/*! \reimp */ -void QXmlSimpleReader::setContentHandler( QXmlContentHandler* handler ) -{ contentHnd = handler; } - -/*! \reimp */ -QXmlContentHandler* QXmlSimpleReader::contentHandler() const -{ return contentHnd; } - -/*! \reimp */ -void QXmlSimpleReader::setErrorHandler( QXmlErrorHandler* handler ) -{ errorHnd = handler; } - -/*! \reimp */ -QXmlErrorHandler* QXmlSimpleReader::errorHandler() const -{ return errorHnd; } - -/*! \reimp */ -void QXmlSimpleReader::setLexicalHandler( QXmlLexicalHandler* handler ) -{ lexicalHnd = handler; } - -/*! \reimp */ -QXmlLexicalHandler* QXmlSimpleReader::lexicalHandler() const -{ return lexicalHnd; } - -/*! \reimp */ -void QXmlSimpleReader::setDeclHandler( QXmlDeclHandler* handler ) -{ declHnd = handler; } - -/*! \reimp */ -QXmlDeclHandler* QXmlSimpleReader::declHandler() const -{ return declHnd; } - - - -/*! \reimp */ -bool QXmlSimpleReader::parse( const QXmlInputSource& input ) -{ - init( input ); - // call the handler - if ( contentHnd ) { - contentHnd->setDocumentLocator( d->locator ); - if ( !contentHnd->startDocument() ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } - // parse prolog - if ( !parseProlog() ) { - d->error = XMLERR_ERRORPARSINGPROLOG; - goto parseError; - } - // parse element - if ( !parseElement() ) { - d->error = XMLERR_ERRORPARSINGMAINELEMENT; - goto parseError; - } - // parse Misc* - while ( !atEnd() ) { - if ( !parseMisc() ) { - d->error = XMLERR_ERRORPARSINGMISC; - goto parseError; - } - } - // is stack empty? - if ( !tags.isEmpty() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - // call the handler - if ( contentHnd ) { - if ( !contentHnd->endDocument() ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } - - return TRUE; - - // error handling - -parseError: - reportParseError(); - tags.clear(); - return FALSE; -} - -/*! - Parses the prolog [22]. -*/ -bool QXmlSimpleReader::parseProlog() -{ - bool xmldecl_possible = TRUE; - bool doctype_read = FALSE; - - const signed char Init = 0; - const signed char EatWS = 1; // eat white spaces - const signed char Lt = 2; // '<' read - const signed char Em = 3; // '!' read - const signed char DocType = 4; // read doctype - const signed char Comment = 5; // read comment - const signed char PI = 6; // read PI - const signed char Done = 7; - - const signed char InpWs = 0; - const signed char InpLt = 1; // < - const signed char InpQm = 2; // ? - const signed char InpEm = 3; // ! - const signed char InpD = 4; // D - const signed char InpDash = 5; // - - const signed char InpUnknown = 6; - - // use some kind of state machine for parsing - static signed char table[7][7] = { - /* InpWs InpLt InpQm InpEm InpD InpDash InpUnknown */ - { EatWS, Lt, -1, -1, -1, -1, -1 }, // Init - { -1, Lt, -1, -1, -1, -1, -1 }, // EatWS - { -1, -1, PI, Em, Done, -1, Done }, // Lt - { -1, -1, -1, -1, DocType, Comment, -1 }, // Em - { EatWS, Lt, -1, -1, -1, -1, -1 }, // DocType - { EatWS, Lt, -1, -1, -1, -1, -1 }, // Comment - { EatWS, Lt, -1, -1, -1, -1, -1 } // PI - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // read input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( c == '<' ) { - input = InpLt; - } else if ( c == '?' ) { - input = InpQm; - } else if ( c == '!' ) { - input = InpEm; - } else if ( c == 'D' ) { - input = InpD; - } else if ( c == '-' ) { - input = InpDash; - } else { - input = InpUnknown; - } - // get new state - state = table[state][input]; - - // in some cases do special actions depending on state - switch ( state ) { - case EatWS: - // XML declaration only on first position possible - xmldecl_possible = FALSE; - // eat white spaces - eat_ws(); - break; - case Lt: - // next character - next(); - break; - case Em: - // XML declaration only on first position possible - xmldecl_possible = FALSE; - // next character - next(); - break; - case DocType: - parseOk = parseDoctype(); - break; - case Comment: - parseOk = parseComment(); - break; - case PI: - parseOk = parsePI( xmldecl_possible ); - break; - } - // no input is read after this - switch ( state ) { - case DocType: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGPROLOG; - goto parseError; - } - if ( doctype_read ) { - d->error = XMLERR_MORETHANONEDOCTYPE; - goto parseError; - } else { - doctype_read = FALSE; - } - break; - case Comment: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGPROLOG; - goto parseError; - } - if ( lexicalHnd ) { - if ( !lexicalHnd->comment( string() ) ) { - d->error = lexicalHnd->errorString(); - goto parseError; - } - } - break; - case PI: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGPROLOG; - goto parseError; - } - // call the handler - if ( contentHnd ) { - if ( xmldecl_possible && !d->xmlVersion.isEmpty() ) { - QString value( "version = '" ); - value += d->xmlVersion; - value += "'"; - if ( !d->encoding.isEmpty() ) { - value += " encoding = '"; - value += d->encoding; - value += "'"; - } - if ( d->standalone == QXmlSimpleReaderPrivate::Yes ) { - value += " standalone = 'yes'"; - } else if ( d->standalone == QXmlSimpleReaderPrivate::No ) { - value += " standalone = 'no'"; - } - if ( !contentHnd->processingInstruction( "xml", value ) ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } else { - if ( !contentHnd->processingInstruction( name(), string() ) ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } - } - // XML declaration only on first position possible - xmldecl_possible = FALSE; - break; - case Done: - return TRUE; - case -1: - d->error = XMLERR_ERRORPARSINGELEMENT; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse an element [39]. - - Precondition: the opening '<' is already read. -*/ -bool QXmlSimpleReader::parseElement() -{ - static QString uri, lname, prefix; - static bool t; - - const signed char Init = 0; - const signed char ReadName = 1; - const signed char Ws1 = 2; - const signed char STagEnd = 3; - const signed char STagEnd2 = 4; - const signed char ETagBegin = 5; - const signed char ETagBegin2 = 6; - const signed char Ws2 = 7; - const signed char EmptyTag = 8; - const signed char Attribute = 9; - const signed char Ws3 = 10; - const signed char Done = 11; - - const signed char InpWs = 0; // whitespace - const signed char InpNameBe = 1; // is_NameBeginning() - const signed char InpGt = 2; // > - const signed char InpSlash = 3; // / - const signed char InpUnknown = 4; - - // use some kind of state machine for parsing - static signed char table[11][5] = { - /* InpWs InpNameBe InpGt InpSlash InpUnknown */ - { -1, ReadName, -1, -1, -1 }, // Init - { Ws1, Attribute, STagEnd, EmptyTag, -1 }, // ReadName - { -1, Attribute, STagEnd, EmptyTag, -1 }, // Ws1 - { STagEnd2, STagEnd2, STagEnd2, STagEnd2, STagEnd2 }, // STagEnd - { -1, -1, -1, ETagBegin, -1 }, // STagEnd2 - { -1, ETagBegin2, -1, -1, -1 }, // ETagBegin - { Ws2, -1, Done, -1, -1 }, // ETagBegin2 - { -1, -1, Done, -1, -1 }, // Ws2 - { -1, -1, Done, -1, -1 }, // EmptyTag - { Ws3, Attribute, STagEnd, EmptyTag, -1 }, // Attribute - { -1, Attribute, STagEnd, EmptyTag, -1 } // Ws3 - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // read input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( is_NameBeginning(c) ) { - input = InpNameBe; - } else if ( c == '>' ) { - input = InpGt; - } else if ( c == '/' ) { - input = InpSlash; - } else { - input = InpUnknown; - } - // get new state -//qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] ); - state = table[state][input]; - - // in some cases do special actions depending on state - switch ( state ) { - case ReadName: - parseOk = parseName(); - break; - case Ws1: - case Ws2: - case Ws3: - eat_ws(); - break; - case STagEnd: - // call the handler - if ( contentHnd ) { - if ( d->useNamespaces ) { - d->namespaceSupport.processName( tags.top(), FALSE, uri, lname ); - t = contentHnd->startElement( uri, lname, tags.top(), d->attList ); - } else { - t = contentHnd->startElement( "", "", tags.top(), d->attList ); - } - if ( !t ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } - next(); - break; - case STagEnd2: - parseOk = parseContent(); - break; - case ETagBegin: - next(); - break; - case ETagBegin2: - // get the name of the tag - parseOk = parseName(); - break; - case EmptyTag: - if ( tags.isEmpty() ) { - d->error = XMLERR_TAGMISMATCH; - goto parseError; - } - if ( !parseElementEmptyTag( t, uri, lname ) ) - goto parseError; - // next character - next(); - break; - case Attribute: - // get name and value of attribute - parseOk = parseAttribute(); - break; - case Done: - next(); - break; - } - // no input is read after this - switch ( state ) { - case ReadName: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - // store it on the stack - tags.push( name() ); - // empty the attributes - d->attList.qnameList.clear(); - d->attList.uriList.clear(); - d->attList.localnameList.clear(); - d->attList.valueList.clear(); - // namespace support? - if ( d->useNamespaces ) { - d->namespaceSupport.pushContext(); - } - break; - case STagEnd2: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGCONTENT; - goto parseError; - } - break; - case ETagBegin2: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - if ( !parseElementETagBegin2( uri, lname ) ) - goto parseError; - break; - case Attribute: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGATTRIBUTE; - goto parseError; - } - if ( !parseElementAttribute( prefix, uri, lname ) ) - goto parseError; - break; - case Done: - return TRUE; - case -1: - d->error = XMLERR_ERRORPARSINGELEMENT; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} -/*! - Helper to break down the size of the code in the case statement. - Return FALSE on error, otherwise TRUE. -*/ -bool QXmlSimpleReader::parseElementEmptyTag( bool &t, QString &uri, QString &lname ) -{ - // pop the stack and call the handler - if ( contentHnd ) { - // report startElement first... - if ( d->useNamespaces ) { - d->namespaceSupport.processName( tags.top(), FALSE, uri, lname ); - t = contentHnd->startElement( uri, lname, tags.top(), d->attList ); - } else { - t = contentHnd->startElement( "", "", tags.top(), d->attList ); - } - if ( !t ) { - d->error = contentHnd->errorString(); - return FALSE; - } - // ... followed by endElement - if ( d->useNamespaces ) { - if ( !contentHnd->endElement( uri, lname,tags.pop() ) ) { - d->error = contentHnd->errorString(); - return FALSE; - } - } - else { - if ( !contentHnd->endElement( "","",tags.pop() ) ) { - d->error = contentHnd->errorString(); - return FALSE; - } - } - // namespace support? - if ( d->useNamespaces ) { - QStringList prefixesBefore, prefixesAfter; - if ( contentHnd ) { - prefixesBefore = d->namespaceSupport.prefixes(); - } - d->namespaceSupport.popContext(); - // call the handler for prefix mapping - if ( contentHnd ) { - prefixesAfter = d->namespaceSupport.prefixes(); - for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) { - if ( prefixesAfter.contains(*it) == 0 ) { - if ( !contentHnd->endPrefixMapping( *it ) ) { - d->error = contentHnd->errorString(); - return FALSE; - } - } - } - } - } - } else { - tags.pop(); - } - return TRUE; -} -/*! - Helper to break down the size of the code in the case statement. - Return FALSE on error, otherwise TRUE. -*/ -bool QXmlSimpleReader::parseElementETagBegin2( QString &uri, QString &lname ) -{ - - // pop the stack and compare it with the name - if ( tags.pop() != name() ) { - d->error = XMLERR_TAGMISMATCH; - return FALSE; - } - // call the handler - if ( contentHnd ) { - if ( d->useNamespaces ) { - d->namespaceSupport.processName( name(), FALSE, uri, lname ); - if ( !contentHnd->endElement(uri,lname,name()) ) { - d->error = contentHnd->errorString(); - return FALSE; - } - } - else { - if ( !contentHnd->endElement("","",name()) ) { - d->error = contentHnd->errorString(); - return FALSE; - } - } - } - // namespace support? - if ( d->useNamespaces ) { - QStringList prefixesBefore, prefixesAfter; - if ( contentHnd ) { - prefixesBefore = d->namespaceSupport.prefixes(); - } - d->namespaceSupport.popContext(); - // call the handler for prefix mapping - if ( contentHnd ) { - prefixesAfter = d->namespaceSupport.prefixes(); - for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) { - if ( prefixesAfter.contains(*it) == 0 ) { - if ( !contentHnd->endPrefixMapping( *it ) ) { - d->error = contentHnd->errorString(); - return FALSE; - } - } - } - } - } - return TRUE; -} -/*! - Helper to break down the size of the code in the case statement. - Return FALSE on error, otherwise TRUE. -*/ -bool QXmlSimpleReader::parseElementAttribute( QString &prefix, QString &uri, QString &lname ) -{ - // add the attribute to the list - if ( d->useNamespaces ) { - // is it a namespace declaration? - d->namespaceSupport.splitName( name(), prefix, lname ); - if ( prefix == "xmlns" ) { - // namespace declaration - d->namespaceSupport.setPrefix( lname, string() ); - if ( d->useNamespacePrefixes ) { - d->attList.qnameList.append( name() ); - d->attList.uriList.append( "" ); - d->attList.localnameList.append( "" ); - d->attList.valueList.append( string() ); - } - // call the handler for prefix mapping - if ( contentHnd ) { - if ( !contentHnd->startPrefixMapping( lname, string() ) ) { - d->error = contentHnd->errorString(); - return FALSE; - } - } - } else { - // no namespace declaration - d->namespaceSupport.processName( name(), TRUE, uri, lname ); - d->attList.qnameList.append( name() ); - d->attList.uriList.append( uri ); - d->attList.localnameList.append( lname ); - d->attList.valueList.append( string() ); - } - } else { - // no namespace support - d->attList.qnameList.append( name() ); - d->attList.uriList.append( "" ); - d->attList.localnameList.append( "" ); - d->attList.valueList.append( string() ); - } - return TRUE; -} - -/*! - Parse a content [43]. - - A content is only used between tags. If a end tag is found the < is already - read and the head stand on the '/' of the end tag '</name>'. -*/ -bool QXmlSimpleReader::parseContent() -{ - bool charDataRead = FALSE; - - const signed char Init = 0; - const signed char ChD = 1; // CharData - const signed char ChD1 = 2; // CharData help state - const signed char ChD2 = 3; // CharData help state - const signed char Ref = 4; // Reference - const signed char Lt = 5; // '<' read - const signed char PI = 6; // PI - const signed char Elem = 7; // Element - const signed char Em = 8; // '!' read - const signed char Com = 9; // Comment - const signed char CDS = 10; // CDSect - const signed char CDS1 = 11; // read a CDSect - const signed char CDS2 = 12; // read a CDSect (help state) - const signed char CDS3 = 13; // read a CDSect (help state) - const signed char Done = 14; // finished reading content - - const signed char InpLt = 0; // < - const signed char InpGt = 1; // > - const signed char InpSlash = 2; // / - const signed char InpQMark = 3; // ? - const signed char InpEMark = 4; // ! - const signed char InpAmp = 5; // & - const signed char InpDash = 6; // - - const signed char InpOpenB = 7; // [ - const signed char InpCloseB = 8; // ] - const signed char InpUnknown = 9; - - static signed char mapCLT2FSMChar[] = { - InpUnknown, // white space - InpUnknown, // % - InpAmp, // & - InpGt, // > - InpLt, // < - InpSlash, // / - InpQMark, // ? - InpEMark, // ! - InpDash, // - - InpCloseB, // ] - InpOpenB, // [ - InpUnknown, // = - InpUnknown, // " - InpUnknown, // ' - InpUnknown // unknown - }; - - // use some kind of state machine for parsing - static signed char const table[14][10] = { - /* InpLt InpGt InpSlash InpQMark InpEMark InpAmp InpDash InpOpenB InpCloseB InpUnknown */ - { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // Init - { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // ChD - { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD1 - { Lt, -1, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD2 - { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Ref (same as Init) - { -1, -1, Done, PI, Em, -1, -1, -1, -1, Elem }, // Lt - { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PI (same as Init) - { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Elem (same as Init) - { -1, -1, -1, -1, -1, -1, Com, CDS, -1, -1 }, // Em - { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Com (same as Init) - { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS - { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS1 - { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 }, // CDS2 - { CDS1, Init, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 } // CDS3 - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input (use lookup-table instead of nested ifs for performance - // reasons) - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( c.row() ) { - input = InpUnknown; - } else { - input = mapCLT2FSMChar[ charLookupTable[ c.cell() ] ]; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Init: - // next character - next(); - break; - case ChD: - // on first call: clear string - if ( !charDataRead ) { - charDataRead = TRUE; - stringClear(); - } - stringAddC(); - next(); - break; - case ChD1: - // on first call: clear string - if ( !charDataRead ) { - charDataRead = TRUE; - stringClear(); - } - stringAddC(); - next(); - break; - case ChD2: - stringAddC(); - next(); - break; - case Ref: - if ( !charDataRead) { - // reference may be CharData; so clear string to be safe - stringClear(); - parseOk = parseReference( charDataRead, InContent ); - } else { - bool tmp; - parseOk = parseReference( tmp, InContent ); - } - break; - case Lt: - // call the handler for CharData - if ( contentHnd ) { - if ( charDataRead ) { - if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) { - if ( !contentHnd->characters( string() ) ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } - } - } - charDataRead = FALSE; - // next character - next(); - break; - case PI: - parseOk = parsePI(); - break; - case Elem: - parseOk = parseElement(); - break; - case Em: - // next character - next(); - break; - case Com: - parseOk = parseComment(); - break; - case CDS: - parseOk = parseString( "[CDATA[" ); - break; - case CDS1: - // read one character and add it - stringAddC(); - next(); - break; - case CDS2: - // skip ']' - next(); - break; - case CDS3: - // skip ']'... - next(); - break; - } - // no input is read after this - switch ( state ) { - case Ref: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGREFERENCE; - goto parseError; - } - break; - case PI: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGPI; - goto parseError; - } - // call the handler - if ( contentHnd ) { - if ( !contentHnd->processingInstruction(name(),string()) ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } - break; - case Elem: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGELEMENT; - goto parseError; - } - break; - case Com: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGCOMMENT; - goto parseError; - } - if ( lexicalHnd ) { - if ( !lexicalHnd->comment( string() ) ) { - d->error = lexicalHnd->errorString(); - goto parseError; - } - } - break; - case CDS: - if( !parseOk ) { - d->error = XMLERR_CDSECTHEADEREXPECTED; - goto parseError; - } - // empty string - stringClear(); - break; - case CDS2: - if (c != ']') { - stringAddC( ']' ); - } - break; - case CDS3: - // test if this skipping was legal - if ( c == '>' ) { - // the end of the CDSect - if ( lexicalHnd ) { - if ( !lexicalHnd->startCDATA() ) { - d->error = lexicalHnd->errorString(); - goto parseError; - } - } - if ( contentHnd ) { - if ( !contentHnd->characters( string() ) ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } - if ( lexicalHnd ) { - if ( !lexicalHnd->endCDATA() ) { - d->error = lexicalHnd->errorString(); - goto parseError; - } - } - } else if (c == ']') { - // three or more ']' - stringAddC( ']' ); - } else { - // after ']]' comes another character - stringAddC( ']' ); - stringAddC( ']' ); - } - break; - case Done: - // call the handler for CharData - if ( contentHnd ) { - if ( charDataRead ) { - if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) { - if ( !contentHnd->characters( string() ) ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } - } - } - // Done - return TRUE; - case -1: - // Error - d->error = XMLERR_ERRORPARSINGCONTENT; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse Misc [27]. -*/ -bool QXmlSimpleReader::parseMisc() -{ - const signed char Init = 0; - const signed char Lt = 1; // '<' was read - const signed char Comment = 2; // read comment - const signed char eatWS = 3; // eat whitespaces - const signed char PI = 4; // read PI - const signed char Comment2 = 5; // read comment - - const signed char InpWs = 0; // S - const signed char InpLt = 1; // < - const signed char InpQm = 2; // ? - const signed char InpEm = 3; // ! - const signed char InpUnknown = 4; - - // use some kind of state machine for parsing - static signed char table[3][5] = { - /* InpWs InpLt InpQm InpEm InpUnknown */ - { eatWS, Lt, -1, -1, -1 }, // Init - { -1, -1, PI, Comment, -1 }, // Lt - { -1, -1, -1, -1, Comment2 } // Comment - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( c == '<' ) { - input = InpLt; - } else if ( c == '?' ) { - input = InpQm; - } else if ( c == '!' ) { - input = InpEm; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case eatWS: - eat_ws(); - break; - case Lt: - next(); - break; - case PI: - parseOk = parsePI(); - break; - case Comment: - next(); - break; - case Comment2: - parseOk = parseComment(); - break; - } - // no input is read after this - switch ( state ) { - case eatWS: - return TRUE; - case PI: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGPI; - goto parseError; - } - if ( contentHnd ) { - if ( !contentHnd->processingInstruction(name(),string()) ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } - return TRUE; - case Comment2: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGCOMMENT; - goto parseError; - } - if ( lexicalHnd ) { - if ( !lexicalHnd->comment( string() ) ) { - d->error = lexicalHnd->errorString(); - goto parseError; - } - } - return TRUE; - case -1: - // Error - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a processing instruction [16]. - - If xmldec is TRUE, it tries to parse a PI or a XML declaration [23]. - - Precondition: the beginning '<' of the PI is already read and the head stand - on the '?' of '<?'. - - If this function was successful, the head-position is on the first - character after the PI. -*/ -bool QXmlSimpleReader::parsePI( bool xmldecl ) -{ - const signed char Init = 0; - const signed char QmI = 1; // ? was read - const signed char Name = 2; // read Name - const signed char XMLDecl = 3; // read XMLDecl - const signed char Ws1 = 4; // eat ws after "xml" of XMLDecl - const signed char PI = 5; // read PI - const signed char Ws2 = 6; // eat ws after Name of PI - const signed char Version = 7; // read versionInfo - const signed char Ws3 = 8; // eat ws after versionInfo - const signed char EorSD = 9; // read EDecl or SDDecl - const signed char Ws4 = 10; // eat ws after EDecl or SDDecl - const signed char SD = 11; // read SDDecl - const signed char Ws5 = 12; // eat ws after SDDecl - const signed char ADone = 13; // almost done - const signed char Char = 14; // Char was read - const signed char Qm = 15; // Qm was read - const signed char Done = 16; // finished reading content - - const signed char InpWs = 0; // whitespace - const signed char InpNameBe = 1; // is_nameBeginning() - const signed char InpGt = 2; // > - const signed char InpQm = 3; // ? - const signed char InpUnknown = 4; - - // use some kind of state machine for parsing - static signed char table[16][5] = { - /* InpWs, InpNameBe InpGt InpQm InpUnknown */ - { -1, -1, -1, QmI, -1 }, // Init - { -1, Name, -1, -1, -1 }, // QmI - { -1, -1, -1, -1, -1 }, // Name (this state is left not through input) - { Ws1, -1, -1, -1, -1 }, // XMLDecl - { -1, Version, -1, -1, -1 }, // Ws1 - { Ws2, -1, -1, Qm, -1 }, // PI - { Char, Char, Char, Qm, Char }, // Ws2 - { Ws3, -1, -1, ADone, -1 }, // Version - { -1, EorSD, -1, ADone, -1 }, // Ws3 - { Ws4, -1, -1, ADone, -1 }, // EorSD - { -1, SD, -1, ADone, -1 }, // Ws4 - { Ws5, -1, -1, ADone, -1 }, // SD - { -1, -1, -1, ADone, -1 }, // Ws5 - { -1, -1, Done, -1, -1 }, // ADone - { Char, Char, Char, Qm, Char }, // Char - { Char, Char, Done, Qm, Char }, // Qm - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( is_NameBeginning(c) ) { - input = InpNameBe; - } else if ( c == '>' ) { - input = InpGt; - } else if ( c == '?' ) { - input = InpQm; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case QmI: - next(); - break; - case Name: - parseOk = parseName(); - break; - case Ws1: - case Ws2: - case Ws3: - case Ws4: - case Ws5: - eat_ws(); - break; - case Version: - parseOk = parseAttribute(); - break; - case EorSD: - parseOk = parseAttribute(); - break; - case SD: - // get the SDDecl (syntax like an attribute) - if ( d->standalone != QXmlSimpleReaderPrivate::Unknown ) { - // already parsed the standalone declaration - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - parseOk = parseAttribute(); - break; - case ADone: - next(); - break; - case Char: - stringAddC(); - next(); - break; - case Qm: - // skip the '?' - next(); - break; - case Done: - next(); - break; - } - // no input is read after this - switch ( state ) { - case Name: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - // test what name was read and determine the next state - // (not very beautiful, I admit) - if ( name().lower() == "xml" ) { - if ( xmldecl && name()=="xml" ) { - state = XMLDecl; - } else { - d->error = XMLERR_INVALIDNAMEFORPI; - goto parseError; - } - } else { - state = PI; - stringClear(); - } - break; - case Version: - // get version (syntax like an attribute) - if ( !parseOk ) { - d->error = XMLERR_VERSIONEXPECTED; - goto parseError; - } - if ( name() != "version" ) { - d->error = XMLERR_VERSIONEXPECTED; - goto parseError; - } - d->xmlVersion = string(); - break; - case EorSD: - // get the EDecl or SDDecl (syntax like an attribute) - if ( !parseOk ) { - d->error = XMLERR_EDECLORSDDECLEXPECTED; - goto parseError; - } - if ( name() == "standalone" ) { - if ( string()=="yes" ) { - d->standalone = QXmlSimpleReaderPrivate::Yes; - } else if ( string()=="no" ) { - d->standalone = QXmlSimpleReaderPrivate::No; - } else { - d->error = XMLERR_WRONGVALUEFORSDECL; - goto parseError; - } - } else if ( name() == "encoding" ) { - d->encoding = string(); - } else { - d->error = XMLERR_EDECLORSDDECLEXPECTED; - goto parseError; - } - break; - case SD: - if ( !parseOk ) { - d->error = XMLERR_SDDECLEXPECTED; - goto parseError; - } - if ( name() != "standalone" ) { - d->error = XMLERR_SDDECLEXPECTED; - goto parseError; - } - if ( string()=="yes" ) { - d->standalone = QXmlSimpleReaderPrivate::Yes; - } else if ( string()=="no" ) { - d->standalone = QXmlSimpleReaderPrivate::No; - } else { - d->error = XMLERR_WRONGVALUEFORSDECL; - goto parseError; - } - break; - case Qm: - // test if the skipping was legal - if ( c != '>' ) { - stringAddC( '?' ); - } - break; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a document type definition (doctypedecl [28]). - - Precondition: the beginning '<!' of the doctype is already read the head - stands on the 'D' of '<!DOCTYPE'. - - If this function was successful, the head-position is on the first - character after the document type definition. -*/ -bool QXmlSimpleReader::parseDoctype() -{ - // some init-stuff - d->systemId = QString::null; - d->publicId = QString::null; - - const signed char Init = 0; - const signed char Doctype = 1; // read the doctype - const signed char Ws1 = 2; // eat_ws - const signed char Doctype2 = 3; // read the doctype, part 2 - const signed char Ws2 = 4; // eat_ws - const signed char Sys = 5; // read SYSTEM - const signed char Ws3 = 6; // eat_ws - const signed char MP = 7; // markupdecl or PEReference - const signed char PER = 8; // PERReference - const signed char Mup = 9; // markupdecl - const signed char Ws4 = 10; // eat_ws - const signed char MPE = 11; // end of markupdecl or PEReference - const signed char Done = 12; - - const signed char InpWs = 0; - const signed char InpD = 1; // 'D' - const signed char InpS = 2; // 'S' or 'P' - const signed char InpOB = 3; // [ - const signed char InpCB = 4; // ] - const signed char InpPer = 5; // % - const signed char InpGt = 6; // > - const signed char InpUnknown = 7; - - // use some kind of state machine for parsing - static signed char table[12][8] = { - /* InpWs, InpD InpS InpOB InpCB InpPer InpGt InpUnknown */ - { -1, Doctype, -1, -1, -1, -1, -1, -1 }, // Init - { Ws1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Doctype - { -1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Ws1 - { Ws2, -1, Sys, MP, -1, -1, Done, -1 }, // Doctype2 - { -1, -1, Sys, MP, -1, -1, Done, -1 }, // Ws2 - { Ws3, -1, -1, MP, -1, -1, Done, -1 }, // Sys - { -1, -1, -1, MP, -1, -1, Done, -1 }, // Ws3 - { -1, -1, -1, -1, MPE, PER, -1, Mup }, // MP - { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // PER - { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // Mup - { -1, -1, -1, -1, MPE, PER, -1, Mup }, // Ws4 - { -1, -1, -1, -1, -1, -1, Done, -1 } // MPE - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( c == 'D' ) { - input = InpD; - } else if ( c == 'S' ) { - input = InpS; - } else if ( c == 'P' ) { - input = InpS; - } else if ( c == '[' ) { - input = InpOB; - } else if ( c == ']' ) { - input = InpCB; - } else if ( c == '%' ) { - input = InpPer; - } else if ( c == '>' ) { - input = InpGt; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Doctype: - parseOk = parseString( "DOCTYPE" ); - break; - case Ws1: - case Ws2: - case Ws3: - case Ws4: - eat_ws(); - break; - case Doctype2: - parseName(); - break; - case Sys: - parseOk = parseExternalID(); - break; - case MP: - next_eat_ws(); - break; - case PER: - parseOk = parsePEReference( InDTD ); - break; - case Mup: - parseOk = parseMarkupdecl(); - break; - case MPE: - next_eat_ws(); - break; - case Done: - if ( lexicalHnd ) { - if ( !lexicalHnd->endDTD() ) { - d->error = lexicalHnd->errorString(); - goto parseError; - } - } - next(); - break; - } - // no input is read after this - switch ( state ) { - case Doctype: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGDOCTYPE; - goto parseError; - } - if ( !is_S(c) ) { - d->error = XMLERR_ERRORPARSINGDOCTYPE; - goto parseError; - } - break; - case Doctype2: - d->doctype = name(); - if ( lexicalHnd ) { - if ( !lexicalHnd->startDTD( d->doctype, d->publicId, d->systemId ) ) { - d->error = lexicalHnd->errorString(); - goto parseError; - } - } - break; - case Sys: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGDOCTYPE; - goto parseError; - } - break; - case PER: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGDOCTYPE; - goto parseError; - } - break; - case Mup: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGDOCTYPE; - goto parseError; - } - break; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_ERRORPARSINGDOCTYPE; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a ExternalID [75]. - - If allowPublicID is TRUE parse ExternalID [75] or PublicID [83]. -*/ -bool QXmlSimpleReader::parseExternalID( bool allowPublicID ) -{ - // some init-stuff - d->systemId = QString::null; - d->publicId = QString::null; - - const signed char Init = 0; - const signed char Sys = 1; // parse 'SYSTEM' - const signed char SysWS = 2; // parse the whitespace after 'SYSTEM' - const signed char SysSQ = 3; // parse SystemLiteral with ' - const signed char SysSQ2 = 4; // parse SystemLiteral with ' - const signed char SysDQ = 5; // parse SystemLiteral with " - const signed char SysDQ2 = 6; // parse SystemLiteral with " - const signed char Pub = 7; // parse 'PUBLIC' - const signed char PubWS = 8; // parse the whitespace after 'PUBLIC' - const signed char PubSQ = 9; // parse PubidLiteral with ' - const signed char PubSQ2 = 10; // parse PubidLiteral with ' - const signed char PubDQ = 11; // parse PubidLiteral with " - const signed char PubDQ2 = 12; // parse PubidLiteral with " - const signed char PubE = 13; // finished parsing the PubidLiteral - const signed char PubWS2 = 14; // parse the whitespace after the PubidLiteral - const signed char PDone = 15; // done if allowPublicID is TRUE - const signed char Done = 16; - - const signed char InpSQ = 0; // ' - const signed char InpDQ = 1; // " - const signed char InpS = 2; // S - const signed char InpP = 3; // P - const signed char InpWs = 4; // white space - const signed char InpUnknown = 5; - - // use some kind of state machine for parsing - static signed char table[15][6] = { - /* InpSQ InpDQ InpS InpP InpWs InpUnknown */ - { -1, -1, Sys, Pub, -1, -1 }, // Init - { -1, -1, -1, -1, SysWS, -1 }, // Sys - { SysSQ, SysDQ, -1, -1, -1, -1 }, // SysWS - { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ - { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ2 - { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ - { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ2 - { -1, -1, -1, -1, PubWS, -1 }, // Pub - { PubSQ, PubDQ, -1, -1, -1, -1 }, // PubWS - { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ - { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ2 - { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ - { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ2 - { PDone, PDone, PDone, PDone, PubWS2, PDone }, // PubE - { SysSQ, SysDQ, PDone, PDone, PDone, PDone } // PubWS2 - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( c == '\'' ) { - input = InpSQ; - } else if ( c == '"' ) { - input = InpDQ; - } else if ( c == 'S' ) { - input = InpS; - } else if ( c == 'P' ) { - input = InpP; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Sys: - parseOk = parseString( "SYSTEM" ); - break; - case SysWS: - eat_ws(); - break; - case SysSQ: - case SysDQ: - stringClear(); - next(); - break; - case SysSQ2: - case SysDQ2: - stringAddC(); - next(); - break; - case Pub: - parseOk = parseString( "PUBLIC" ); - break; - case PubWS: - eat_ws(); - break; - case PubSQ: - case PubDQ: - stringClear(); - next(); - break; - case PubSQ2: - case PubDQ2: - stringAddC(); - next(); - break; - case PubE: - next(); - break; - case PubWS2: - d->publicId = string(); - eat_ws(); - break; - case Done: - d->systemId = string(); - next(); - break; - } - // no input is read after this - switch ( state ) { - case Sys: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case Pub: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case PDone: - if ( allowPublicID ) { - d->publicId = string(); - return TRUE; - } else { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a markupdecl [29]. -*/ -bool QXmlSimpleReader::parseMarkupdecl() -{ - const signed char Init = 0; - const signed char Lt = 1; // < was read - const signed char Em = 2; // ! was read - const signed char CE = 3; // E was read - const signed char Qm = 4; // ? was read - const signed char Dash = 5; // - was read - const signed char CA = 6; // A was read - const signed char CEL = 7; // EL was read - const signed char CEN = 8; // EN was read - const signed char CN = 9; // N was read - const signed char Done = 10; - - const signed char InpLt = 0; // < - const signed char InpQm = 1; // ? - const signed char InpEm = 2; // ! - const signed char InpDash = 3; // - - const signed char InpA = 4; // A - const signed char InpE = 5; // E - const signed char InpL = 6; // L - const signed char InpN = 7; // N - const signed char InpUnknown = 8; - - // use some kind of state machine for parsing - static signed char table[4][9] = { - /* InpLt InpQm InpEm InpDash InpA InpE InpL InpN InpUnknown */ - { Lt, -1, -1, -1, -1, -1, -1, -1, -1 }, // Init - { -1, Qm, Em, -1, -1, -1, -1, -1, -1 }, // Lt - { -1, -1, -1, Dash, CA, CE, -1, CN, -1 }, // Em - { -1, -1, -1, -1, -1, -1, CEL, CEN, -1 } // CE - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( c == '<' ) { - input = InpLt; - } else if ( c == '?' ) { - input = InpQm; - } else if ( c == '!' ) { - input = InpEm; - } else if ( c == '-' ) { - input = InpDash; - } else if ( c == 'A' ) { - input = InpA; - } else if ( c == 'E' ) { - input = InpE; - } else if ( c == 'L' ) { - input = InpL; - } else if ( c == 'N' ) { - input = InpN; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Lt: - next(); - break; - case Em: - next(); - break; - case CE: - next(); - break; - case Qm: - parseOk = parsePI(); - break; - case Dash: - parseOk = parseComment(); - break; - case CA: - parseOk = parseAttlistDecl(); - break; - case CEL: - parseOk = parseElementDecl(); - break; - case CEN: - parseOk = parseEntityDecl(); - break; - case CN: - parseOk = parseNotationDecl(); - break; - } - // no input is read after this - switch ( state ) { - case Qm: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGPI; - goto parseError; - } - if ( contentHnd ) { - if ( !contentHnd->processingInstruction(name(),string()) ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } - return TRUE; - case Dash: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGCOMMENT; - goto parseError; - } - if ( lexicalHnd ) { - if ( !lexicalHnd->comment( string() ) ) { - d->error = lexicalHnd->errorString(); - goto parseError; - } - } - return TRUE; - case CA: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGATTLISTDECL; - goto parseError; - } - return TRUE; - case CEL: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGELEMENTDECL; - goto parseError; - } - return TRUE; - case CEN: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGENTITYDECL; - goto parseError; - } - return TRUE; - case CN: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNOTATIONDECL; - goto parseError; - } - return TRUE; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_LETTEREXPECTED; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a PEReference [69] -*/ -bool QXmlSimpleReader::parsePEReference( EntityRecognitionContext context ) -{ - const signed char Init = 0; - const signed char Next = 1; - const signed char Name = 2; - const signed char Done = 3; - - const signed char InpSemi = 0; // ; - const signed char InpPer = 1; // % - const signed char InpUnknown = 2; - - // use some kind of state machine for parsing - static signed char table[3][3] = { - /* InpSemi InpPer InpUnknown */ - { -1, Next, -1 }, // Init - { -1, -1, Name }, // Next - { Done, -1, -1 } // Name - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( c == ';' ) { - input = InpSemi; - } else if ( c == '%' ) { - input = InpPer; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Next: - next(); - break; - case Name: - parseOk = parseName( TRUE ); - break; - case Done: - next(); - break; - } - // no input is read after this - switch ( state ) { - case Name: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - if ( d->parameterEntities.find( ref() ) == d->parameterEntities.end() ) { - // ### skip it??? - if ( contentHnd ) { - if ( !contentHnd->skippedEntity( QString("%") + ref() ) ) { - d->error = contentHnd->errorString(); - goto parseError; - } - } - } else { - if ( context == InEntityValue ) { - // Included in literal - xmlRef = d->parameterEntities.find( ref() ) - .data().replace( QRegExp("\""), """ ).replace( QRegExp("'"), "'" ) - + xmlRef; - } else if ( context == InDTD ) { - // Included as PE - xmlRef = QString(" ") + - d->parameterEntities.find( ref() ).data() + - QString(" ") + xmlRef; - } - } - break; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_LETTEREXPECTED; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a AttlistDecl [52]. - - Precondition: the beginning '<!' is already read and the head - stands on the 'A' of '<!ATTLIST' -*/ -bool QXmlSimpleReader::parseAttlistDecl() -{ - const signed char Init = 0; - const signed char Attlist = 1; // parse the string "ATTLIST" - const signed char Ws = 2; // whitespace read - const signed char Name = 3; // parse name - const signed char Ws1 = 4; // whitespace read - const signed char Attdef = 5; // parse the AttDef - const signed char Ws2 = 6; // whitespace read - const signed char Atttype = 7; // parse the AttType - const signed char Ws3 = 8; // whitespace read - const signed char DDecH = 9; // DefaultDecl with # - const signed char DefReq = 10; // parse the string "REQUIRED" - const signed char DefImp = 11; // parse the string "IMPLIED" - const signed char DefFix = 12; // parse the string "FIXED" - const signed char Attval = 13; // parse the AttValue - const signed char Ws4 = 14; // whitespace read - const signed char Done = 15; - - const signed char InpWs = 0; // white space - const signed char InpGt = 1; // > - const signed char InpHash = 2; // # - const signed char InpA = 3; // A - const signed char InpI = 4; // I - const signed char InpF = 5; // F - const signed char InpR = 6; // R - const signed char InpUnknown = 7; - - // use some kind of state machine for parsing - static signed char table[15][8] = { - /* InpWs InpGt InpHash InpA InpI InpF InpR InpUnknown */ - { -1, -1, -1, Attlist, -1, -1, -1, -1 }, // Init - { Ws, -1, -1, -1, -1, -1, -1, -1 }, // Attlist - { -1, -1, -1, Name, Name, Name, Name, Name }, // Ws - { Ws1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Name - { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Ws1 - { Ws2, -1, -1, -1, -1, -1, -1, -1 }, // Attdef - { -1, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype }, // Ws2 - { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // Atttype - { -1, Attval, DDecH, Attval, Attval, Attval, Attval, Attval }, // Ws3 - { -1, -1, -1, -1, DefImp, DefFix, DefReq, -1 }, // DDecH - { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefReq - { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefImp - { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // DefFix - { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // Attval - { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef } // Ws4 - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( c == '>' ) { - input = InpGt; - } else if ( c == '#' ) { - input = InpHash; - } else if ( c == 'A' ) { - input = InpA; - } else if ( c == 'I' ) { - input = InpI; - } else if ( c == 'F' ) { - input = InpF; - } else if ( c == 'R' ) { - input = InpR; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Attlist: - parseOk = parseString( "ATTLIST" ); - break; - case Ws: - case Ws1: - case Ws2: - case Ws3: - eat_ws(); - break; - case Name: - parseOk = parseName(); - break; - case Attdef: - parseOk = parseName(); - break; - case Atttype: - parseOk = parseAttType(); - break; - case DDecH: - next(); - break; - case DefReq: - parseOk = parseString( "REQUIRED" ); - break; - case DefImp: - parseOk = parseString( "IMPLIED" ); - break; - case DefFix: - parseOk = parseString( "FIXED" ); - break; - case Attval: - parseOk = parseAttValue(); - break; - case Ws4: - if ( declHnd ) { - // TODO: not all values are computed yet... - if ( !declHnd->attributeDecl( d->attDeclEName, d->attDeclAName, "", "", "" ) ) { - d->error = declHnd->errorString(); - goto parseError; - } - } - eat_ws(); - break; - case Done: - next(); - break; - } - // no input is read after this - switch ( state ) { - case Attlist: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case Name: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - d->attDeclEName = name(); - break; - case Attdef: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - d->attDeclAName = name(); - break; - case Atttype: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGATTTYPE; - goto parseError; - } - break; - case DefReq: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case DefImp: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case DefFix: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case Attval: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGATTVALUE; - goto parseError; - } - break; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_LETTEREXPECTED; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a AttType [54] -*/ -bool QXmlSimpleReader::parseAttType() -{ - const signed char Init = 0; - const signed char ST = 1; // StringType - const signed char TTI = 2; // TokenizedType starting with 'I' - const signed char TTI2 = 3; // TokenizedType helpstate - const signed char TTI3 = 4; // TokenizedType helpstate - const signed char TTE = 5; // TokenizedType starting with 'E' - const signed char TTEY = 6; // TokenizedType starting with 'ENTITY' - const signed char TTEI = 7; // TokenizedType starting with 'ENTITI' - const signed char N = 8; // N read (TokenizedType or Notation) - const signed char TTNM = 9; // TokenizedType starting with 'NM' - const signed char TTNM2 = 10; // TokenizedType helpstate - const signed char NO = 11; // Notation - const signed char NO2 = 12; // Notation helpstate - const signed char NO3 = 13; // Notation helpstate - const signed char NOName = 14; // Notation, read name - const signed char NO4 = 15; // Notation helpstate - const signed char EN = 16; // Enumeration - const signed char ENNmt = 17; // Enumeration, read Nmtoken - const signed char EN2 = 18; // Enumeration helpstate - const signed char ADone = 19; // almost done (make next and accept) - const signed char Done = 20; - - const signed char InpWs = 0; // whitespace - const signed char InpOp = 1; // ( - const signed char InpCp = 2; // ) - const signed char InpPipe = 3; // | - const signed char InpC = 4; // C - const signed char InpE = 5; // E - const signed char InpI = 6; // I - const signed char InpM = 7; // M - const signed char InpN = 8; // N - const signed char InpO = 9; // O - const signed char InpR = 10; // R - const signed char InpS = 11; // S - const signed char InpY = 12; // Y - const signed char InpUnknown = 13; - - // use some kind of state machine for parsing - static signed char table[19][14] = { - /* InpWs InpOp InpCp InpPipe InpC InpE InpI InpM InpN InpO InpR InpS InpY InpUnknown */ - { -1, EN, -1, -1, ST, TTE, TTI, -1, N, -1, -1, -1, -1, -1 }, // Init - { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // ST - { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI2, Done, Done, Done }, // TTI - { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI3, Done, Done }, // TTI2 - { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTI3 - { -1, -1, -1, -1, -1, -1, TTEI, -1, -1, -1, -1, -1, TTEY, -1 }, // TTE - { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEY - { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEI - { -1, -1, -1, -1, -1, -1, -1, TTNM, -1, NO, -1, -1, -1, -1 }, // N - { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTNM2, Done, Done }, // TTNM - { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTNM2 - { NO2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO - { -1, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO2 - { NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName }, // NO3 - { NO4, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NOName - { -1, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO4 - { -1, -1, ENNmt, -1, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt }, // EN - { EN2, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // ENNmt - { -1, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // EN2 - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( c == '(' ) { - input = InpOp; - } else if ( c == ')' ) { - input = InpCp; - } else if ( c == '|' ) { - input = InpPipe; - } else if ( c == 'C' ) { - input = InpC; - } else if ( c == 'E' ) { - input = InpE; - } else if ( c == 'I' ) { - input = InpI; - } else if ( c == 'M' ) { - input = InpM; - } else if ( c == 'N' ) { - input = InpN; - } else if ( c == 'O' ) { - input = InpO; - } else if ( c == 'R' ) { - input = InpR; - } else if ( c == 'S' ) { - input = InpS; - } else if ( c == 'Y' ) { - input = InpY; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case ST: - parseOk = parseString( "CDATA" ); - break; - case TTI: - parseOk = parseString( "ID" ); - break; - case TTI2: - parseOk = parseString( "REF" ); - break; - case TTI3: - next(); // S - break; - case TTE: - parseOk = parseString( "ENTIT" ); - break; - case TTEY: - next(); // Y - break; - case TTEI: - parseOk = parseString( "IES" ); - break; - case N: - next(); // N - break; - case TTNM: - parseOk = parseString( "MTOKEN" ); - break; - case TTNM2: - next(); // S - break; - case NO: - parseOk = parseString( "OTATION" ); - break; - case NO2: - eat_ws(); - break; - case NO3: - next_eat_ws(); - break; - case NOName: - parseOk = parseName(); - break; - case NO4: - eat_ws(); - break; - case EN: - next_eat_ws(); - break; - case ENNmt: - parseOk = parseNmtoken(); - break; - case EN2: - eat_ws(); - break; - case ADone: - next(); - break; - } - // no input is read after this - switch ( state ) { - case ST: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case TTI: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case TTI2: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case TTE: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case TTEI: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case TTNM: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case NO: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case NOName: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - break; - case ENNmt: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNMTOKEN; - goto parseError; - } - break; - case ADone: - return TRUE; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_LETTEREXPECTED; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a AttValue [10] - - Precondition: the head stands on the beginning " or ' - - If this function was successful, the head stands on the first - character after the closing " or ' and the value of the attribute - is in string(). -*/ -bool QXmlSimpleReader::parseAttValue() -{ - bool tmp; - - const signed char Init = 0; - const signed char Dq = 1; // double quotes were read - const signed char DqRef = 2; // read references in double quotes - const signed char DqC = 3; // signed character read in double quotes - const signed char Sq = 4; // single quotes were read - const signed char SqRef = 5; // read references in single quotes - const signed char SqC = 6; // signed character read in single quotes - const signed char Done = 7; - - const signed char InpDq = 0; // " - const signed char InpSq = 1; // ' - const signed char InpAmp = 2; // & - const signed char InpLt = 3; // < - const signed char InpUnknown = 4; - - // use some kind of state machine for parsing - static signed char table[7][5] = { - /* InpDq InpSq InpAmp InpLt InpUnknown */ - { Dq, Sq, -1, -1, -1 }, // Init - { Done, DqC, DqRef, -1, DqC }, // Dq - { Done, DqC, DqRef, -1, DqC }, // DqRef - { Done, DqC, DqRef, -1, DqC }, // DqC - { SqC, Done, SqRef, -1, SqC }, // Sq - { SqC, Done, SqRef, -1, SqC }, // SqRef - { SqC, Done, SqRef, -1, SqC } // SqRef - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( c == '"' ) { - input = InpDq; - } else if ( c == '\'' ) { - input = InpSq; - } else if ( c == '&' ) { - input = InpAmp; - } else if ( c == '<' ) { - input = InpLt; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Dq: - case Sq: - stringClear(); - next(); - break; - case DqRef: - case SqRef: - parseOk = parseReference( tmp, InAttributeValue ); - break; - case DqC: - case SqC: - stringAddC(); - next(); - break; - case Done: - next(); - break; - } - // no input is read after this - switch ( state ) { - case DqRef: - case SqRef: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGREFERENCE; - goto parseError; - } - break; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a elementdecl [45]. - - Precondition: the beginning '<!E' is already read and the head - stands on the 'L' of '<!ELEMENT' -*/ -bool QXmlSimpleReader::parseElementDecl() -{ - const signed char Init = 0; - const signed char Elem = 1; // parse the beginning string - const signed char Ws1 = 2; // whitespace required - const signed char Nam = 3; // parse Name - const signed char Ws2 = 4; // whitespace required - const signed char Empty = 5; // read EMPTY - const signed char Any = 6; // read ANY - const signed char Cont = 7; // read contentspec (except ANY or EMPTY) - const signed char Mix = 8; // read Mixed - const signed char Mix2 = 9; // - const signed char Mix3 = 10; // - const signed char MixN1 = 11; // - const signed char MixN2 = 12; // - const signed char MixN3 = 13; // - const signed char MixN4 = 14; // - const signed char Cp = 15; // parse cp - const signed char Cp2 = 16; // - const signed char WsD = 17; // eat whitespace before Done - const signed char Done = 18; - - const signed char InpWs = 0; - const signed char InpGt = 1; // > - const signed char InpPipe = 2; // | - const signed char InpOp = 3; // ( - const signed char InpCp = 4; // ) - const signed char InpHash = 5; // # - const signed char InpQm = 6; // ? - const signed char InpAst = 7; // * - const signed char InpPlus = 8; // + - const signed char InpA = 9; // A - const signed char InpE = 10; // E - const signed char InpL = 11; // L - const signed char InpUnknown = 12; - - // use some kind of state machine for parsing - static signed char table[18][13] = { - /* InpWs InpGt InpPipe InpOp InpCp InpHash InpQm InpAst InpPlus InpA InpE InpL InpUnknown */ - { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, Elem, -1 }, // Init - { Ws1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Elem - { -1, -1, -1, -1, -1, -1, -1, -1, -1, Nam, Nam, Nam, Nam }, // Ws1 - { Ws2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Nam - { -1, -1, -1, Cont, -1, -1, -1, -1, -1, Any, Empty, -1, -1 }, // Ws2 - { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Empty - { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Any - { -1, -1, -1, Cp, Cp, Mix, -1, -1, -1, Cp, Cp, Cp, Cp }, // Cont - { Mix2, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix - { -1, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix2 - { WsD, Done, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // Mix3 - { -1, -1, -1, -1, -1, -1, -1, -1, -1, MixN2, MixN2, MixN2, MixN2 }, // MixN1 - { MixN3, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN2 - { -1, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN3 - { -1, -1, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // MixN4 - { WsD, Done, -1, -1, -1, -1, Cp2, Cp2, Cp2, -1, -1, -1, -1 }, // Cp - { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Cp2 - { -1, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // WsD - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // read input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( c == '>' ) { - input = InpGt; - } else if ( c == '|' ) { - input = InpPipe; - } else if ( c == '(' ) { - input = InpOp; - } else if ( c == ')' ) { - input = InpCp; - } else if ( c == '#' ) { - input = InpHash; - } else if ( c == '?' ) { - input = InpQm; - } else if ( c == '*' ) { - input = InpAst; - } else if ( c == '+' ) { - input = InpPlus; - } else if ( c == 'A' ) { - input = InpA; - } else if ( c == 'E' ) { - input = InpE; - } else if ( c == 'L' ) { - input = InpL; - } else { - input = InpUnknown; - } - // get new state -//qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] ); - state = table[state][input]; - - // in some cases do special actions depending on state - switch ( state ) { - case Elem: - parseOk = parseString( "LEMENT" ); - break; - case Ws1: - eat_ws(); - break; - case Nam: - parseOk = parseName(); - break; - case Ws2: - eat_ws(); - break; - case Empty: - parseOk = parseString( "EMPTY" ); - break; - case Any: - parseOk = parseString( "ANY" ); - break; - case Cont: - next_eat_ws(); - break; - case Mix: - parseOk = parseString( "#PCDATA" ); - break; - case Mix2: - eat_ws(); - break; - case Mix3: - next(); - break; - case MixN1: - next_eat_ws(); - break; - case MixN2: - parseOk = parseName(); - break; - case MixN3: - eat_ws(); - break; - case MixN4: - next(); - break; - case Cp: - parseOk = parseChoiceSeq(); - break; - case Cp2: - next(); - break; - case WsD: - next_eat_ws(); - break; - case Done: - next(); - break; - } - // no input is read after this - switch ( state ) { - case Elem: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case Nam: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - break; - case Empty: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case Any: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case Mix: - if( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case MixN2: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - break; - case Cp: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGCHOICE; - goto parseError; - } - break; - case Done: - return TRUE; - case -1: - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a NotationDecl [82]. - - Precondition: the beginning '<!' is already read and the head - stands on the 'N' of '<!NOTATION' -*/ -bool QXmlSimpleReader::parseNotationDecl() -{ - const signed char Init = 0; - const signed char Not = 1; // read NOTATION - const signed char Ws1 = 2; // eat whitespaces - const signed char Nam = 3; // read Name - const signed char Ws2 = 4; // eat whitespaces - const signed char ExtID = 5; // parse ExternalID - const signed char Ws3 = 6; // eat whitespaces - const signed char Done = 7; - - const signed char InpWs = 0; - const signed char InpGt = 1; // > - const signed char InpN = 2; // N - const signed char InpUnknown = 3; - - // use some kind of state machine for parsing - static signed char table[7][4] = { - /* InpWs InpGt InpN InpUnknown */ - { -1, -1, Not, -1 }, // Init - { Ws1, -1, -1, -1 }, // Not - { -1, -1, Nam, Nam }, // Ws1 - { Ws2, Done, -1, -1 }, // Nam - { -1, Done, ExtID, ExtID }, // Ws2 - { Ws3, Done, -1, -1 }, // ExtID - { -1, Done, -1, -1 } // Ws3 - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( c == '>' ) { - input = InpGt; - } else if ( c == 'N' ) { - input = InpN; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Not: - parseOk = parseString( "NOTATION" ); - break; - case Ws1: - eat_ws(); - break; - case Nam: - parseOk = parseName(); - break; - case Ws2: - eat_ws(); - break; - case ExtID: - parseOk = parseExternalID( TRUE ); - break; - case Ws3: - eat_ws(); - break; - case Done: - next(); - break; - } - // no input is read after this - switch ( state ) { - case Not: - if ( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case Nam: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - break; - case ExtID: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGEXTERNALID; - goto parseError; - } - // call the handler - if ( dtdHnd ) { - if ( !dtdHnd->notationDecl( name(), d->publicId, d->systemId ) ) { - d->error = dtdHnd->errorString(); - goto parseError; - } - } - break; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse choice [49] or seq [50]. - - Precondition: the beginning '('S? is already read and the head - stands on the first non-whitespace character after it. -*/ -bool QXmlSimpleReader::parseChoiceSeq() -{ - const signed char Init = 0; - const signed char Ws1 = 1; // eat whitespace - const signed char CS_ = 2; // choice or set - const signed char Ws2 = 3; // eat whitespace - const signed char More = 4; // more cp to read - const signed char Name = 5; // read name - const signed char Done = 6; // - - const signed char InpWs = 0; // S - const signed char InpOp = 1; // ( - const signed char InpCp = 2; // ) - const signed char InpQm = 3; // ? - const signed char InpAst = 4; // * - const signed char InpPlus = 5; // + - const signed char InpPipe = 6; // | - const signed char InpComm = 7; // , - const signed char InpUnknown = 8; - - // use some kind of state machine for parsing - static signed char table[6][9] = { - /* InpWs InpOp InpCp InpQm InpAst InpPlus InpPipe InpComm InpUnknown */ - { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // Init - { -1, CS_, -1, -1, -1, -1, -1, -1, CS_ }, // Ws1 - { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 }, // CS_ - { -1, -1, Done, -1, -1, -1, More, More, -1 }, // Ws2 - { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // More (same as Init) - { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 } // Name (same as CS_) - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( c == '(' ) { - input = InpOp; - } else if ( c == ')' ) { - input = InpCp; - } else if ( c == '?' ) { - input = InpQm; - } else if ( c == '*' ) { - input = InpAst; - } else if ( c == '+' ) { - input = InpPlus; - } else if ( c == '|' ) { - input = InpPipe; - } else if ( c == ',' ) { - input = InpComm; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Ws1: - next_eat_ws(); - break; - case CS_: - parseOk = parseChoiceSeq(); - break; - case Ws2: - next_eat_ws(); - break; - case More: - next_eat_ws(); - break; - case Name: - parseOk = parseName(); - break; - case Done: - next(); - break; - } - // no input is read after this - switch ( state ) { - case CS_: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGCHOICE; - goto parseError; - } - break; - case Name: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - break; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a EntityDecl [70]. - - Precondition: the beginning '<!E' is already read and the head - stand on the 'N' of '<!ENTITY' -*/ -bool QXmlSimpleReader::parseEntityDecl() -{ - const signed char Init = 0; - const signed char Ent = 1; // parse "ENTITY" - const signed char Ws1 = 2; // white space read - const signed char Name = 3; // parse name - const signed char Ws2 = 4; // white space read - const signed char EValue = 5; // parse entity value - const signed char ExtID = 6; // parse ExternalID - const signed char Ws3 = 7; // white space read - const signed char Ndata = 8; // parse "NDATA" - const signed char Ws4 = 9; // white space read - const signed char NNam = 10; // parse name - const signed char PEDec = 11; // parse PEDecl - const signed char Ws6 = 12; // white space read - const signed char PENam = 13; // parse name - const signed char Ws7 = 14; // white space read - const signed char PEVal = 15; // parse entity value - const signed char PEEID = 16; // parse ExternalID - const signed char WsE = 17; // white space read - const signed char EDDone = 19; // done, but also report an external, unparsed entity decl - const signed char Done = 18; - - const signed char InpWs = 0; // white space - const signed char InpPer = 1; // % - const signed char InpQuot = 2; // " or ' - const signed char InpGt = 3; // > - const signed char InpN = 4; // N - const signed char InpUnknown = 5; - - // use some kind of state machine for parsing - static signed char table[18][6] = { - /* InpWs InpPer InpQuot InpGt InpN InpUnknown */ - { -1, -1, -1, -1, Ent, -1 }, // Init - { Ws1, -1, -1, -1, -1, -1 }, // Ent - { -1, PEDec, -1, -1, Name, Name }, // Ws1 - { Ws2, -1, -1, -1, -1, -1 }, // Name - { -1, -1, EValue, -1, -1, ExtID }, // Ws2 - { WsE, -1, -1, Done, -1, -1 }, // EValue - { Ws3, -1, -1, EDDone,-1, -1 }, // ExtID - { -1, -1, -1, EDDone,Ndata, -1 }, // Ws3 - { Ws4, -1, -1, -1, -1, -1 }, // Ndata - { -1, -1, -1, -1, NNam, NNam }, // Ws4 - { WsE, -1, -1, Done, -1, -1 }, // NNam - { Ws6, -1, -1, -1, -1, -1 }, // PEDec - { -1, -1, -1, -1, PENam, PENam }, // Ws6 - { Ws7, -1, -1, -1, -1, -1 }, // PENam - { -1, -1, PEVal, -1, -1, PEEID }, // Ws7 - { WsE, -1, -1, Done, -1, -1 }, // PEVal - { WsE, -1, -1, Done, -1, -1 }, // PEEID - { -1, -1, -1, Done, -1, -1 } // WsE - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_S(c) ) { - input = InpWs; - } else if ( c == '%' ) { - input = InpPer; - } else if ( c == '"' || c == '\'' ) { - input = InpQuot; - } else if ( c == '>' ) { - input = InpGt; - } else if ( c == 'N' ) { - input = InpN; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Ent: - parseOk = parseString( "NTITY" ); - break; - case Ws1: - eat_ws(); - break; - case Name: - parseOk = parseName(); - break; - case Ws2: - eat_ws(); - break; - case EValue: - parseOk = parseEntityValue(); - break; - case ExtID: - parseOk = parseExternalID(); - break; - case Ws3: - eat_ws(); - break; - case Ndata: - parseOk = parseString( "NDATA" ); - break; - case Ws4: - eat_ws(); - break; - case NNam: - parseOk = parseName( TRUE ); - break; - case PEDec: - next(); - break; - case Ws6: - eat_ws(); - break; - case PENam: - parseOk = parseName(); - break; - case Ws7: - eat_ws(); - break; - case PEVal: - parseOk = parseEntityValue(); - break; - case PEEID: - parseOk = parseExternalID(); - break; - case WsE: - eat_ws(); - break; - case EDDone: - next(); - break; - case Done: - next(); - break; - } - // no input is read after this - switch ( state ) { - case Ent: - if ( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case Name: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - break; - case EValue: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGENTITYVALUE; - goto parseError; - } - if ( !entityExist( name() ) ) { - d->entities.insert( name(), string() ); - if ( declHnd ) { - if ( !declHnd->internalEntityDecl( name(), string() ) ) { - d->error = declHnd->errorString(); - goto parseError; - } - } - } - break; - case ExtID: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGEXTERNALID; - goto parseError; - } - break; - case Ndata: - if ( !parseOk ) { - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - break; - case NNam: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - if ( !entityExist( name() ) ) { - d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, ref() ) ); - if ( dtdHnd ) { - if ( !dtdHnd->unparsedEntityDecl( name(), d->publicId, d->systemId, ref() ) ) { - d->error = declHnd->errorString(); - goto parseError; - } - } - } - break; - case PENam: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - break; - case PEVal: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGENTITYVALUE; - goto parseError; - } - if ( !entityExist( name() ) ) { - d->parameterEntities.insert( name(), string() ); - if ( declHnd ) { - if ( !declHnd->internalEntityDecl( QString("%")+name(), string() ) ) { - d->error = declHnd->errorString(); - goto parseError; - } - } - } - break; - case PEEID: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGEXTERNALID; - goto parseError; - } - if ( !entityExist( name() ) ) { - d->externParameterEntities.insert( name(), QXmlSimpleReaderPrivate::ExternParameterEntity( d->publicId, d->systemId ) ); - if ( declHnd ) { - if ( !declHnd->externalEntityDecl( QString("%")+name(), d->publicId, d->systemId ) ) { - d->error = declHnd->errorString(); - goto parseError; - } - } - } - break; - case EDDone: - if ( !entityExist( name() ) ) { - d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, QString::null ) ); - if ( declHnd ) { - if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) { - d->error = declHnd->errorString(); - goto parseError; - } - } - } - return TRUE; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_LETTEREXPECTED; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a EntityValue [9] -*/ -bool QXmlSimpleReader::parseEntityValue() -{ - bool tmp; - - const signed char Init = 0; - const signed char Dq = 1; // EntityValue is double quoted - const signed char DqC = 2; // signed character - const signed char DqPER = 3; // PEReference - const signed char DqRef = 4; // Reference - const signed char Sq = 5; // EntityValue is double quoted - const signed char SqC = 6; // signed character - const signed char SqPER = 7; // PEReference - const signed char SqRef = 8; // Reference - const signed char Done = 9; - - const signed char InpDq = 0; // " - const signed char InpSq = 1; // ' - const signed char InpAmp = 2; // & - const signed char InpPer = 3; // % - const signed char InpUnknown = 4; - - // use some kind of state machine for parsing - static signed char table[9][5] = { - /* InpDq InpSq InpAmp InpPer InpUnknown */ - { Dq, Sq, -1, -1, -1 }, // Init - { Done, DqC, DqRef, DqPER, DqC }, // Dq - { Done, DqC, DqRef, DqPER, DqC }, // DqC - { Done, DqC, DqRef, DqPER, DqC }, // DqPER - { Done, DqC, DqRef, DqPER, DqC }, // DqRef - { SqC, Done, SqRef, SqPER, SqC }, // Sq - { SqC, Done, SqRef, SqPER, SqC }, // SqC - { SqC, Done, SqRef, SqPER, SqC }, // SqPER - { SqC, Done, SqRef, SqPER, SqC } // SqRef - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( c == '"' ) { - input = InpDq; - } else if ( c == '\'' ) { - input = InpSq; - } else if ( c == '&' ) { - input = InpAmp; - } else if ( c == '%' ) { - input = InpPer; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Dq: - case Sq: - stringClear(); - next(); - break; - case DqC: - case SqC: - stringAddC(); - next(); - break; - case DqPER: - case SqPER: - parseOk = parsePEReference( InEntityValue ); - break; - case DqRef: - case SqRef: - parseOk = parseReference( tmp, InEntityValue ); - break; - case Done: - next(); - break; - } - // no input is read after this - switch ( state ) { - case DqPER: - case SqPER: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGDOCTYPE; - goto parseError; - } - break; - case DqRef: - case SqRef: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGREFERENCE; - goto parseError; - } - break; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_LETTEREXPECTED; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a comment [15]. - - Precondition: the beginning '<!' of the comment is already read and the head - stands on the first '-' of '<!--'. - - If this function was successful, the head-position is on the first - character after the comment. -*/ -bool QXmlSimpleReader::parseComment() -{ - const signed char Init = 0; - const signed char Dash1 = 1; // the first dash was read - const signed char Dash2 = 2; // the second dash was read - const signed char Com = 3; // read comment - const signed char Com2 = 4; // read comment (help state) - const signed char ComE = 5; // finished reading comment - const signed char Done = 6; - - const signed char InpDash = 0; // - - const signed char InpGt = 1; // > - const signed char InpUnknown = 2; - - // use some kind of state machine for parsing - static signed char table[6][3] = { - /* InpDash InpGt InpUnknown */ - { Dash1, -1, -1 }, // Init - { Dash2, -1, -1 }, // Dash1 - { Com2, Com, Com }, // Dash2 - { Com2, Com, Com }, // Com - { ComE, Com, Com }, // Com2 - { -1, Done, -1 } // ComE - }; - signed char state = Init; - signed char input; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( c == '-' ) { - input = InpDash; - } else if ( c == '>' ) { - input = InpGt; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Dash1: - next(); - break; - case Dash2: - next(); - break; - case Com: - stringAddC(); - next(); - break; - case Com2: - next(); - break; - case ComE: - next(); - break; - case Done: - next(); - break; - } - // no input is read after this - switch ( state ) { - case Dash2: - stringClear(); - break; - case Com2: - // if next character is not a dash than don't skip it - if ( c != '-' ) { - stringAddC( '-' ); - } - break; - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_ERRORPARSINGCOMMENT; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a Attribute [41]. - - Precondition: the head stands on the first character of the name of the - attribute (i.e. all whitespaces are already parsed). - - The head stand on the next character after the end quotes. The variable name - contains the name of the attribute and the variable string contains the value - of the attribute. -*/ -bool QXmlSimpleReader::parseAttribute() -{ - const signed char Init = 0; - const signed char PName = 1; // parse name - const signed char Ws = 2; // eat ws - const signed char Eq = 3; // the '=' was read - const signed char Quotes = 4; // " or ' were read - - const signed char InpNameBe = 0; - const signed char InpEq = 1; // = - const signed char InpDq = 2; // " - const signed char InpSq = 3; // ' - const signed char InpUnknown = 4; - - // use some kind of state machine for parsing - static signed char table[4][5] = { - /* InpNameBe InpEq InpDq InpSq InpUnknown */ - { PName, -1, -1, -1, -1 }, // Init - { -1, Eq, -1, -1, Ws }, // PName - { -1, Eq, -1, -1, -1 }, // Ws - { -1, -1, Quotes, Quotes, -1 } // Eq - }; - signed char state = Init; - signed char input; - bool parseOk = TRUE; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_NameBeginning(c) ) { - input = InpNameBe; - } else if ( c == '=' ) { - input = InpEq; - } else if ( c == '"' ) { - input = InpDq; - } else if ( c == '\'' ) { - input = InpSq; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case PName: - parseOk = parseName(); - break; - case Ws: - eat_ws(); - break; - case Eq: - next_eat_ws(); - break; - case Quotes: - parseOk = parseAttValue(); - break; - } - // no input is read after this - switch ( state ) { - case PName: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGNAME; - goto parseError; - } - break; - case Quotes: - if ( !parseOk ) { - d->error = XMLERR_ERRORPARSINGATTVALUE; - goto parseError; - } - // Done - return TRUE; - case -1: - // Error - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a Name [5] and store the name in name or ref (if useRef is TRUE). -*/ -bool QXmlSimpleReader::parseName( bool useRef ) -{ - const signed char Init = 0; - const signed char Name1 = 1; // parse first signed character of the name - const signed char Name = 2; // parse name - const signed char Done = 3; - - const signed char InpNameBe = 0; // name beginning signed characters - const signed char InpNameCh = 1; // NameChar without InpNameBe - const signed char InpUnknown = 2; - - // use some kind of state machine for parsing - static signed char table[3][3] = { - /* InpNameBe InpNameCh InpUnknown */ - { Name1, -1, -1 }, // Init - { Name, Name, Done }, // Name1 - { Name, Name, Done } // Name - }; - signed char state = Init; - signed char input; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_NameBeginning(c) ) { - input = InpNameBe; - } else if ( is_NameChar(c) ) { - input = InpNameCh; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case Name1: - if ( useRef ) { - refClear(); - refAddC(); - } else { - nameClear(); - nameAddC(); - } - next(); - break; - case Name: - if ( useRef ) { - refAddC(); - } else { - nameAddC(); - } - next(); - break; - } - // no input is read after this - switch ( state ) { - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_LETTEREXPECTED; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a Nmtoken [7] and store the name in name. -*/ -bool QXmlSimpleReader::parseNmtoken() -{ - const signed char Init = 0; - const signed char NameF = 1; - const signed char Name = 2; - const signed char Done = 3; - - const signed char InpNameCh = 0; // NameChar without InpNameBe - const signed char InpUnknown = 1; - - // use some kind of state machine for parsing - static signed char table[3][2] = { - /* InpNameCh InpUnknown */ - { NameF, -1 }, // Init - { Name, Done }, // NameF - { Name, Done } // Name - }; - signed char state = Init; - signed char input; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( is_NameChar(c) ) { - input = InpNameCh; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case NameF: - nameClear(); - nameAddC(); - next(); - break; - case Name: - nameAddC(); - next(); - break; - } - // no input is read after this - switch ( state ) { - case Done: - return TRUE; - case -1: - // Error - d->error = XMLERR_LETTEREXPECTED; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Parse a Reference [67]. - - charDataRead is set to TRUE if the reference must not be parsed. The - character(s) which the reference mapped to are appended to string. The - head stands on the first character after the reference. - - charDataRead is set to FALSE if the reference must be parsed. The - character(s) which the reference mapped to are inserted at the reference - position. The head stands on the first character of the replacement). -*/ -bool QXmlSimpleReader::parseReference( bool &charDataRead, EntityRecognitionContext context ) -{ - // temporary variables - uint tmp; - bool ok; - - const signed char Init = 0; - const signed char SRef = 1; // start of a reference - const signed char ChRef = 2; // parse CharRef - const signed char ChDec = 3; // parse CharRef decimal - const signed char ChHexS = 4; // start CharRef hexadecimal - const signed char ChHex = 5; // parse CharRef hexadecimal - const signed char Name = 6; // parse name - const signed char DoneD = 7; // done CharRef decimal - const signed char DoneH = 8; // done CharRef hexadecimal - const signed char DoneN = 9; // done EntityRef - - const signed char InpAmp = 0; // & - const signed char InpSemi = 1; // ; - const signed char InpHash = 2; // # - const signed char InpX = 3; // x - const signed char InpNum = 4; // 0-9 - const signed char InpHex = 5; // a-f A-F - const signed char InpUnknown = 6; - - // use some kind of state machine for parsing - static signed char table[8][7] = { - /* InpAmp InpSemi InpHash InpX InpNum InpHex InpUnknown */ - { SRef, -1, -1, -1, -1, -1, -1 }, // Init - { -1, -1, ChRef, Name, Name, Name, Name }, // SRef - { -1, -1, -1, ChHexS, ChDec, -1, -1 }, // ChRef - { -1, DoneD, -1, -1, ChDec, -1, -1 }, // ChDec - { -1, -1, -1, -1, ChHex, ChHex, -1 }, // ChHexS - { -1, DoneH, -1, -1, ChHex, ChHex, -1 }, // ChHex - { -1, DoneN, -1, -1, -1, -1, -1 } // Name - }; - signed char state = Init; - signed char input; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( c.row() ) { - input = InpUnknown; - } else if ( c.cell() == '&' ) { - input = InpAmp; - } else if ( c.cell() == ';' ) { - input = InpSemi; - } else if ( c.cell() == '#' ) { - input = InpHash; - } else if ( c.cell() == 'x' ) { - input = InpX; - } else if ( '0' <= c.cell() && c.cell() <= '9' ) { - input = InpNum; - } else if ( 'a' <= c.cell() && c.cell() <= 'f' ) { - input = InpHex; - } else if ( 'A' <= c.cell() && c.cell() <= 'F' ) { - input = InpHex; - } else { - input = InpUnknown; - } - - // set state according to input - state = table[state][input]; - - // do some actions according to state - switch ( state ) { - case SRef: - refClear(); - next(); - break; - case ChRef: - next(); - break; - case ChDec: - refAddC(); - next(); - break; - case ChHexS: - next(); - break; - case ChHex: - refAddC(); - next(); - break; - case Name: - // read the name into the ref - parseName( TRUE ); - break; - case DoneD: - tmp = ref().toUInt( &ok, 10 ); - if ( ok ) { - stringAddC( QChar(tmp) ); - } else { - d->error = XMLERR_ERRORPARSINGREFERENCE; - goto parseError; - } - charDataRead = TRUE; - next(); - break; - case DoneH: - tmp = ref().toUInt( &ok, 16 ); - if ( ok ) { - stringAddC( QChar(tmp) ); - } else { - d->error = XMLERR_ERRORPARSINGREFERENCE; - goto parseError; - } - charDataRead = TRUE; - next(); - break; - case DoneN: - if ( !processReference( charDataRead, context ) ) - goto parseError; - next(); - break; - } - // no input is read after this - switch ( state ) { - case DoneD: - return TRUE; - case DoneH: - return TRUE; - case DoneN: - return TRUE; - case -1: - // Error - d->error = XMLERR_ERRORPARSINGREFERENCE; - goto parseError; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - -/*! - Helper function for parseReference() -*/ -bool QXmlSimpleReader::processReference( bool &charDataRead, EntityRecognitionContext context ) -{ - QString reference = ref(); - if ( reference == "amp" ) { - if ( context == InEntityValue ) { - // Bypassed - stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'm' ); stringAddC( 'p' ); stringAddC( ';' ); - } else { - // Included or Included in literal - stringAddC( '&' ); - } - charDataRead = TRUE; - } else if ( reference == "lt" ) { - if ( context == InEntityValue ) { - // Bypassed - stringAddC( '&' ); stringAddC( 'l' ); stringAddC( 't' ); stringAddC( ';' ); - } else { - // Included or Included in literal - stringAddC( '<' ); - } - charDataRead = TRUE; - } else if ( reference == "gt" ) { - if ( context == InEntityValue ) { - // Bypassed - stringAddC( '&' ); stringAddC( 'g' ); stringAddC( 't' ); stringAddC( ';' ); - } else { - // Included or Included in literal - stringAddC( '>' ); - } - charDataRead = TRUE; - } else if ( reference == "apos" ) { - if ( context == InEntityValue ) { - // Bypassed - stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'p' ); stringAddC( 'o' ); stringAddC( 's' ); stringAddC( ';' ); - } else { - // Included or Included in literal - stringAddC( '\'' ); - } - charDataRead = TRUE; - } else if ( reference == "quot" ) { - if ( context == InEntityValue ) { - // Bypassed - stringAddC( '&' ); stringAddC( 'q' ); stringAddC( 'u' ); stringAddC( 'o' ); stringAddC( 't' ); stringAddC( ';' ); - } else { - // Included or Included in literal - stringAddC( '"' ); - } - charDataRead = TRUE; - } else { - QMap<QString,QString>::Iterator it; - it = d->entities.find( reference ); - if ( it != d->entities.end() ) { - // "Internal General" - switch ( context ) { - case InContent: - // Included - xmlRef = it.data() + xmlRef; - charDataRead = FALSE; - break; - case InAttributeValue: - // Included in literal - xmlRef = it.data().replace( QRegExp("\""), """ ).replace( QRegExp("'"), "'" ) - + xmlRef; - charDataRead = FALSE; - break; - case InEntityValue: - { - // Bypassed - stringAddC( '&' ); - for ( int i=0; i<(int)reference.length(); i++ ) { - stringAddC( reference[i] ); - } - stringAddC( ';'); - charDataRead = TRUE; - } - break; - case InDTD: - // Forbidden - d->error = XMLERR_INTERNALGENERALENTITYINDTD; - charDataRead = FALSE; - break; - } - } else { - QMap<QString,QXmlSimpleReaderPrivate::ExternEntity>::Iterator itExtern; - itExtern = d->externEntities.find( reference ); - if ( itExtern == d->externEntities.end() ) { - // entity not declared - // ### check this case for conformance - if ( context == InEntityValue ) { - // Bypassed - stringAddC( '&' ); - for ( int i=0; i<(int)reference.length(); i++ ) { - stringAddC( reference[i] ); - } - stringAddC( ';'); - charDataRead = TRUE; - } else { - if ( contentHnd ) { - if ( !contentHnd->skippedEntity( reference ) ) { - d->error = contentHnd->errorString(); - return FALSE; // error - } - } - } - } else if ( (*itExtern).notation.isNull() ) { - // "External Parsed General" - switch ( context ) { - case InContent: - // Included if validating - if ( contentHnd ) { - if ( !contentHnd->skippedEntity( reference ) ) { - d->error = contentHnd->errorString(); - return FALSE; // error - } - } - charDataRead = FALSE; - break; - case InAttributeValue: - // Forbidden - d->error = XMLERR_EXTERNALGENERALENTITYINAV; - charDataRead = FALSE; - break; - case InEntityValue: - { - // Bypassed - stringAddC( '&' ); - for ( int i=0; i<(int)reference.length(); i++ ) { - stringAddC( reference[i] ); - } - stringAddC( ';'); - charDataRead = TRUE; - } - break; - case InDTD: - // Forbidden - d->error = XMLERR_EXTERNALGENERALENTITYINDTD; - charDataRead = FALSE; - break; - } - } else { - // "Unparsed" - // ### notify for "Occurs as Attribute Value" missing (but this is no reference, anyway) - // Forbidden - d->error = XMLERR_UNPARSEDENTITYREFERENCE; - charDataRead = FALSE; - return FALSE; // error - } - } - } - return TRUE; // no error -} - - -/*! - Parse over a simple string. - - After the string was successfully parsed, the head is on the first - character after the string. -*/ -bool QXmlSimpleReader::parseString( const QString& s ) -{ - signed char Done = s.length(); - - const signed char InpCharExpected = 0; // the character that was expected - const signed char InpUnknown = 1; - - signed char state = 0; // state in this function is the position in the string s - signed char input; - - while ( TRUE ) { - - // get input - if ( atEnd() ) { - d->error = XMLERR_UNEXPECTEDEOF; - goto parseError; - } - if ( c == s[(int)state] ) { - input = InpCharExpected; - } else { - input = InpUnknown; - } - - // set state according to input - if ( input == InpCharExpected ) { - state++; - } else { - // Error - d->error = XMLERR_UNEXPECTEDCHARACTER; - goto parseError; - } - - // do some actions according to state - next(); - // no input is read after this - if ( state == Done ) { - return TRUE; - } - - } - - return TRUE; - -parseError: - reportParseError(); - return FALSE; -} - - -/*! - Inits the data values. -*/ -void QXmlSimpleReader::init( const QXmlInputSource& i ) -{ - xml = i.data(); - xmlLength = xml.length(); - xmlRef = ""; - - d->externParameterEntities.clear(); - d->parameterEntities.clear(); - d->externEntities.clear(); - d->entities.clear(); - - tags.clear(); - - d->doctype = ""; - d->xmlVersion = ""; - d->encoding = ""; - d->standalone = QXmlSimpleReaderPrivate::Unknown; - - lineNr = 0; - columnNr = -1; - pos = 0; - next(); - d->error = XMLERR_OK; -} - -/*! - Returns TRUE if a entity with the name \a e exists, - otherwise returns FALSE. -*/ -bool QXmlSimpleReader::entityExist( const QString& e ) const -{ - if ( d->parameterEntities.find(e) == d->parameterEntities.end() && - d->externParameterEntities.find(e) == d->externParameterEntities.end() ) { - return FALSE; - } else { - return TRUE; - } -} - -void QXmlSimpleReader::reportParseError() -{ - if ( errorHnd ) - errorHnd->fatalError( QXmlParseException( d->error, columnNr+1, lineNr+1 ) ); -} - -#endif //QT_NO_XML diff --git a/qtools/qxml.h b/qtools/qxml.h deleted file mode 100644 index b44e42c..0000000 --- a/qtools/qxml.h +++ /dev/null @@ -1,671 +0,0 @@ -/**************************************************************************** -** -** -** Definition of QXmlSimpleReader and related classes. -** -** Created : 000518 -** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the XML module of the Qt GUI Toolkit. -** -** This file may be distributed under the terms of the Q Public License -** as defined by Trolltech AS of Norway and appearing in the file -** LICENSE.QPL included in the packaging of this file. -** -** This file may be distributed and/or modified under the terms of the -** GNU General Public License version 2 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. -** -** Licensees holding valid Qt Enterprise Edition licenses may use this -** file in accordance with the Qt Commercial License Agreement provided -** with the Software. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for -** information about Qt Commercial License Agreements. -** See http://www.trolltech.com/qpl/ for QPL licensing information. -** See http://www.trolltech.com/gpl/ for GPL licensing information. -** -** Contact info@trolltech.com if any conditions of this licensing are -** not clear to you. -** -**********************************************************************/ - -#ifndef QXML_H -#define QXML_H - -#include <qmodules.h> - -#if !defined(QT_MODULE_XML) -#define QM_EXPORT -#else -#define QM_EXPORT Q_EXPORT -#endif - -#ifndef QT_H -#include <qtextstream.h> -#include <qfile.h> -#include <qstring.h> -#include <qstringlist.h> -#include <qvaluestack.h> -#include <qmap.h> -#endif // QT_H - -#ifndef QT_NO_XML - -class QXmlNamespaceSupport; -class QXmlAttributes; -class QXmlContentHandler; -class QXmlDefaultHandler; -class QXmlDTDHandler; -class QXmlEntityResolver; -class QXmlErrorHandler; -class QXmlLexicalHandler; -class QXmlDeclHandler; -class QXmlInputSource; -class QXmlLocator; -class QXmlNamespaceSupport; -class QXmlParseException; - -class QXmlReader; -class QXmlSimpleReader; - -class QXmlSimpleReaderPrivate; -class QXmlNamespaceSupportPrivate; -class QXmlAttributesPrivate; -class QXmlInputSourcePrivate; -class QXmlParseExceptionPrivate; -class QXmlLocatorPrivate; -class QXmlDefaultHandlerPrivate; - - -// -// SAX Namespace Support -// - -#if defined(Q_TEMPLATEDLL) -// MOC_SKIP_BEGIN -template class QM_EXPORT QMap<QString, QString>; -template class QM_EXPORT QValueStack<QMap<QString, QString> >; -template class QM_EXPORT QValueStack<QString>; -// MOC_SKIP_END -#endif - -class QM_EXPORT QXmlNamespaceSupport -{ -public: - QXmlNamespaceSupport(); - ~QXmlNamespaceSupport(); - - void setPrefix( const QString&, const QString& ); - - QString prefix( const QString& ) const; - QString uri( const QString& ) const; - void splitName( const QString&, QString&, QString& ) const; - void processName( const QString&, bool, QString&, QString& ) const; - QStringList prefixes() const; - QStringList prefixes( const QString& ) const; - - void pushContext(); - void popContext(); - void reset(); -private: - QValueStack<QMap<QString, QString> > nsStack; - QMap<QString, QString> ns; - - //QXmlNamespaceSupportPrivate *d; -}; - - -// -// SAX Attributes -// - -class QM_EXPORT QXmlAttributes -{ -public: - QXmlAttributes() {} - virtual ~QXmlAttributes() {} - - int index( const QString& qName ) const; - int index( const QString& uri, const QString& localPart ) const; - int length() const; - QString localName( int index ) const; - QString qName( int index ) const; - QString uri( int index ) const; - QString type( int index ) const; - QString type( const QString& qName ) const; - QString type( const QString& uri, const QString& localName ) const; - QString value( int index ) const; - QString value( const QString& qName ) const; - QString value( const QString& uri, const QString& localName ) const; - -private: - QStringList qnameList; - QStringList uriList; - QStringList localnameList; - QStringList valueList; - - //QXmlAttributesPrivate *d; - - friend class QXmlSimpleReader; -}; - -// -// SAX Input Source -// - -class QM_EXPORT QXmlInputSource -{ -public: - QXmlInputSource(); - QXmlInputSource( QTextStream& stream ); - QXmlInputSource( QFile& file ); - virtual ~QXmlInputSource(); - - virtual const QString& data() const; - virtual void setData( const QString& d ); - -private: - void readInput( QByteArray& rawData ); - - QString input; - - //QXmlInputSourcePrivate *d; -}; - -// -// SAX Exception Classes -// - -class QM_EXPORT QXmlParseException -{ -public: - QXmlParseException( const QString& name="", int c=-1, int l=-1, const QString& p="", const QString& s="" ) - : msg( name ), column( c ), line( l ), pub( p ), sys( s ) - { } - - int columnNumber() const; - int lineNumber() const; - QString publicId() const; - QString systemId() const; - QString message() const; - -private: - QString msg; - int column; - int line; - QString pub; - QString sys; - - //QXmlParseExceptionPrivate *d; -}; - - -// -// XML Reader -// - -class QM_EXPORT QXmlReader -{ -public: - virtual ~QXmlReader() {} - virtual bool feature( const QString& name, bool *ok = 0 ) const = 0; - virtual void setFeature( const QString& name, bool value ) = 0; - virtual bool hasFeature( const QString& name ) const = 0; - virtual void* property( const QString& name, bool *ok = 0 ) const = 0; - virtual void setProperty( const QString& name, void* value ) = 0; - virtual bool hasProperty( const QString& name ) const = 0; - virtual void setEntityResolver( QXmlEntityResolver* handler ) = 0; - virtual QXmlEntityResolver* entityResolver() const = 0; - virtual void setDTDHandler( QXmlDTDHandler* handler ) = 0; - virtual QXmlDTDHandler* DTDHandler() const = 0; - virtual void setContentHandler( QXmlContentHandler* handler ) = 0; - virtual QXmlContentHandler* contentHandler() const = 0; - virtual void setErrorHandler( QXmlErrorHandler* handler ) = 0; - virtual QXmlErrorHandler* errorHandler() const = 0; - virtual void setLexicalHandler( QXmlLexicalHandler* handler ) = 0; - virtual QXmlLexicalHandler* lexicalHandler() const = 0; - virtual void setDeclHandler( QXmlDeclHandler* handler ) = 0; - virtual QXmlDeclHandler* declHandler() const = 0; - virtual bool parse( const QXmlInputSource& input ) = 0; -}; - -class QM_EXPORT QXmlSimpleReader : public QXmlReader -{ -public: - QXmlSimpleReader(); - virtual ~QXmlSimpleReader(); - - bool feature( const QString& name, bool *ok = 0 ) const; - void setFeature( const QString& name, bool value ); - bool hasFeature( const QString& name ) const; - - void* property( const QString& name, bool *ok = 0 ) const; - void setProperty( const QString& name, void* value ); - bool hasProperty( const QString& name ) const; - - void setEntityResolver( QXmlEntityResolver* handler ); - QXmlEntityResolver* entityResolver() const; - void setDTDHandler( QXmlDTDHandler* handler ); - QXmlDTDHandler* DTDHandler() const; - void setContentHandler( QXmlContentHandler* handler ); - QXmlContentHandler* contentHandler() const; - void setErrorHandler( QXmlErrorHandler* handler ); - QXmlErrorHandler* errorHandler() const; - void setLexicalHandler( QXmlLexicalHandler* handler ); - QXmlLexicalHandler* lexicalHandler() const; - void setDeclHandler( QXmlDeclHandler* handler ); - QXmlDeclHandler* declHandler() const; - - bool parse( const QXmlInputSource& input ); - -private: - // variables - QXmlContentHandler* contentHnd; - QXmlErrorHandler* errorHnd; - QXmlDTDHandler* dtdHnd; - QXmlEntityResolver* entityRes; - QXmlLexicalHandler* lexicalHnd; - QXmlDeclHandler* declHnd; - - QChar c; // the character at reading position - int lineNr; // number of line - int columnNr; // position in line - int pos; // position in string - - int namePos; - QChar nameArray[256]; // only used for names - QString nameValue; // only used for names - int refPos; - QChar refArray[256]; // only used for references - QString refValue; // only used for references - int stringPos; - QChar stringArray[256]; // used for any other strings that are parsed - QString stringValue; // used for any other strings that are parsed - - QString xml; - int xmlLength; - QString xmlRef; // used for parsing of entity references - - QValueStack<QString> tags; - - QXmlSimpleReaderPrivate* d; - - static const QChar QEOF; - - // inlines - virtual bool is_S( const QChar& ); - virtual bool is_Letter( const QChar& ); - virtual bool is_NameBeginning( const QChar& ); - virtual bool is_Digit( const QChar& ); - virtual bool is_CombiningChar( const QChar& ); - virtual bool is_Extender( const QChar& ); - virtual bool is_NameChar( const QChar& ); - - QString& string(); - void stringClear(); - void stringAddC(); - void stringAddC(const QChar&); - QString& name(); - void nameClear(); - void nameAddC(); - void nameAddC(const QChar&); - QString& ref(); - void refClear(); - void refAddC(); - void refAddC(const QChar&); - - // used by parseReference() and parsePEReference() - enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD }; - - // private functions - void eat_ws(); - void next_eat_ws(); - - void next(); - bool atEnd(); - - void init( const QXmlInputSource& i ); - - bool entityExist( const QString& ) const; - - bool parseProlog(); - bool parseElement(); - bool parseElementEmptyTag( bool &t, QString &uri, QString &lname ); - bool parseElementETagBegin2( QString &uri, QString &lname ); - bool parseElementAttribute( QString &prefix, QString &uri, QString &lname ); - bool parseMisc(); - bool parseContent(); - - bool parsePI(bool xmldecl=FALSE); - bool parseDoctype(); - bool parseComment(); - - bool parseName( bool useRef=FALSE ); - bool parseNmtoken(); - bool parseAttribute(); - bool parseReference( bool &charDataRead, EntityRecognitionContext context ); - bool processReference( bool &charDataRead, EntityRecognitionContext context ); - - bool parseExternalID( bool allowPublicID = FALSE ); - bool parsePEReference( EntityRecognitionContext context ); - bool parseMarkupdecl(); - bool parseAttlistDecl(); - bool parseAttType(); - bool parseAttValue(); - bool parseElementDecl(); - bool parseNotationDecl(); - bool parseChoiceSeq(); - bool parseEntityDecl(); - bool parseEntityValue(); - - bool parseString( const QString& s ); - - void reportParseError(); - - friend class QXmlSimpleReaderPrivate; - friend class QXmlLocator; -}; - -// -// SAX Locator -// - -class QM_EXPORT QXmlLocator -{ -public: - QXmlLocator( QXmlSimpleReader* parent ) - { reader = parent; } - ~QXmlLocator() - { } - - int columnNumber(); - int lineNumber(); -// QString getPublicId() -// QString getSystemId() - -private: - QXmlSimpleReader* reader; - - //QXmlLocatorPrivate *d; -}; - -// -// SAX handler classes -// - -class QM_EXPORT QXmlContentHandler -{ -public: - virtual ~QXmlContentHandler() {} - virtual void setDocumentLocator( QXmlLocator* locator ) = 0; - virtual bool startDocument() = 0; - virtual bool endDocument() = 0; - virtual bool startPrefixMapping( const QString& prefix, const QString& uri ) = 0; - virtual bool endPrefixMapping( const QString& prefix ) = 0; - virtual bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts ) = 0; - virtual bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName ) = 0; - virtual bool characters( const QString& ch ) = 0; - virtual bool ignorableWhitespace( const QString& ch ) = 0; - virtual bool processingInstruction( const QString& target, const QString& data ) = 0; - virtual bool skippedEntity( const QString& name ) = 0; - virtual QString errorString() = 0; -}; - -class QM_EXPORT QXmlErrorHandler -{ -public: - virtual ~QXmlErrorHandler() {} - virtual bool warning( const QXmlParseException& exception ) = 0; - virtual bool error( const QXmlParseException& exception ) = 0; - virtual bool fatalError( const QXmlParseException& exception ) = 0; - virtual QString errorString() = 0; -}; - -class QM_EXPORT QXmlDTDHandler -{ -public: - virtual ~QXmlDTDHandler() {} - virtual bool notationDecl( const QString& name, const QString& publicId, const QString& systemId ) = 0; - virtual bool unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName ) = 0; - virtual QString errorString() = 0; -}; - -class QM_EXPORT QXmlEntityResolver -{ -public: - virtual ~QXmlEntityResolver() {} - virtual bool resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* &ret ) = 0; - virtual QString errorString() = 0; -}; - -class QM_EXPORT QXmlLexicalHandler -{ -public: - virtual ~QXmlLexicalHandler() {} - virtual bool startDTD( const QString& name, const QString& publicId, const QString& systemId ) = 0; - virtual bool endDTD() = 0; -// virtual bool startEntity( const QString& name ) = 0; -// virtual bool endEntity( const QString& name ) = 0; - virtual bool startCDATA() = 0; - virtual bool endCDATA() = 0; - virtual bool comment( const QString& ch ) = 0; - virtual QString errorString() = 0; -}; - -class QM_EXPORT QXmlDeclHandler -{ -public: - virtual ~QXmlDeclHandler() {} - virtual bool attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value ) = 0; - virtual bool internalEntityDecl( const QString& name, const QString& value ) = 0; - virtual bool externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId ) = 0; - virtual QString errorString() = 0; -}; - - -class QM_EXPORT QXmlDefaultHandler : public QXmlContentHandler, public QXmlErrorHandler, public QXmlDTDHandler, public QXmlEntityResolver, public QXmlLexicalHandler, public QXmlDeclHandler -{ -public: - QXmlDefaultHandler() { } - virtual ~QXmlDefaultHandler() { } - - void setDocumentLocator( QXmlLocator* locator ); - bool startDocument(); - bool endDocument(); - bool startPrefixMapping( const QString& prefix, const QString& uri ); - bool endPrefixMapping( const QString& prefix ); - bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts ); - bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName ); - bool characters( const QString& ch ); - bool ignorableWhitespace( const QString& ch ); - bool processingInstruction( const QString& target, const QString& data ); - bool skippedEntity( const QString& name ); - - bool warning( const QXmlParseException& exception ); - bool error( const QXmlParseException& exception ); - bool fatalError( const QXmlParseException& exception ); - - bool notationDecl( const QString& name, const QString& publicId, const QString& systemId ); - bool unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName ); - - bool resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* &ret ); - - bool startDTD( const QString& name, const QString& publicId, const QString& systemId ); - bool endDTD(); -// bool startEntity( const QString& name ); -// bool endEntity( const QString& name ); - bool startCDATA(); - bool endCDATA(); - bool comment( const QString& ch ); - - bool attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value ); - bool internalEntityDecl( const QString& name, const QString& value ); - bool externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId ); - - QString errorString(); - -private: - //QXmlDefaultHandlerPrivate *d; -}; - -#ifdef _WS_QWS_ -#ifdef QT_XML_CPP -#define inline -#else -#define QT_NO_XML_INLINE -#endif -#endif - -#ifndef QT_NO_XML_INLINE -// -// inlines -// - -inline bool QXmlSimpleReader::is_S(const QChar& ch) -{ return ch==' ' || ch=='\t' || ch=='\n' || ch=='\r'; } - -inline bool QXmlSimpleReader::is_Letter( const QChar& ch ) -{ return ch.isLetter(); } - -inline bool QXmlSimpleReader::is_NameBeginning( const QChar& ch ) -{ return ch=='_' || ch==':' || ch.isLetter(); } - -inline bool QXmlSimpleReader::is_Digit( const QChar& ch ) -{ return ch.isDigit(); } - -inline bool QXmlSimpleReader::is_CombiningChar( const QChar& ) -{ return FALSE; } - -inline bool QXmlSimpleReader::is_Extender( const QChar& ) -{ return FALSE; } - -inline bool QXmlSimpleReader::is_NameChar( const QChar& ch ) -{ - return ch=='.' || ch=='-' || ch=='_' || ch==':' || - is_Letter(ch) || is_Digit(ch) || - is_CombiningChar(ch) || is_Extender(ch); -} - -inline void QXmlSimpleReader::next() -{ - if ( !xmlRef.isEmpty() ) { - c = xmlRef[0]; - xmlRef.remove( 0, 1 ); - } else { - if ( c=='\n' || c=='\r' ) { - lineNr++; - columnNr = -1; - } - if ( pos >= xmlLength ) { - c = QEOF; - } else { - c = xml[pos]; - columnNr++; - pos++; - } - } -} - -inline bool QXmlSimpleReader::atEnd() -{ return c == QEOF; } - -inline void QXmlSimpleReader::eat_ws() -{ while ( !atEnd() && is_S(c) ) next(); } - -inline void QXmlSimpleReader::next_eat_ws() -{ next(); eat_ws(); } - - -// use buffers instead of QString::operator+= when single characters are read -inline QString& QXmlSimpleReader::string() -{ - stringValue += QString( stringArray, stringPos ); - stringPos = 0; - return stringValue; -} -inline QString& QXmlSimpleReader::name() -{ - nameValue += QString( nameArray, namePos ); - namePos = 0; - return nameValue; -} -inline QString& QXmlSimpleReader::ref() -{ - refValue += QString( refArray, refPos ); - refPos = 0; - return refValue; -} - -inline void QXmlSimpleReader::stringClear() -{ stringValue = ""; stringPos = 0; } -inline void QXmlSimpleReader::nameClear() -{ nameValue = ""; namePos = 0; } -inline void QXmlSimpleReader::refClear() -{ refValue = ""; refPos = 0; } - -inline void QXmlSimpleReader::stringAddC() -{ - if ( stringPos >= 256 ) { - stringValue += QString( stringArray, stringPos ); - stringPos = 0; - } - stringArray[stringPos++] = c; -} -inline void QXmlSimpleReader::nameAddC() -{ - if ( namePos >= 256 ) { - nameValue += QString( nameArray, namePos ); - namePos = 0; - } - nameArray[namePos++] = c; -} -inline void QXmlSimpleReader::refAddC() -{ - if ( refPos >= 256 ) { - refValue += QString( refArray, refPos ); - refPos = 0; - } - refArray[refPos++] = c; -} - -inline void QXmlSimpleReader::stringAddC(const QChar& ch) -{ - if ( stringPos >= 256 ) { - stringValue += QString( stringArray, stringPos ); - stringPos = 0; - } - stringArray[stringPos++] = ch; -} -inline void QXmlSimpleReader::nameAddC(const QChar& ch) -{ - if ( namePos >= 256 ) { - nameValue += QString( nameArray, namePos ); - namePos = 0; - } - nameArray[namePos++] = ch; -} -inline void QXmlSimpleReader::refAddC(const QChar& ch) -{ - if ( refPos >= 256 ) { - refValue += QString( refArray, refPos ); - refPos = 0; - } - refArray[refPos++] = ch; -} -#endif - -#ifdef _WS_QWS_ -#ifdef QT_XML_CPP -#undef inline -#endif -#endif - -#endif //QT_NO_XML - -#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4f4d132..912c67e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -122,6 +122,7 @@ set(LEX_FILES scanner commentcnv commentscan constexp + xml xmlcode sqlcode configimpl) @@ -197,6 +198,7 @@ add_library(doxymain STATIC ${GENERATED_SRC}/scanner.l.h ${GENERATED_SRC}/sqlcode.l.h ${GENERATED_SRC}/vhdlcode.l.h + ${GENERATED_SRC}/xml.l.h ${GENERATED_SRC}/xmlcode.l.h ${GENERATED_SRC}/code.cpp ${GENERATED_SRC}/commentcnv.cpp @@ -212,6 +214,7 @@ add_library(doxymain STATIC ${GENERATED_SRC}/scanner.cpp ${GENERATED_SRC}/sqlcode.cpp ${GENERATED_SRC}/vhdlcode.cpp + ${GENERATED_SRC}/xml.cpp ${GENERATED_SRC}/xmlcode.cpp # ${GENERATED_SRC}/ce_parse.cpp diff --git a/src/layout.cpp b/src/layout.cpp index fd31803..6ebe4b6 100644 --- a/src/layout.cpp +++ b/src/layout.cpp @@ -16,6 +16,10 @@ * */ +#include <assert.h> +#include <qfile.h> +#include <qfileinfo.h> + #include "layout.h" #include "message.h" #include "language.h" @@ -24,38 +28,60 @@ #include "doxygen.h" #include "version.h" #include "config.h" - -#include <assert.h> -#include <qxml.h> -#include <qfile.h> -#include <qstring.h> -#include <qfileinfo.h> -#include <qtextstream.h> +#include "xml.h" static const char layout_default[] = #include "layout_default.xml.h" ; -#define ADD_OPTION(langId,text) "|"+QCString().setNum(langId)+"="+text +inline QCString compileOptions(const QCString &def) +{ + return def; +} -#define COMPILE_FOR_1_OPTION(def,langId1,text1) \ - def+ADD_OPTION(langId1,text1) +inline QCString compileOptions(const QCString &def,SrcLangExt langId1,const QCString &value1) +{ + return compileOptions(def)+"|"+QCString().setNum(langId1)+"="+value1; +} + +inline QCString compileOptions(const QCString &def,SrcLangExt langId1,const QCString &value1, + SrcLangExt langId2,const QCString &value2) +{ + return compileOptions(def,langId1,value1)+ + "|"+QCString().setNum(langId2)+"="+value2; +} -#define COMPILE_FOR_2_OPTIONS(def,langId1,text1,langId2,text2) \ - COMPILE_FOR_1_OPTION(def,langId1,text1)+ADD_OPTION(langId2,text2) +inline QCString compileOptions(const QCString &def,SrcLangExt langId1,const QCString &value1, + SrcLangExt langId2,const QCString &value2, + SrcLangExt langId3,const QCString &value3) +{ + return compileOptions(def,langId1,value1,langId2,value2)+ + "|"+QCString().setNum(langId3)+"="+value3; +} -#define COMPILE_FOR_3_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3) \ - COMPILE_FOR_2_OPTIONS(def,langId1,text1,langId2,text2)+ADD_OPTION(langId3,text3) +inline QCString compileOptions(const QCString &def,SrcLangExt langId1,const QCString &value1, + SrcLangExt langId2,const QCString &value2, + SrcLangExt langId3,const QCString &value3, + SrcLangExt langId4,const QCString &value4) +{ + return compileOptions(def,langId1,value1,langId2,value2,langId3,value3)+ + "|"+QCString().setNum(langId4)+"="+value4; +} -#define COMPILE_FOR_4_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3,langId4,text4) \ - COMPILE_FOR_3_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3)+ADD_OPTION(langId4,text4) +inline QCString compileOptions(const QCString &def,SrcLangExt langId1,const QCString &value1, + SrcLangExt langId2,const QCString &value2, + SrcLangExt langId3,const QCString &value3, + SrcLangExt langId4,const QCString &value4, + SrcLangExt langId5,const QCString &value5) +{ + return compileOptions(def,langId1,value1,langId2,value2,langId3,value3,langId4,value4)+ + "|"+QCString().setNum(langId5)+"="+value5; +} -#define COMPILE_FOR_5_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3,langId4,text4,langId5,text5) \ - COMPILE_FOR_4_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3,langId4,text4)+ADD_OPTION(langId5,text5) -static bool elemIsVisible(const QXmlAttributes &attrib,bool defVal=TRUE) +static bool elemIsVisible(const XMLHandlers::Attributes &attrib,bool defVal=TRUE) { - QCString visible = attrib.value("visible").utf8(); + QCString visible = XMLHandlers::value(attrib,"visible"); if (visible.isEmpty()) return defVal; if (visible.at(0)=='$' && visible.length()>1) { @@ -96,6 +122,8 @@ LayoutNavEntry *LayoutNavEntry::find(LayoutNavEntry::Kind kind, return result; } + + QCString LayoutNavEntry::url() const { QCString url = baseFile().stripWhiteSpace(); @@ -132,762 +160,28 @@ QCString LayoutNavEntry::url() const //--------------------------------------------------------------------------------- -class LayoutParser : public QXmlDefaultHandler +class LayoutParser { - private: - class StartElementHandler - { - typedef void (LayoutParser::*Handler)(const QXmlAttributes &attrib); - public: - StartElementHandler(LayoutParser *parent, Handler h) - : m_parent(parent), m_handler(h) {} - virtual ~StartElementHandler() {} - virtual void operator()(const QXmlAttributes &attrib) - { - (m_parent->*m_handler)(attrib); - } - protected: - StartElementHandler() : m_parent(0), m_handler(0) {} - private: - LayoutParser *m_parent; - Handler m_handler; - }; - - class StartElementHandlerKind : public StartElementHandler - { - typedef void (LayoutParser::*Handler)(LayoutDocEntry::Kind kind, - const QXmlAttributes &attrib); - public: - StartElementHandlerKind(LayoutParser *parent, LayoutDocEntry::Kind k,Handler h) - : m_parent(parent), m_kind(k), m_handler(h) {} - void operator()(const QXmlAttributes &attrib) - { - (m_parent->*m_handler)(m_kind,attrib); - } - private: - LayoutParser *m_parent; - LayoutDocEntry::Kind m_kind; - Handler m_handler; - }; - - class StartElementHandlerSection : public StartElementHandler - { - typedef void (LayoutParser::*Handler)(LayoutDocEntry::Kind kind, - const QXmlAttributes &attrib, - const QCString &title); - public: - StartElementHandlerSection(LayoutParser *parent, LayoutDocEntry::Kind k,Handler h, - const QCString &title) - : m_parent(parent), m_kind(k), m_handler(h), m_title(title) {} - void operator()(const QXmlAttributes &attrib) - { - (m_parent->*m_handler)(m_kind,attrib,m_title); - } - private: - LayoutParser *m_parent; - LayoutDocEntry::Kind m_kind; - Handler m_handler; - QCString m_title; - }; - - class StartElementHandlerMember : public StartElementHandler - { - typedef void (LayoutParser::*Handler)(const QXmlAttributes &attrib, - MemberListType type, - const QCString &title, - const QCString &subtitle); - public: - StartElementHandlerMember(LayoutParser *parent, - Handler h, - MemberListType type, - const QCString &tl, - const QCString &ss = QCString() - ) - : m_parent(parent), m_handler(h), m_type(type), - m_title(tl), m_subscript(ss) {} - void operator()(const QXmlAttributes &attrib) - { - (m_parent->*m_handler)(attrib,m_type,m_title,m_subscript); - } - private: - LayoutParser *m_parent; - Handler m_handler; - MemberListType m_type; - QCString m_title; - QCString m_subscript; - }; - - class StartElementHandlerNavEntry : public StartElementHandler - { - typedef void (LayoutParser::*Handler)(LayoutNavEntry::Kind kind, - const QXmlAttributes &attrib, - const QCString &title); - public: - StartElementHandlerNavEntry(LayoutParser *parent, - LayoutNavEntry::Kind kind, - Handler h, - const QCString &tl - ) - : m_parent(parent), m_kind(kind), m_handler(h), m_title(tl) {} - void operator()(const QXmlAttributes &attrib) - { - (m_parent->*m_handler)(m_kind,attrib,m_title); - } - private: - LayoutParser *m_parent; - LayoutNavEntry::Kind m_kind; - Handler m_handler; - QCString m_title; - }; - - class EndElementHandler - { - typedef void (LayoutParser::*Handler)(); - public: - EndElementHandler(LayoutParser *parent, Handler h) : m_parent(parent), m_handler(h) {} - void operator()() { (m_parent->*m_handler)(); } - private: - LayoutParser *m_parent; - Handler m_handler; - }; - - public: static LayoutParser &instance() { static LayoutParser *theInstance = new LayoutParser; return *theInstance; } - void init() + + // =========== XMLHandler events + void setDocumentLocator(const XMLLocator *locator) { - m_sHandler.setAutoDelete(TRUE); - m_eHandler.setAutoDelete(TRUE); - m_part = -1; // invalid - m_rootNav = 0; - - //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); - //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); - //bool javaOpt = Config_getBool(OPTIMIZE_OUTPUT_JAVA); - bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); - - // start & end handlers - m_sHandler.insert("doxygenlayout", - new StartElementHandler(this,&LayoutParser::startLayout)); - m_eHandler.insert("doxygenlayout", - new EndElementHandler(this,&LayoutParser::endLayout)); - - // class layout handlers - m_sHandler.insert("navindex", - new StartElementHandler(this,&LayoutParser::startNavIndex)); - m_sHandler.insert("navindex/tab", - new StartElementHandler(this,&LayoutParser::startNavEntry)); - m_eHandler.insert("navindex/tab", - new EndElementHandler(this,&LayoutParser::endNavEntry)); - m_eHandler.insert("navindex", - new EndElementHandler(this,&LayoutParser::endNavIndex)); - - // class layout handlers - m_sHandler.insert("class", - new StartElementHandler(this,&LayoutParser::startClass)); - m_sHandler.insert("class/briefdescription", - new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("class/detaileddescription", - new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry, - theTranslator->trDetailedDescription())); - m_sHandler.insert("class/authorsection", - new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("class/includes", - new StartElementHandlerKind(this,LayoutDocEntry::ClassIncludes,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("class/inheritancegraph", - new StartElementHandlerKind(this,LayoutDocEntry::ClassInheritanceGraph,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("class/collaborationgraph", - new StartElementHandlerKind(this,LayoutDocEntry::ClassCollaborationGraph,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("class/allmemberslink", - new StartElementHandlerKind(this,LayoutDocEntry::ClassAllMembersLink,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("class/usedfiles", - new StartElementHandlerKind(this,LayoutDocEntry::ClassUsedFiles,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("class/memberdecl", - new StartElementHandler(this,&LayoutParser::startMemberDecl)); - m_sHandler.insert("class/memberdecl/membergroups", - new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("class/memberdecl/nestedclasses", - new StartElementHandlerSection(this,LayoutDocEntry::ClassNestedClasses,&LayoutParser::startSectionEntry, - COMPILE_FOR_2_OPTIONS( - theTranslator->trCompounds(), - SrcLangExt_VHDL,theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), - SrcLangExt_Fortran,theTranslator->trDataTypes() - ))); - m_sHandler.insert("class/memberdecl/services", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_services,theTranslator->trServices())); - m_sHandler.insert("class/memberdecl/interfaces", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_interfaces,theTranslator->trInterfaces())); - m_sHandler.insert("class/memberdecl/publictypes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pubTypes,theTranslator->trPublicTypes())); - m_sHandler.insert("class/memberdecl/publicslots", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pubSlots,theTranslator->trPublicSlots())); - m_sHandler.insert("class/memberdecl/signals", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_signals,theTranslator->trSignals())); - m_sHandler.insert("class/memberdecl/publicmethods", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pubMethods, - COMPILE_FOR_2_OPTIONS( - theTranslator->trPublicMembers(), - SrcLangExt_ObjC,theTranslator->trInstanceMethods(), - SrcLangExt_Slice,theTranslator->trOperations() - ))); - m_sHandler.insert("class/memberdecl/publicstaticmethods", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pubStaticMethods, - COMPILE_FOR_1_OPTION( - theTranslator->trStaticPublicMembers(), - SrcLangExt_ObjC,theTranslator->trClassMethods() - ))); - m_sHandler.insert("class/memberdecl/publicattributes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pubAttribs, - COMPILE_FOR_1_OPTION( - theTranslator->trPublicAttribs(), - SrcLangExt_Slice,theTranslator->trDataMembers() - ))); - m_sHandler.insert("class/memberdecl/publicstaticattributes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs())); - m_sHandler.insert("class/memberdecl/protectedtypes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_proTypes,theTranslator->trProtectedTypes())); - m_sHandler.insert("class/memberdecl/protectedslots", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_proSlots,theTranslator->trProtectedSlots())); - m_sHandler.insert("class/memberdecl/protectedmethods", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_proMethods,theTranslator->trProtectedMembers())); - m_sHandler.insert("class/memberdecl/protectedstaticmethods", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers())); - m_sHandler.insert("class/memberdecl/protectedattributes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_proAttribs,theTranslator->trProtectedAttribs())); - m_sHandler.insert("class/memberdecl/protectedstaticattributes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs())); - m_sHandler.insert("class/memberdecl/packagetypes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pacTypes,theTranslator->trPackageTypes())); - m_sHandler.insert("class/memberdecl/packagemethods", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pacMethods,theTranslator->trPackageMembers())); - m_sHandler.insert("class/memberdecl/packagestaticmethods", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers())); - m_sHandler.insert("class/memberdecl/packageattributes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pacAttribs,theTranslator->trPackageAttribs())); - m_sHandler.insert("class/memberdecl/packagestaticattributes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs())); - m_sHandler.insert("class/memberdecl/properties", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_properties,theTranslator->trProperties())); - m_sHandler.insert("class/memberdecl/events", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_events,theTranslator->trEvents())); - m_sHandler.insert("class/memberdecl/privatetypes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_priTypes,theTranslator->trPrivateTypes())); - m_sHandler.insert("class/memberdecl/privateslots", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_priSlots,theTranslator->trPrivateSlots())); - m_sHandler.insert("class/memberdecl/privatemethods", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_priMethods,theTranslator->trPrivateMembers())); - m_sHandler.insert("class/memberdecl/privatestaticmethods", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers())); - m_sHandler.insert("class/memberdecl/privateattributes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_priAttribs,theTranslator->trPrivateAttribs())); - m_sHandler.insert("class/memberdecl/privatestaticattributes", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs())); - m_sHandler.insert("class/memberdecl/friends", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_friends,theTranslator->trFriends())); - m_sHandler.insert("class/memberdecl/related", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_related,theTranslator->trRelatedFunctions(), - theTranslator->trRelatedSubscript())); - m_eHandler.insert("class/memberdecl", - new EndElementHandler(this,&LayoutParser::endMemberDecl)); - m_sHandler.insert("class/memberdef", - new StartElementHandler(this,&LayoutParser::startMemberDef)); - m_sHandler.insert("class/memberdef/inlineclasses", - new StartElementHandlerSection(this,LayoutDocEntry::ClassInlineClasses,&LayoutParser::startSectionEntry, - COMPILE_FOR_1_OPTION( - theTranslator->trClassDocumentation(), - SrcLangExt_Fortran,theTranslator->trTypeDocumentation() - ))); - m_sHandler.insert("class/memberdef/typedefs", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation())); - m_sHandler.insert("class/memberdef/enums", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_enumMembers,theTranslator->trMemberEnumerationDocumentation())); - m_sHandler.insert("class/memberdef/services", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_serviceMembers,theTranslator->trInterfaces())); - m_sHandler.insert("class/memberdef/interfaces", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_interfaceMembers,theTranslator->trInterfaces())); - m_sHandler.insert("class/memberdef/constructors", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_constructors,theTranslator->trConstructorDocumentation())); - m_sHandler.insert("class/memberdef/functions", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_functionMembers, - COMPILE_FOR_3_OPTIONS( - theTranslator->trMemberFunctionDocumentation(), - SrcLangExt_ObjC,theTranslator->trMethodDocumentation(), - SrcLangExt_Fortran,theTranslator->trMemberFunctionDocumentationFortran(), - SrcLangExt_Slice,theTranslator->trOperationDocumentation() - ))); - m_sHandler.insert("class/memberdef/related", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_relatedMembers,theTranslator->trRelatedFunctionDocumentation())); - m_sHandler.insert("class/memberdef/variables", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_variableMembers, - COMPILE_FOR_1_OPTION( - theTranslator->trMemberDataDocumentation(), - SrcLangExt_Slice,theTranslator->trDataMemberDocumentation() - ))); - m_sHandler.insert("class/memberdef/properties", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_propertyMembers,theTranslator->trPropertyDocumentation())); - m_sHandler.insert("class/memberdef/events", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_eventMembers,theTranslator->trEventDocumentation())); - m_eHandler.insert("class/memberdef", - new EndElementHandler(this,&LayoutParser::endMemberDef)); - m_eHandler.insert("class", - new EndElementHandler(this,&LayoutParser::endClass)); - - - // namespace layout handlers - m_sHandler.insert("namespace", - new StartElementHandler(this,&LayoutParser::startNamespace)); - m_sHandler.insert("namespace/briefdescription", - new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("namespace/detaileddescription", - new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry, - theTranslator->trDetailedDescription())); - m_sHandler.insert("namespace/authorsection", - new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("namespace/memberdecl", - new StartElementHandler(this,&LayoutParser::startMemberDecl)); - m_sHandler.insert("namespace/memberdecl/nestednamespaces", - new StartElementHandlerSection(this,LayoutDocEntry::NamespaceNestedNamespaces,&LayoutParser::startSectionEntry, - COMPILE_FOR_5_OPTIONS( - theTranslator->trNamespaces(), - SrcLangExt_Java,theTranslator->trPackages(), - SrcLangExt_VHDL,theTranslator->trPackages(), - SrcLangExt_IDL,theTranslator->trModules(), - SrcLangExt_Fortran,theTranslator->trModules(), - SrcLangExt_Slice,(sliceOpt ? - theTranslator->trModules() : - theTranslator->trNamespaces())))); - m_sHandler.insert("namespace/memberdecl/constantgroups", - new StartElementHandlerSection(this,LayoutDocEntry::NamespaceNestedConstantGroups,&LayoutParser::startSectionEntry, - theTranslator->trConstantGroups())); - m_sHandler.insert("namespace/memberdecl/interfaces", - new StartElementHandlerSection(this,LayoutDocEntry::NamespaceInterfaces,&LayoutParser::startSectionEntry, - theTranslator->trSliceInterfaces())); - m_sHandler.insert("namespace/memberdecl/classes", - new StartElementHandlerSection(this,LayoutDocEntry::NamespaceClasses,&LayoutParser::startSectionEntry, - COMPILE_FOR_2_OPTIONS( - theTranslator->trCompounds(), - SrcLangExt_VHDL,theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), - SrcLangExt_Fortran,theTranslator->trDataTypes() - ))); - m_sHandler.insert("namespace/memberdecl/structs", - new StartElementHandlerSection(this,LayoutDocEntry::NamespaceStructs,&LayoutParser::startSectionEntry, - theTranslator->trStructs())); - m_sHandler.insert("namespace/memberdecl/exceptions", - new StartElementHandlerSection(this,LayoutDocEntry::NamespaceExceptions,&LayoutParser::startSectionEntry, - theTranslator->trExceptions())); - m_sHandler.insert("namespace/memberdecl/membergroups", - new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("namespace/memberdecl/typedefs", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decTypedefMembers,theTranslator->trTypedefs())); - m_sHandler.insert("namespace/memberdecl/sequences", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decSequenceMembers,theTranslator->trSequences())); - m_sHandler.insert("namespace/memberdecl/dictionaries", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decDictionaryMembers,theTranslator->trDictionaries())); - m_sHandler.insert("namespace/memberdecl/enums", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decEnumMembers,theTranslator->trEnumerations())); - m_sHandler.insert("namespace/memberdecl/functions", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decFuncMembers, - COMPILE_FOR_2_OPTIONS( - theTranslator->trFunctions(), - SrcLangExt_Fortran,theTranslator->trSubprograms(), - SrcLangExt_VHDL,theTranslator->trFunctionAndProc() - ))); - m_sHandler.insert("namespace/memberdecl/variables", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decVarMembers, - sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables())); - m_eHandler.insert("namespace/memberdecl", - new EndElementHandler(this,&LayoutParser::endMemberDecl)); - m_sHandler.insert("namespace/memberdef", - new StartElementHandler(this,&LayoutParser::startMemberDef)); - m_sHandler.insert("namespace/memberdef/inlineclasses", - new StartElementHandlerSection(this,LayoutDocEntry::NamespaceInlineClasses,&LayoutParser::startSectionEntry, - COMPILE_FOR_1_OPTION( - theTranslator->trClassDocumentation(), - SrcLangExt_Fortran,theTranslator->trTypeDocumentation() - ))); - m_sHandler.insert("namespace/memberdef/typedefs", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation())); - m_sHandler.insert("namespace/memberdef/sequences", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation())); - m_sHandler.insert("namespace/memberdef/dictionaries", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docDictionaryMembers, - theTranslator->trDictionaryDocumentation())); - m_sHandler.insert("namespace/memberdef/enums", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation())); - m_sHandler.insert("namespace/memberdef/functions", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docFuncMembers, - COMPILE_FOR_1_OPTION( - theTranslator->trFunctionDocumentation(), - SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation() - ))); - m_sHandler.insert("namespace/memberdef/variables", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docVarMembers, - sliceOpt ? theTranslator->trConstantDocumentation() : - theTranslator->trVariableDocumentation())); - m_eHandler.insert("namespace/memberdef", - new EndElementHandler(this,&LayoutParser::endMemberDef)); - m_eHandler.insert("namespace", - new EndElementHandler(this,&LayoutParser::endNamespace)); - - // file layout handlers - m_sHandler.insert("file", - new StartElementHandler(this,&LayoutParser::startFile)); - m_sHandler.insert("file/briefdescription", - new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("file/detaileddescription", - new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry, - theTranslator->trDetailedDescription())); - m_sHandler.insert("file/authorsection", - new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("file/includes", - new StartElementHandlerKind(this,LayoutDocEntry::FileIncludes,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("file/includegraph", - new StartElementHandlerKind(this,LayoutDocEntry::FileIncludeGraph,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("file/includedbygraph", - new StartElementHandlerKind(this,LayoutDocEntry::FileIncludedByGraph,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("file/sourcelink", - new StartElementHandlerKind(this,LayoutDocEntry::FileSourceLink,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("file/memberdecl/membergroups", - new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("file/memberdecl", - new StartElementHandler(this,&LayoutParser::startMemberDecl)); - m_sHandler.insert("file/memberdecl/interfaces", - new StartElementHandlerSection(this,LayoutDocEntry::FileInterfaces,&LayoutParser::startSectionEntry, - theTranslator->trSliceInterfaces())); - m_sHandler.insert("file/memberdecl/classes", - new StartElementHandlerSection(this,LayoutDocEntry::FileClasses,&LayoutParser::startSectionEntry, - COMPILE_FOR_2_OPTIONS( - theTranslator->trCompounds(), - SrcLangExt_VHDL,theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), - SrcLangExt_Fortran,theTranslator->trDataTypes() - ))); - m_sHandler.insert("file/memberdecl/structs", - new StartElementHandlerSection(this,LayoutDocEntry::FileStructs,&LayoutParser::startSectionEntry, - theTranslator->trStructs())); - m_sHandler.insert("file/memberdecl/exceptions", - new StartElementHandlerSection(this,LayoutDocEntry::FileExceptions,&LayoutParser::startSectionEntry, - theTranslator->trExceptions())); - m_sHandler.insert("file/memberdecl/namespaces", - new StartElementHandlerSection(this,LayoutDocEntry::FileNamespaces,&LayoutParser::startSectionEntry, - COMPILE_FOR_4_OPTIONS( - theTranslator->trNamespaces(), - SrcLangExt_Java,theTranslator->trPackages(), - SrcLangExt_IDL,theTranslator->trModules(), - SrcLangExt_Fortran,theTranslator->trModules(), - SrcLangExt_Slice,theTranslator->trModules() - ))); - m_sHandler.insert("file/memberdecl/constantgroups", - new StartElementHandlerSection(this,LayoutDocEntry::FileConstantGroups,&LayoutParser::startSectionEntry, - theTranslator->trConstantGroups())); - m_sHandler.insert("file/memberdecl/defines", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decDefineMembers,theTranslator->trDefines())); - m_sHandler.insert("file/memberdecl/typedefs", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decTypedefMembers,theTranslator->trTypedefs())); - m_sHandler.insert("file/memberdecl/sequences", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decSequenceMembers,theTranslator->trSequences())); - m_sHandler.insert("file/memberdecl/dictionaries", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decDictionaryMembers,theTranslator->trDictionaries())); - m_sHandler.insert("file/memberdecl/enums", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decEnumMembers,theTranslator->trEnumerations())); - m_sHandler.insert("file/memberdecl/functions", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decFuncMembers, - COMPILE_FOR_2_OPTIONS( - theTranslator->trFunctions(), - SrcLangExt_Fortran,theTranslator->trSubprograms(), - SrcLangExt_VHDL,theTranslator->trFunctionAndProc() - ))); - m_sHandler.insert("file/memberdecl/variables", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decVarMembers, - sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables())); - - m_eHandler.insert("file/memberdecl", - new EndElementHandler(this,&LayoutParser::endMemberDecl)); - m_sHandler.insert("file/memberdef", - new StartElementHandler(this,&LayoutParser::startMemberDef)); - m_sHandler.insert("file/memberdef/inlineclasses", - new StartElementHandlerSection(this,LayoutDocEntry::FileInlineClasses,&LayoutParser::startSectionEntry, - COMPILE_FOR_1_OPTION( - theTranslator->trClassDocumentation(), - SrcLangExt_Fortran,theTranslator->trTypeDocumentation() - ))); - m_sHandler.insert("file/memberdef/defines", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docDefineMembers,theTranslator->trDefineDocumentation())); - m_sHandler.insert("file/memberdef/typedefs", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation())); - m_sHandler.insert("file/memberdef/sequences", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation())); - m_sHandler.insert("file/memberdef/dictionaries", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docDictionaryMembers, - theTranslator->trDictionaryDocumentation())); - m_sHandler.insert("file/memberdef/enums", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docEnumMembers, - theTranslator->trEnumerationTypeDocumentation())); - m_sHandler.insert("file/memberdef/functions", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docFuncMembers, - COMPILE_FOR_1_OPTION( - theTranslator->trFunctionDocumentation(), - SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation() - ))); - m_sHandler.insert("file/memberdef/variables", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docVarMembers,theTranslator->trVariableDocumentation())); - m_eHandler.insert("file/memberdef", - new EndElementHandler(this,&LayoutParser::endMemberDef)); - m_eHandler.insert("file", - new EndElementHandler(this,&LayoutParser::endFile)); - - // group layout handlers - m_sHandler.insert("group", - new StartElementHandler(this,&LayoutParser::startGroup)); - m_sHandler.insert("group/briefdescription", - new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("group/detaileddescription", - new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry, - theTranslator->trDetailedDescription())); - m_sHandler.insert("group/authorsection", - new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("group/groupgraph", - new StartElementHandlerKind(this,LayoutDocEntry::GroupGraph,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("group/memberdecl/membergroups", - new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("group/memberdecl", - new StartElementHandler(this,&LayoutParser::startMemberDecl)); - m_sHandler.insert("group/memberdecl/classes", - new StartElementHandlerSection(this,LayoutDocEntry::GroupClasses,&LayoutParser::startSectionEntry, - COMPILE_FOR_2_OPTIONS( - theTranslator->trCompounds(), - SrcLangExt_VHDL,theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), - SrcLangExt_Fortran,theTranslator->trDataTypes() - ))); - m_sHandler.insert("group/memberdecl/namespaces", - new StartElementHandlerSection(this,LayoutDocEntry::GroupNamespaces,&LayoutParser::startSectionEntry, - COMPILE_FOR_2_OPTIONS( - theTranslator->trNamespaces(), - SrcLangExt_Java,theTranslator->trPackages(), - SrcLangExt_Fortran,theTranslator->trModules() - ))); - m_sHandler.insert("group/memberdecl/dirs", - new StartElementHandlerSection(this,LayoutDocEntry::GroupDirs,&LayoutParser::startSectionEntry, - theTranslator->trDirectories() - )); - m_sHandler.insert("group/memberdecl/nestedgroups", - new StartElementHandlerSection(this,LayoutDocEntry::GroupNestedGroups,&LayoutParser::startSectionEntry, - theTranslator->trModules() - )); - m_sHandler.insert("group/memberdecl/files", - new StartElementHandlerSection(this,LayoutDocEntry::GroupFiles,&LayoutParser::startSectionEntry, - theTranslator->trFile(TRUE,FALSE) - )); - - m_sHandler.insert("group/memberdecl/defines", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decDefineMembers,theTranslator->trDefines())); - m_sHandler.insert("group/memberdecl/typedefs", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decTypedefMembers,theTranslator->trTypedefs())); - m_sHandler.insert("group/memberdecl/sequences", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decSequenceMembers,theTranslator->trSequences())); - m_sHandler.insert("group/memberdecl/dictionaries", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decDictionaryMembers,theTranslator->trDictionaries())); - m_sHandler.insert("group/memberdecl/enums", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decEnumMembers,theTranslator->trEnumerations())); - m_sHandler.insert("group/memberdecl/enumvalues", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decEnumValMembers,theTranslator->trEnumerationValues())); - m_sHandler.insert("group/memberdecl/functions", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decFuncMembers, - COMPILE_FOR_2_OPTIONS( - theTranslator->trFunctions(), - SrcLangExt_Fortran,theTranslator->trSubprograms(), - SrcLangExt_VHDL,theTranslator->trFunctionAndProc() - ))); - m_sHandler.insert("group/memberdecl/variables", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decVarMembers,theTranslator->trVariables())); - m_sHandler.insert("group/memberdecl/signals", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decSignalMembers,theTranslator->trSignals())); - m_sHandler.insert("group/memberdecl/publicslots", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decPubSlotMembers,theTranslator->trPublicSlots())); - m_sHandler.insert("group/memberdecl/protectedslots", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decProSlotMembers,theTranslator->trProtectedSlots())); - m_sHandler.insert("group/memberdecl/privateslots", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decPriSlotMembers,theTranslator->trPrivateSlots())); - m_sHandler.insert("group/memberdecl/events", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decEventMembers,theTranslator->trEvents())); - m_sHandler.insert("group/memberdecl/properties", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decPropMembers,theTranslator->trProperties())); - m_sHandler.insert("group/memberdecl/friends", - new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry, - MemberListType_decFriendMembers,theTranslator->trFriends())); - m_eHandler.insert("group/memberdecl", - new EndElementHandler(this,&LayoutParser::endMemberDecl)); - m_sHandler.insert("group/memberdef", - new StartElementHandler(this,&LayoutParser::startMemberDef)); - m_sHandler.insert("group/memberdef/pagedocs", - new StartElementHandlerKind(this,LayoutDocEntry::GroupPageDocs,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("group/memberdef/inlineclasses", - new StartElementHandlerSection(this,LayoutDocEntry::GroupInlineClasses,&LayoutParser::startSectionEntry, - COMPILE_FOR_1_OPTION( - theTranslator->trClassDocumentation(), - SrcLangExt_Fortran,theTranslator->trTypeDocumentation() - ))); - m_sHandler.insert("group/memberdef/defines", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docDefineMembers,theTranslator->trDefineDocumentation())); - m_sHandler.insert("group/memberdef/typedefs", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation())); - m_sHandler.insert("group/memberdef/sequences", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation())); - m_sHandler.insert("group/memberdef/dictionaries", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docDictionaryMembers, - theTranslator->trDictionaryDocumentation())); - m_sHandler.insert("group/memberdef/enums", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation())); - m_sHandler.insert("group/memberdef/enumvalues", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docEnumValMembers,theTranslator->trEnumerationValueDocumentation())); - m_sHandler.insert("group/memberdef/functions", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docFuncMembers, - COMPILE_FOR_1_OPTION( - theTranslator->trFunctionDocumentation(), - SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation() - ))); - m_sHandler.insert("group/memberdef/variables", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docVarMembers,theTranslator->trVariableDocumentation())); - m_sHandler.insert("group/memberdef/signals", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docSignalMembers,theTranslator->trSignals())); - m_sHandler.insert("group/memberdef/publicslots", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docPubSlotMembers,theTranslator->trPublicSlots())); - m_sHandler.insert("group/memberdef/protectedslots", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docProSlotMembers,theTranslator->trProtectedSlots())); - m_sHandler.insert("group/memberdef/privateslots", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docPriSlotMembers,theTranslator->trPrivateSlots())); - m_sHandler.insert("group/memberdef/events", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docEventMembers,theTranslator->trEvents())); - m_sHandler.insert("group/memberdef/properties", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docPropMembers,theTranslator->trProperties())); - m_sHandler.insert("group/memberdef/friends", - new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry, - MemberListType_docFriendMembers,theTranslator->trFriends())); - m_eHandler.insert("group/memberdef", - new EndElementHandler(this,&LayoutParser::endMemberDef)); - m_eHandler.insert("group", - new EndElementHandler(this,&LayoutParser::endGroup)); - - // directory layout handlers - m_sHandler.insert("directory", - new StartElementHandler(this,&LayoutParser::startDirectory)); - m_sHandler.insert("directory/briefdescription", - new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("directory/detaileddescription", - new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry, - theTranslator->trDetailedDescription())); - m_sHandler.insert("directory/directorygraph", - new StartElementHandlerKind(this,LayoutDocEntry::DirGraph,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("directory/memberdecl", - new StartElementHandler(this,&LayoutParser::startMemberDecl)); - m_sHandler.insert("directory/memberdecl/dirs", - new StartElementHandlerKind(this,LayoutDocEntry::DirSubDirs,&LayoutParser::startSimpleEntry)); - m_sHandler.insert("directory/memberdecl/files", - new StartElementHandlerKind(this,LayoutDocEntry::DirFiles,&LayoutParser::startSimpleEntry)); - m_eHandler.insert("directory/memberdecl", - new EndElementHandler(this,&LayoutParser::endMemberDecl)); - m_eHandler.insert("directory", - new EndElementHandler(this,&LayoutParser::endDirectory)); + m_locator = locator; } + void error( const std::string &fileName,int lineNr,const std::string &msg) + { + ::warn(fileName.c_str(),lineNr,"%s",msg.c_str()); + } + void startElement( const std::string &name, const XMLHandlers::Attributes& attrib ); + void endElement( const std::string &name ); - void startSimpleEntry(LayoutDocEntry::Kind k,const QXmlAttributes &attrib) + void startSimpleEntry(LayoutDocEntry::Kind k,const XMLHandlers::Attributes &attrib) { bool isVisible = elemIsVisible(attrib); if (m_part!=-1 && isVisible) @@ -897,11 +191,13 @@ class LayoutParser : public QXmlDefaultHandler } } - void startSectionEntry(LayoutDocEntry::Kind k,const QXmlAttributes &attrib, + // ============ Specific callbacks + + void startSectionEntry(LayoutDocEntry::Kind k,const XMLHandlers::Attributes &attrib, const QCString &title) { bool isVisible = elemIsVisible(attrib); - QCString userTitle = attrib.value("title").utf8(); + QCString userTitle = XMLHandlers::value(attrib,"title"); //printf("startSectionEntry: title='%s' userTitle='%s'\n", // title.data(),userTitle.data()); if (userTitle.isEmpty()) userTitle = title; @@ -913,13 +209,13 @@ class LayoutParser : public QXmlDefaultHandler } - void startMemberDeclEntry(const QXmlAttributes &attrib,MemberListType type, + void startMemberDeclEntry(const XMLHandlers::Attributes &attrib,MemberListType type, const QCString &title,const QCString &subscript) { - //QCString visible = convertToQCString(attrib.value("visible")); + //QCString visible = convertToQCString(XMLHandlers::value(attrib,"visible")); //bool isVisible = visible.isEmpty() || (visible!="no" && visible!="0"); - QCString userTitle = attrib.value("title").utf8(); - QCString userSubscript = attrib.value("subtitle").utf8(); + QCString userTitle = XMLHandlers::value(attrib,"title"); + QCString userSubscript = XMLHandlers::value(attrib,"subtitle"); if (userTitle.isEmpty()) userTitle = title; if (userSubscript.isEmpty()) userSubscript = subscript; //printf("memberdecl: %s\n",userTitle.data()); @@ -930,10 +226,10 @@ class LayoutParser : public QXmlDefaultHandler } } - void startMemberDefEntry(const QXmlAttributes &attrib,MemberListType type, + void startMemberDefEntry(const XMLHandlers::Attributes &attrib,MemberListType type, const QCString &title,const QCString &) { - QCString userTitle = attrib.value("title").utf8(); + QCString userTitle = XMLHandlers::value(attrib,"title"); if (userTitle.isEmpty()) userTitle = title; //printf("memberdef: %s\n",userTitle.data()); if (m_part!=-1 /*&& isVisible*/) @@ -943,15 +239,11 @@ class LayoutParser : public QXmlDefaultHandler } } - void startLayout(const QXmlAttributes &) + void startLayout(const XMLHandlers::Attributes &) { } - void endLayout() - { - } - - void startNavIndex(const QXmlAttributes &) + void startNavIndex(const XMLHandlers::Attributes &) { m_scope="navindex/"; m_rootNav = LayoutDocManager::instance().rootNavEntry(); @@ -970,7 +262,7 @@ class LayoutParser : public QXmlDefaultHandler } } - void startNavEntry(const QXmlAttributes &attrib) + void startNavEntry(const XMLHandlers::Attributes &attrib) { static bool javaOpt = Config_getBool(OPTIMIZE_OUTPUT_JAVA); static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); @@ -1203,7 +495,7 @@ class LayoutParser : public QXmlDefaultHandler LayoutNavEntry::Kind kind; // find type in the table int i=0; - QString type = attrib.value("type"); + QCString type = XMLHandlers::value(attrib,"type"); while (mapping[i].typeStr) { if (mapping[i].typeStr==type) @@ -1215,19 +507,20 @@ class LayoutParser : public QXmlDefaultHandler } if (mapping[i].typeStr==0) { + std::string fileName = m_locator->fileName(); if (type.isEmpty()) { - err("an entry tag within a navindex has no type attribute! Check your layout file!\n"); + ::warn(fileName.c_str(),m_locator->lineNr(),"an entry tag within a navindex has no type attribute! Check your layout file!\n"); } else { - err("the type '%s' is not supported for the entry tag within a navindex! Check your layout file!\n",type.data()); + ::warn(fileName.c_str(),m_locator->lineNr(),"the type '%s' is not supported for the entry tag within a navindex! Check your layout file!\n",type.data()); } m_invalidEntry=TRUE; return; } QCString baseFile = mapping[i].baseFile; - QCString title = attrib.value("title").utf8(); + QCString title = XMLHandlers::value(attrib,"title"); bool isVisible = elemIsVisible(attrib); if (title.isEmpty()) // use default title { @@ -1238,12 +531,12 @@ class LayoutParser : public QXmlDefaultHandler // this is mainly done to get compatible naming with older versions. } } - QCString intro = attrib.value("intro").utf8(); + QCString intro = XMLHandlers::value(attrib,"intro"); if (intro.isEmpty()) // use default intro text { intro = mapping[i].intro; } - QCString url = attrib.value("url").utf8(); + QCString url = XMLHandlers::value(attrib,"url"); if (mapping[i].kind==LayoutNavEntry::User && !url.isEmpty()) { baseFile=url; @@ -1270,7 +563,7 @@ class LayoutParser : public QXmlDefaultHandler m_invalidEntry=FALSE; } - void startClass(const QXmlAttributes &) + void startClass(const XMLHandlers::Attributes &) { LayoutDocManager::instance().clear(LayoutDocManager::Class); m_scope="class/"; @@ -1283,7 +576,7 @@ class LayoutParser : public QXmlDefaultHandler m_part = -1; } - void startNamespace(const QXmlAttributes &) + void startNamespace(const XMLHandlers::Attributes &) { LayoutDocManager::instance().clear(LayoutDocManager::Namespace); m_scope="namespace/"; @@ -1296,7 +589,7 @@ class LayoutParser : public QXmlDefaultHandler m_part = -1; } - void startFile(const QXmlAttributes &) + void startFile(const XMLHandlers::Attributes &) { LayoutDocManager::instance().clear(LayoutDocManager::File); m_scope="file/"; @@ -1309,7 +602,7 @@ class LayoutParser : public QXmlDefaultHandler m_part = -1; } - void startGroup(const QXmlAttributes &) + void startGroup(const XMLHandlers::Attributes &) { LayoutDocManager::instance().clear(LayoutDocManager::Group); m_scope="group/"; @@ -1322,7 +615,7 @@ class LayoutParser : public QXmlDefaultHandler m_part = -1; } - void startDirectory(const QXmlAttributes &) + void startDirectory(const XMLHandlers::Attributes &) { LayoutDocManager::instance().clear(LayoutDocManager::Directory); m_scope="directory/"; @@ -1335,7 +628,7 @@ class LayoutParser : public QXmlDefaultHandler m_part = -1; } - void startMemberDef(const QXmlAttributes &) + void startMemberDef(const XMLHandlers::Attributes &) { m_scope+="memberdef/"; if (m_part!=-1) @@ -1359,7 +652,7 @@ class LayoutParser : public QXmlDefaultHandler } } - void startMemberDecl(const QXmlAttributes &) + void startMemberDecl(const XMLHandlers::Attributes &) { m_scope+="memberdecl/"; if (m_part!=-1) @@ -1383,95 +676,802 @@ class LayoutParser : public QXmlDefaultHandler } } - // reimplemented from QXmlDefaultHandler - bool startElement( const QString&, const QString&, - const QString& name, const QXmlAttributes& attrib ) - { - //printf("startElement [%s]::[%s]\n",m_scope.data(),name.data()); - StartElementHandler *handler = m_sHandler[m_scope+name.utf8()]; - if (handler) - { - (*handler)(attrib); - } - else - { - err("Unexpected start tag '%s' found in scope='%s'!\n", - name.data(),m_scope.data()); - } - return TRUE; - } - bool endElement( const QString&, const QString&, const QString& name ) - { - //printf("endElement [%s]::[%s]\n",m_scope.data(),name.data()); - EndElementHandler *handler; - if (!m_scope.isEmpty() && m_scope.right(name.length()+1)==name.utf8()+"/") - { // element ends current scope - handler = m_eHandler[m_scope.left(m_scope.length()-1)]; - } - else // continue with current scope - { - handler = m_eHandler[m_scope+name.utf8()]; - } - if (handler) - { - (*handler)(); - } - return TRUE; - } - bool startDocument() - { - return TRUE; - } private: - LayoutParser() : m_sHandler(163), m_eHandler(17) { } + LayoutParser() { } ~LayoutParser() { delete m_rootNav; } - QDict<StartElementHandler> m_sHandler; - QDict<EndElementHandler> m_eHandler; QCString m_scope; - int m_part = 0; + int m_part = -1; LayoutNavEntry *m_rootNav = 0; bool m_invalidEntry = false; static int m_userGroupCount; + const XMLLocator *m_locator = nullptr; }; -int LayoutParser::m_userGroupCount=0; - //--------------------------------------------------------------------------------- -class LayoutErrorHandler : public QXmlErrorHandler +struct ElementCallbacks { - public: - LayoutErrorHandler(const char *fn) : fileName(fn) {} - bool warning( const QXmlParseException &exception ) - { - warn_uncond("at line %d column %d of %s: %s\n", - exception.lineNumber(),exception.columnNumber(),fileName.data(), - exception.message().data()); - return FALSE; - } - bool error( const QXmlParseException &exception ) - { - err("at line %d column %d of %s: %s\n", - exception.lineNumber(),exception.columnNumber(),fileName.data(), - exception.message().data()); - return FALSE; - } - bool fatalError( const QXmlParseException &exception ) - { - err("fatal: at line %d column %d of %s: %s\n", - exception.lineNumber(),exception.columnNumber(),fileName.data(), - exception.message().data()); - return FALSE; - } - QString errorString() { return ""; } + using StartCallback = std::function<void(LayoutParser&,const XMLHandlers::Attributes&)>; + using EndCallback = std::function<void(LayoutParser&)>; + + StartCallback startCb; + EndCallback endCb; +}; + +static ElementCallbacks::StartCallback startCb(void (LayoutParser::*fn)(const XMLHandlers::Attributes &)) +{ + return [fn](LayoutParser &parser,const XMLHandlers::Attributes &attr) { (parser.*fn)(attr); }; +} + +static ElementCallbacks::StartCallback startCb(void (LayoutParser::*fn)(LayoutDocEntry::Kind,const XMLHandlers::Attributes &),LayoutDocEntry::Kind kind) +{ + return [fn,kind](LayoutParser &parser,const XMLHandlers::Attributes &attr) { (parser.*fn)(kind,attr); }; +} + +static ElementCallbacks::StartCallback startCb(void (LayoutParser::*fn)(LayoutDocEntry::Kind,const XMLHandlers::Attributes &,const QCString &), + LayoutDocEntry::Kind kind, + std::function<QCString()> title + ) +{ + return [fn,kind,title](LayoutParser &parser,const XMLHandlers::Attributes &attr) { (parser.*fn)(kind,attr,title()); }; +} + +static ElementCallbacks::StartCallback startCb(void (LayoutParser::*fn)(const XMLHandlers::Attributes &,MemberListType,const QCString &,const QCString &), + MemberListType type, + std::function<QCString()> title, + std::function<QCString()> subtitle=[](){ return QCString(); } + ) +{ + return [fn,type,title,subtitle](LayoutParser &parser,const XMLHandlers::Attributes &attr) { (parser.*fn)(attr,type,title(),subtitle()); }; +} + +static ElementCallbacks::EndCallback endCb(void (LayoutParser::*fn)()) +{ + return [fn](LayoutParser &parser) { (parser.*fn)(); }; +} + +static ElementCallbacks::EndCallback endCb() +{ + return [](LayoutParser &){}; +} + +static const std::map< std::string, ElementCallbacks > g_elementHandlers = +{ + // path/name + { "doxygenlayout", { startCb(&LayoutParser::startLayout), + endCb() + } }, + { "navindex", { startCb(&LayoutParser::startNavIndex), + endCb(&LayoutParser::endNavIndex) + } }, + { "navindex/tab", { startCb(&LayoutParser::startNavEntry), + endCb(&LayoutParser::endNavEntry) + } }, + + // class layout handlers + { "class", { startCb(&LayoutParser::startClass), + endCb(&LayoutParser::endClass) + } }, + { "class/briefdescription", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::BriefDesc), + endCb() + } }, + { "class/detaileddescription", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::DetailedDesc, + [](){ return compileOptions(theTranslator->trDetailedDescription()); }), + endCb() + } }, + { "class/authorsection", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::AuthorSection), + endCb() + } }, + { "class/includes", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::ClassIncludes), + endCb() + } }, + { "class/inheritancegraph", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::ClassInheritanceGraph), + endCb() + } }, + { "class/collaborationgraph", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::ClassCollaborationGraph), + endCb() + } }, + { "class/allmemberslink", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::ClassAllMembersLink), + endCb() + } }, + { "class/usedfiles", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::ClassUsedFiles), + endCb() + } }, + { "class/memberdecl", { startCb(&LayoutParser::startMemberDecl), + endCb(&LayoutParser::endMemberDecl) + } }, + { "class/memberdecl/membergroups", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::MemberGroups), + endCb() + } }, + { "class/memberdecl/nestedclasses", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::ClassNestedClasses, + []() { return compileOptions(/*default*/ theTranslator->trCompounds(), + SrcLangExt_VHDL, theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), + SrcLangExt_Fortran,theTranslator->trDataTypes()); }), + endCb() + } }, + { "class/memberdecl/services", { startCb(&LayoutParser::startMemberDeclEntry,MemberListType_services, + []() { return compileOptions(theTranslator->trServices()); }), + endCb() + } }, + { "class/memberdecl/interfaces", { startCb(&LayoutParser::startMemberDeclEntry,MemberListType_interfaces, + []() { return compileOptions(theTranslator->trInterfaces()); }), + endCb() + } }, + { "class/memberdecl/publictypes", { startCb(&LayoutParser::startMemberDeclEntry,MemberListType_pubTypes, + []() { return compileOptions(theTranslator->trPublicTypes()); }), + endCb() + } }, + { "class/memberdecl/publicslots", { startCb(&LayoutParser::startMemberDeclEntry,MemberListType_pubSlots, + []() { return compileOptions(theTranslator->trPublicSlots()); }), + endCb() + } }, + { "class/memberdecl/signals", { startCb(&LayoutParser::startMemberDeclEntry,MemberListType_signals, + []() { return compileOptions(theTranslator->trSignals()); }), + endCb() + } }, + { "class/memberdecl/publicmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pubMethods, + []() { return compileOptions(/* default */ theTranslator->trPublicMembers(), + SrcLangExt_ObjC, theTranslator->trInstanceMethods(), + SrcLangExt_Slice,theTranslator->trOperations()); }), + endCb() + } }, + { "class/memberdecl/publicstaticmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pubStaticMethods, + []() { return compileOptions(/* default */ theTranslator->trStaticPublicMembers(), + SrcLangExt_ObjC, theTranslator->trClassMethods()); }), + endCb() + } }, + { "class/memberdecl/publicattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pubAttribs, + []() { return compileOptions(/* default */ theTranslator->trPublicAttribs(), + SrcLangExt_Slice,theTranslator->trDataMembers()); }), + endCb() + } }, + { "class/memberdecl/publicstaticattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pubStaticAttribs, + []() { return compileOptions(theTranslator->trStaticPublicAttribs()); }), + endCb() + } }, + { "class/memberdecl/protectedtypes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_proTypes, + []() { return compileOptions(theTranslator->trProtectedTypes()); }), + endCb() + } }, + { "class/memberdecl/protectedslots", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_proSlots, + []() { return compileOptions(theTranslator->trProtectedSlots()); }), + endCb() + } }, + { "class/memberdecl/protectedmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_proMethods, + []() { return compileOptions(theTranslator->trProtectedMembers()); }), + endCb() + } }, + { "class/memberdecl/protectedstaticmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_proStaticMethods, + []() { return compileOptions(theTranslator->trStaticProtectedMembers()); }), + endCb() + } }, + { "class/memberdecl/protectedattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_proAttribs, + []() { return compileOptions(theTranslator->trProtectedAttribs()); }), + endCb() + } }, + { "class/memberdecl/protectedstaticattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_proStaticAttribs, + []() { return compileOptions(theTranslator->trStaticProtectedAttribs()); }), + endCb() + } }, + { "class/memberdecl/packagetypes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pacTypes, + []() { return compileOptions(theTranslator->trPackageTypes()); }), + endCb() + } }, + { "class/memberdecl/packagemethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pacMethods, + []() { return compileOptions(theTranslator->trPackageMembers()); }), + endCb() + } }, + { "class/memberdecl/packagestaticmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pacStaticMethods, + []() { return compileOptions(theTranslator->trStaticPackageMembers()); }), + endCb() + } }, + { "class/memberdecl/packageattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pacAttribs, + []() { return compileOptions(theTranslator->trPackageAttribs()); }), + endCb() + } }, + { "class/memberdecl/packagestaticattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_pacStaticAttribs, + []() { return compileOptions(theTranslator->trStaticPackageAttribs()); }), + endCb() + } }, + { "class/memberdecl/properties", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_properties, + []() { return compileOptions(theTranslator->trProperties()); }), + endCb() + } }, + { "class/memberdecl/events", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_events, + []() { return compileOptions(theTranslator->trEvents()); }), + endCb() + } }, + { "class/memberdecl/privatetypes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_priTypes, + []() { return compileOptions(theTranslator->trPrivateTypes()); }), + endCb() + } }, + { "class/memberdecl/privateslots", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_priSlots, + []() { return compileOptions(theTranslator->trPrivateSlots()); }), + endCb() + } }, + { "class/memberdecl/privatemethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_priMethods, + []() { return compileOptions(theTranslator->trPrivateMembers()); }), + endCb() + } }, + { "class/memberdecl/privatestaticmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_priStaticMethods, + []() { return compileOptions(theTranslator->trStaticPrivateMembers()); }), + endCb() + } }, + { "class/memberdecl/privateattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_priAttribs, + []() { return compileOptions(theTranslator->trPrivateAttribs()); }), + endCb() + } }, + { "class/memberdecl/privatestaticattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_priStaticAttribs, + []() { return compileOptions(theTranslator->trStaticPrivateAttribs()); }), + endCb() + } }, + { "class/memberdecl/friends", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_friends, + []() { return compileOptions(theTranslator->trFriends()); }), + endCb() + } }, + { "class/memberdecl/related", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_related, + []() { return compileOptions(theTranslator->trRelatedFunctions()); }, + []() { return compileOptions(theTranslator->trRelatedSubscript()); }), + endCb() + } }, + { "class/memberdef", { startCb(&LayoutParser::startMemberDef), + endCb(&LayoutParser::endMemberDef) + } }, + { "class/memberdef/inlineclasses", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::ClassInlineClasses, + []() { return compileOptions(/* default */ theTranslator->trClassDocumentation(), + SrcLangExt_Fortran,theTranslator->trTypeDocumentation()); }), + endCb() + } }, + { "class/memberdef/typedefs", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_typedefMembers, + []() { return compileOptions(theTranslator->trMemberTypedefDocumentation()); }), + endCb() + } }, + { "class/memberdef/enums", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_enumMembers, + []() { return compileOptions(theTranslator->trMemberEnumerationDocumentation()); }), + endCb() + } }, + { "class/memberdef/services", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_serviceMembers, + []() { return compileOptions(theTranslator->trInterfaces()); }), + endCb() + } }, + { "class/memberdef/interfaces", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_interfaceMembers, + []() { return compileOptions(theTranslator->trInterfaces()); }), + endCb() + } }, + { "class/memberdef/constructors", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_constructors, + []() { return compileOptions(theTranslator->trConstructorDocumentation()); }), + endCb() + } }, + { "class/memberdef/functions", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_functionMembers, + []() { return compileOptions(/* default */ theTranslator->trMemberFunctionDocumentation(), SrcLangExt_ObjC, theTranslator->trMethodDocumentation(), + SrcLangExt_Fortran,theTranslator->trMemberFunctionDocumentationFortran(), + SrcLangExt_Slice, theTranslator->trOperationDocumentation()); }), + endCb() + } }, + { "class/memberdef/related", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_relatedMembers, + []() { return compileOptions(theTranslator->trRelatedFunctionDocumentation()); }), + endCb() + } }, + { "class/memberdef/variables", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_variableMembers, + []() { return compileOptions(/* default */ theTranslator->trMemberDataDocumentation(), + SrcLangExt_Slice, theTranslator->trDataMemberDocumentation()); }), + endCb() + } }, + { "class/memberdef/properties", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_propertyMembers, + []() { return compileOptions(theTranslator->trPropertyDocumentation()); }), + endCb() + } }, + { "class/memberdef/events", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_eventMembers, + []() { return compileOptions(theTranslator->trEventDocumentation()); }), + endCb() + } }, + + // namespace layout handlers + { "namespace", { startCb(&LayoutParser::startNamespace), + endCb(&LayoutParser::endNamespace) + } }, + + { "namespace/briefdescription", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::BriefDesc), + endCb() + } }, + { "namespace/detaileddescription", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::DetailedDesc, + []() { return compileOptions(theTranslator->trDetailedDescription()); }), + endCb() + } }, + { "namespace/authorsection", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::AuthorSection), + endCb() + } }, + { "namespace/memberdecl", { startCb(&LayoutParser::startMemberDecl), + endCb(&LayoutParser::endMemberDecl) + } }, + { "namespace/memberdecl/nestednamespaces", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::NamespaceNestedNamespaces, + []() { return compileOptions(/* default */ theTranslator->trNamespaces(), + SrcLangExt_Java, theTranslator->trPackages(), + SrcLangExt_VHDL, theTranslator->trPackages(), + SrcLangExt_IDL, theTranslator->trModules(), + SrcLangExt_Fortran,theTranslator->trModules(), + SrcLangExt_Slice,(Config_getBool(OPTIMIZE_OUTPUT_SLICE) ? + theTranslator->trModules() : + theTranslator->trNamespaces())); }), + endCb() + } }, + { "namespace/memberdecl/constantgroups", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::NamespaceNestedConstantGroups, + []() { return compileOptions(theTranslator->trConstantGroups()); }), + endCb() + } }, + { "namespace/memberdecl/interfaces", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::NamespaceInterfaces, + []() { return compileOptions(theTranslator->trSliceInterfaces()); }), + endCb() + } }, + { "namespace/memberdecl/classes", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::NamespaceClasses, + []() { return compileOptions(/* default */ theTranslator->trCompounds(), + SrcLangExt_VHDL, theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), + SrcLangExt_Fortran,theTranslator->trDataTypes()); }), + endCb() + } }, + { "namespace/memberdecl/structs", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::NamespaceStructs, + []() { return compileOptions(theTranslator->trStructs()); }), + endCb() + } }, + { "namespace/memberdecl/exceptions", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::NamespaceExceptions, + []() { return compileOptions(theTranslator->trExceptions()); }), + endCb() + } }, + { "namespace/memberdecl/membergroups", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::MemberGroups), + endCb() + } }, + { "namespace/memberdecl/typedefs", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decTypedefMembers, + []() { return compileOptions(theTranslator->trTypedefs()); }), + endCb() + } }, + { "namespace/memberdecl/sequences", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decSequenceMembers, + []() { return compileOptions(theTranslator->trSequences()); }), + endCb() + } }, + { "namespace/memberdecl/dictionaries", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decDictionaryMembers, + []() { return compileOptions(theTranslator->trDictionaries()); }), + endCb() + } }, + { "namespace/memberdecl/enums", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decEnumMembers, + []() { return compileOptions(theTranslator->trEnumerations()); }), + endCb() + } }, + { "namespace/memberdecl/functions", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decFuncMembers, + []() { return compileOptions(/* default */ theTranslator->trFunctions(), + SrcLangExt_Fortran,theTranslator->trSubprograms(), + SrcLangExt_VHDL, theTranslator->trFunctionAndProc()); }), + endCb() + } }, + { "namespace/memberdecl/variables", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decVarMembers, + []() { return compileOptions(Config_getBool(OPTIMIZE_OUTPUT_SLICE) ? + theTranslator->trConstants() : + theTranslator->trVariables()); }), + endCb() + } }, + { "namespace/memberdef", { startCb(&LayoutParser::startMemberDef), + endCb(&LayoutParser::endMemberDef) + } }, + { "namespace/memberdef/inlineclasses", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::NamespaceInlineClasses, + []() { return compileOptions(/* default */ theTranslator->trClassDocumentation(), + SrcLangExt_Fortran,theTranslator->trTypeDocumentation()); }), + endCb() + } }, + { "namespace/memberdef/typedefs", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docTypedefMembers, + []() { return compileOptions(theTranslator->trTypedefDocumentation()); }), + endCb() + } }, + { "namespace/memberdef/sequences", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docSequenceMembers, + []() { return compileOptions(theTranslator->trSequenceDocumentation()); }), + endCb() + } }, + { "namespace/memberdef/dictionaries", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docDictionaryMembers, + []() { return compileOptions(theTranslator->trDictionaryDocumentation()); }), + endCb() + } }, + { "namespace/memberdef/enums", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docEnumMembers, + []() { return compileOptions(theTranslator->trEnumerationTypeDocumentation()); }), + endCb() + } }, + { "namespace/memberdef/functions", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docFuncMembers, + []() { return compileOptions(/* default */ theTranslator->trFunctionDocumentation(), + SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation()); }), + endCb() + } }, + { "namespace/memberdef/variables", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docVarMembers, + []() { return compileOptions(Config_getBool(OPTIMIZE_OUTPUT_SLICE) ? + theTranslator->trConstantDocumentation() : + theTranslator->trVariableDocumentation()); }), + endCb() + } }, + + // file layout handlers + { "file", { startCb(&LayoutParser::startFile), + endCb(&LayoutParser::endFile) + } }, + + { "file/briefdescription", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::BriefDesc), + endCb() + } }, + { "file/detaileddescription", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::DetailedDesc, + []() { return compileOptions(theTranslator->trDetailedDescription()); }), + endCb() + } }, + { "file/authorsection", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::AuthorSection), + endCb() + } }, + { "file/includes", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::FileIncludes), + endCb() + } }, + { "file/includegraph", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::FileIncludeGraph), + endCb() + } }, + { "file/includedbygraph", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::FileIncludedByGraph), + endCb() + } }, + { "file/sourcelink", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::FileSourceLink), + endCb() + } }, + { "file/memberdecl/membergroups", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::MemberGroups), + endCb() + } }, + { "file/memberdecl", { startCb(&LayoutParser::startMemberDecl), + endCb(&LayoutParser::endMemberDecl) + } }, + + { "file/memberdecl/interfaces", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileInterfaces, + []() { return compileOptions(theTranslator->trSliceInterfaces()); }), + endCb() + } }, + { "file/memberdecl/classes", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileClasses, + []() { return compileOptions(/* default */ theTranslator->trCompounds(), + SrcLangExt_VHDL, theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), + SrcLangExt_Fortran,theTranslator->trDataTypes()); }), + endCb() + } }, + { "file/memberdecl/structs", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileStructs, + []() { return compileOptions(theTranslator->trStructs()); }), + endCb() + } }, + { "file/memberdecl/exceptions", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileExceptions, + []() { return compileOptions(theTranslator->trExceptions()); }), + endCb() + } }, + { "file/memberdecl/namespaces", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileNamespaces, + []() { return compileOptions(/* default */ theTranslator->trNamespaces(), + SrcLangExt_Java, theTranslator->trPackages(), + SrcLangExt_IDL, theTranslator->trModules(), + SrcLangExt_Fortran,theTranslator->trModules(), + SrcLangExt_Slice, theTranslator->trModules()); }), + endCb() + } }, + { "file/memberdecl/constantgroups", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileConstantGroups, + []() { return compileOptions(theTranslator->trConstantGroups()); }), + endCb() + } }, + { "file/memberdecl/defines", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decDefineMembers, + []() { return compileOptions(theTranslator->trDefines()); }), + endCb() + } }, + { "file/memberdecl/typedefs", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decTypedefMembers, + []() { return compileOptions(theTranslator->trTypedefs()); }), + endCb() + } }, + { "file/memberdecl/sequences", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decSequenceMembers, + []() { return compileOptions(theTranslator->trSequences()); }), + endCb() + } }, + { "file/memberdecl/dictionaries", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decDictionaryMembers, + []() { return compileOptions(theTranslator->trDictionaries()); }), + endCb() + } }, + { "file/memberdecl/enums", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decEnumMembers, + []() { return compileOptions(theTranslator->trEnumerations()); }), + endCb() + } }, + { "file/memberdecl/functions", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decFuncMembers, + []() { return compileOptions(/* default */ theTranslator->trFunctions(), + SrcLangExt_Fortran,theTranslator->trSubprograms(), + SrcLangExt_VHDL, theTranslator->trFunctionAndProc()); }), + endCb() + } }, + { "file/memberdecl/variables", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decVarMembers, + []() { return compileOptions(Config_getBool(OPTIMIZE_OUTPUT_SLICE) ? + theTranslator->trConstants() : + theTranslator->trVariables()); }), + endCb() + } }, + { "file/memberdef", { startCb(&LayoutParser::startMemberDef), + endCb(&LayoutParser::endMemberDef) + } }, + + { "file/memberdef/inlineclasses", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileInlineClasses, + []() { return compileOptions(/* default */ theTranslator->trClassDocumentation(), + SrcLangExt_Fortran, theTranslator->trTypeDocumentation()); }), + endCb() + } }, + { "file/memberdef/defines", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docDefineMembers, + []() { return compileOptions(theTranslator->trDefineDocumentation()); }), + endCb() + } }, + { "file/memberdef/typedefs", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docTypedefMembers, + []() { return compileOptions(theTranslator->trTypedefDocumentation()); }), + endCb() + } }, + { "file/memberdef/sequences", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docSequenceMembers, + []() { return compileOptions(theTranslator->trSequenceDocumentation()); }), + endCb() + } }, + { "file/memberdef/dictionaries", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docDictionaryMembers, + []() { return compileOptions(theTranslator->trDictionaryDocumentation()); }), + endCb() + } }, + { "file/memberdef/enums", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docEnumMembers, + []() { return compileOptions(theTranslator->trEnumerationTypeDocumentation()); }), + endCb() + } }, + { "file/memberdef/functions", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docFuncMembers, + []() { return compileOptions(/* default */ theTranslator->trFunctionDocumentation(), + SrcLangExt_Fortran, theTranslator->trSubprogramDocumentation()); }), + endCb() + } }, + { "file/memberdef/variables", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docVarMembers, + []() { return compileOptions(theTranslator->trVariableDocumentation()); }), + endCb() + } }, + + // group layout handlers + { "group", { startCb(&LayoutParser::startGroup), + endCb(&LayoutParser::endGroup) + } }, + { "group/briefdescription", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::BriefDesc), + endCb() + } }, + { "group/detaileddescription", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::DetailedDesc, + []() { return compileOptions(theTranslator->trDetailedDescription()); }), + endCb() + } }, + { "group/authorsection", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::AuthorSection), + endCb() + } }, + { "group/groupgraph", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::GroupGraph), + endCb() + } }, + { "group/memberdecl/membergroups", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::MemberGroups), + endCb() + } }, + + { "group/memberdecl", { startCb(&LayoutParser::startMemberDecl), + endCb(&LayoutParser::endMemberDecl) + } }, + + { "group/memberdecl/classes", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupClasses, + []() { return compileOptions(/* default */ theTranslator->trCompounds(), + SrcLangExt_VHDL, theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE), + SrcLangExt_Fortran, theTranslator->trDataTypes()); }), + endCb() + } }, + { "group/memberdecl/namespaces", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupNamespaces, + []() { return compileOptions(/* default */ theTranslator->trNamespaces(), + SrcLangExt_Java, theTranslator->trPackages(), + SrcLangExt_Fortran, theTranslator->trModules()); }), + endCb() + } }, + { "group/memberdecl/dirs", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupDirs, + []() { return compileOptions(theTranslator->trDirectories()); }), + endCb() + } }, + { "group/memberdecl/nestedgroups", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupNestedGroups, + []() { return compileOptions(theTranslator->trModules()); }), + endCb() + } }, + { "group/memberdecl/files", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupFiles, + []() { return compileOptions(theTranslator->trFile(TRUE,FALSE)); }), + endCb() + } }, + { "group/memberdecl/defines", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decDefineMembers, + []() { return compileOptions(theTranslator->trDefines()); }), + endCb() + } }, + { "group/memberdecl/typedefs", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decTypedefMembers, + []() { return compileOptions(theTranslator->trTypedefs()); }), + endCb() + } }, + { "group/memberdecl/sequences", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decSequenceMembers, + []() { return compileOptions(theTranslator->trSequences()); }), + endCb() + } }, + { "group/memberdecl/dictionaries", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decDictionaryMembers, + []() { return compileOptions(theTranslator->trDictionaries()); }), + endCb() + } }, + { "group/memberdecl/enums", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decEnumMembers, + []() { return compileOptions(theTranslator->trEnumerations()); }), + endCb() + } }, + { "group/memberdecl/enumvalues", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decEnumValMembers, + []() { return compileOptions(theTranslator->trEnumerationValues()); }), + endCb() + } }, + { "group/memberdecl/functions", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decFuncMembers, + []() { return compileOptions(/* default */ theTranslator->trFunctions(), + SrcLangExt_Fortran,theTranslator->trSubprograms(), + SrcLangExt_VHDL, theTranslator->trFunctionAndProc()); }), + endCb() + } }, + { "group/memberdecl/variables", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decVarMembers, + []() { return compileOptions(theTranslator->trVariables()); }), + endCb() + } }, + { "group/memberdecl/signals", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decSignalMembers, + []() { return compileOptions(theTranslator->trSignals()); }), + endCb() + } }, + { "group/memberdecl/publicslots", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decPubSlotMembers, + []() { return compileOptions(theTranslator->trPublicSlots()); }), + endCb() + } }, + { "group/memberdecl/protectedslots", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decProSlotMembers, + []() { return compileOptions(theTranslator->trProtectedSlots()); }), + endCb() + } }, + { "group/memberdecl/privateslots", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decPriSlotMembers, + []() { return compileOptions(theTranslator->trPrivateSlots()); }), + endCb() + } }, + { "group/memberdecl/events", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decEventMembers, + []() { return compileOptions(theTranslator->trEvents()); }), + endCb() + } }, + { "group/memberdecl/properties", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decPropMembers, + []() { return compileOptions(theTranslator->trProperties()); }), + endCb() + } }, + { "group/memberdecl/friends", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType_decFriendMembers, + []() { return compileOptions(theTranslator->trFriends()); }), + endCb() + } }, + { "group/memberdef", { startCb(&LayoutParser::startMemberDef), + endCb(&LayoutParser::endMemberDef) + } }, + + { "group/memberdef/pagedocs", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::GroupPageDocs), + endCb() + } }, + { "group/memberdef/inlineclasses", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupInlineClasses, + []() { return compileOptions(/* default */ theTranslator->trClassDocumentation(), + SrcLangExt_Fortran,theTranslator->trTypeDocumentation()); }), + endCb() + } }, + { "group/memberdef/defines", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docDefineMembers, + []() { return compileOptions(theTranslator->trDefineDocumentation()); }), + endCb() + } }, + { "group/memberdef/typedefs", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docTypedefMembers, + []() { return compileOptions(theTranslator->trTypedefDocumentation()); }), + endCb() + } }, + { "group/memberdef/sequences", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docSequenceMembers, + []() { return compileOptions(theTranslator->trSequenceDocumentation()); }), + endCb() + } }, + { "group/memberdef/dictionaries", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docDictionaryMembers, + []() { return compileOptions(theTranslator->trDictionaryDocumentation()); }), + endCb() + } }, + { "group/memberdef/enums", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docEnumMembers, + []() { return compileOptions(theTranslator->trEnumerationTypeDocumentation()); }), + endCb() + } }, + { "group/memberdef/enumvalues", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docEnumValMembers, + []() { return compileOptions(theTranslator->trEnumerationValueDocumentation()); }), + endCb() + } }, + { "group/memberdef/functions", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docFuncMembers, + []() { return compileOptions(/* default */ theTranslator->trFunctionDocumentation(), + SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation()); }), + endCb() + } }, + { "group/memberdef/variables", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docVarMembers, + []() { return compileOptions(theTranslator->trVariableDocumentation()); }), + endCb() + } }, + { "group/memberdef/signals", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docSignalMembers, + []() { return compileOptions(theTranslator->trSignals()); }), + endCb() + } }, + { "group/memberdef/publicslots", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docPubSlotMembers, + []() { return compileOptions(theTranslator->trPublicSlots()); }), + endCb() + } }, + { "group/memberdef/protectedslots", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docProSlotMembers, + []() { return compileOptions(theTranslator->trProtectedSlots()); }), + endCb() + } }, + { "group/memberdef/privateslots", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docPriSlotMembers, + []() { return compileOptions(theTranslator->trPrivateSlots()); }), + endCb() + } }, + { "group/memberdef/events", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docEventMembers, + []() { return compileOptions(theTranslator->trEvents()); }), + endCb() + } }, + { "group/memberdef/properties", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docPropMembers, + []() { return compileOptions(theTranslator->trProperties()); }), + endCb() + } }, { "group/memberdef/friends", { startCb(&LayoutParser::startMemberDefEntry, MemberListType_docFriendMembers, + []() { return compileOptions(theTranslator->trFriends()); }), + endCb() + } }, + + // directory layout handlers + { "directory", { startCb(&LayoutParser::startDirectory), + endCb(&LayoutParser::endDirectory) + } }, + + { "directory/briefdescription", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::BriefDesc), + endCb() + } }, + { "directory/detaileddescription", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::DetailedDesc, + []() { return compileOptions(theTranslator->trDetailedDescription()); }), + endCb() + } }, + { "directory/directorygraph", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::DirGraph), + endCb() + } }, + { "directory/memberdecl", { startCb(&LayoutParser::startMemberDecl), + endCb(&LayoutParser::endMemberDecl) + } }, + + { "directory/memberdecl/dirs", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::DirSubDirs), + endCb() + } }, + { "directory/memberdecl/files", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::DirFiles), + endCb() + } }, - private: - QString errorMsg; - QString fileName; }; +void LayoutParser::startElement( const std::string &name, const XMLHandlers::Attributes& attrib ) +{ + //printf("startElement [%s]::[%s]\n",m_scope.data(),name.data()); + auto it = g_elementHandlers.find(m_scope.str()+name); + if (it!=g_elementHandlers.end()) + { + it->second.startCb(*this,attrib); + } + else + { + std::string fileName = m_locator->fileName(); + ::warn(fileName.c_str(),m_locator->lineNr(),"Unexpected start tag '%s' found in scope='%s'!\n", + name.data(),m_scope.data()); + } +} + +void LayoutParser::endElement( const std::string &name ) +{ + //printf("endElement [%s]::[%s]\n",m_scope.data(),name.data()); + auto it=g_elementHandlers.end(); + + if (!m_scope.isEmpty() && m_scope.right(name.length()+1)==name+"/") + { // element ends current scope + it = g_elementHandlers.find(m_scope.left(m_scope.length()-1).str()); + } + else // continue with current scope + { + it = g_elementHandlers.find(m_scope.str()+name); + } + if (it!=g_elementHandlers.end()) + { + it->second.endCb(*this); + } +} + +//--------------------------------------------------------------------------------- + +int LayoutParser::m_userGroupCount=0; + //--------------------------------------------------------------------------------- class LayoutDocManager::Private @@ -1481,35 +1481,32 @@ class LayoutDocManager::Private LayoutNavEntry *rootNav; }; -LayoutDocManager::LayoutDocManager() +LayoutDocManager::LayoutDocManager() : d(std::make_unique<Private>()) { - d = new Private; int i; for (i=0;i<LayoutDocManager::NrParts;i++) { d->docEntries[i].setAutoDelete(TRUE); } d->rootNav = new LayoutNavEntry; - LayoutParser::instance().init(); } void LayoutDocManager::init() { - // parse the default layout - LayoutErrorHandler errorHandler( "layout_default.xml" ); - QXmlInputSource source; - source.setData( layout_default ); - QXmlSimpleReader reader; - reader.setContentHandler( &LayoutParser::instance() ); - reader.setErrorHandler( &errorHandler ); - reader.parse( source ); + LayoutParser &layoutParser = LayoutParser::instance(); + XMLHandlers handlers; + handlers.startElement = [&layoutParser](const std::string &name,const XMLHandlers::Attributes &attrs) { layoutParser.startElement(name,attrs); }; + handlers.endElement = [&layoutParser](const std::string &name) { layoutParser.endElement(name); }; + handlers.error = [&layoutParser](const std::string &fileName,int lineNr,const std::string &msg) { layoutParser.error(fileName,lineNr,msg); }; + XMLParser parser(handlers); + layoutParser.setDocumentLocator(&parser); + parser.parse("layout_default.xml",layout_default); } LayoutDocManager::~LayoutDocManager() { delete d->rootNav; - delete d; } LayoutDocManager & LayoutDocManager::instance() @@ -1540,13 +1537,14 @@ void LayoutDocManager::clear(LayoutDocManager::LayoutPart p) void LayoutDocManager::parse(const char *fileName) { - LayoutErrorHandler errorHandler(fileName); - QXmlInputSource source; - source.setData(fileToString(fileName)); - QXmlSimpleReader reader; - reader.setContentHandler( &LayoutParser::instance() ); - reader.setErrorHandler( &errorHandler ); - reader.parse( source ); + LayoutParser &layoutParser = LayoutParser::instance(); + XMLHandlers handlers; + handlers.startElement = [&layoutParser](const std::string &name,const XMLHandlers::Attributes &attrs) { layoutParser.startElement(name,attrs); }; + handlers.endElement = [&layoutParser](const std::string &name) { layoutParser.endElement(name); }; + handlers.error = [&layoutParser](const std::string &fileName,int lineNr,const std::string &msg) { layoutParser.error(fileName,lineNr,msg); }; + XMLParser parser(handlers); + layoutParser.setDocumentLocator(&parser); + parser.parse(fileName,fileToString(fileName)); } //--------------------------------------------------------------------------------- @@ -1560,8 +1558,7 @@ void writeDefaultLayoutFile(const char *fileName) err("Failed to open file %s for writing!\n",fileName); return; } - QTextStream t(&f); - t.setEncoding(QTextStream::UnicodeUTF8); + FTextStream t(&f); t << substitute(layout_default,"$doxygenversion",getDoxygenVersion()); } diff --git a/src/layout.h b/src/layout.h index b1facf5..68d5c6e 100644 --- a/src/layout.h +++ b/src/layout.h @@ -1,13 +1,13 @@ /****************************************************************************** * - * + * * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -19,6 +19,7 @@ #ifndef LAYOUT_H #define LAYOUT_H +#include <memory> #include <qlist.h> #include "types.h" @@ -30,14 +31,14 @@ class QTextStream; struct LayoutDocEntry { virtual ~LayoutDocEntry() {} - enum Kind { + enum Kind { // Generic items for all pages MemberGroups, MemberDeclStart, MemberDeclEnd, MemberDecl, MemberDefStart, MemberDefEnd, MemberDef, BriefDesc, DetailedDesc, AuthorSection, - + // Class specific items ClassIncludes, ClassInlineClasses, ClassInheritanceGraph, ClassNestedClasses, @@ -51,7 +52,7 @@ struct LayoutDocEntry // File specific items FileClasses, FileInterfaces, FileStructs, FileExceptions, FileConstantGroups, FileNamespaces, - FileIncludes, FileIncludeGraph, + FileIncludes, FileIncludeGraph, FileIncludedByGraph, FileSourceLink, FileInlineClasses, @@ -90,7 +91,7 @@ private: struct LayoutDocEntryMemberDecl: public LayoutDocEntry { LayoutDocEntryMemberDecl(MemberListType tp, - const QCString &tl,const QCString &ss) + const QCString &tl,const QCString &ss) : type(tp), m_title(tl), m_subscript(ss) {} Kind kind() const { return MemberDecl; } @@ -105,7 +106,7 @@ private: /** @brief Represents of a member definition list with configurable title. */ struct LayoutDocEntryMemberDef: public LayoutDocEntry { - LayoutDocEntryMemberDef(MemberListType tp,const QCString &tl) + LayoutDocEntryMemberDef(MemberListType tp,const QCString &tl) : type(tp), m_title(tl) {} Kind kind() const { return MemberDef; } @@ -116,44 +117,44 @@ private: }; /** @brief Base class for the layout of a navigation item at the top of the HTML pages. */ -struct LayoutNavEntry +struct LayoutNavEntry { public: - enum Kind { - None = -1, - MainPage, + enum Kind { + None = -1, + MainPage, Pages, - Modules, - Namespaces, + Modules, + Namespaces, NamespaceList, NamespaceMembers, Classes, - ClassList, - ClassIndex, - ClassHierarchy, + ClassList, + ClassIndex, + ClassHierarchy, ClassMembers, Interfaces, - InterfaceList, - InterfaceIndex, - InterfaceHierarchy, + InterfaceList, + InterfaceIndex, + InterfaceHierarchy, Structs, - StructList, - StructIndex, + StructList, + StructIndex, Exceptions, - ExceptionList, - ExceptionIndex, - ExceptionHierarchy, - Files, + ExceptionList, + ExceptionIndex, + ExceptionHierarchy, + Files, FileList, FileGlobals, Examples, User, UserGroup }; - LayoutNavEntry(LayoutNavEntry *parent,Kind k,bool vs,const QCString &bf, - const QCString &tl,const QCString &intro,bool prepend=FALSE) + LayoutNavEntry(LayoutNavEntry *parent,Kind k,bool vs,const QCString &bf, + const QCString &tl,const QCString &intro,bool prepend=FALSE) : m_parent(parent), m_kind(k), m_visible(vs), m_baseFile(bf), m_title(tl), m_intro(intro) - { m_children.setAutoDelete(TRUE); + { m_children.setAutoDelete(TRUE); if (parent) { if (prepend) parent->prependChild(this); else parent->addChild(this); } } LayoutNavEntry *parent() const { return m_parent; } @@ -208,7 +209,7 @@ class LayoutDocManager void clear(LayoutPart p); LayoutDocManager(); ~LayoutDocManager(); - Private *d; + std::unique_ptr<Private> d; friend class LayoutParser; }; diff --git a/src/tagreader.cpp b/src/tagreader.cpp index 62aadc3..d5f8d5f 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -21,17 +21,13 @@ #include <map> #include <functional> #include <utility> +#include <algorithm> #include <assert.h> #include <stdio.h> #include <stdarg.h> -#include <algorithm> - - -#include <qxml.h> -#include <qfileinfo.h> -#include <qstring.h> +#include "xml.h" #include "entry.h" #include "doxygen.h" #include "util.h" @@ -47,32 +43,32 @@ class TagAnchorInfo { public: - TagAnchorInfo(const QCString &f, - const QCString &l, - const QCString &t=QCString()) + TagAnchorInfo(const std::string &f, + const std::string &l, + const std::string &t=std::string()) : label(l), fileName(f), title(t) {} - QCString label; - QCString fileName; - QCString title; + std::string label; + std::string fileName; + std::string title; }; /** Container for enum values that are scoped within an enum */ class TagEnumValueInfo { public: - QCString name; - QCString file; - QCString anchor; - QCString clangid; + std::string name; + std::string file; + std::string anchor; + std::string clangid; }; /** Container for include info that can be read from a tagfile */ class TagIncludeInfo { public: - QCString id; - QCString name; - QCString text; + std::string id; + std::string name; + std::string text; bool isLocal; bool isImported; }; @@ -81,13 +77,13 @@ class TagIncludeInfo class TagMemberInfo { public: - QCString type; - QCString name; - QCString anchorFile; - QCString anchor; - QCString arglist; - QCString kind; - QCString clangId; + std::string type; + std::string name; + std::string anchorFile; + std::string anchor; + std::string arglist; + std::string kind; + std::string clangId; std::vector<TagAnchorInfo> docAnchors; Protection prot = Public; Specifier virt = Normal; @@ -104,8 +100,8 @@ class TagCompoundInfo virtual ~TagCompoundInfo() {} CompoundType compoundType() const { return m_type; } std::vector<TagMemberInfo> members; - QCString name; - QCString filename; + std::string name; + std::string filename; std::vector<TagAnchorInfo> docAnchors; private: CompoundType m_type; @@ -117,8 +113,8 @@ class TagClassInfo : public TagCompoundInfo public: enum class Kind { None=-1, Class, Struct, Union, Interface, Exception, Protocol, Category, Enum, Service, Singleton }; TagClassInfo(Kind k) : TagCompoundInfo(CompoundType::Class), kind(k) {} - QCString clangId; - QCString anchor; + std::string clangId; + std::string anchor; std::vector<BaseInfo> bases; StringVector templateArguments; StringVector classList; @@ -139,7 +135,7 @@ class TagNamespaceInfo : public TagCompoundInfo { public: TagNamespaceInfo() :TagCompoundInfo(CompoundType::Namespace) {} - QCString clangId; + std::string clangId; StringVector classList; StringVector namespaceList; static TagNamespaceInfo *get(std::unique_ptr<TagCompoundInfo> &t) @@ -173,7 +169,7 @@ class TagFileInfo : public TagCompoundInfo { public: TagFileInfo() : TagCompoundInfo(CompoundType::File) { } - QCString path; + std::string path; StringVector classList; StringVector namespaceList; std::vector<TagIncludeInfo> includes; @@ -192,7 +188,7 @@ class TagGroupInfo : public TagCompoundInfo { public: TagGroupInfo() : TagCompoundInfo(CompoundType::Group) { } - QCString title; + std::string title; StringVector subgroupList; StringVector classList; StringVector namespaceList; @@ -214,7 +210,7 @@ class TagPageInfo : public TagCompoundInfo { public: TagPageInfo() : TagCompoundInfo(CompoundType::Page) {} - QCString title; + std::string title; static TagPageInfo *get(std::unique_ptr<TagCompoundInfo> &t) { return dynamic_cast<TagPageInfo*>(t.get()); @@ -230,7 +226,7 @@ class TagDirInfo : public TagCompoundInfo { public: TagDirInfo() : TagCompoundInfo(CompoundType::Dir) {} - QCString path; + std::string path; StringVector subdirList; StringVector fileList; static TagDirInfo *get(std::unique_ptr<TagCompoundInfo> &t) @@ -249,75 +245,33 @@ class TagDirInfo : public TagCompoundInfo * memory. The method buildLists() is used to transfer/translate * the structures to the doxygen engine. */ -class TagFileParser : public QXmlDefaultHandler +class TagFileParser { - enum State { Invalid, - InClass, - InFile, - InNamespace, - InGroup, - InPage, - InMember, - InEnumValue, - InPackage, - InDir, - InTempArgList - }; - - struct CompoundFactory - { - using CreateFunc = std::function<std::unique_ptr<TagCompoundInfo>()>; - CompoundFactory(State s,CreateFunc f) : state(s), make_instance(f) {} - State state; - CreateFunc make_instance; - }; public: TagFileParser(const char *tagName) : m_tagName(tagName) {} - void setDocumentLocator ( QXmlLocator * locator ) + void setDocumentLocator ( const XMLLocator * locator ) { m_locator = locator; } - void setFileName( const QString &fileName ) - { - m_inputFileName = fileName.utf8(); - } - - void warn(const char *fmt) + void startDocument() { - ::warn(m_inputFileName,m_locator->lineNumber(),"%s", fmt); + m_state = Invalid; } - void warn(const char *fmt,const char *s) + void startElement( const std::string &name, const XMLHandlers::Attributes& attrib ); + void endElement( const std::string &name ); + void characters ( const std::string & ch ) { m_curString+=ch; } + void error( const std::string &fileName,int lineNr,const std::string &msg) { - ::warn(m_inputFileName,m_locator->lineNumber(),fmt,s); + ::warn(fileName.c_str(),lineNr,"%s",msg.c_str()); } - void startCompound( const QXmlAttributes& attrib ) - { - m_curString = ""; - QString kind = attrib.value("kind"); - QString isObjC = attrib.value("objc"); - - auto it = m_compoundFactory.find(kind.utf8().str()); - if (it!=m_compoundFactory.end()) - { - m_curCompound = it->second.make_instance(); - m_state = it->second.state; - } - else - { - warn("Unknown compound attribute '%s' found!",kind.data()); - m_state = Invalid; - } - - if (isObjC=="yes" && m_curCompound && - m_curCompound->compoundType()==TagCompoundInfo::CompoundType::Class) - { - TagClassInfo::get(m_curCompound)->isObjC = TRUE; - } - } + void dump(); + void buildLists(const std::shared_ptr<Entry> &root); + void addIncludes(); + void startCompound( const XMLHandlers::Attributes& attrib ); void endCompound() { @@ -338,13 +292,13 @@ class TagFileParser : public QXmlDefaultHandler } } - void startMember( const QXmlAttributes& attrib) + void startMember( const XMLHandlers::Attributes& attrib) { m_curMember = TagMemberInfo(); - m_curMember.kind = attrib.value("kind").utf8(); - QCString protStr = attrib.value("protection").utf8(); - QCString virtStr = attrib.value("virtualness").utf8(); - QCString staticStr = attrib.value("static").utf8(); + m_curMember.kind = XMLHandlers::value(attrib,"kind"); + std::string protStr = XMLHandlers::value(attrib,"protection"); + std::string virtStr = XMLHandlers::value(attrib,"virtualness"); + std::string staticStr = XMLHandlers::value(attrib,"static"); if (protStr=="protected") { m_curMember.prot = Protected; @@ -388,15 +342,15 @@ class TagFileParser : public QXmlDefaultHandler } } - void startEnumValue( const QXmlAttributes& attrib) + void startEnumValue( const XMLHandlers::Attributes& attrib) { if (m_state==InMember) { m_curString = ""; m_curEnumValue = TagEnumValueInfo(); - m_curEnumValue.file = attrib.value("file").utf8(); - m_curEnumValue.anchor = attrib.value("anchor").utf8(); - m_curEnumValue.clangid = attrib.value("clangid").utf8(); + m_curEnumValue.file = XMLHandlers::value(attrib,"file"); + m_curEnumValue.anchor = XMLHandlers::value(attrib,"anchor"); + m_curEnumValue.clangid = XMLHandlers::value(attrib,"clangid"); m_stateStack.push(m_state); m_state = InEnumValue; } @@ -431,7 +385,7 @@ class TagFileParser : public QXmlDefaultHandler case InMember: case InPackage: case InDir: - if (QString(m_curString).startsWith("autotoc_md")) return; + if (m_curString.rfind("autotoc_md",0)==0) return; break; default: warn("Unexpected tag 'docanchor' found"); @@ -541,15 +495,15 @@ class TagFileParser : public QXmlDefaultHandler } } - void startStringValue(const QXmlAttributes& ) + void startStringValue(const XMLHandlers::Attributes& ) { m_curString = ""; } - void startDocAnchor(const QXmlAttributes& attrib ) + void startDocAnchor(const XMLHandlers::Attributes& attrib ) { - m_fileName = attrib.value("file").utf8(); - m_title = attrib.value("title").utf8(); + m_fileName = XMLHandlers::value(attrib,"file"); + m_title = XMLHandlers::value(attrib,"title"); m_curString = ""; } @@ -587,13 +541,13 @@ class TagFileParser : public QXmlDefaultHandler } } - void startBase(const QXmlAttributes& attrib ) + void startBase(const XMLHandlers::Attributes& attrib ) { m_curString=""; if (m_state==InClass && m_curCompound) { - QString protStr = attrib.value("protection"); - QString virtStr = attrib.value("virtualness"); + std::string protStr = XMLHandlers::value(attrib,"protection"); + std::string virtStr = XMLHandlers::value(attrib,"virtualness"); Protection prot = Public; Specifier virt = Normal; if (protStr=="protected") @@ -628,13 +582,13 @@ class TagFileParser : public QXmlDefaultHandler } } - void startIncludes(const QXmlAttributes& attrib ) + void startIncludes(const XMLHandlers::Attributes& attrib ) { m_curIncludes = TagIncludeInfo(); - m_curIncludes.id = attrib.value("id").utf8(); - m_curIncludes.name = attrib.value("name").utf8(); - m_curIncludes.isLocal = attrib.value("local").utf8()=="yes" ? TRUE : FALSE; - m_curIncludes.isImported = attrib.value("imported").utf8()=="yes" ? TRUE : FALSE; + m_curIncludes.id = XMLHandlers::value(attrib,"id"); + m_curIncludes.name = XMLHandlers::value(attrib,"name"); + m_curIncludes.isLocal = XMLHandlers::value(attrib,"local")=="yes"; + m_curIncludes.isImported = XMLHandlers::value(attrib,"imported")=="yes"; m_curString=""; } @@ -788,7 +742,7 @@ class TagFileParser : public QXmlDefaultHandler } } - void startIgnoreElement(const QXmlAttributes& ) + void startIgnoreElement(const XMLHandlers::Attributes& ) { } @@ -796,134 +750,40 @@ class TagFileParser : public QXmlDefaultHandler { } - bool startDocument() - { - m_state = Invalid; + void buildMemberList(const std::shared_ptr<Entry> &ce,const std::vector<TagMemberInfo> &members); + void addDocAnchors(const std::shared_ptr<Entry> &e,const std::vector<TagAnchorInfo> &l); - m_startElementHandlers.insert({ - { "compound", std::bind(&TagFileParser::startCompound, this, std::placeholders::_1) }, - { "member", std::bind(&TagFileParser::startMember, this, std::placeholders::_1) }, - { "enumvalue", std::bind(&TagFileParser::startEnumValue, this, std::placeholders::_1) }, - { "name", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "base", std::bind(&TagFileParser::startBase, this, std::placeholders::_1) }, - { "filename", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "includes", std::bind(&TagFileParser::startIncludes, this, std::placeholders::_1) }, - { "path", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "anchorfile", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "anchor", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "clangid", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "arglist", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "title", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "subgroup", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "class", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "namespace", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "file", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "dir", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "page", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "docanchor", std::bind(&TagFileParser::startDocAnchor, this, std::placeholders::_1) }, - { "tagfile", std::bind(&TagFileParser::startIgnoreElement,this, std::placeholders::_1) }, - { "templarg", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) }, - { "type", std::bind(&TagFileParser::startStringValue, this, std::placeholders::_1) } - }); - - m_endElementHandlers.insert({ - { "compound", std::bind(&TagFileParser::endCompound, this) }, - { "member", std::bind(&TagFileParser::endMember, this) }, - { "enumvalue", std::bind(&TagFileParser::endEnumValue, this) }, - { "name", std::bind(&TagFileParser::endName, this) }, - { "base", std::bind(&TagFileParser::endBase, this) }, - { "filename", std::bind(&TagFileParser::endFilename, this) }, - { "includes", std::bind(&TagFileParser::endIncludes, this) }, - { "path", std::bind(&TagFileParser::endPath, this) }, - { "anchorfile", std::bind(&TagFileParser::endAnchorFile, this) }, - { "anchor", std::bind(&TagFileParser::endAnchor, this) }, - { "clangid", std::bind(&TagFileParser::endClangId, this) }, - { "arglist", std::bind(&TagFileParser::endArglist, this) }, - { "title", std::bind(&TagFileParser::endTitle, this) }, - { "subgroup", std::bind(&TagFileParser::endSubgroup, this) }, - { "class" , std::bind(&TagFileParser::endClass, this) }, - { "namespace", std::bind(&TagFileParser::endNamespace, this) }, - { "file", std::bind(&TagFileParser::endFile, this) }, - { "dir", std::bind(&TagFileParser::endDir, this) }, - { "page", std::bind(&TagFileParser::endPage, this) }, - { "docanchor", std::bind(&TagFileParser::endDocAnchor, this) }, - { "tagfile", std::bind(&TagFileParser::endIgnoreElement,this) }, - { "templarg", std::bind(&TagFileParser::endTemplateArg, this) }, - { "type", std::bind(&TagFileParser::endType, this) } - }); - - return TRUE; - } - - bool startElement( const QString&, const QString&, - const QString&name, const QXmlAttributes& attrib ) - { - //printf("startElement '%s'\n",name.data()); - auto it = m_startElementHandlers.find(name.utf8().str()); - if (it!=std::end(m_startElementHandlers)) - { - it->second(attrib); - } - else - { - warn("Unknown tag '%s' found!",name.data()); - } - return TRUE; - } - bool endElement( const QString&, const QString&, const QString& name ) + enum State { Invalid, + InClass, + InFile, + InNamespace, + InGroup, + InPage, + InMember, + InEnumValue, + InPackage, + InDir, + InTempArgList + }; + private: + + void warn(const char *fmt) { - //printf("endElement '%s'\n",name.data()); - auto it = m_endElementHandlers.find(name.utf8().str()); - if (it!=std::end(m_endElementHandlers)) - { - it->second(); - } - else - { - warn("Unknown tag '%s' found!",name.data()); - } - return TRUE; + std::string fileName = m_locator->fileName(); + ::warn(fileName.c_str(),m_locator->lineNr(),"%s", fmt); } - bool characters ( const QString & ch ) + void warn(const char *fmt,const char *s) { - m_curString+=ch.utf8(); - return TRUE; + std::string fileName = m_locator->fileName(); + ::warn(fileName.c_str(),m_locator->lineNr(),fmt,s); } - void dump(); - void buildLists(const std::shared_ptr<Entry> &root); - void addIncludes(); - private: - void buildMemberList(const std::shared_ptr<Entry> &ce,const std::vector<TagMemberInfo> &members); - void addDocAnchors(const std::shared_ptr<Entry> &e,const std::vector<TagAnchorInfo> &l); - std::vector< std::unique_ptr<TagCompoundInfo> > m_tagFileCompounds; - - std::map< std::string, std::function<void(const QXmlAttributes&)> > m_startElementHandlers; - std::map< std::string, std::function<void()> > m_endElementHandlers; - std::map< std::string, CompoundFactory > m_compoundFactory = - { - // kind tag state creation function - { "class", { InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Class); } } }, - { "struct", { InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Struct); } } }, - { "union", { InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Union); } } }, - { "interface", { InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Interface); } } }, - { "enum", { InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Enum); } } }, - { "exception", { InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Exception); } } }, - { "protocol", { InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Protocol); } } }, - { "category", { InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Category); } } }, - { "service", { InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Service); } } }, - { "singleton", { InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Singleton); } } }, - { "file", { InFile, []() { return std::make_unique<TagFileInfo>(); } } }, - { "namespace", { InNamespace, []() { return std::make_unique<TagNamespaceInfo>(); } } }, - { "group", { InGroup, []() { return std::make_unique<TagGroupInfo>(); } } }, - { "page", { InPage, []() { return std::make_unique<TagPageInfo>(); } } }, - { "package", { InPackage, []() { return std::make_unique<TagPackageInfo>(); } } }, - { "dir", { InDir, []() { return std::make_unique<TagDirInfo>(); } } } - }; + //------------------------------------ + std::vector< std::unique_ptr<TagCompoundInfo> > m_tagFileCompounds; std::unique_ptr<TagCompoundInfo> m_curCompound; TagMemberInfo m_curMember; @@ -931,44 +791,149 @@ class TagFileParser : public QXmlDefaultHandler TagIncludeInfo m_curIncludes; std::string m_curString; - QCString m_tagName; - QCString m_fileName; - QCString m_title; + std::string m_tagName; + std::string m_fileName; + std::string m_title; State m_state = Invalid; std::stack<State> m_stateStack; - QXmlLocator *m_locator = nullptr; - QCString m_inputFileName; + const XMLLocator *m_locator = nullptr; }; -/** Error handler for the XML tag file parser. - * - * Basically dumps all fatal error to stderr using err(). - */ -class TagFileErrorHandler : public QXmlErrorHandler +//--------------------------------------------------------------------------------------------------------------- + +struct ElementCallbacks { - public: - virtual ~TagFileErrorHandler() {} - bool warning( const QXmlParseException & ) - { - return FALSE; - } - bool error( const QXmlParseException & ) - { - return FALSE; - } - bool fatalError( const QXmlParseException &exception ) - { - err("Fatal error at line %d column %d: %s\n", - exception.lineNumber(),exception.columnNumber(), - exception.message().data()); - return FALSE; - } - QString errorString() { return ""; } + using StartCallback = std::function<void(TagFileParser&,const XMLHandlers::Attributes&)>; + using EndCallback = std::function<void(TagFileParser&)>; - private: - QString errorMsg; + StartCallback startCb; + EndCallback endCb; +}; + +ElementCallbacks::StartCallback startCb(void (TagFileParser::*fn)(const XMLHandlers::Attributes &)) +{ + return [fn](TagFileParser &parser,const XMLHandlers::Attributes &attr) { (parser.*fn)(attr); }; +} + +ElementCallbacks::EndCallback endCb(void (TagFileParser::*fn)()) +{ + return [fn](TagFileParser &parser) { (parser.*fn)(); }; +} + +static const std::map< std::string, ElementCallbacks > g_elementHandlers = +{ + // name, start element callback, end element callback + { "compound", { startCb(&TagFileParser::startCompound ), endCb(&TagFileParser::endCompound ) } }, + { "member", { startCb(&TagFileParser::startMember ), endCb(&TagFileParser::endMember ) } }, + { "enumvalue", { startCb(&TagFileParser::startEnumValue ), endCb(&TagFileParser::endEnumValue ) } }, + { "name", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endName ) } }, + { "base", { startCb(&TagFileParser::startBase ), endCb(&TagFileParser::endBase ) } }, + { "filename", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endFilename ) } }, + { "includes", { startCb(&TagFileParser::startIncludes ), endCb(&TagFileParser::endIncludes ) } }, + { "path", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endPath ) } }, + { "anchorfile", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endAnchorFile ) } }, + { "anchor", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endAnchor ) } }, + { "clangid", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endClangId ) } }, + { "arglist", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endArglist ) } }, + { "title", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endTitle ) } }, + { "subgroup", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endSubgroup ) } }, + { "class", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endClass ) } }, + { "namespace", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endNamespace ) } }, + { "file", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endFile ) } }, + { "dir", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endDir ) } }, + { "page", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endPage ) } }, + { "docanchor", { startCb(&TagFileParser::startDocAnchor ), endCb(&TagFileParser::endDocAnchor ) } }, + { "tagfile", { startCb(&TagFileParser::startIgnoreElement), endCb(&TagFileParser::endIgnoreElement) } }, + { "templarg", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endTemplateArg ) } }, + { "type", { startCb(&TagFileParser::startStringValue ), endCb(&TagFileParser::endType ) } } +}; + +//--------------------------------------------------------------------------------------------------------------- + +struct CompoundFactory +{ + using CreateFunc = std::function<std::unique_ptr<TagCompoundInfo>()>; + CompoundFactory(TagFileParser::State s,CreateFunc f) : state(s), make_instance(f) {} + TagFileParser::State state; + CreateFunc make_instance; }; +static const std::map< std::string, CompoundFactory > g_compoundFactory = +{ + // kind tag state creation function + { "class", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Class); } } }, + { "struct", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Struct); } } }, + { "union", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Union); } } }, + { "interface", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Interface); } } }, + { "enum", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Enum); } } }, + { "exception", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Exception); } } }, + { "protocol", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Protocol); } } }, + { "category", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Category); } } }, + { "service", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Service); } } }, + { "singleton", { TagFileParser::InClass, []() { return std::make_unique<TagClassInfo>(TagClassInfo::Kind::Singleton); } } }, + { "file", { TagFileParser::InFile, []() { return std::make_unique<TagFileInfo>(); } } }, + { "namespace", { TagFileParser::InNamespace, []() { return std::make_unique<TagNamespaceInfo>(); } } }, + { "group", { TagFileParser::InGroup, []() { return std::make_unique<TagGroupInfo>(); } } }, + { "page", { TagFileParser::InPage, []() { return std::make_unique<TagPageInfo>(); } } }, + { "package", { TagFileParser::InPackage, []() { return std::make_unique<TagPackageInfo>(); } } }, + { "dir", { TagFileParser::InDir, []() { return std::make_unique<TagDirInfo>(); } } } +}; + +//--------------------------------------------------------------------------------------------------------------- + +void TagFileParser::startElement( const std::string &name, const XMLHandlers::Attributes& attrib ) +{ + //printf("startElement '%s'\n",name.data()); + auto it = g_elementHandlers.find(name); + if (it!=std::end(g_elementHandlers)) + { + it->second.startCb(*this,attrib); + } + else + { + warn("Unknown start tag '%s' found!",name.data()); + } +} + +void TagFileParser::endElement( const std::string &name ) +{ + //printf("endElement '%s'\n",name.data()); + auto it = g_elementHandlers.find(name); + if (it!=std::end(g_elementHandlers)) + { + it->second.endCb(*this); + } + else + { + warn("Unknown end tag '%s' found!",name.data()); + } +} + +void TagFileParser::startCompound( const XMLHandlers::Attributes& attrib ) +{ + m_curString = ""; + std::string kind = XMLHandlers::value(attrib,"kind"); + std::string isObjC = XMLHandlers::value(attrib,"objc"); + + auto it = g_compoundFactory.find(kind); + if (it!=g_compoundFactory.end()) + { + m_curCompound = it->second.make_instance(); + m_state = it->second.state; + } + else + { + warn("Unknown compound attribute '%s' found!",kind.c_str()); + m_state = Invalid; + } + + if (isObjC=="yes" && m_curCompound && + m_curCompound->compoundType()==TagCompoundInfo::CompoundType::Class) + { + TagClassInfo::get(m_curCompound)->isObjC = TRUE; + } +} + /*! Dumps the internal structures. For debugging only! */ void TagFileParser::dump() { @@ -1134,13 +1099,13 @@ void TagFileParser::addDocAnchors(const std::shared_ptr<Entry> &e,const std::vec { for (const auto &ta : l) { - if (SectionManager::instance().find(ta.label)==0) + if (SectionManager::instance().find(ta.label.c_str())==0) { //printf("New sectionInfo file=%s anchor=%s\n", // ta->fileName.data(),ta->label.data()); SectionInfo *si=SectionManager::instance().add( - ta.label,ta.fileName,-1,ta.title, - SectionType::Anchor,0,m_tagName); + ta.label.c_str(),ta.fileName.c_str(),-1,ta.title.c_str(), + SectionType::Anchor,0,m_tagName.c_str()); e->anchors.push_back(si); } else @@ -1347,27 +1312,28 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) const TagFileInfo *tfi = TagFileInfo::get(comp); std::shared_ptr<Entry> fe = std::make_shared<Entry>(); - fe->section = guessSection(tfi->name); - fe->name = tfi->name; + fe->section = guessSection(tfi->name.c_str()); + fe->name = tfi->name.c_str(); addDocAnchors(fe,tfi->docAnchors); fe->tagInfoData.tagName = m_tagName; fe->tagInfoData.fileName = tfi->filename; fe->hasTagInfo = TRUE; - QCString fullName = m_tagName+":"+tfi->path+stripPath(tfi->name); + std::string fullName = m_tagName+":"+tfi->path+stripPath(tfi->name).str(); fe->fileName = fullName; //printf("createFileDef() filename=%s\n",tfi->filename.data()); - std::unique_ptr<FileDef> fd { createFileDef(m_tagName+":"+tfi->path, - tfi->name,m_tagName, - tfi->filename) }; + std::string tagid = m_tagName+":"+tfi->path; + std::unique_ptr<FileDef> fd { createFileDef(tagid.c_str(), + tfi->name.c_str(),m_tagName.c_str(), + tfi->filename.c_str()) }; FileName *mn; - if ((mn=Doxygen::inputNameLinkedMap->find(tfi->name))) + if ((mn=Doxygen::inputNameLinkedMap->find(tfi->name.c_str()))) { mn->push_back(std::move(fd)); } else { - mn = Doxygen::inputNameLinkedMap->add(tfi->name,fullName); + mn = Doxygen::inputNameLinkedMap->add(tfi->name.c_str(),fullName.c_str()); mn->push_back(std::move(fd)); } buildMemberList(fe,tfi->members); @@ -1451,7 +1417,7 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) [&](const std::shared_ptr<Entry> &e) { return e->name == sg.c_str(); }); if (i!=children.end()) { - (*i)->groups.push_back(Grouping(tgi->name,Grouping::GROUPING_INGROUP)); + (*i)->groups.push_back(Grouping(tgi->name.c_str(),Grouping::GROUPING_INGROUP)); } } } @@ -1465,7 +1431,7 @@ void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) const TagPageInfo *tpi = TagPageInfo::get(comp); std::shared_ptr<Entry> pe = std::make_shared<Entry>(); - bool isIndex = (stripExtensionGeneral(tpi->filename,getFileNameExtension(tpi->filename))=="index"); + bool isIndex = (stripExtensionGeneral(tpi->filename.c_str(),getFileNameExtension(tpi->filename.c_str()))=="index"); pe->section = isIndex ? Entry::MAINPAGEDOC_SEC : Entry::PAGEDOC_SEC; pe->name = tpi->name; pe->args = tpi->title; @@ -1486,7 +1452,7 @@ void TagFileParser::addIncludes() { const TagFileInfo *tfi = TagFileInfo::get(comp); //printf("tag file tagName=%s path=%s name=%s\n",m_tagName.data(),tfi->path.data(),tfi->name.data()); - FileName *fn = Doxygen::inputNameLinkedMap->find(tfi->name); + FileName *fn = Doxygen::inputNameLinkedMap->find(tfi->name.c_str()); if (fn) { for (const auto &fd : *fn) @@ -1498,7 +1464,7 @@ void TagFileParser::addIncludes() for (const auto &ii : tfi->includes) { //printf("ii->name='%s'\n",ii->name.data()); - FileName *ifn = Doxygen::inputNameLinkedMap->find(ii.name); + FileName *ifn = Doxygen::inputNameLinkedMap->find(ii.name.c_str()); ASSERT(ifn!=0); if (ifn) { @@ -1508,7 +1474,7 @@ void TagFileParser::addIncludes() // ifd->getOutputFileBase().data(),ii->id.data()); if (ifd->getOutputFileBase()==QCString(ii.id)) { - fd->addIncludeDependency(ifd.get(),ii.text,ii.isLocal,ii.isImported); + fd->addIncludeDependency(ifd.get(),ii.text.c_str(),ii.isLocal,ii.isImported); } } } @@ -1522,18 +1488,19 @@ void TagFileParser::addIncludes() void parseTagFile(const std::shared_ptr<Entry> &root,const char *fullName) { - QFileInfo fi(fullName); - if (!fi.exists()) return; - TagFileParser handler( fullName ); // tagName - handler.setFileName(fullName); - TagFileErrorHandler errorHandler; - QFile xmlFile( fullName ); - QXmlInputSource source( xmlFile ); - QXmlSimpleReader reader; - reader.setContentHandler( &handler ); - reader.setErrorHandler( &errorHandler ); - reader.parse( source ); - handler.buildLists(root); - handler.addIncludes(); - //handler.dump(); + TagFileParser tagFileParser(fullName); + QCString inputStr = fileToString(fullName); + XMLHandlers handlers; + // connect the generic events handlers of the XML parser to the specific handlers of the tagFileParser object + handlers.startDocument = [&tagFileParser]() { tagFileParser.startDocument(); }; + handlers.startElement = [&tagFileParser](const std::string &name,const XMLHandlers::Attributes &attrs) { tagFileParser.startElement(name,attrs); }; + handlers.endElement = [&tagFileParser](const std::string &name) { tagFileParser.endElement(name); }; + handlers.characters = [&tagFileParser](const std::string &chars) { tagFileParser.characters(chars); }; + handlers.error = [&tagFileParser](const std::string &fileName,int lineNr,const std::string &msg) { tagFileParser.error(fileName,lineNr,msg); }; + XMLParser parser(handlers); + tagFileParser.setDocumentLocator(&parser); + parser.parse(fullName,inputStr); + tagFileParser.buildLists(root); + tagFileParser.addIncludes(); + //tagFileParser.dump(); } diff --git a/src/xml.h b/src/xml.h new file mode 100644 index 0000000..add95f1 --- /dev/null +++ b/src/xml.h @@ -0,0 +1,74 @@ +#ifndef XML_H +#define XML_H + +#include <memory> +#include <functional> +#include <string> +#include <unordered_map> + +/*! @brief Event handlers that can installed by the client and called while parsing a XML document. + */ +class XMLHandlers +{ + public: + using Attributes = std::unordered_map<std::string,std::string>; + using StartDocType = void(); + using EndDocType = void(); + using StartElementType = void(const std::string &,const Attributes &); + using EndElementType = void(const std::string &); + using ErrorType = void(const std::string,int,const std::string &); + using CharsType = void(const std::string &); + + std::function<StartDocType> startDocument; /**< handler invoked at the start of the document */ + std::function<EndDocType> endDocument; /**< handler invoked at the end of the document */ + std::function<StartElementType> startElement; /**< handler invoked when an opening tag has been found */ + std::function<EndElementType> endElement; /**< handler invoked when a closing tag has been found */ + std::function<CharsType> characters; /**< handler invoked when content between tags has been found */ + std::function<ErrorType> error; /**< handler invoked when the parser encounters an error */ + + static std::string value(const Attributes &attrib,const std::string &key) + { + auto it = attrib.find(key); + if (it!=attrib.end()) + { + return it->second; + } + return ""; + } +}; + +class XMLLocator +{ + public: + virtual ~XMLLocator() {} + virtual int lineNr() const = 0; + virtual std::string fileName() const = 0; +}; + +/*! Very basic SAX style parser to parse XML documents. */ +class XMLParser : public XMLLocator +{ + public: + /*! Creates an instance of the parser object. Different instances can run on different + * threads without interference. + * + * @param handlers The event handlers passed by the client. + */ + XMLParser(const XMLHandlers &handlers); + /*! Destructor */ + ~XMLParser(); + + /*! Parses a file gives the contents of the file as a string. + * @param fileName the name of the file, used for error reporting. + * @param inputString the contents of the file as a zero terminated UTF-8 string. + */ + void parse(const char *fileName,const char *inputString); + + private: + virtual int lineNr() const override; + virtual std::string fileName() const override; + struct Private; + std::unique_ptr<Private> p; +}; + +#endif diff --git a/src/xml.l b/src/xml.l new file mode 100644 index 0000000..ace35d5 --- /dev/null +++ b/src/xml.l @@ -0,0 +1,484 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2020 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ +/****************************************************************************** + * Minimal flex based parser for XML + ******************************************************************************/ + +%option never-interactive +%option prefix="xmlYY" +%option reentrant +%option extra-type="struct xmlYY_state *" +%option 8bit noyywrap +%top{ +#include <stdint.h> +} + +%{ + +#include <ctype.h> +#include <vector> +#include <stdio.h> +#include "xml.h" +#include "message.h" + +#define YY_NEVER_INTERACTIVE 1 +#define YY_NO_INPUT 1 +#define YY_NO_UNISTD_H 1 + +struct xmlYY_state +{ + std::string fileName; + int lineNr = 1; + const char * inputString = 0; //!< the code fragment as text + yy_size_t inputPosition = 0; //!< read offset during parsing + std::string name; + bool isEnd = false; + bool selfClose = false; + std::string data; + std::string attrValue; + std::string attrName; + XMLHandlers::Attributes attrs; + XMLHandlers handlers; + int cdataContext; + int commentContext; + char stringChar; + std::vector<std::string> xpath; +}; + +#if USE_STATE2STRING +static const char *stateToString(int state); +#endif + +static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); +static void initElement(yyscan_t yyscanner); +static void addCharacters(yyscan_t yyscanner); +static void addElement(yyscan_t yyscanner); +static void addAttribute(yyscan_t yyscanner); +static void countLines(yyscan_t yyscanner, const char *txt,yy_size_t len); +static void reportError(yyscan_t yyscanner, const std::string &msg); +static std::string processData(yyscan_t yyscanner,const char *txt,yy_size_t len); + +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size); + +%} + +NL (\r\n|\r|\n) +SP [ \t\r\n]+ +OPEN {SP}?"<" +OPENSPECIAL {SP}?"<?" +CLOSE ">"{NL}? +CLOSESPECIAL "?>"{NL}? +NAMESTART [:A-Za-z\200-\377_] +NAMECHAR [:A-Za-z\200-\377_0-9.-] +NAME {NAMESTART}{NAMECHAR}* +ESC "&#"[0-9]+";"|"&#x"[0-9a-fA-F]+";" +COLON ":" +PCDATA [^<]+ +COMMENT {OPEN}"!--" +COMMENTEND "--"{CLOSE} +STRING \"([^"&]|{ESC})*\"|\'([^'&]|{ESC})*\' +DOCTYPE {SP}?"<!DOCTYPE"{SP} +CDATA {SP}?"<![CDATA[" +ENDCDATA "]]>" + +%option noyywrap + +%s Initial +%s Content +%s CDataSection +%s Element +%s Attributes +%s AttributeValue +%s AttrValueStr +%s Prolog +%s Comment + +%% + +<Initial>{ + {SP} { countLines(yyscanner,yytext,yyleng); } + {DOCTYPE} { countLines(yyscanner,yytext,yyleng); } + {OPENSPECIAL} { countLines(yyscanner,yytext,yyleng); BEGIN(Prolog); } + {OPEN} { countLines(yyscanner,yytext,yyleng); + initElement(yyscanner); + BEGIN(Element); } + {COMMENT} { yyextra->commentContext = YY_START; + BEGIN(Comment); + } +} +<Content>{ + {CDATA} { countLines(yyscanner,yytext,yyleng); + yyextra->cdataContext = YY_START; + BEGIN(CDataSection); + } + {PCDATA} { yyextra->data += processData(yyscanner,yytext,yyleng); } + {OPEN} { countLines(yyscanner,yytext,yyleng); + addCharacters(yyscanner); + initElement(yyscanner); + BEGIN(Element); + } + {COMMENT} { yyextra->commentContext = YY_START; + countLines(yyscanner,yytext,yyleng); + BEGIN(Comment); + } +} +<Element>{ + "/" { yyextra->isEnd = true; } + {NAME} { yyextra->name = yytext; + BEGIN(Attributes); } + {CLOSE} { addElement(yyscanner); + countLines(yyscanner,yytext,yyleng); + yyextra->data = ""; + BEGIN(Content); + } + {SP} { countLines(yyscanner,yytext,yyleng); } +} +<Attributes>{ + "/" { yyextra->selfClose = true; } + {NAME} { yyextra->attrName = yytext; } + "=" { BEGIN(AttributeValue); } + {CLOSE} { addElement(yyscanner); + countLines(yyscanner,yytext,yyleng); + yyextra->data = ""; + BEGIN(Content); + } + {SP} { countLines(yyscanner,yytext,yyleng); } +} +<AttributeValue>{ + {SP} { countLines(yyscanner,yytext,yyleng); } + ['"] { yyextra->stringChar = *yytext; + yyextra->attrValue = ""; + BEGIN(AttrValueStr); + } + . { std::string msg = std::string("Missing attribute value. Unexpected character `")+yytext+"` found"; + reportError(yyscanner,msg); + unput(*yytext); + BEGIN(Attributes); + } +} +<AttrValueStr>{ + [^'"\n]+ { yyextra->attrValue += processData(yyscanner,yytext,yyleng); } + ['"] { if (*yytext==yyextra->stringChar) + { + addAttribute(yyscanner); + BEGIN(Attributes); + } + else + { + yyextra->attrValue += processData(yyscanner,yytext,yyleng); + } + } + \n { yyextra->lineNr++; yyextra->attrValue+=' '; } +} +<CDataSection>{ + {ENDCDATA} { BEGIN(yyextra->cdataContext); } + [^]\n]+ { yyextra->data += yytext; } + \n { yyextra->data += yytext; + yyextra->lineNr++; + } + . { yyextra->data += yytext; } +} +<Prolog>{ + {CLOSESPECIAL} { countLines(yyscanner,yytext,yyleng); + BEGIN(Initial); + } + [^?\n]+ { } + \n { yyextra->lineNr++; } + . { } +} +<Comment>{ + {COMMENTEND} { countLines(yyscanner,yytext,yyleng); + BEGIN(yyextra->commentContext); + } + [^\n-]+ { } + \n { yyextra->lineNr++; } + . { } +} +\n { yyextra->lineNr++; } +. { std::string msg = "Unexpected character `"; + msg+=yytext; + msg+="` found"; + reportError(yyscanner,msg); + } + +%% + +//---------------------------------------------------------------------------------------- + +static yy_size_t yyread(yyscan_t yyscanner,char *buf,size_t max_size) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yy_size_t inputPosition = yyextra->inputPosition; + const char *s = yyextra->inputString + inputPosition; + yy_size_t c=0; + while( c < max_size && *s) + { + *buf++ = *s++; + c++; + } + yyextra->inputPosition += c; + return c; +} + +static void countLines(yyscan_t yyscanner, const char *txt,yy_size_t len) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + for (yy_size_t i=0;i<len;i++) + { + if (txt[i]=='\n') yyextra->lineNr++; + } +} + +static void initElement(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->isEnd = false; // true => </tag> + yyextra->selfClose = false; // true => <tag/> + yyextra->name = ""; + yyextra->attrs.clear(); +} + +static void checkAndUpdatePath(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->xpath.empty()) + { + std::string msg = "found closing tag '"+yyextra->name+"' without matching opening tag"; + reportError(yyscanner,msg); + } + else + { + std::string expectedTagName = yyextra->xpath.back(); + if (expectedTagName!=yyextra->name) + { + std::string msg = "Found closing tag '"+yyextra->name+"' that does not match the opening tag '"+expectedTagName+"' at the same level"; + reportError(yyscanner,msg); + } + else // matching end tag + { + yyextra->xpath.pop_back(); + } + } +} + +static void addElement(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (!yyextra->isEnd) + { + yyextra->xpath.push_back(yyextra->name); + if (yyextra->handlers.startElement) + { + yyextra->handlers.startElement(yyextra->name,yyextra->attrs); + } + if (yy_flex_debug) + { + fprintf(stderr,"%d: startElement(%s,attr=[",yyextra->lineNr,yyextra->name.data()); + for (auto attr : yyextra->attrs) + { + fprintf(stderr,"%s='%s' ",attr.first.c_str(),attr.second.c_str()); + } + fprintf(stderr,"])\n"); + } + } + if (yyextra->isEnd || yyextra->selfClose) + { + if (yy_flex_debug) + { + fprintf(stderr,"%d: endElement(%s)\n",yyextra->lineNr,yyextra->name.data()); + } + checkAndUpdatePath(yyscanner); + if (yyextra->handlers.endElement) + { + yyextra->handlers.endElement(yyextra->name); + } + } +} + +static std::string trimSpaces(const std::string &str) +{ + const int l = static_cast<int>(str.length()); + int s=0, e=l-1; + while (s<l && isspace(str.at(s))) s++; + while (e>s && isspace(str.at(e))) e--; + return str.substr(s,1+e-s); +} + +static void addCharacters(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + std::string data = trimSpaces(yyextra->data); + if (yyextra->handlers.characters) + { + yyextra->handlers.characters(data); + } + if (!data.empty()) + { + if (yy_flex_debug) + { + fprintf(stderr,"characters(%s)\n",data.c_str()); + } + } +} + +static void addAttribute(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->attrs.insert(std::make_pair(yyextra->attrName,yyextra->attrValue)); +} + +static void reportError(yyscan_t yyscanner,const std::string &msg) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yy_flex_debug) + { + fprintf(stderr,"%s:%d: Error '%s'\n",yyextra->fileName.c_str(),yyextra->lineNr,msg.c_str()); + } + if (yyextra->handlers.error) + { + yyextra->handlers.error(yyextra->fileName,yyextra->lineNr,msg); + } +} + +static const char *entities_enc[] = { "amp", "quot", "gt", "lt", "apos" }; +static const char entities_dec[] = { '&', '"', '>', '<', '\'' }; +static const int num_entities = 5; + +// replace character entities such as & in txt and return the string where entities +// are replaced +static std::string processData(yyscan_t yyscanner,const char *txt,yy_size_t len) +{ + std::string result; + result.reserve(len); + for (yy_size_t i=0; i<len; i++) + { + char c = txt[i]; + if (c=='&') + { + const int maxEntityLen = 10; + char entity[maxEntityLen+1]; + entity[maxEntityLen]='\0'; + for (yy_size_t j=0; j<maxEntityLen && i+j+1<len; j++) + { + if (txt[i+j+1]!=';') + { + entity[j]=txt[i+j+1]; + } + else + { + entity[j]=0; + break; + } + } + bool found=false; + for (int e=0; !found && e<num_entities; e++) + { + if (strcmp(entity,entities_enc[e])==0) + { + result+=entities_dec[e]; + i+=strlen(entities_enc[e])+1; + found=true; + } + } + if (!found) + { + std::string msg = std::string("Invalid character entity '&") + entity + ";' found\n"; + reportError(yyscanner,msg); + } + } + else + { + result+=c; + } + } + return result; +} + +//-------------------------------------------------------------- + +struct XMLParser::Private +{ + yyscan_t yyscanner; + struct xmlYY_state xmlYY_extra; +}; + +XMLParser::XMLParser(const XMLHandlers &handlers) : p(new Private) +{ + xmlYYlex_init_extra(&p->xmlYY_extra,&p->yyscanner); + p->xmlYY_extra.handlers = handlers; +} + +XMLParser::~XMLParser() +{ + xmlYYlex_destroy(p->yyscanner); +} + +void XMLParser::parse(const char *fileName,const char *inputStr) +{ + yyscan_t yyscanner = p->yyscanner; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + +#ifdef FLEX_DEBUG + xmlYYset_debug(1,p->yyscanner); +#endif + + if (inputStr==nullptr || inputStr[0]=='\0') return; // empty input + + printlex(yy_flex_debug, true, __FILE__, fileName); + + BEGIN(Initial); + yyextra->fileName = fileName; + yyextra->lineNr = 1; + yyextra->inputString = inputStr; + yyextra->inputPosition = 0; + + xmlYYrestart( 0, yyscanner ); + + if (yyextra->handlers.startDocument) + { + yyextra->handlers.startDocument(); + } + xmlYYlex(yyscanner); + if (yyextra->handlers.endDocument) + { + yyextra->handlers.endDocument(); + } + + if (!yyextra->xpath.empty()) + { + std::string tagName = yyextra->xpath.back(); + std::string msg = "End of file reached while expecting closing tag '"+tagName+"'"; + reportError(yyscanner,msg); + } + + printlex(yy_flex_debug, false, __FILE__, fileName); +} + +int XMLParser::lineNr() const +{ + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + return yyextra->lineNr; +} + +std::string XMLParser::fileName() const +{ + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + return yyextra->fileName; +} + +#if USE_STATE2STRING +#include "xml.l.h" +#endif |