summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2020-12-08 19:30:25 (GMT)
committerDimitri van Heesch <doxygen@gmail.com>2020-12-08 19:52:23 (GMT)
commit714f89d30cf04ad972df84a6a398258b751d3553 (patch)
treeb99b10526dddb051add94b34be6232627b149e12
parent644997f85f327d3f8456f1c5cf0cde78a3bd1d28 (diff)
downloadDoxygen-714f89d30cf04ad972df84a6a398258b751d3553.zip
Doxygen-714f89d30cf04ad972df84a6a398258b751d3553.tar.gz
Doxygen-714f89d30cf04ad972df84a6a398258b751d3553.tar.bz2
Make tagreader use the new XML parser
-rw-r--r--src/tagreader.cpp549
-rw-r--r--src/xml.h10
2 files changed, 268 insertions, 291 deletions
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
index 6ba36b2..add95f1 100644
--- a/src/xml.h
+++ b/src/xml.h
@@ -25,6 +25,16 @@ class XMLHandlers
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