Blame addon/doxmlparser/src/mainhandler.cpp

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