Blame src/tagreader.cpp

Packit 1c1d7e
/******************************************************************************
Packit 1c1d7e
 *
Packit 1c1d7e
 * 
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
 * Documents produced by Doxygen are derivative works derived from the
Packit 1c1d7e
 * input used in their production; they are not affected by this license.
Packit 1c1d7e
 *
Packit 1c1d7e
 */
Packit 1c1d7e
Packit 1c1d7e
#include "tagreader.h"
Packit 1c1d7e
Packit 1c1d7e
#include <stdio.h>
Packit 1c1d7e
#include <stdarg.h>
Packit 1c1d7e
Packit 1c1d7e
#include <qxml.h>
Packit 1c1d7e
#include <qstack.h>
Packit 1c1d7e
#include <qdict.h>
Packit 1c1d7e
#include <qfileinfo.h>
Packit 1c1d7e
#include <qlist.h>
Packit 1c1d7e
#include <qstring.h>
Packit 1c1d7e
#include <qstringlist.h>
Packit 1c1d7e
Packit 1c1d7e
#include "entry.h"
Packit 1c1d7e
#include "classdef.h"
Packit 1c1d7e
#include "doxygen.h"
Packit 1c1d7e
#include "util.h"
Packit 1c1d7e
#include "message.h"
Packit 1c1d7e
#include "defargs.h"
Packit 1c1d7e
#include "arguments.h"
Packit 1c1d7e
#include "filedef.h"
Packit 1c1d7e
#include "filename.h"
Packit 1c1d7e
#include "section.h"
Packit 1c1d7e
Packit 1c1d7e
/** Information about an linkable anchor */
Packit 1c1d7e
class TagAnchorInfo
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    TagAnchorInfo(const QCString &f,
Packit 1c1d7e
                  const QCString &l,
Packit 1c1d7e
                  const QCString &t=QCString()) 
Packit 1c1d7e
      : label(l), fileName(f), title(t) {}
Packit 1c1d7e
    QCString label;
Packit 1c1d7e
    QCString fileName;
Packit 1c1d7e
    QCString title;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** List of TagAnchorInfo objects. */
Packit 1c1d7e
class TagAnchorInfoList : public QList<TagAnchorInfo>
Packit 1c1d7e
{
Packit 1c1d7e
  public: 
Packit 1c1d7e
    TagAnchorInfoList() : QList<TagAnchorInfo>() { setAutoDelete(TRUE); }
Packit 1c1d7e
    virtual ~TagAnchorInfoList() {}
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Container for enum values that are scoped within an enum */
Packit 1c1d7e
class TagEnumValueInfo
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    QCString name;
Packit 1c1d7e
    QCString file;
Packit 1c1d7e
    QCString anchor;
Packit 1c1d7e
    QCString clangid;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Container for member specific info that can be read from a tagfile */
Packit 1c1d7e
class TagMemberInfo
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    TagMemberInfo() : prot(Public), virt(Normal), isStatic(FALSE) 
Packit 1c1d7e
    { enumValues.setAutoDelete(TRUE); }
Packit 1c1d7e
    QCString type;
Packit 1c1d7e
    QCString name;
Packit 1c1d7e
    QCString anchorFile;
Packit 1c1d7e
    QCString anchor;
Packit 1c1d7e
    QCString arglist;
Packit 1c1d7e
    QCString kind;
Packit 1c1d7e
    QCString clangId;
Packit 1c1d7e
    TagAnchorInfoList docAnchors;
Packit 1c1d7e
    Protection prot;
Packit 1c1d7e
    Specifier virt;
Packit 1c1d7e
    bool isStatic; 
Packit 1c1d7e
    QList<TagEnumValueInfo> enumValues;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Container for class specific info that can be read from a tagfile */
Packit 1c1d7e
class TagClassInfo
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    enum Kind { Class, Struct, Union, Interface, Exception, Protocol, Category, Enum, Service, Singleton };
Packit 1c1d7e
    TagClassInfo() { bases=0, templateArguments=0; members.setAutoDelete(TRUE); isObjC=FALSE; }
Packit 1c1d7e
   ~TagClassInfo() { delete bases; delete templateArguments; }
Packit 1c1d7e
    QCString name;
Packit 1c1d7e
    QCString filename;
Packit 1c1d7e
    QCString clangId;
Packit 1c1d7e
    TagAnchorInfoList docAnchors;
Packit 1c1d7e
    QList<BaseInfo> *bases;
Packit 1c1d7e
    QList<TagMemberInfo> members;
Packit 1c1d7e
    QList<QCString> *templateArguments;
Packit 1c1d7e
    QStringList classList;
Packit 1c1d7e
    Kind kind;
Packit 1c1d7e
    bool isObjC;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Container for namespace specific info that can be read from a tagfile */
Packit 1c1d7e
class TagNamespaceInfo
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    TagNamespaceInfo() { members.setAutoDelete(TRUE); }
Packit 1c1d7e
    QCString name;
Packit 1c1d7e
    QCString filename;
Packit 1c1d7e
    QCString clangId;
Packit 1c1d7e
    QStringList classList;
Packit 1c1d7e
    QStringList namespaceList;
Packit 1c1d7e
    TagAnchorInfoList docAnchors;
Packit 1c1d7e
    QList<TagMemberInfo> members;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Container for package specific info that can be read from a tagfile */
Packit 1c1d7e
class TagPackageInfo
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    TagPackageInfo() { members.setAutoDelete(TRUE); }
Packit 1c1d7e
    QCString name;
Packit 1c1d7e
    QCString filename;
Packit 1c1d7e
    TagAnchorInfoList docAnchors;
Packit 1c1d7e
    QList<TagMemberInfo> members;
Packit 1c1d7e
    QStringList classList;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Container for include info that can be read from a tagfile */
Packit 1c1d7e
class TagIncludeInfo
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    QCString id;
Packit 1c1d7e
    QCString name;
Packit 1c1d7e
    QCString text;
Packit 1c1d7e
    bool isLocal;
Packit 1c1d7e
    bool isImported;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Container for file specific info that can be read from a tagfile */
Packit 1c1d7e
class TagFileInfo
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    TagFileInfo() { members.setAutoDelete(TRUE); includes.setAutoDelete(TRUE); }
Packit 1c1d7e
    QCString name;
Packit 1c1d7e
    QCString path;
Packit 1c1d7e
    QCString filename;
Packit 1c1d7e
    TagAnchorInfoList docAnchors;
Packit 1c1d7e
    QList<TagMemberInfo> members;
Packit 1c1d7e
    QStringList classList;
Packit 1c1d7e
    QStringList namespaceList;
Packit 1c1d7e
    QList<TagIncludeInfo> includes;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Container for group specific info that can be read from a tagfile */
Packit 1c1d7e
class TagGroupInfo
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    TagGroupInfo() { members.setAutoDelete(TRUE); }
Packit 1c1d7e
    QCString name;
Packit 1c1d7e
    QCString title;
Packit 1c1d7e
    QCString filename;
Packit 1c1d7e
    TagAnchorInfoList docAnchors;
Packit 1c1d7e
    QList<TagMemberInfo> members;
Packit 1c1d7e
    QStringList subgroupList;
Packit 1c1d7e
    QStringList classList;
Packit 1c1d7e
    QStringList namespaceList;
Packit 1c1d7e
    QStringList fileList;
Packit 1c1d7e
    QStringList pageList;
Packit 1c1d7e
    QStringList dirList;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Container for page specific info that can be read from a tagfile */
Packit 1c1d7e
class TagPageInfo
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    QCString name;
Packit 1c1d7e
    QCString title;
Packit 1c1d7e
    QCString filename;
Packit 1c1d7e
    TagAnchorInfoList docAnchors;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Container for directory specific info that can be read from a tagfile */
Packit 1c1d7e
class TagDirInfo
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    QCString name;
Packit 1c1d7e
    QCString filename;
Packit 1c1d7e
    QCString path;
Packit 1c1d7e
    QStringList subdirList;
Packit 1c1d7e
    QStringList fileList;
Packit 1c1d7e
    TagAnchorInfoList docAnchors;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Tag file parser. 
Packit 1c1d7e
 *
Packit 1c1d7e
 *  Reads an XML-structured tagfile and builds up the structure in
Packit 1c1d7e
 *  memory. The method buildLists() is used to transfer/translate 
Packit 1c1d7e
 *  the structures to the doxygen engine.
Packit 1c1d7e
 */
Packit 1c1d7e
class TagFileParser : public QXmlDefaultHandler
Packit 1c1d7e
{
Packit 1c1d7e
    enum State { Invalid,
Packit 1c1d7e
                 InClass,
Packit 1c1d7e
                 InFile,
Packit 1c1d7e
                 InNamespace,
Packit 1c1d7e
                 InGroup,
Packit 1c1d7e
                 InPage,
Packit 1c1d7e
                 InMember,
Packit 1c1d7e
                 InEnumValue,
Packit 1c1d7e
                 InPackage,
Packit 1c1d7e
                 InDir,
Packit 1c1d7e
                 InTempArgList
Packit 1c1d7e
               };
Packit 1c1d7e
    class StartElementHandler
Packit 1c1d7e
    {
Packit 1c1d7e
        typedef void (TagFileParser::*Handler)(const QXmlAttributes &attrib); 
Packit 1c1d7e
      public:
Packit 1c1d7e
        StartElementHandler(TagFileParser *parent, Handler h) : m_parent(parent), m_handler(h) {}
Packit 1c1d7e
        void operator()(const QXmlAttributes &attrib) { (m_parent->*m_handler)(attrib); }
Packit 1c1d7e
      private:
Packit 1c1d7e
        TagFileParser *m_parent;
Packit 1c1d7e
        Handler m_handler;
Packit 1c1d7e
    };
Packit 1c1d7e
Packit 1c1d7e
    class EndElementHandler
Packit 1c1d7e
    {
Packit 1c1d7e
        typedef void (TagFileParser::*Handler)(); 
Packit 1c1d7e
      public:
Packit 1c1d7e
        EndElementHandler(TagFileParser *parent, Handler h) : m_parent(parent), m_handler(h) {}
Packit 1c1d7e
        void operator()() { (m_parent->*m_handler)(); }
Packit 1c1d7e
      private:
Packit 1c1d7e
        TagFileParser *m_parent;
Packit 1c1d7e
        Handler m_handler;
Packit 1c1d7e
    };
Packit 1c1d7e
Packit 1c1d7e
  public:
Packit 1c1d7e
    TagFileParser(const char *tagName) : m_startElementHandlers(17),
Packit 1c1d7e
                                         m_endElementHandlers(17),
Packit 1c1d7e
                                         m_tagName(tagName)
Packit 1c1d7e
    {
Packit 1c1d7e
      m_startElementHandlers.setAutoDelete(TRUE);
Packit 1c1d7e
      m_endElementHandlers.setAutoDelete(TRUE);
Packit 1c1d7e
      m_curClass=0;
Packit 1c1d7e
      m_curFile=0;
Packit 1c1d7e
      m_curNamespace=0;
Packit 1c1d7e
      m_curPackage=0;
Packit 1c1d7e
      m_curGroup=0;
Packit 1c1d7e
      m_curPage=0;
Packit 1c1d7e
      m_curDir=0;
Packit 1c1d7e
      m_curMember=0;
Packit 1c1d7e
      m_curEnumValue=0;
Packit 1c1d7e
      m_curIncludes=0;
Packit 1c1d7e
      m_state = Invalid;
Packit 1c1d7e
      m_locator = 0;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void setDocumentLocator ( QXmlLocator * locator )
Packit 1c1d7e
    {
Packit 1c1d7e
      m_locator = locator;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void setFileName( const QString &fileName )
Packit 1c1d7e
    {
Packit 1c1d7e
      m_inputFileName = fileName.utf8();
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void warn(const char *fmt)
Packit 1c1d7e
    {
Packit 1c1d7e
      ::warn(m_inputFileName,m_locator->lineNumber(),fmt);
Packit 1c1d7e
    }
Packit 1c1d7e
    void warn(const char *fmt,const char *s)
Packit 1c1d7e
    {
Packit 1c1d7e
      ::warn(m_inputFileName,m_locator->lineNumber(),fmt,s);
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void startCompound( const QXmlAttributes& attrib )
Packit 1c1d7e
    {
Packit 1c1d7e
      m_curString = "";
Packit 1c1d7e
      QString kind = attrib.value("kind");
Packit 1c1d7e
      QString isObjC = attrib.value("objc");
Packit 1c1d7e
      if (kind=="class")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass = new TagClassInfo;
Packit 1c1d7e
        m_curClass->kind = TagClassInfo::Class;
Packit 1c1d7e
        m_state = InClass;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="struct")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass = new TagClassInfo;
Packit 1c1d7e
        m_curClass->kind = TagClassInfo::Struct;
Packit 1c1d7e
        m_state = InClass;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="union")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass = new TagClassInfo;
Packit 1c1d7e
        m_curClass->kind = TagClassInfo::Union;
Packit 1c1d7e
        m_state = InClass;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="interface")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass = new TagClassInfo;
Packit 1c1d7e
        m_curClass->kind = TagClassInfo::Interface;
Packit 1c1d7e
        m_state = InClass;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="enum")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass = new TagClassInfo;
Packit 1c1d7e
        m_curClass->kind = TagClassInfo::Enum;
Packit 1c1d7e
        m_state = InClass;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="exception")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass = new TagClassInfo;
Packit 1c1d7e
        m_curClass->kind = TagClassInfo::Exception;
Packit 1c1d7e
        m_state = InClass;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="protocol")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass = new TagClassInfo;
Packit 1c1d7e
        m_curClass->kind = TagClassInfo::Protocol;
Packit 1c1d7e
        m_state = InClass;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="category")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass = new TagClassInfo;
Packit 1c1d7e
        m_curClass->kind = TagClassInfo::Category;
Packit 1c1d7e
        m_state = InClass;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="service")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass = new TagClassInfo;
Packit 1c1d7e
        m_curClass->kind = TagClassInfo::Service;
Packit 1c1d7e
        m_state = InClass;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="singleton")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass = new TagClassInfo;
Packit 1c1d7e
        m_curClass->kind = TagClassInfo::Singleton;
Packit 1c1d7e
        m_state = InClass;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="file")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curFile = new TagFileInfo;
Packit 1c1d7e
        m_state = InFile;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="namespace")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curNamespace = new TagNamespaceInfo;
Packit 1c1d7e
        m_state = InNamespace;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="group")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curGroup = new TagGroupInfo;
Packit 1c1d7e
        m_state = InGroup;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="page")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curPage = new TagPageInfo;
Packit 1c1d7e
        m_state = InPage;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="package")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curPackage = new TagPackageInfo;
Packit 1c1d7e
        m_state = InPackage;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (kind=="dir")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curDir = new TagDirInfo;
Packit 1c1d7e
        m_state = InDir;
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unknown compound attribute `%s' found!\n",kind.data());
Packit 1c1d7e
        m_state = Invalid;
Packit 1c1d7e
      }
Packit 1c1d7e
      if (isObjC=="yes" && m_curClass)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass->isObjC = TRUE; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endCompound()
Packit 1c1d7e
    {
Packit 1c1d7e
      switch (m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InClass:     m_tagFileClasses.append(m_curClass); 
Packit 1c1d7e
                          m_curClass=0; break; 
Packit 1c1d7e
        case InFile:      m_tagFileFiles.append(m_curFile); 
Packit 1c1d7e
                          m_curFile=0; break; 
Packit 1c1d7e
        case InNamespace: m_tagFileNamespaces.append(m_curNamespace); 
Packit 1c1d7e
                          m_curNamespace=0; break; 
Packit 1c1d7e
        case InGroup:     m_tagFileGroups.append(m_curGroup); 
Packit 1c1d7e
                          m_curGroup=0; break; 
Packit 1c1d7e
        case InPage:      m_tagFilePages.append(m_curPage); 
Packit 1c1d7e
                          m_curPage=0; break; 
Packit 1c1d7e
        case InDir:       m_tagFileDirs.append(m_curDir);
Packit 1c1d7e
                          m_curDir=0; break;
Packit 1c1d7e
        case InPackage:   m_tagFilePackages.append(m_curPackage); 
Packit 1c1d7e
                          m_curPackage=0; break; 
Packit 1c1d7e
        default:
Packit 1c1d7e
                          warn("tag `compound' was not expected!\n");
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void startMember( const QXmlAttributes& attrib)
Packit 1c1d7e
    {
Packit 1c1d7e
      m_curMember = new TagMemberInfo;
Packit 1c1d7e
      m_curMember->kind = attrib.value("kind").utf8();
Packit 1c1d7e
      QCString protStr   = attrib.value("protection").utf8();
Packit 1c1d7e
      QCString virtStr   = attrib.value("virtualness").utf8();
Packit 1c1d7e
      QCString staticStr = attrib.value("static").utf8();
Packit 1c1d7e
      if (protStr=="protected")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curMember->prot = Protected;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (protStr=="private")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curMember->prot = Private;
Packit 1c1d7e
      }
Packit 1c1d7e
      if (virtStr=="virtual")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curMember->virt = Virtual;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (virtStr=="pure")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curMember->virt = Pure;
Packit 1c1d7e
      }
Packit 1c1d7e
      if (staticStr=="yes")
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curMember->isStatic = TRUE;
Packit 1c1d7e
      }
Packit 1c1d7e
      m_stateStack.push(new State(m_state));
Packit 1c1d7e
      m_state = InMember;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endMember()
Packit 1c1d7e
    {
Packit 1c1d7e
      m_state = *m_stateStack.top();
Packit 1c1d7e
      m_stateStack.remove();
Packit 1c1d7e
      switch(m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InClass:     m_curClass->members.append(m_curMember); break;
Packit 1c1d7e
        case InFile:      m_curFile->members.append(m_curMember); break;
Packit 1c1d7e
        case InNamespace: m_curNamespace->members.append(m_curMember); break;
Packit 1c1d7e
        case InGroup:     m_curGroup->members.append(m_curMember); break;
Packit 1c1d7e
        case InPackage:   m_curPackage->members.append(m_curMember); break;
Packit 1c1d7e
        default:   warn("Unexpected tag `member' found\n"); break; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void startEnumValue( const QXmlAttributes& attrib)
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_state==InMember)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curString = "";
Packit 1c1d7e
        m_curEnumValue = new TagEnumValueInfo;
Packit 1c1d7e
        m_curEnumValue->file = attrib.value("file").utf8();
Packit 1c1d7e
        m_curEnumValue->anchor = attrib.value("anchor").utf8();
Packit 1c1d7e
        m_curEnumValue->clangid = attrib.value("clangid").utf8();
Packit 1c1d7e
        m_stateStack.push(new State(m_state));
Packit 1c1d7e
        m_state = InEnumValue;
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Found enumvalue tag outside of member tag\n");
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endEnumValue()
Packit 1c1d7e
    {
Packit 1c1d7e
      m_curEnumValue->name = m_curString.stripWhiteSpace(); 
Packit 1c1d7e
      m_state = *m_stateStack.top();
Packit 1c1d7e
      m_stateStack.remove();
Packit 1c1d7e
      if (m_state==InMember)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curMember->enumValues.append(m_curEnumValue);
Packit 1c1d7e
        m_curEnumValue=0;
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endDocAnchor()
Packit 1c1d7e
    {
Packit 1c1d7e
      switch(m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InClass:     m_curClass->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
Packit 1c1d7e
        case InFile:      m_curFile->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
Packit 1c1d7e
        case InNamespace: m_curNamespace->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
Packit 1c1d7e
        case InGroup:     m_curGroup->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
Packit 1c1d7e
        case InPage:      m_curPage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
Packit 1c1d7e
        case InMember:    m_curMember->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
Packit 1c1d7e
        case InPackage:   m_curPackage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
Packit 1c1d7e
        case InDir:       m_curDir->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
Packit 1c1d7e
        default:   warn("Unexpected tag `member' found\n"); break; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endClass()
Packit 1c1d7e
    {
Packit 1c1d7e
      switch(m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InClass:     m_curClass->classList.append(m_curString); break;
Packit 1c1d7e
        case InFile:      m_curFile->classList.append(m_curString); break;
Packit 1c1d7e
        case InNamespace: m_curNamespace->classList.append(m_curString); break;
Packit 1c1d7e
        case InGroup:     m_curGroup->classList.append(m_curString); break;
Packit 1c1d7e
        case InPackage:   m_curPackage->classList.append(m_curString); break;
Packit 1c1d7e
        default:   warn("Unexpected tag `class' found\n"); break; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endNamespace()
Packit 1c1d7e
    {
Packit 1c1d7e
      switch(m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InNamespace: m_curNamespace->classList.append(m_curString); break;
Packit 1c1d7e
        case InFile:      m_curFile->namespaceList.append(m_curString); break;
Packit 1c1d7e
        case InGroup:     m_curGroup->namespaceList.append(m_curString); break;
Packit 1c1d7e
        default:   warn("Unexpected tag `namespace' found\n"); break; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endFile()
Packit 1c1d7e
    {
Packit 1c1d7e
      switch(m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InGroup:      m_curGroup->fileList.append(m_curString); break;
Packit 1c1d7e
        case InDir:        m_curDir->fileList.append(m_curString); break;
Packit 1c1d7e
        default:   warn("Unexpected tag `file' found\n"); break; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endPage()
Packit 1c1d7e
    {
Packit 1c1d7e
      switch(m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InGroup:      m_curGroup->fileList.append(m_curString); break;
Packit 1c1d7e
        default:   warn("Unexpected tag `page' found\n"); break; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endDir()
Packit 1c1d7e
    {
Packit 1c1d7e
      switch(m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InDir:      m_curDir->subdirList.append(m_curString); break;
Packit 1c1d7e
        default:   warn("Unexpected tag `page' found\n"); break; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void startStringValue(const QXmlAttributes& )
Packit 1c1d7e
    {
Packit 1c1d7e
      m_curString = "";
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void startDocAnchor(const QXmlAttributes& attrib )
Packit 1c1d7e
    {
Packit 1c1d7e
      m_fileName = attrib.value("file").utf8();
Packit 1c1d7e
      m_title = attrib.value("title").utf8();
Packit 1c1d7e
      m_curString = "";
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endType()
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_state==InMember)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curMember->type = m_curString; 
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unexpected tag `type' found\n");
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endName()
Packit 1c1d7e
    {
Packit 1c1d7e
      switch (m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InClass:     m_curClass->name     = m_curString; break;
Packit 1c1d7e
        case InFile:      m_curFile->name      = m_curString; break;
Packit 1c1d7e
        case InNamespace: m_curNamespace->name = m_curString; break;
Packit 1c1d7e
        case InGroup:     m_curGroup->name     = m_curString; break;
Packit 1c1d7e
        case InPage:      m_curPage->name      = m_curString; break;
Packit 1c1d7e
        case InDir:       m_curDir->name       = m_curString; break;
Packit 1c1d7e
        case InMember:    m_curMember->name    = m_curString; break;
Packit 1c1d7e
        case InPackage:   m_curPackage->name   = m_curString; break;
Packit 1c1d7e
        default: warn("Unexpected tag `name' found\n"); break; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void startBase(const QXmlAttributes& attrib )
Packit 1c1d7e
    {
Packit 1c1d7e
      m_curString="";
Packit 1c1d7e
      if (m_state==InClass && m_curClass)
Packit 1c1d7e
      {
Packit 1c1d7e
        QString protStr = attrib.value("protection");
Packit 1c1d7e
        QString virtStr = attrib.value("virtualness");
Packit 1c1d7e
        Protection prot = Public;
Packit 1c1d7e
        Specifier  virt = Normal;
Packit 1c1d7e
        if (protStr=="protected")
Packit 1c1d7e
        {
Packit 1c1d7e
          prot = Protected;
Packit 1c1d7e
        }
Packit 1c1d7e
        else if (protStr=="private")
Packit 1c1d7e
        {
Packit 1c1d7e
          prot = Private;
Packit 1c1d7e
        }
Packit 1c1d7e
        if (virtStr=="virtual")
Packit 1c1d7e
        {
Packit 1c1d7e
          virt = Virtual;
Packit 1c1d7e
        }
Packit 1c1d7e
        if (m_curClass->bases==0) 
Packit 1c1d7e
        {
Packit 1c1d7e
          m_curClass->bases = new QList<BaseInfo>;
Packit 1c1d7e
          m_curClass->bases->setAutoDelete(TRUE);
Packit 1c1d7e
        }
Packit 1c1d7e
        m_curClass->bases->append(new BaseInfo(m_curString,prot,virt));
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unexpected tag `base' found\n");
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endBase()
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_state==InClass && m_curClass)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass->bases->getLast()->name = m_curString;
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unexpected tag `base' found\n");
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void startIncludes(const QXmlAttributes& attrib )
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_state==InFile && m_curFile)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curIncludes = new TagIncludeInfo;
Packit 1c1d7e
        m_curIncludes->id = attrib.value("id").utf8();
Packit 1c1d7e
        m_curIncludes->name = attrib.value("name").utf8();
Packit 1c1d7e
        m_curIncludes->isLocal = attrib.value("local").utf8()=="yes" ? TRUE : FALSE;
Packit 1c1d7e
        m_curIncludes->isImported = attrib.value("imported").utf8()=="yes" ? TRUE : FALSE;
Packit 1c1d7e
        m_curFile->includes.append(m_curIncludes);
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unexpected tag `includes' found\n");
Packit 1c1d7e
      }
Packit 1c1d7e
      m_curString="";
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endIncludes()
Packit 1c1d7e
    {
Packit 1c1d7e
      m_curIncludes->text = m_curString;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endTemplateArg()
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_state==InClass && m_curClass)
Packit 1c1d7e
      {
Packit 1c1d7e
        if (m_curClass->templateArguments==0) 
Packit 1c1d7e
        {
Packit 1c1d7e
          m_curClass->templateArguments = new QList<QCString>;
Packit 1c1d7e
          m_curClass->templateArguments->setAutoDelete(TRUE);
Packit 1c1d7e
        }
Packit 1c1d7e
        m_curClass->templateArguments->append(new QCString(m_curString));
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unexpected tag `templarg' found\n");
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endFilename()
Packit 1c1d7e
    {
Packit 1c1d7e
      switch (m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InClass:     m_curClass->filename     = m_curString;    break;
Packit 1c1d7e
        case InNamespace: m_curNamespace->filename = m_curString;    break;
Packit 1c1d7e
        case InFile:      m_curFile->filename      = m_curString;    break;
Packit 1c1d7e
        case InGroup:     m_curGroup->filename     = m_curString;    break;
Packit 1c1d7e
        case InPage:      m_curPage->filename      = m_curString;    break;
Packit 1c1d7e
        case InPackage:   m_curPackage->filename   = m_curString;    break;
Packit 1c1d7e
        case InDir:       m_curDir->filename       = m_curString;    break;
Packit 1c1d7e
        default: warn("Unexpected tag `filename' found\n"); break; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endPath()
Packit 1c1d7e
    {
Packit 1c1d7e
      switch (m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InFile:      m_curFile->path          = m_curString;    break;
Packit 1c1d7e
        case InDir:       m_curDir->path           = m_curString;    break;
Packit 1c1d7e
        default: warn("Unexpected tag `path' found\n");     break; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    
Packit 1c1d7e
    void endAnchor()
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_state==InMember)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curMember->anchor = m_curString; 
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unexpected tag `anchor' found\n");
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endClangId()
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_state==InMember)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curMember->clangId = m_curString; 
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (m_state==InClass)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curClass->clangId =  m_curString;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (m_state==InNamespace)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curNamespace->clangId = m_curString;
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("warning: Unexpected tag `anchor' found\n");
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
    
Packit 1c1d7e
    void endAnchorFile()
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_state==InMember)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curMember->anchorFile = m_curString; 
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unexpected tag `anchorfile' found\n");
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    
Packit 1c1d7e
    void endArglist()
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_state==InMember)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curMember->arglist = m_curString; 
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unexpected tag `arglist' found\n");
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    void endTitle()
Packit 1c1d7e
    {
Packit 1c1d7e
      switch (m_state)
Packit 1c1d7e
      {
Packit 1c1d7e
        case InGroup:     m_curGroup->title     = m_curString;    break;
Packit 1c1d7e
        case InPage:      m_curPage->title      = m_curString;    break;
Packit 1c1d7e
        default: warn("Unexpected tag `title' found\n"); break; 
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endSubgroup()
Packit 1c1d7e
    {
Packit 1c1d7e
      if (m_state==InGroup)
Packit 1c1d7e
      {
Packit 1c1d7e
        m_curGroup->subgroupList.append(m_curString);
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unexpected tag `subgroup' found\n");
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void startIgnoreElement(const QXmlAttributes& )
Packit 1c1d7e
    {
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void endIgnoreElement()
Packit 1c1d7e
    {
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    bool startDocument()
Packit 1c1d7e
    {
Packit 1c1d7e
      m_state = Invalid;
Packit 1c1d7e
Packit 1c1d7e
      m_curClass=0;
Packit 1c1d7e
      m_curNamespace=0;
Packit 1c1d7e
      m_curFile=0;
Packit 1c1d7e
      m_curGroup=0;
Packit 1c1d7e
      m_curPage=0;
Packit 1c1d7e
      m_curPackage=0;
Packit 1c1d7e
      m_curDir=0;
Packit 1c1d7e
Packit 1c1d7e
      m_stateStack.setAutoDelete(TRUE);
Packit 1c1d7e
      m_tagFileClasses.setAutoDelete(TRUE);
Packit 1c1d7e
      m_tagFileFiles.setAutoDelete(TRUE);
Packit 1c1d7e
      m_tagFileNamespaces.setAutoDelete(TRUE);
Packit 1c1d7e
      m_tagFileGroups.setAutoDelete(TRUE);
Packit 1c1d7e
      m_tagFilePages.setAutoDelete(TRUE);
Packit 1c1d7e
      m_tagFilePackages.setAutoDelete(TRUE);
Packit 1c1d7e
      m_tagFileDirs.setAutoDelete(TRUE);
Packit 1c1d7e
Packit 1c1d7e
      m_startElementHandlers.insert("compound",    new StartElementHandler(this,&TagFileParser::startCompound));
Packit 1c1d7e
      m_startElementHandlers.insert("member",      new StartElementHandler(this,&TagFileParser::startMember));
Packit 1c1d7e
      m_startElementHandlers.insert("enumvalue",   new StartElementHandler(this,&TagFileParser::startEnumValue));
Packit 1c1d7e
      m_startElementHandlers.insert("name",        new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("base",        new StartElementHandler(this,&TagFileParser::startBase));
Packit 1c1d7e
      m_startElementHandlers.insert("filename",    new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("includes",    new StartElementHandler(this,&TagFileParser::startIncludes));
Packit 1c1d7e
      m_startElementHandlers.insert("path",        new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("anchorfile",  new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("anchor",      new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("clangid",     new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("arglist",     new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("title",       new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("subgroup",    new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("class",       new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("namespace",   new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("file",        new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("dir",         new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("page",        new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("docanchor",   new StartElementHandler(this,&TagFileParser::startDocAnchor));
Packit 1c1d7e
      m_startElementHandlers.insert("tagfile",     new StartElementHandler(this,&TagFileParser::startIgnoreElement));
Packit 1c1d7e
      m_startElementHandlers.insert("templarg",    new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
      m_startElementHandlers.insert("type",        new StartElementHandler(this,&TagFileParser::startStringValue));
Packit 1c1d7e
Packit 1c1d7e
      m_endElementHandlers.insert("compound",    new EndElementHandler(this,&TagFileParser::endCompound));
Packit 1c1d7e
      m_endElementHandlers.insert("member",      new EndElementHandler(this,&TagFileParser::endMember));
Packit 1c1d7e
      m_endElementHandlers.insert("enumvalue",   new EndElementHandler(this,&TagFileParser::endEnumValue));
Packit 1c1d7e
      m_endElementHandlers.insert("name",        new EndElementHandler(this,&TagFileParser::endName));
Packit 1c1d7e
      m_endElementHandlers.insert("base",        new EndElementHandler(this,&TagFileParser::endBase));
Packit 1c1d7e
      m_endElementHandlers.insert("filename",    new EndElementHandler(this,&TagFileParser::endFilename));
Packit 1c1d7e
      m_endElementHandlers.insert("includes",    new EndElementHandler(this,&TagFileParser::endIncludes));
Packit 1c1d7e
      m_endElementHandlers.insert("path",        new EndElementHandler(this,&TagFileParser::endPath));
Packit 1c1d7e
      m_endElementHandlers.insert("anchorfile",  new EndElementHandler(this,&TagFileParser::endAnchorFile));
Packit 1c1d7e
      m_endElementHandlers.insert("anchor",      new EndElementHandler(this,&TagFileParser::endAnchor));
Packit 1c1d7e
      m_endElementHandlers.insert("clangid",     new EndElementHandler(this,&TagFileParser::endClangId));
Packit 1c1d7e
      m_endElementHandlers.insert("arglist",     new EndElementHandler(this,&TagFileParser::endArglist));
Packit 1c1d7e
      m_endElementHandlers.insert("title",       new EndElementHandler(this,&TagFileParser::endTitle));
Packit 1c1d7e
      m_endElementHandlers.insert("subgroup",    new EndElementHandler(this,&TagFileParser::endSubgroup));
Packit 1c1d7e
      m_endElementHandlers.insert("class"   ,    new EndElementHandler(this,&TagFileParser::endClass));
Packit 1c1d7e
      m_endElementHandlers.insert("namespace",   new EndElementHandler(this,&TagFileParser::endNamespace));
Packit 1c1d7e
      m_endElementHandlers.insert("file",        new EndElementHandler(this,&TagFileParser::endFile));
Packit 1c1d7e
      m_endElementHandlers.insert("dir",         new EndElementHandler(this,&TagFileParser::endDir));
Packit 1c1d7e
      m_endElementHandlers.insert("page",        new EndElementHandler(this,&TagFileParser::endPage));
Packit 1c1d7e
      m_endElementHandlers.insert("docanchor",   new EndElementHandler(this,&TagFileParser::endDocAnchor));
Packit 1c1d7e
      m_endElementHandlers.insert("tagfile",     new EndElementHandler(this,&TagFileParser::endIgnoreElement));
Packit 1c1d7e
      m_endElementHandlers.insert("templarg",    new EndElementHandler(this,&TagFileParser::endTemplateArg));
Packit 1c1d7e
      m_endElementHandlers.insert("type",        new EndElementHandler(this,&TagFileParser::endType));
Packit 1c1d7e
Packit 1c1d7e
      return TRUE;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    bool startElement( const QString&, const QString&, 
Packit 1c1d7e
                       const QString&name, const QXmlAttributes& attrib )
Packit 1c1d7e
    {
Packit 1c1d7e
      //printf("startElement `%s'\n",name.data());
Packit 1c1d7e
      StartElementHandler *handler = m_startElementHandlers[name.utf8()];
Packit 1c1d7e
      if (handler)
Packit 1c1d7e
      {
Packit 1c1d7e
        (*handler)(attrib);
Packit 1c1d7e
      }
Packit 1c1d7e
      else 
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unknown tag `%s' found!\n",name.data());
Packit 1c1d7e
      }
Packit 1c1d7e
      return TRUE;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    bool endElement( const QString&, const QString&, const QString& name )
Packit 1c1d7e
    {
Packit 1c1d7e
      //printf("endElement `%s'\n",name.data());
Packit 1c1d7e
      EndElementHandler *handler = m_endElementHandlers[name.utf8()];
Packit 1c1d7e
      if (handler)
Packit 1c1d7e
      {
Packit 1c1d7e
        (*handler)();
Packit 1c1d7e
      }
Packit 1c1d7e
      else 
Packit 1c1d7e
      {
Packit 1c1d7e
        warn("Unknown tag `%s' found!\n",name.data());
Packit 1c1d7e
      }
Packit 1c1d7e
      return TRUE;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    bool characters ( const QString & ch ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      m_curString+=ch.utf8();
Packit 1c1d7e
      return TRUE;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    void dump();
Packit 1c1d7e
    void buildLists(Entry *root);
Packit 1c1d7e
    void addIncludes();
Packit 1c1d7e
    
Packit 1c1d7e
  private:
Packit 1c1d7e
    void buildMemberList(Entry *ce,QList<TagMemberInfo> &members);
Packit 1c1d7e
    void addDocAnchors(Entry *e,const TagAnchorInfoList &l);
Packit 1c1d7e
    QList<TagClassInfo>        m_tagFileClasses;
Packit 1c1d7e
    QList<TagFileInfo>         m_tagFileFiles;
Packit 1c1d7e
    QList<TagNamespaceInfo>    m_tagFileNamespaces;
Packit 1c1d7e
    QList<TagGroupInfo>        m_tagFileGroups;
Packit 1c1d7e
    QList<TagPageInfo>         m_tagFilePages;
Packit 1c1d7e
    QList<TagPackageInfo>      m_tagFilePackages;
Packit 1c1d7e
    QList<TagDirInfo>          m_tagFileDirs;
Packit 1c1d7e
    QDict<StartElementHandler> m_startElementHandlers;
Packit 1c1d7e
    QDict<EndElementHandler>   m_endElementHandlers;
Packit 1c1d7e
    TagClassInfo              *m_curClass;
Packit 1c1d7e
    TagFileInfo               *m_curFile;
Packit 1c1d7e
    TagNamespaceInfo          *m_curNamespace;
Packit 1c1d7e
    TagPackageInfo            *m_curPackage;
Packit 1c1d7e
    TagGroupInfo              *m_curGroup;
Packit 1c1d7e
    TagPageInfo               *m_curPage;
Packit 1c1d7e
    TagDirInfo                *m_curDir;
Packit 1c1d7e
    TagMemberInfo             *m_curMember;
Packit 1c1d7e
    TagEnumValueInfo          *m_curEnumValue;
Packit 1c1d7e
    TagIncludeInfo            *m_curIncludes;
Packit 1c1d7e
    QCString                   m_curString;
Packit 1c1d7e
    QCString                   m_tagName;
Packit 1c1d7e
    QCString                   m_fileName;
Packit 1c1d7e
    QCString                   m_title;
Packit 1c1d7e
    State                      m_state;
Packit 1c1d7e
    QStack<State>              m_stateStack;
Packit 1c1d7e
    QXmlLocator               *m_locator;
Packit 1c1d7e
    QCString                   m_inputFileName;
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/** Error handler for the XML tag file parser. 
Packit 1c1d7e
 *
Packit 1c1d7e
 *  Basically dumps all fatal error to stderr using err().
Packit 1c1d7e
 */
Packit 1c1d7e
class TagFileErrorHandler : public QXmlErrorHandler
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    virtual ~TagFileErrorHandler() {}
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
      err("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
/*! Dumps the internal structures. For debugging only! */
Packit 1c1d7e
void TagFileParser::dump()
Packit 1c1d7e
{
Packit 1c1d7e
  msg("Result:\n");
Packit 1c1d7e
  QListIterator<TagClassInfo> lci(m_tagFileClasses);
Packit 1c1d7e
Packit 1c1d7e
  //============== CLASSES
Packit 1c1d7e
  TagClassInfo *cd;
Packit 1c1d7e
  for (;(cd=lci.current());++lci)
Packit 1c1d7e
  {
Packit 1c1d7e
    msg("class `%s'\n",cd->name.data());
Packit 1c1d7e
    msg("  filename `%s'\n",cd->filename.data());
Packit 1c1d7e
    if (cd->bases)
Packit 1c1d7e
    {
Packit 1c1d7e
      QListIterator<BaseInfo> bii(*cd->bases);
Packit 1c1d7e
      BaseInfo *bi;
Packit 1c1d7e
      for ( bii.toFirst() ; (bi=bii.current()) ; ++bii) 
Packit 1c1d7e
      {
Packit 1c1d7e
        msg( "  base: %s \n", bi->name.data() );
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    QListIterator<TagMemberInfo> mci(cd->members);
Packit 1c1d7e
    TagMemberInfo *md;
Packit 1c1d7e
    for (;(md=mci.current());++mci)
Packit 1c1d7e
    {
Packit 1c1d7e
      msg("  member:\n");
Packit 1c1d7e
      msg("    kind: `%s'\n",md->kind.data());
Packit 1c1d7e
      msg("    name: `%s'\n",md->name.data());
Packit 1c1d7e
      msg("    anchor: `%s'\n",md->anchor.data());
Packit 1c1d7e
      msg("    arglist: `%s'\n",md->arglist.data());
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
  //============== NAMESPACES
Packit 1c1d7e
  QListIterator<TagNamespaceInfo> lni(m_tagFileNamespaces);
Packit 1c1d7e
  TagNamespaceInfo *nd;
Packit 1c1d7e
  for (;(nd=lni.current());++lni)
Packit 1c1d7e
  {
Packit 1c1d7e
    msg("namespace `%s'\n",nd->name.data());
Packit 1c1d7e
    msg("  filename `%s'\n",nd->filename.data());
Packit 1c1d7e
    QStringList::Iterator it;
Packit 1c1d7e
    for ( it = nd->classList.begin(); 
Packit 1c1d7e
        it != nd->classList.end(); ++it ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      msg( "  class: %s \n", (*it).latin1() );
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    QListIterator<TagMemberInfo> mci(nd->members);
Packit 1c1d7e
    TagMemberInfo *md;
Packit 1c1d7e
    for (;(md=mci.current());++mci)
Packit 1c1d7e
    {
Packit 1c1d7e
      msg("  member:\n");
Packit 1c1d7e
      msg("    kind: `%s'\n",md->kind.data());
Packit 1c1d7e
      msg("    name: `%s'\n",md->name.data());
Packit 1c1d7e
      msg("    anchor: `%s'\n",md->anchor.data());
Packit 1c1d7e
      msg("    arglist: `%s'\n",md->arglist.data());
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
  //============== FILES
Packit 1c1d7e
  QListIterator<TagFileInfo> lfi(m_tagFileFiles);
Packit 1c1d7e
  TagFileInfo *fd;
Packit 1c1d7e
  for (;(fd=lfi.current());++lfi)
Packit 1c1d7e
  {
Packit 1c1d7e
    msg("file `%s'\n",fd->name.data());
Packit 1c1d7e
    msg("  filename `%s'\n",fd->filename.data());
Packit 1c1d7e
    QStringList::Iterator it;
Packit 1c1d7e
    for ( it = fd->namespaceList.begin(); 
Packit 1c1d7e
        it != fd->namespaceList.end(); ++it ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      msg( "  namespace: %s \n", (*it).latin1() );
Packit 1c1d7e
    }
Packit 1c1d7e
    for ( it = fd->classList.begin(); 
Packit 1c1d7e
        it != fd->classList.end(); ++it ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      msg( "  class: %s \n", (*it).latin1() );
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    QListIterator<TagMemberInfo> mci(fd->members);
Packit 1c1d7e
    TagMemberInfo *md;
Packit 1c1d7e
    for (;(md=mci.current());++mci)
Packit 1c1d7e
    {
Packit 1c1d7e
      msg("  member:\n");
Packit 1c1d7e
      msg("    kind: `%s'\n",md->kind.data());
Packit 1c1d7e
      msg("    name: `%s'\n",md->name.data());
Packit 1c1d7e
      msg("    anchor: `%s'\n",md->anchor.data());
Packit 1c1d7e
      msg("    arglist: `%s'\n",md->arglist.data());
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    QListIterator<TagIncludeInfo> mii(fd->includes);
Packit 1c1d7e
    TagIncludeInfo *ii;
Packit 1c1d7e
    for (;(ii=mii.current());++mii)
Packit 1c1d7e
    {
Packit 1c1d7e
      msg("  includes id: %s name: %s\n",ii->id.data(),ii->name.data());
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  //============== GROUPS
Packit 1c1d7e
  QListIterator<TagGroupInfo> lgi(m_tagFileGroups);
Packit 1c1d7e
  TagGroupInfo *gd;
Packit 1c1d7e
  for (;(gd=lgi.current());++lgi)
Packit 1c1d7e
  {
Packit 1c1d7e
    msg("group `%s'\n",gd->name.data());
Packit 1c1d7e
    msg("  filename `%s'\n",gd->filename.data());
Packit 1c1d7e
    QStringList::Iterator it;
Packit 1c1d7e
    for ( it = gd->namespaceList.begin(); 
Packit 1c1d7e
        it != gd->namespaceList.end(); ++it ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      msg( "  namespace: %s \n", (*it).latin1() );
Packit 1c1d7e
    }
Packit 1c1d7e
    for ( it = gd->classList.begin(); 
Packit 1c1d7e
        it != gd->classList.end(); ++it ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      msg( "  class: %s \n", (*it).latin1() );
Packit 1c1d7e
    }
Packit 1c1d7e
    for ( it = gd->fileList.begin(); 
Packit 1c1d7e
        it != gd->fileList.end(); ++it ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      msg( "  file: %s \n", (*it).latin1() );
Packit 1c1d7e
    }
Packit 1c1d7e
    for ( it = gd->subgroupList.begin(); 
Packit 1c1d7e
        it != gd->subgroupList.end(); ++it ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      msg( "  subgroup: %s \n", (*it).latin1() );
Packit 1c1d7e
    }
Packit 1c1d7e
    for ( it = gd->pageList.begin(); 
Packit 1c1d7e
        it != gd->pageList.end(); ++it ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      msg( "  page: %s \n", (*it).latin1() );
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    QListIterator<TagMemberInfo> mci(gd->members);
Packit 1c1d7e
    TagMemberInfo *md;
Packit 1c1d7e
    for (;(md=mci.current());++mci)
Packit 1c1d7e
    {
Packit 1c1d7e
      msg("  member:\n");
Packit 1c1d7e
      msg("    kind: `%s'\n",md->kind.data());
Packit 1c1d7e
      msg("    name: `%s'\n",md->name.data());
Packit 1c1d7e
      msg("    anchor: `%s'\n",md->anchor.data());
Packit 1c1d7e
      msg("    arglist: `%s'\n",md->arglist.data());
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
  //============== PAGES
Packit 1c1d7e
  QListIterator<TagPageInfo> lpi(m_tagFilePages);
Packit 1c1d7e
  TagPageInfo *pd;
Packit 1c1d7e
  for (;(pd=lpi.current());++lpi)
Packit 1c1d7e
  {
Packit 1c1d7e
    msg("page `%s'\n",pd->name.data());
Packit 1c1d7e
    msg("  title `%s'\n",pd->title.data());
Packit 1c1d7e
    msg("  filename `%s'\n",pd->filename.data());
Packit 1c1d7e
  }
Packit 1c1d7e
  //============== DIRS
Packit 1c1d7e
  QListIterator<TagDirInfo> ldi(m_tagFileDirs);
Packit 1c1d7e
  TagDirInfo *dd;
Packit 1c1d7e
  for (;(dd=ldi.current());++ldi)
Packit 1c1d7e
  {
Packit 1c1d7e
    msg("dir `%s'\n",dd->name.data());
Packit 1c1d7e
    msg("  path `%s'\n",dd->path.data());
Packit 1c1d7e
    QStringList::Iterator it;
Packit 1c1d7e
    for ( it = dd->fileList.begin(); 
Packit 1c1d7e
        it != dd->fileList.end(); ++it ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      msg( "  file: %s \n", (*it).latin1() );
Packit 1c1d7e
    }
Packit 1c1d7e
    for ( it = dd->subdirList.begin(); 
Packit 1c1d7e
        it != dd->subdirList.end(); ++it ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      msg( "  subdir: %s \n", (*it).latin1() );
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l)
Packit 1c1d7e
{
Packit 1c1d7e
  QListIterator<TagAnchorInfo> tli(l);
Packit 1c1d7e
  TagAnchorInfo *ta;
Packit 1c1d7e
  for (tli.toFirst();(ta=tli.current());++tli)
Packit 1c1d7e
  {
Packit 1c1d7e
    if (Doxygen::sectionDict->find(ta->label)==0)
Packit 1c1d7e
    {
Packit 1c1d7e
      //printf("New sectionInfo file=%s anchor=%s\n",
Packit 1c1d7e
      //    ta->fileName.data(),ta->label.data());
Packit 1c1d7e
      SectionInfo *si=new SectionInfo(ta->fileName,-1,ta->label,ta->title,
Packit 1c1d7e
          SectionInfo::Anchor,0,m_tagName);
Packit 1c1d7e
      Doxygen::sectionDict->append(ta->label,si);
Packit 1c1d7e
      e->anchors->append(si);
Packit 1c1d7e
    }
Packit 1c1d7e
    else
Packit 1c1d7e
    {
Packit 1c1d7e
      warn("Duplicate anchor %s found\n",ta->label.data());
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void TagFileParser::buildMemberList(Entry *ce,QList<TagMemberInfo> &members)
Packit 1c1d7e
{
Packit 1c1d7e
  QListIterator<TagMemberInfo> mii(members);
Packit 1c1d7e
  TagMemberInfo *tmi;
Packit 1c1d7e
  for (;(tmi=mii.current());++mii)
Packit 1c1d7e
  {
Packit 1c1d7e
    Entry *me      = new Entry;
Packit 1c1d7e
    me->type       = tmi->type;
Packit 1c1d7e
    me->name       = tmi->name;
Packit 1c1d7e
    me->args       = tmi->arglist;
Packit 1c1d7e
    if (!me->args.isEmpty())
Packit 1c1d7e
    {
Packit 1c1d7e
      delete me->argList;
Packit 1c1d7e
      me->argList = new ArgumentList;
Packit 1c1d7e
      stringToArgumentList(me->args,me->argList);
Packit 1c1d7e
    }
Packit 1c1d7e
    if (tmi->enumValues.count()>0)
Packit 1c1d7e
    {
Packit 1c1d7e
      me->spec |= Entry::Strong;
Packit 1c1d7e
      QListIterator<TagEnumValueInfo> evii(tmi->enumValues);
Packit 1c1d7e
      TagEnumValueInfo *evi;
Packit 1c1d7e
      for (evii.toFirst();(evi=evii.current());++evii)
Packit 1c1d7e
      {
Packit 1c1d7e
        Entry *ev      = new Entry;
Packit 1c1d7e
        ev->type       = "@";
Packit 1c1d7e
        ev->name       = evi->name;
Packit 1c1d7e
        ev->id         = evi->clangid;
Packit 1c1d7e
        ev->section    = Entry::VARIABLE_SEC;
Packit 1c1d7e
        TagInfo *ti    = new TagInfo;
Packit 1c1d7e
        ti->tagName    = m_tagName;
Packit 1c1d7e
        ti->anchor     = evi->anchor;
Packit 1c1d7e
        ti->fileName   = evi->file;
Packit 1c1d7e
        ev->tagInfo    = ti;
Packit 1c1d7e
        me->addSubEntry(ev);
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    me->protection = tmi->prot;
Packit 1c1d7e
    me->virt       = tmi->virt;
Packit 1c1d7e
    me->stat       = tmi->isStatic;
Packit 1c1d7e
    me->fileName   = ce->fileName;
Packit 1c1d7e
    me->id         = tmi->clangId;
Packit 1c1d7e
    if (ce->section == Entry::GROUPDOC_SEC)
Packit 1c1d7e
    {
Packit 1c1d7e
      me->groups->append(new Grouping(ce->name,Grouping::GROUPING_INGROUP));
Packit 1c1d7e
    }
Packit 1c1d7e
    addDocAnchors(me,tmi->docAnchors);
Packit 1c1d7e
    TagInfo *ti    = new TagInfo;
Packit 1c1d7e
    ti->tagName    = m_tagName;
Packit 1c1d7e
    ti->anchor     = tmi->anchor;
Packit 1c1d7e
    ti->fileName   = tmi->anchorFile;
Packit 1c1d7e
    me->tagInfo    = ti;
Packit 1c1d7e
    if (tmi->kind=="define")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->type="#define";
Packit 1c1d7e
      me->section = Entry::DEFINE_SEC;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="enumvalue")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::VARIABLE_SEC;
Packit 1c1d7e
      me->mtype = Method;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="property")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::VARIABLE_SEC;
Packit 1c1d7e
      me->mtype = Property;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="event")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::VARIABLE_SEC;
Packit 1c1d7e
      me->mtype = Event;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="variable")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::VARIABLE_SEC;
Packit 1c1d7e
      me->mtype = Method;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="typedef")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::VARIABLE_SEC; //Entry::TYPEDEF_SEC;
Packit 1c1d7e
      me->type.prepend("typedef ");
Packit 1c1d7e
      me->mtype = Method;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="enumeration")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::ENUM_SEC;
Packit 1c1d7e
      me->mtype = Method;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="function")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::FUNCTION_SEC;
Packit 1c1d7e
      me->mtype = Method;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="signal")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::FUNCTION_SEC;
Packit 1c1d7e
      me->mtype = Signal;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="prototype")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::FUNCTION_SEC;
Packit 1c1d7e
      me->mtype = Method;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="friend")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::FUNCTION_SEC;
Packit 1c1d7e
      me->type.prepend("friend ");
Packit 1c1d7e
      me->mtype = Method;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="dcop")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::FUNCTION_SEC;
Packit 1c1d7e
      me->mtype = DCOP;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (tmi->kind=="slot")
Packit 1c1d7e
    {
Packit 1c1d7e
      me->section = Entry::FUNCTION_SEC;
Packit 1c1d7e
      me->mtype = Slot;
Packit 1c1d7e
    }
Packit 1c1d7e
    ce->addSubEntry(me);
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
static QCString stripPath(const QCString &s)
Packit 1c1d7e
{
Packit 1c1d7e
  int i=s.findRev('/');
Packit 1c1d7e
  if (i!=-1)
Packit 1c1d7e
  {
Packit 1c1d7e
    return s.right(s.length()-i-1);
Packit 1c1d7e
  }
Packit 1c1d7e
  else
Packit 1c1d7e
  {
Packit 1c1d7e
    return s;
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/*! Injects the info gathered by the XML parser into the Entry tree.
Packit 1c1d7e
 *  This tree contains the information extracted from the input in a 
Packit 1c1d7e
 *  "unrelated" form.
Packit 1c1d7e
 */
Packit 1c1d7e
void TagFileParser::buildLists(Entry *root)
Packit 1c1d7e
{
Packit 1c1d7e
  // build class list
Packit 1c1d7e
  QListIterator<TagClassInfo> cit(m_tagFileClasses);
Packit 1c1d7e
  TagClassInfo *tci;
Packit 1c1d7e
  for (cit.toFirst();(tci=cit.current());++cit)
Packit 1c1d7e
  {
Packit 1c1d7e
    Entry *ce = new Entry;
Packit 1c1d7e
    ce->section = Entry::CLASS_SEC;
Packit 1c1d7e
    switch (tci->kind)
Packit 1c1d7e
    {
Packit 1c1d7e
      case TagClassInfo::Class:     break;
Packit 1c1d7e
      case TagClassInfo::Struct:    ce->spec = Entry::Struct;    break;
Packit 1c1d7e
      case TagClassInfo::Union:     ce->spec = Entry::Union;     break;
Packit 1c1d7e
      case TagClassInfo::Interface: ce->spec = Entry::Interface; break;
Packit 1c1d7e
      case TagClassInfo::Enum:      ce->spec = Entry::Enum;      break;
Packit 1c1d7e
      case TagClassInfo::Exception: ce->spec = Entry::Exception; break;
Packit 1c1d7e
      case TagClassInfo::Protocol:  ce->spec = Entry::Protocol;  break;
Packit 1c1d7e
      case TagClassInfo::Category:  ce->spec = Entry::Category;  break;
Packit 1c1d7e
      case TagClassInfo::Service:   ce->spec = Entry::Service;   break;
Packit 1c1d7e
      case TagClassInfo::Singleton: ce->spec = Entry::Singleton; break;
Packit 1c1d7e
    }
Packit 1c1d7e
    ce->name     = tci->name;
Packit 1c1d7e
    if (tci->kind==TagClassInfo::Protocol)
Packit 1c1d7e
    {
Packit 1c1d7e
      ce->name+="-p";
Packit 1c1d7e
    }
Packit 1c1d7e
    addDocAnchors(ce,tci->docAnchors);
Packit 1c1d7e
    TagInfo *ti  = new TagInfo;
Packit 1c1d7e
    ti->tagName  = m_tagName;
Packit 1c1d7e
    ti->fileName = tci->filename;
Packit 1c1d7e
    ce->id       = tci->clangId;
Packit 1c1d7e
    ce->tagInfo  = ti;
Packit 1c1d7e
    ce->lang     = tci->isObjC ? SrcLangExt_ObjC : SrcLangExt_Unknown;
Packit 1c1d7e
    // transfer base class list
Packit 1c1d7e
    if (tci->bases)
Packit 1c1d7e
    {
Packit 1c1d7e
      delete ce->extends;
Packit 1c1d7e
      ce->extends = tci->bases; tci->bases = 0;
Packit 1c1d7e
    }
Packit 1c1d7e
    if (tci->templateArguments)
Packit 1c1d7e
    {
Packit 1c1d7e
      if (ce->tArgLists==0)
Packit 1c1d7e
      {
Packit 1c1d7e
        ce->tArgLists = new QList<ArgumentList>;
Packit 1c1d7e
        ce->tArgLists->setAutoDelete(TRUE);
Packit 1c1d7e
      }
Packit 1c1d7e
      ArgumentList *al = new ArgumentList;
Packit 1c1d7e
      ce->tArgLists->append(al);
Packit 1c1d7e
Packit 1c1d7e
      QListIterator<QCString> sli(*tci->templateArguments);
Packit 1c1d7e
      QCString *argName;
Packit 1c1d7e
      for (;(argName=sli.current());++sli)
Packit 1c1d7e
      {
Packit 1c1d7e
        Argument *a = new Argument;
Packit 1c1d7e
        a->type = "class";
Packit 1c1d7e
        a->name = *argName;
Packit 1c1d7e
        al->append(a);
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    buildMemberList(ce,tci->members);
Packit 1c1d7e
    root->addSubEntry(ce);
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  // build file list
Packit 1c1d7e
  QListIterator<TagFileInfo> fit(m_tagFileFiles);
Packit 1c1d7e
  TagFileInfo *tfi;
Packit 1c1d7e
  for (fit.toFirst();(tfi=fit.current());++fit)
Packit 1c1d7e
  {
Packit 1c1d7e
    Entry *fe = new Entry;
Packit 1c1d7e
    fe->section = guessSection(tfi->name);
Packit 1c1d7e
    fe->name     = tfi->name;
Packit 1c1d7e
    addDocAnchors(fe,tfi->docAnchors);
Packit 1c1d7e
    TagInfo *ti  = new TagInfo;
Packit 1c1d7e
    ti->tagName  = m_tagName;
Packit 1c1d7e
    ti->fileName = tfi->filename;
Packit 1c1d7e
    fe->tagInfo  = ti;
Packit 1c1d7e
    
Packit 1c1d7e
    QCString fullName = m_tagName+":"+tfi->path+stripPath(tfi->name);
Packit 1c1d7e
    fe->fileName = fullName;
Packit 1c1d7e
    //printf("new FileDef() filename=%s\n",tfi->filename.data());
Packit 1c1d7e
    FileDef *fd = new FileDef(m_tagName+":"+tfi->path,
Packit 1c1d7e
                              tfi->name,m_tagName,
Packit 1c1d7e
                              tfi->filename
Packit 1c1d7e
                             );
Packit 1c1d7e
    FileName *mn;
Packit 1c1d7e
    if ((mn=Doxygen::inputNameDict->find(tfi->name)))
Packit 1c1d7e
    {
Packit 1c1d7e
      mn->append(fd);
Packit 1c1d7e
    }
Packit 1c1d7e
    else
Packit 1c1d7e
    {
Packit 1c1d7e
      mn = new FileName(fullName,tfi->name);
Packit 1c1d7e
      mn->append(fd);
Packit 1c1d7e
      Doxygen::inputNameList->inSort(mn);
Packit 1c1d7e
      Doxygen::inputNameDict->insert(tfi->name,mn);
Packit 1c1d7e
    }
Packit 1c1d7e
    buildMemberList(fe,tfi->members);
Packit 1c1d7e
    root->addSubEntry(fe);
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  // build namespace list
Packit 1c1d7e
  QListIterator<TagNamespaceInfo> nit(m_tagFileNamespaces);
Packit 1c1d7e
  TagNamespaceInfo *tni;
Packit 1c1d7e
  for (nit.toFirst();(tni=nit.current());++nit)
Packit 1c1d7e
  {
Packit 1c1d7e
    Entry *ne    = new Entry;
Packit 1c1d7e
    ne->section  = Entry::NAMESPACE_SEC;
Packit 1c1d7e
    ne->name     = tni->name;
Packit 1c1d7e
    addDocAnchors(ne,tni->docAnchors);
Packit 1c1d7e
    TagInfo *ti  = new TagInfo;
Packit 1c1d7e
    ti->tagName  = m_tagName;
Packit 1c1d7e
    ti->fileName = tni->filename;
Packit 1c1d7e
    ne->id       = tni->clangId;
Packit 1c1d7e
    ne->tagInfo  = ti;
Packit 1c1d7e
Packit 1c1d7e
    buildMemberList(ne,tni->members);
Packit 1c1d7e
    root->addSubEntry(ne);
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  // build package list
Packit 1c1d7e
  QListIterator<TagPackageInfo> pit(m_tagFilePackages);
Packit 1c1d7e
  TagPackageInfo *tpgi;
Packit 1c1d7e
  for (pit.toFirst();(tpgi=pit.current());++pit)
Packit 1c1d7e
  {
Packit 1c1d7e
    Entry *pe    = new Entry;
Packit 1c1d7e
    pe->section  = Entry::PACKAGE_SEC;
Packit 1c1d7e
    pe->name     = tpgi->name;
Packit 1c1d7e
    addDocAnchors(pe,tpgi->docAnchors);
Packit 1c1d7e
    TagInfo *ti  = new TagInfo;
Packit 1c1d7e
    ti->tagName  = m_tagName;
Packit 1c1d7e
    ti->fileName = tpgi->filename;
Packit 1c1d7e
    pe->tagInfo  = ti;
Packit 1c1d7e
Packit 1c1d7e
    buildMemberList(pe,tpgi->members);
Packit 1c1d7e
    root->addSubEntry(pe);
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  // build group list
Packit 1c1d7e
  QListIterator<TagGroupInfo> git(m_tagFileGroups);
Packit 1c1d7e
  TagGroupInfo *tgi;
Packit 1c1d7e
  for (git.toFirst();(tgi=git.current());++git)
Packit 1c1d7e
  {
Packit 1c1d7e
    Entry *ge    = new Entry;
Packit 1c1d7e
    ge->section  = Entry::GROUPDOC_SEC;
Packit 1c1d7e
    ge->name     = tgi->name;
Packit 1c1d7e
    ge->type     = tgi->title;
Packit 1c1d7e
    addDocAnchors(ge,tgi->docAnchors);
Packit 1c1d7e
    TagInfo *ti  = new TagInfo;
Packit 1c1d7e
    ti->tagName  = m_tagName;
Packit 1c1d7e
    ti->fileName = tgi->filename;
Packit 1c1d7e
    ge->tagInfo  = ti;
Packit 1c1d7e
Packit 1c1d7e
    buildMemberList(ge,tgi->members);
Packit 1c1d7e
    root->addSubEntry(ge);
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  // build page list
Packit 1c1d7e
  QListIterator<TagPageInfo> pgit(m_tagFilePages);
Packit 1c1d7e
  TagPageInfo *tpi;
Packit 1c1d7e
  for (pgit.toFirst();(tpi=pgit.current());++pgit)
Packit 1c1d7e
  {
Packit 1c1d7e
    Entry *pe    = new Entry;
Packit 1c1d7e
    pe->section  = tpi->filename=="index" ? Entry::MAINPAGEDOC_SEC : Entry::PAGEDOC_SEC;
Packit 1c1d7e
    pe->name     = tpi->name;
Packit 1c1d7e
    pe->args     = tpi->title;
Packit 1c1d7e
    addDocAnchors(pe,tpi->docAnchors);
Packit 1c1d7e
    TagInfo *ti  = new TagInfo;
Packit 1c1d7e
    ti->tagName  = m_tagName;
Packit 1c1d7e
    ti->fileName = tpi->filename;
Packit 1c1d7e
    pe->tagInfo  = ti;
Packit 1c1d7e
    root->addSubEntry(pe);
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void TagFileParser::addIncludes()
Packit 1c1d7e
{
Packit 1c1d7e
  QListIterator<TagFileInfo> fit(m_tagFileFiles);
Packit 1c1d7e
  TagFileInfo *tfi;
Packit 1c1d7e
  for (fit.toFirst();(tfi=fit.current());++fit)
Packit 1c1d7e
  {
Packit 1c1d7e
    //printf("tag file tagName=%s path=%s name=%s\n",m_tagName.data(),tfi->path.data(),tfi->name.data());
Packit 1c1d7e
    FileName *fn = Doxygen::inputNameDict->find(tfi->name);
Packit 1c1d7e
    if (fn)
Packit 1c1d7e
    {
Packit 1c1d7e
      //printf("found\n");
Packit 1c1d7e
      FileNameIterator fni(*fn);
Packit 1c1d7e
      FileDef *fd;
Packit 1c1d7e
      for (;(fd=fni.current());++fni)
Packit 1c1d7e
      {
Packit 1c1d7e
        //printf("input file path=%s name=%s\n",fd->getPath().data(),fd->name().data());
Packit 1c1d7e
        if (fd->getPath()==QCString(m_tagName+":"+tfi->path))
Packit 1c1d7e
        {
Packit 1c1d7e
          //printf("found\n");
Packit 1c1d7e
          QListIterator<TagIncludeInfo> mii(tfi->includes);
Packit 1c1d7e
          TagIncludeInfo *ii;
Packit 1c1d7e
          for (;(ii=mii.current());++mii)
Packit 1c1d7e
          {
Packit 1c1d7e
            //printf("ii->name=`%s'\n",ii->name.data());
Packit 1c1d7e
            FileName *ifn = Doxygen::inputNameDict->find(ii->name);
Packit 1c1d7e
            ASSERT(ifn!=0);
Packit 1c1d7e
            if (ifn)
Packit 1c1d7e
            {
Packit 1c1d7e
              FileNameIterator ifni(*ifn);
Packit 1c1d7e
              FileDef *ifd;
Packit 1c1d7e
              for (;(ifd=ifni.current());++ifni)
Packit 1c1d7e
              {
Packit 1c1d7e
                //printf("ifd->getOutputFileBase()=%s ii->id=%s\n",
Packit 1c1d7e
                //        ifd->getOutputFileBase().data(),ii->id.data());
Packit 1c1d7e
                if (ifd->getOutputFileBase()==QCString(ii->id))
Packit 1c1d7e
                {
Packit 1c1d7e
                  fd->addIncludeDependency(ifd,ii->text,ii->isLocal,ii->isImported,FALSE);
Packit 1c1d7e
                }
Packit 1c1d7e
              }
Packit 1c1d7e
            }
Packit 1c1d7e
          }
Packit 1c1d7e
        }
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void parseTagFile(Entry *root,const char *fullName)
Packit 1c1d7e
{
Packit 1c1d7e
  QFileInfo fi(fullName);
Packit 1c1d7e
  if (!fi.exists()) return;
Packit 1c1d7e
  TagFileParser handler( fullName ); // tagName
Packit 1c1d7e
  handler.setFileName(fullName);
Packit 1c1d7e
  TagFileErrorHandler errorHandler;
Packit 1c1d7e
  QFile xmlFile( fullName );
Packit 1c1d7e
  QXmlInputSource source( xmlFile );
Packit 1c1d7e
  QXmlSimpleReader reader;
Packit 1c1d7e
  reader.setContentHandler( &handler );
Packit 1c1d7e
  reader.setErrorHandler( &errorHandler );
Packit 1c1d7e
  reader.parse( source );
Packit 1c1d7e
  handler.buildLists(root);
Packit 1c1d7e
  handler.addIncludes();
Packit 1c1d7e
  //handler.dump();
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e