Orb/Doxygen/addon/doxmlparser/src/mainhandler.cpp
changeset 0 42188c7ea2d9
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /******************************************************************************
       
     2  *
       
     3  * $Id: mainhandler.cpp 645 2008-08-19 13:23:22Z dimitri $
       
     4  *
       
     5  *
       
     6  * Copyright (C) 1997-2006 by Dimitri van Heesch.
       
     7  *
       
     8  * Permission to use, copy, modify, and distribute this software and its
       
     9  * documentation under the terms of the GNU General Public License is hereby 
       
    10  * granted. No representations are made about the suitability of this software 
       
    11  * for any purpose. It is provided "as is" without express or implied warranty.
       
    12  * See the GNU General Public License for more details.
       
    13  *
       
    14  */
       
    15 
       
    16 #include <qxml.h>
       
    17 #include "mainhandler.h"
       
    18 #include "compoundhandler.h"
       
    19 #include "sectionhandler.h"
       
    20 #include "graphhandler.h"
       
    21 #include "dochandler.h"
       
    22 #include "memberhandler.h"
       
    23 #include "debug.h"
       
    24 
       
    25 
       
    26 class ErrorHandler : public QXmlErrorHandler
       
    27 {
       
    28     public:
       
    29       virtual ~ErrorHandler() {}
       
    30       bool warning( const QXmlParseException & )
       
    31       {
       
    32         return FALSE;
       
    33       }
       
    34       bool error( const QXmlParseException & )
       
    35       {
       
    36         return FALSE;
       
    37       }
       
    38       bool fatalError( const QXmlParseException &exception )
       
    39       {
       
    40         debug(1,"Fatal error at line %d column %d: %s\n",
       
    41             exception.lineNumber(),exception.columnNumber(),
       
    42             exception.message().data());
       
    43         return FALSE;
       
    44       }
       
    45       QString errorString() { return ""; }
       
    46 
       
    47     private:
       
    48       QString errorMsg;
       
    49 };
       
    50 
       
    51 //--------------------------------------------------------------------------
       
    52 
       
    53 class CompoundEntryIterator : public ICompoundIterator, 
       
    54                               public QListIterator<CompoundEntry>
       
    55 {
       
    56   public:
       
    57     CompoundEntryIterator(const MainHandler *m,const QList<CompoundEntry> &list) :
       
    58       QListIterator<CompoundEntry>(list), m_mainHandler(m) {}
       
    59     virtual ~CompoundEntryIterator() {}
       
    60 
       
    61     virtual void toFirst()
       
    62     { 
       
    63       QListIterator<CompoundEntry>::toFirst(); 
       
    64     }
       
    65     virtual void toLast()
       
    66     { 
       
    67       QListIterator<CompoundEntry>::toLast(); 
       
    68     }
       
    69     virtual void toNext()
       
    70     { 
       
    71       QListIterator<CompoundEntry>::operator++(); 
       
    72     }
       
    73     virtual void toPrev()
       
    74     { 
       
    75       QListIterator<CompoundEntry>::operator--(); 
       
    76     }
       
    77     virtual ICompound *current() const
       
    78     { 
       
    79       CompoundEntry *ch = QListIterator<CompoundEntry>::current(); 
       
    80       return ch ? m_mainHandler->compoundById(ch->id) : 0;
       
    81     }
       
    82     virtual void release()
       
    83     { delete this; }
       
    84 
       
    85   private:
       
    86     const MainHandler *m_mainHandler;
       
    87 };
       
    88 
       
    89 //--------------------------------------------------------------------------
       
    90 
       
    91 MainHandler::MainHandler() : m_compoundDict(2999), m_compoundNameDict(2999),
       
    92                              m_memberDict(12251), m_memberNameDict(12251),
       
    93                              m_compoundsLoaded(1009)
       
    94 {
       
    95   m_compounds.setAutoDelete(TRUE);
       
    96   m_memberNameDict.setAutoDelete(TRUE);
       
    97   addStartHandler("doxygenindex"); 
       
    98   addEndHandler("doxygenindex");
       
    99   addStartHandler("compound",this,&MainHandler::startCompound);
       
   100   addEndHandler("compound");
       
   101   addStartHandler("member",this,&MainHandler::startMember);
       
   102   addEndHandler("member",this,&MainHandler::endMember);
       
   103   addStartHandler("name",this,&MainHandler::startName);
       
   104   addEndHandler("name",this,&MainHandler::endName);
       
   105   m_curCompound = 0;
       
   106   m_insideMember = FALSE;
       
   107 }
       
   108 
       
   109 MainHandler::~MainHandler()
       
   110 {
       
   111   debug(2,"MainHandler::~MainHandler()\n");
       
   112 }
       
   113 
       
   114 void MainHandler::startCompound(const QXmlAttributes& attrib)
       
   115 {
       
   116   m_curCompound = new CompoundEntry(257);
       
   117   m_curCompound->id = attrib.value("refid");
       
   118   m_compounds.append(m_curCompound);
       
   119   m_compoundDict.insert(m_curCompound->id,m_curCompound);
       
   120 }
       
   121 
       
   122 void MainHandler::startName(const QXmlAttributes& /*attrib*/)
       
   123 {
       
   124   m_curString = "";
       
   125 }
       
   126 
       
   127 void MainHandler::endName()
       
   128 {
       
   129   if (m_insideMember)
       
   130   {
       
   131     m_curMember->name = m_curString;
       
   132   }
       
   133   else
       
   134   {
       
   135     m_curCompound->name = m_curString;
       
   136     m_compoundNameDict.insert(m_curString,m_curCompound);
       
   137   }
       
   138 }
       
   139 
       
   140 void MainHandler::startMember(const QXmlAttributes& attrib)
       
   141 {
       
   142   m_insideMember = TRUE;
       
   143   m_curMember = new MemberEntry;
       
   144   m_curMember->id = attrib.value("refid");
       
   145   m_curMember->compound = m_curCompound;
       
   146   m_memberDict.insert(m_curMember->id,m_curMember);
       
   147 }
       
   148 
       
   149 void MainHandler::endMember()
       
   150 {
       
   151   m_curCompound->memberDict.insert(m_curMember->name,m_curMember);
       
   152   QList<CompoundEntry> *cel=0;
       
   153   if ((cel=m_memberNameDict.find(m_curMember->name))==0)
       
   154   {
       
   155     cel = new QList<CompoundEntry>;
       
   156     m_memberNameDict.insert(m_curMember->name,cel);
       
   157   }
       
   158   cel->append(m_curCompound);
       
   159   m_insideMember = FALSE;
       
   160 }
       
   161 
       
   162 void MainHandler::setDebugLevel(int level)
       
   163 {
       
   164   ::setDebugLevel(level);
       
   165 }
       
   166 
       
   167 void MainHandler::dump()
       
   168 {
       
   169   QListIterator<CompoundEntry> cli(m_compounds);
       
   170   CompoundEntry *ce;
       
   171   for (cli.toFirst();(ce=cli.current());++cli)
       
   172   {
       
   173     debug(2,"compound id=`%s' name=`%s'\n",ce->id.data(),ce->name.data());
       
   174     QDictIterator<MemberEntry> mdi(ce->memberDict);
       
   175     MemberEntry *me;
       
   176     for (mdi.toFirst();(me=mdi.current());++mdi)
       
   177     {
       
   178       debug(2,"  member id=`%s' name=`%s'\n",me->id.data(),me->name.data());
       
   179     }
       
   180   }
       
   181 }
       
   182 
       
   183 bool MainHandler::readXMLDir(const char * xmlDirName)
       
   184 {
       
   185   m_xmlDirName = xmlDirName;
       
   186   QString xmlFileName=m_xmlDirName+"/index.xml";
       
   187   QFile xmlFile(xmlFileName);
       
   188   //printf("Trying %s xmlFile.exists()=%d isReadable()=%d\n",
       
   189   //    xmlFileName.data(),xmlFile.exists(),xmlFile.isReadable());
       
   190   if (xmlFile.exists())
       
   191   {
       
   192     ErrorHandler errorHandler;
       
   193     QXmlInputSource source( xmlFile );
       
   194     QXmlSimpleReader reader;
       
   195     reader.setContentHandler( this );
       
   196     reader.setErrorHandler( &errorHandler );
       
   197     reader.parse( source );
       
   198     dump();
       
   199     return TRUE;
       
   200   }
       
   201   return FALSE;
       
   202 }
       
   203 
       
   204 ICompoundIterator *MainHandler::compounds() const
       
   205 {
       
   206   return new CompoundEntryIterator(this,m_compounds);
       
   207 }
       
   208 
       
   209 ICompound *MainHandler::compoundById(const char *id) const
       
   210 {
       
   211   QString ids = id;
       
   212   if (ids.isEmpty()) return 0;
       
   213   CompoundHandler *ch = m_compoundsLoaded[ids];
       
   214   if (ch) // compound already in memory
       
   215   {
       
   216     ch->addref(); // returning alias -> increase reference counter
       
   217     return ch->toICompound(); 
       
   218   }
       
   219   CompoundEntry *ce = m_compoundDict.find(ids);
       
   220   if (ce==0) return 0; // id not found
       
   221   // create and load a new compound
       
   222   ch = new CompoundHandler(m_xmlDirName);
       
   223   if (!ch->parseXML(id))
       
   224   {
       
   225     // compound could not be initialized.
       
   226     delete ch;
       
   227     return 0;
       
   228   }
       
   229 
       
   230   // we disregard the constness here, because the object stays conceptually
       
   231   // unchanged.
       
   232   MainHandler *that = (MainHandler *)this;
       
   233   ch->initialize(that);
       
   234   //printf("loading compound %s in memory\n",id);
       
   235   that->m_compoundsLoaded.insert(id,ch);
       
   236   return ch->toICompound();
       
   237 }
       
   238 
       
   239 void MainHandler::unloadCompound(CompoundHandler *ch)
       
   240 {
       
   241   //printf("unloading compound %s from memory\n",ch->id()->latin1());
       
   242   bool result = m_compoundsLoaded.remove(ch->id()->latin1()); 
       
   243   if (!result) debug(1,"Failed to unload component!\n");
       
   244 }
       
   245 
       
   246 ICompound *MainHandler::compoundByName(const char *name) const
       
   247 {
       
   248   QString nameStr = name;
       
   249   if (nameStr.isEmpty()) return 0;
       
   250   CompoundEntry *ce = m_compoundNameDict[name];
       
   251   if (ce==0) return 0; // name not found
       
   252   return compoundById(ce->id);
       
   253 }
       
   254 
       
   255 ICompound *MainHandler::memberById(const char *id) const
       
   256 {
       
   257   QString ids = id;
       
   258   if (ids.isEmpty()) return 0;
       
   259   MemberEntry *me = m_memberDict[id];
       
   260   if (me==0) return 0; // id not found
       
   261   return compoundById(me->compound->id);
       
   262 }
       
   263 
       
   264 ICompoundIterator *MainHandler::memberByName(const char *name) const
       
   265 {
       
   266   QString nameStr = name;
       
   267   if (nameStr.isEmpty()) return 0;
       
   268   QList<CompoundEntry> *cel = m_memberNameDict[name];
       
   269   if (cel==0) return 0; // name not found
       
   270   return new CompoundEntryIterator(this,*cel);
       
   271 }
       
   272 
       
   273 IDoxygen *createObjectModel()
       
   274 {
       
   275   compoundhandler_init();
       
   276   sectionhandler_init();
       
   277   memberhandler_init();
       
   278   dochandler_init();
       
   279   graphhandler_init();
       
   280   return new MainHandler;
       
   281 }
       
   282 
       
   283 void MainHandler::release()
       
   284 {
       
   285   //printf("MainHandler::release()\n");
       
   286   QDictIterator<CompoundHandler> chi(m_compoundsLoaded);
       
   287   CompoundHandler *ch;
       
   288   for (chi.toFirst();(ch=chi.current());++chi)
       
   289   {
       
   290     debug(1,"Compound %s not released\n",ch->name()->latin1());
       
   291   }
       
   292   graphhandler_exit();
       
   293   dochandler_exit();
       
   294   memberhandler_exit();
       
   295   sectionhandler_exit();
       
   296   compoundhandler_exit();
       
   297   delete this;
       
   298 }
       
   299