|
Packit |
1c1d7e |
/******************************************************************************
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* $Id$
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Copyright (C) 1997-2015 by Dimitri van Heesch.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Permission to use, copy, modify, and distribute this software and its
|
|
Packit |
1c1d7e |
* documentation under the terms of the GNU General Public License is hereby
|
|
Packit |
1c1d7e |
* granted. No representations are made about the suitability of this software
|
|
Packit |
1c1d7e |
* for any purpose. It is provided "as is" without express or implied warranty.
|
|
Packit |
1c1d7e |
* See the GNU General Public License for more details.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#include <qxml.h>
|
|
Packit |
1c1d7e |
#include "mainhandler.h"
|
|
Packit |
1c1d7e |
#include "compoundhandler.h"
|
|
Packit |
1c1d7e |
#include "sectionhandler.h"
|
|
Packit |
1c1d7e |
#include "graphhandler.h"
|
|
Packit |
1c1d7e |
#include "dochandler.h"
|
|
Packit |
1c1d7e |
#include "memberhandler.h"
|
|
Packit |
1c1d7e |
#include "debug.h"
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
class ErrorHandler : public QXmlErrorHandler
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
virtual ~ErrorHandler() {}
|
|
Packit |
1c1d7e |
bool warning( const QXmlParseException & )
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
return FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
bool error( const QXmlParseException & )
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
return FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
bool fatalError( const QXmlParseException &exception )
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
debug(1,"Fatal error at line %d column %d: %s\n",
|
|
Packit |
1c1d7e |
exception.lineNumber(),exception.columnNumber(),
|
|
Packit |
1c1d7e |
exception.message().data());
|
|
Packit |
1c1d7e |
return FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
QString errorString() { return ""; }
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
private:
|
|
Packit |
1c1d7e |
QString errorMsg;
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//--------------------------------------------------------------------------
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
class CompoundEntryIterator : public ICompoundIterator,
|
|
Packit |
1c1d7e |
public QListIterator<CompoundEntry>
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
CompoundEntryIterator(const MainHandler *m,const QList<CompoundEntry> &list) :
|
|
Packit |
1c1d7e |
QListIterator<CompoundEntry>(list), m_mainHandler(m) {}
|
|
Packit |
1c1d7e |
virtual ~CompoundEntryIterator() {}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
virtual void toFirst()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<CompoundEntry>::toFirst();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
virtual void toLast()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<CompoundEntry>::toLast();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
virtual void toNext()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<CompoundEntry>::operator++();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
virtual void toPrev()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<CompoundEntry>::operator--();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
virtual ICompound *current() const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
CompoundEntry *ch = QListIterator<CompoundEntry>::current();
|
|
Packit |
1c1d7e |
return ch ? m_mainHandler->compoundById(ch->id.utf8()) : 0;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
virtual void release()
|
|
Packit |
1c1d7e |
{ delete this; }
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
private:
|
|
Packit |
1c1d7e |
const MainHandler *m_mainHandler;
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//--------------------------------------------------------------------------
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
MainHandler::MainHandler() : m_compoundDict(2999), m_compoundNameDict(2999),
|
|
Packit |
1c1d7e |
m_memberDict(12251), m_memberNameDict(12251),
|
|
Packit |
1c1d7e |
m_compoundsLoaded(1009)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_compounds.setAutoDelete(TRUE);
|
|
Packit |
1c1d7e |
m_memberNameDict.setAutoDelete(TRUE);
|
|
Packit |
1c1d7e |
addStartHandler("doxygenindex");
|
|
Packit |
1c1d7e |
addEndHandler("doxygenindex");
|
|
Packit |
1c1d7e |
addStartHandler("compound",this,&MainHandler::startCompound);
|
|
Packit |
1c1d7e |
addEndHandler("compound");
|
|
Packit |
1c1d7e |
addStartHandler("member",this,&MainHandler::startMember);
|
|
Packit |
1c1d7e |
addEndHandler("member",this,&MainHandler::endMember);
|
|
Packit |
1c1d7e |
addStartHandler("name",this,&MainHandler::startName);
|
|
Packit |
1c1d7e |
addEndHandler("name",this,&MainHandler::endName);
|
|
Packit |
1c1d7e |
m_curCompound = 0;
|
|
Packit |
1c1d7e |
m_insideMember = FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
MainHandler::~MainHandler()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
debug(2,"MainHandler::~MainHandler()\n");
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void MainHandler::startCompound(const QXmlAttributes& attrib)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_curCompound = new CompoundEntry(257);
|
|
Packit |
1c1d7e |
m_curCompound->id = attrib.value("refid");
|
|
Packit |
1c1d7e |
m_compounds.append(m_curCompound);
|
|
Packit |
1c1d7e |
m_compoundDict.insert(m_curCompound->id.utf8(),m_curCompound);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void MainHandler::startName(const QXmlAttributes& /*attrib*/)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_curString = "";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void MainHandler::endName()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (m_insideMember)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_curMember->name = m_curString;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_curCompound->name = m_curString;
|
|
Packit |
1c1d7e |
m_compoundNameDict.insert(m_curString.utf8(),m_curCompound);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void MainHandler::startMember(const QXmlAttributes& attrib)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_insideMember = TRUE;
|
|
Packit |
1c1d7e |
m_curMember = new MemberEntry;
|
|
Packit |
1c1d7e |
m_curMember->id = attrib.value("refid");
|
|
Packit |
1c1d7e |
m_curMember->compound = m_curCompound;
|
|
Packit |
1c1d7e |
m_memberDict.insert(m_curMember->id.utf8(),m_curMember);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void MainHandler::endMember()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_curCompound->memberDict.insert(m_curMember->name.utf8(),m_curMember);
|
|
Packit |
1c1d7e |
QList<CompoundEntry> *cel=0;
|
|
Packit |
1c1d7e |
if ((cel=m_memberNameDict.find(m_curMember->name.utf8()))==0)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
cel = new QList<CompoundEntry>;
|
|
Packit |
1c1d7e |
m_memberNameDict.insert(m_curMember->name.utf8(),cel);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
cel->append(m_curCompound);
|
|
Packit |
1c1d7e |
m_insideMember = FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void MainHandler::setDebugLevel(int level)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
::setDebugLevel(level);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void MainHandler::dump()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<CompoundEntry> cli(m_compounds);
|
|
Packit |
1c1d7e |
CompoundEntry *ce;
|
|
Packit |
1c1d7e |
for (cli.toFirst();(ce=cli.current());++cli)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
debug(2,"compound id=`%s' name=`%s'\n",ce->id.data(),ce->name.data());
|
|
Packit |
1c1d7e |
QDictIterator<MemberEntry> mdi(ce->memberDict);
|
|
Packit |
1c1d7e |
MemberEntry *me;
|
|
Packit |
1c1d7e |
for (mdi.toFirst();(me=mdi.current());++mdi)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
debug(2," member id=`%s' name=`%s'\n",me->id.data(),me->name.data());
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
bool MainHandler::readXMLDir(const char * xmlDirName)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_xmlDirName = xmlDirName;
|
|
Packit |
1c1d7e |
QString xmlFileName=m_xmlDirName+"/index.xml";
|
|
Packit |
1c1d7e |
QFile xmlFile(xmlFileName);
|
|
Packit |
1c1d7e |
//printf("Trying %s xmlFile.exists()=%d isReadable()=%d\n",
|
|
Packit |
1c1d7e |
// xmlFileName.data(),xmlFile.exists(),xmlFile.isReadable());
|
|
Packit |
1c1d7e |
if (xmlFile.exists())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ErrorHandler errorHandler;
|
|
Packit |
1c1d7e |
QXmlInputSource source( xmlFile );
|
|
Packit |
1c1d7e |
QXmlSimpleReader reader;
|
|
Packit |
1c1d7e |
reader.setContentHandler( this );
|
|
Packit |
1c1d7e |
reader.setErrorHandler( &errorHandler );
|
|
Packit |
1c1d7e |
reader.parse( source );
|
|
Packit |
1c1d7e |
dump();
|
|
Packit |
1c1d7e |
return TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ICompoundIterator *MainHandler::compounds() const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
return new CompoundEntryIterator(this,m_compounds);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ICompound *MainHandler::compoundById(const char *id) const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QString ids = id;
|
|
Packit |
1c1d7e |
if (ids.isEmpty()) return 0;
|
|
Packit |
1c1d7e |
CompoundHandler *ch = m_compoundsLoaded[ids.utf8()];
|
|
Packit |
1c1d7e |
if (ch) // compound already in memory
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ch->addref(); // returning alias -> increase reference counter
|
|
Packit |
1c1d7e |
return ch->toICompound();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
CompoundEntry *ce = m_compoundDict.find(ids.utf8());
|
|
Packit |
1c1d7e |
if (ce==0) return 0; // id not found
|
|
Packit |
1c1d7e |
// create and load a new compound
|
|
Packit |
1c1d7e |
ch = new CompoundHandler(m_xmlDirName);
|
|
Packit |
1c1d7e |
if (!ch->parseXML(id))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
// compound could not be initialized.
|
|
Packit |
1c1d7e |
delete ch;
|
|
Packit |
1c1d7e |
return 0;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// we disregard the constness here, because the object stays conceptually
|
|
Packit |
1c1d7e |
// unchanged.
|
|
Packit |
1c1d7e |
MainHandler *that = (MainHandler *)this;
|
|
Packit |
1c1d7e |
ch->initialize(that);
|
|
Packit |
1c1d7e |
//printf("loading compound %s in memory\n",id);
|
|
Packit |
1c1d7e |
that->m_compoundsLoaded.insert(id,ch);
|
|
Packit |
1c1d7e |
return ch->toICompound();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void MainHandler::unloadCompound(CompoundHandler *ch)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("unloading compound %s from memory\n",ch->id()->latin1());
|
|
Packit |
1c1d7e |
bool result = m_compoundsLoaded.remove(ch->id()->latin1());
|
|
Packit |
1c1d7e |
if (!result) debug(1,"Failed to unload component!\n");
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ICompound *MainHandler::compoundByName(const char *name) const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QString nameStr = name;
|
|
Packit |
1c1d7e |
if (nameStr.isEmpty()) return 0;
|
|
Packit |
1c1d7e |
CompoundEntry *ce = m_compoundNameDict[name];
|
|
Packit |
1c1d7e |
if (ce==0) return 0; // name not found
|
|
Packit |
1c1d7e |
return compoundById(ce->id.utf8());
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ICompound *MainHandler::memberById(const char *id) const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QString ids = id;
|
|
Packit |
1c1d7e |
if (ids.isEmpty()) return 0;
|
|
Packit |
1c1d7e |
MemberEntry *me = m_memberDict[id];
|
|
Packit |
1c1d7e |
if (me==0) return 0; // id not found
|
|
Packit |
1c1d7e |
return compoundById(me->compound->id.utf8());
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ICompoundIterator *MainHandler::memberByName(const char *name) const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QString nameStr = name;
|
|
Packit |
1c1d7e |
if (nameStr.isEmpty()) return 0;
|
|
Packit |
1c1d7e |
QList<CompoundEntry> *cel = m_memberNameDict[name];
|
|
Packit |
1c1d7e |
if (cel==0) return 0; // name not found
|
|
Packit |
1c1d7e |
return new CompoundEntryIterator(this,*cel);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
IDoxygen *createObjectModel()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
compoundhandler_init();
|
|
Packit |
1c1d7e |
sectionhandler_init();
|
|
Packit |
1c1d7e |
memberhandler_init();
|
|
Packit |
1c1d7e |
dochandler_init();
|
|
Packit |
1c1d7e |
graphhandler_init();
|
|
Packit |
1c1d7e |
return new MainHandler;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void MainHandler::release()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("MainHandler::release()\n");
|
|
Packit |
1c1d7e |
QDictIterator<CompoundHandler> chi(m_compoundsLoaded);
|
|
Packit |
1c1d7e |
CompoundHandler *ch;
|
|
Packit |
1c1d7e |
for (chi.toFirst();(ch=chi.current());++chi)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
debug(1,"Compound %s not released\n",ch->name()->latin1());
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
graphhandler_exit();
|
|
Packit |
1c1d7e |
dochandler_exit();
|
|
Packit |
1c1d7e |
memberhandler_exit();
|
|
Packit |
1c1d7e |
sectionhandler_exit();
|
|
Packit |
1c1d7e |
compoundhandler_exit();
|
|
Packit |
1c1d7e |
delete this;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|