diff options
Diffstat (limited to 'src')
-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 |
6 files changed, 1735 insertions, 1209 deletions
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 |