tagreader.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * $Id: tagreader.cpp,v 1.2 2001/03/19 19:27:41 root Exp $
00004  *
00005  *
00006  * Copyright (C) 1997-2008 by Dimitri van Heesch.
00007  *
00008  * Permission to use, copy, modify, and distribute this software and its
00009  * documentation under the terms of the GNU General Public License is hereby 
00010  * granted. No representations are made about the suitability of this software 
00011  * for any purpose. It is provided "as is" without express or implied warranty.
00012  * See the GNU General Public License for more details.
00013  *
00014  * Documents produced by Doxygen are derivative works derived from the
00015  * input used in their production; they are not affected by this license.
00016  *
00017  */
00018 
00019 #include "tagreader.h"
00020 
00021 #include <stdio.h>
00022 #include <stdarg.h>
00023 
00024 #include <qxml.h>
00025 #include <qstack.h>
00026 #include <qdict.h>
00027 #include <qfileinfo.h>
00028 #include <qlist.h>
00029 #include <qstring.h>
00030 #include <qstringlist.h>
00031 
00032 #include "entry.h"
00033 #include "classdef.h"
00034 #include "doxygen.h"
00035 #include "util.h"
00036 #include "message.h"
00037 #include "defargs.h"
00038 //#include "reflist.h"
00039 
00041 class TagAnchorInfo
00042 {
00043   public:
00044     TagAnchorInfo(const QString &f,const QString &l) : label(l), fileName(f) {}
00045     QString label;
00046     QString fileName;
00047 };
00048 
00049 class TagAnchorInfoList : public QList<TagAnchorInfo>
00050 {
00051   public: 
00052     TagAnchorInfoList() : QList<TagAnchorInfo>() { setAutoDelete(TRUE); }
00053     virtual ~TagAnchorInfoList() {}
00054 };
00055 
00057 class TagMemberInfo
00058 {
00059   public:
00060     TagMemberInfo() : prot(Public), virt(Normal), isStatic(FALSE) {}
00061     QString type;
00062     QString name;
00063     QString anchorFile;
00064     QString anchor;
00065     QString arglist;
00066     QString kind;
00067     TagAnchorInfoList docAnchors;
00068     Protection prot;
00069     Specifier virt;
00070     bool isStatic; 
00071 };
00072 
00074 class TagClassInfo
00075 {
00076   public:
00077     enum Kind { Class, Struct, Union, Interface, Exception, Protocol, Category };
00078     TagClassInfo() { bases=0, templateArguments=0; members.setAutoDelete(TRUE); isObjC=FALSE; }
00079    ~TagClassInfo() { delete bases; delete templateArguments; }
00080     QString name;
00081     QString filename;
00082     TagAnchorInfoList docAnchors;
00083     QList<BaseInfo> *bases;
00084     QList<TagMemberInfo> members;
00085     QList<QString> *templateArguments;
00086     QStringList classList;
00087     Kind kind;
00088     bool isObjC;
00089 };
00090 
00092 class TagNamespaceInfo
00093 {
00094   public:
00095     TagNamespaceInfo() { members.setAutoDelete(TRUE); }
00096     QString name;
00097     QString filename;
00098     QStringList classList;
00099     QStringList namespaceList;
00100     TagAnchorInfoList docAnchors;
00101     QList<TagMemberInfo> members;
00102 };
00103 
00105 class TagPackageInfo
00106 {
00107   public:
00108     TagPackageInfo() { members.setAutoDelete(TRUE); }
00109     QString name;
00110     QString filename;
00111     TagAnchorInfoList docAnchors;
00112     QList<TagMemberInfo> members;
00113     QStringList classList;
00114 };
00115 
00116 class TagIncludeInfo
00117 {
00118   public:
00119     QString id;
00120     QString name;
00121     QString text;
00122     bool isLocal;
00123     bool isImported;
00124 };
00125 
00127 class TagFileInfo
00128 {
00129   public:
00130     TagFileInfo() { members.setAutoDelete(TRUE); includes.setAutoDelete(TRUE); }
00131     QString name;
00132     QString path;
00133     QString filename;
00134     TagAnchorInfoList docAnchors;
00135     QList<TagMemberInfo> members;
00136     QStringList classList;
00137     QStringList namespaceList;
00138     QList<TagIncludeInfo> includes;
00139 };
00140 
00142 class TagGroupInfo
00143 {
00144   public:
00145     TagGroupInfo() { members.setAutoDelete(TRUE); }
00146     QString name;
00147     QString title;
00148     QString filename;
00149     TagAnchorInfoList docAnchors;
00150     QList<TagMemberInfo> members;
00151     QStringList subgroupList;
00152     QStringList classList;
00153     QStringList namespaceList;
00154     QStringList fileList;
00155     QStringList pageList;
00156     QStringList dirList;
00157 };
00158 
00160 class TagPageInfo
00161 {
00162   public:
00163     QString name;
00164     QString title;
00165     QString filename;
00166     TagAnchorInfoList docAnchors;
00167 };
00168 
00170 class TagDirInfo
00171 {
00172   public:
00173     QString name;
00174     QString filename;
00175     QString path;
00176     QStringList subdirList;
00177     QStringList fileList;
00178     TagAnchorInfoList docAnchors;
00179 };
00180 
00186 class TagFileParser : public QXmlDefaultHandler
00187 {
00188     enum State { Invalid,
00189                  InClass,
00190                  InFile,
00191                  InNamespace,
00192                  InGroup,
00193                  InPage,
00194                  InMember,
00195                  InPackage,
00196                  InDir,
00197                  InTempArgList
00198                };
00199     class StartElementHandler
00200     {
00201         typedef void (TagFileParser::*Handler)(const QXmlAttributes &attrib); 
00202       public:
00203         StartElementHandler(TagFileParser *parent, Handler h) : m_parent(parent), m_handler(h) {}
00204         void operator()(const QXmlAttributes &attrib) { (m_parent->*m_handler)(attrib); }
00205       private:
00206         TagFileParser *m_parent;
00207         Handler m_handler;
00208     };
00209 
00210     class EndElementHandler
00211     {
00212         typedef void (TagFileParser::*Handler)(); 
00213       public:
00214         EndElementHandler(TagFileParser *parent, Handler h) : m_parent(parent), m_handler(h) {}
00215         void operator()() { (m_parent->*m_handler)(); }
00216       private:
00217         TagFileParser *m_parent;
00218         Handler m_handler;
00219     };
00220 
00221   public:
00222     TagFileParser(const char *tagName) : m_startElementHandlers(17),
00223                                          m_endElementHandlers(17),
00224                                          m_tagName(tagName)
00225     {
00226       m_startElementHandlers.setAutoDelete(TRUE);
00227       m_endElementHandlers.setAutoDelete(TRUE);
00228     }
00229     
00230     void setDocumentLocator ( QXmlLocator * locator )
00231     {
00232       m_locator = locator;
00233     }
00234 
00235     void setFileName( const QString &fileName )
00236     {
00237       m_inputFileName = fileName;
00238     }
00239 
00240     void warn(const char *fmt)
00241     {
00242       ::warn(m_inputFileName,m_locator->lineNumber(),fmt);
00243     }
00244     void warn(const char *fmt,const char *s)
00245     {
00246       ::warn(m_inputFileName,m_locator->lineNumber(),fmt,s);
00247     }
00248 
00249     void startCompound( const QXmlAttributes& attrib )
00250     {
00251       m_curString = "";
00252       QString kind = attrib.value("kind");
00253       QString isObjC = attrib.value("objc");
00254       if (kind=="class")
00255       {
00256         m_curClass = new TagClassInfo;
00257         m_curClass->kind = TagClassInfo::Class;
00258         m_state = InClass;
00259       }
00260       else if (kind=="struct")
00261       {
00262         m_curClass = new TagClassInfo;
00263         m_curClass->kind = TagClassInfo::Struct;
00264         m_state = InClass;
00265       }
00266       else if (kind=="union")
00267       {
00268         m_curClass = new TagClassInfo;
00269         m_curClass->kind = TagClassInfo::Union;
00270         m_state = InClass;
00271       }
00272       else if (kind=="interface")
00273       {
00274         m_curClass = new TagClassInfo;
00275         m_curClass->kind = TagClassInfo::Interface;
00276         m_state = InClass;
00277       }
00278       else if (kind=="exception")
00279       {
00280         m_curClass = new TagClassInfo;
00281         m_curClass->kind = TagClassInfo::Exception;
00282         m_state = InClass;
00283       }
00284       else if (kind=="protocol")
00285       {
00286         m_curClass = new TagClassInfo;
00287         m_curClass->kind = TagClassInfo::Protocol;
00288         m_state = InClass;
00289       }
00290       else if (kind=="category")
00291       {
00292         m_curClass = new TagClassInfo;
00293         m_curClass->kind = TagClassInfo::Category;
00294         m_state = InClass;
00295       }
00296       else if (kind=="file")
00297       {
00298         m_curFile = new TagFileInfo;
00299         m_state = InFile;
00300       }
00301       else if (kind=="namespace")
00302       {
00303         m_curNamespace = new TagNamespaceInfo;
00304         m_state = InNamespace;
00305       }
00306       else if (kind=="group")
00307       {
00308         m_curGroup = new TagGroupInfo;
00309         m_state = InGroup;
00310       }
00311       else if (kind=="page")
00312       {
00313         m_curPage = new TagPageInfo;
00314         m_state = InPage;
00315       }
00316       else if (kind=="package")
00317       {
00318         m_curPackage = new TagPackageInfo;
00319         m_state = InPackage;
00320       }
00321       else if (kind=="dir")
00322       {
00323         m_curDir = new TagDirInfo;
00324         m_state = InDir;
00325       }
00326       else
00327       {
00328         warn("Warning: Unknown compound attribute `%s' found!\n",kind.data());
00329       }
00330       if (isObjC=="yes" && m_curClass)
00331       {
00332         m_curClass->isObjC = TRUE; 
00333       }
00334     }
00335 
00336     void endCompound()
00337     {
00338       switch (m_state)
00339       {
00340         case InClass:     m_tagFileClasses.append(m_curClass); 
00341                           m_curClass=0; break; 
00342         case InFile:      m_tagFileFiles.append(m_curFile); 
00343                           m_curFile=0; break; 
00344         case InNamespace: m_tagFileNamespaces.append(m_curNamespace); 
00345                           m_curNamespace=0; break; 
00346         case InGroup:     m_tagFileGroups.append(m_curGroup); 
00347                           m_curGroup=0; break; 
00348         case InPage:      m_tagFilePages.append(m_curPage); 
00349                           m_curPage=0; break; 
00350         case InDir:       m_tagFileDirs.append(m_curDir);
00351                           m_curDir=0; break;
00352         case InPackage:   m_tagFilePackages.append(m_curPackage); 
00353                           m_curPackage=0; break; 
00354         default:
00355                           warn("Warning: tag `compound' was not expected!\n");
00356       }
00357     }
00358 
00359     void startMember( const QXmlAttributes& attrib)
00360     {
00361       m_curMember = new TagMemberInfo;
00362       m_curMember->kind = attrib.value("kind");
00363       QString protStr   = attrib.value("protection");
00364       QString virtStr   = attrib.value("virtualness");
00365       QString staticStr = attrib.value("static");
00366       if (protStr=="protected")
00367       {
00368         m_curMember->prot = Protected;
00369       }
00370       else if (protStr=="private")
00371       {
00372         m_curMember->prot = Private;
00373       }
00374       if (virtStr=="virtual")
00375       {
00376         m_curMember->virt = Virtual;
00377       }
00378       else if (virtStr=="pure")
00379       {
00380         m_curMember->virt = Pure;
00381       }
00382       if (staticStr=="yes")
00383       {
00384         m_curMember->isStatic = TRUE;
00385       }
00386       m_stateStack.push(new State(m_state));
00387       m_state = InMember;
00388     }
00389 
00390     void endMember()
00391     {
00392       m_state = *m_stateStack.top();
00393       m_stateStack.remove();
00394       switch(m_state)
00395       {
00396         case InClass:     m_curClass->members.append(m_curMember); break;
00397         case InFile:      m_curFile->members.append(m_curMember); break;
00398         case InNamespace: m_curNamespace->members.append(m_curMember); break;
00399         case InGroup:     m_curGroup->members.append(m_curMember); break;
00400         case InPackage:   m_curPackage->members.append(m_curMember); break;
00401         default:   warn("Warning: Unexpected tag `member' found\n"); break; 
00402       }
00403     }
00404 
00405     void endDocAnchor()
00406     {
00407       switch(m_state)
00408       {
00409         case InClass:     m_curClass->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
00410         case InFile:      m_curFile->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
00411         case InNamespace: m_curNamespace->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
00412         case InGroup:     m_curGroup->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
00413         case InPage:      m_curPage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
00414         case InMember:    m_curMember->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
00415         case InPackage:   m_curPackage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
00416         case InDir:       m_curDir->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString)); break;
00417         default:   warn("Warning: Unexpected tag `member' found\n"); break; 
00418       }
00419     }
00420 
00421     void endClass()
00422     {
00423       switch(m_state)
00424       {
00425         case InClass:     m_curClass->classList.append(m_curString); break;
00426         case InFile:      m_curFile->classList.append(m_curString); break;
00427         case InNamespace: m_curNamespace->classList.append(m_curString); break;
00428         case InGroup:     m_curGroup->classList.append(m_curString); break;
00429         case InPackage:   m_curPackage->classList.append(m_curString); break;
00430         default:   warn("Warning: Unexpected tag `class' found\n"); break; 
00431       }
00432     }
00433 
00434     void endNamespace()
00435     {
00436       switch(m_state)
00437       {
00438         case InNamespace: m_curNamespace->classList.append(m_curString); break;
00439         case InFile:      m_curFile->namespaceList.append(m_curString); break;
00440         case InGroup:     m_curGroup->namespaceList.append(m_curString); break;
00441         default:   warn("Warning: Unexpected tag `namespace' found\n"); break; 
00442       }
00443     }
00444 
00445     void endFile()
00446     {
00447       switch(m_state)
00448       {
00449         case InGroup:      m_curGroup->fileList.append(m_curString); break;
00450         case InDir:        m_curDir->fileList.append(m_curString); break;
00451         default:   warn("Warning: Unexpected tag `file' found\n"); break; 
00452       }
00453     }
00454 
00455     void endPage()
00456     {
00457       switch(m_state)
00458       {
00459         case InGroup:      m_curGroup->fileList.append(m_curString); break;
00460         default:   warn("Warning: Unexpected tag `page' found\n"); break; 
00461       }
00462     }
00463 
00464     void endDir()
00465     {
00466       switch(m_state)
00467       {
00468         case InDir:      m_curDir->subdirList.append(m_curString); break;
00469         default:   warn("Warning: Unexpected tag `page' found\n"); break; 
00470       }
00471     }
00472 
00473     void startStringValue(const QXmlAttributes& )
00474     {
00475       m_curString = "";
00476     }
00477 
00478     void startDocAnchor(const QXmlAttributes& attrib )
00479     {
00480       m_fileName = attrib.value("file");
00481       m_curString = "";
00482     }
00483 
00484     void endType()
00485     {
00486       if (m_state==InMember)
00487       {
00488         m_curMember->type = m_curString; 
00489       }
00490       else
00491       {
00492         warn("Warning: Unexpected tag `type' found\n");
00493       }
00494     }
00495 
00496     void endName()
00497     {
00498       switch (m_state)
00499       {
00500         case InClass:     m_curClass->name     = m_curString; break;
00501         case InFile:      m_curFile->name      = m_curString; break;
00502         case InNamespace: m_curNamespace->name = m_curString; break;
00503         case InGroup:     m_curGroup->name     = m_curString; break;
00504         case InPage:      m_curPage->name      = m_curString; break;
00505         case InDir:       m_curDir->name       = m_curString; break;
00506         case InMember:    m_curMember->name    = m_curString; break;
00507         case InPackage:   m_curPackage->name   = m_curString; break;
00508         default: warn("Warning: Unexpected tag `name' found\n"); break; 
00509       }
00510     }
00511 
00512     void startBase(const QXmlAttributes& attrib )
00513     {
00514       m_curString="";
00515       if (m_state==InClass && m_curClass)
00516       {
00517         QString protStr = attrib.value("protection");
00518         QString virtStr = attrib.value("virtualness");
00519         Protection prot = Public;
00520         Specifier  virt = Normal;
00521         if (protStr=="protected")
00522         {
00523           prot = Protected;
00524         }
00525         else if (protStr=="private")
00526         {
00527           prot = Private;
00528         }
00529         if (virtStr=="virtual")
00530         {
00531           virt = Virtual;
00532         }
00533         if (m_curClass->bases==0) 
00534         {
00535           m_curClass->bases = new QList<BaseInfo>;
00536           m_curClass->bases->setAutoDelete(TRUE);
00537         }
00538         m_curClass->bases->append(new BaseInfo(m_curString,prot,virt));
00539       }
00540       else
00541       {
00542         warn("Warning: Unexpected tag `base' found\n");
00543       }
00544     }
00545 
00546     void endBase()
00547     {
00548       if (m_state==InClass && m_curClass)
00549       {
00550         m_curClass->bases->getLast()->name = m_curString;
00551       }
00552       else
00553       {
00554         warn("Warning: Unexpected tag `base' found\n");
00555       }
00556     }
00557 
00558     void startIncludes(const QXmlAttributes& attrib )
00559     {
00560       if (m_state==InFile && m_curFile)
00561       {
00562         m_curIncludes = new TagIncludeInfo;
00563         m_curIncludes->id = attrib.value("id");
00564         m_curIncludes->name = attrib.value("name");
00565         m_curIncludes->isLocal = attrib.value("local")=="yes" ? TRUE : FALSE;
00566         m_curIncludes->isImported = attrib.value("imported")=="yes" ? TRUE : FALSE;
00567         m_curFile->includes.append(m_curIncludes);
00568       }
00569       else
00570       {
00571         warn("Warning: Unexpected tag `includes' found\n");
00572       }
00573       m_curString="";
00574     }
00575 
00576     void endIncludes()
00577     {
00578       m_curIncludes->text = m_curString;
00579     }
00580 
00581     void endTemplateArg()
00582     {
00583       if (m_state==InClass && m_curClass)
00584       {
00585         if (m_curClass->templateArguments==0) 
00586         {
00587           m_curClass->templateArguments = new QList<QString>;
00588           m_curClass->templateArguments->setAutoDelete(TRUE);
00589         }
00590         m_curClass->templateArguments->append(new QString(m_curString));
00591       }
00592       else
00593       {
00594         warn("Warning: Unexpected tag `templarg' found\n");
00595       }
00596     }
00597 
00598     void endFilename()
00599     {
00600       switch (m_state)
00601       {
00602         case InClass:     m_curClass->filename     = m_curString;    break;
00603         case InNamespace: m_curNamespace->filename = m_curString;    break;
00604         case InFile:      m_curFile->filename      = m_curString;    break;
00605         case InGroup:     m_curGroup->filename     = m_curString;    break;
00606         case InPage:      m_curPage->filename      = m_curString;    break;
00607         case InPackage:   m_curPackage->filename   = m_curString;    break;
00608         case InDir:       m_curDir->filename       = m_curString;    break;
00609         default: warn("Warning: Unexpected tag `filename' found\n"); break; 
00610       }
00611     }
00612 
00613     void endPath()
00614     {
00615       switch (m_state)
00616       {
00617         case InFile:      m_curFile->path          = m_curString;    break;
00618         case InDir:       m_curDir->path           = m_curString;    break;
00619         default: warn("Warning: Unexpected tag `path' found\n");     break; 
00620       }
00621     }
00622     
00623     void endAnchor()
00624     {
00625       if (m_state==InMember)
00626       {
00627         m_curMember->anchor = m_curString; 
00628       }
00629       else
00630       {
00631         warn("Warning: Unexpected tag `anchor' found\n");
00632       }
00633     }
00634     
00635     void endAnchorFile()
00636     {
00637       if (m_state==InMember)
00638       {
00639         m_curMember->anchorFile = m_curString; 
00640       }
00641       else
00642       {
00643         warn("Warning: Unexpected tag `anchorfile' found\n");
00644       }
00645     }
00646     
00647     void endArglist()
00648     {
00649       if (m_state==InMember)
00650       {
00651         m_curMember->arglist = m_curString; 
00652       }
00653       else
00654       {
00655         warn("Warning: Unexpected tag `arglist' found\n");
00656       }
00657     }
00658     void endTitle()
00659     {
00660       switch (m_state)
00661       {
00662         case InGroup:     m_curGroup->title     = m_curString;    break;
00663         case InPage:      m_curPage->title      = m_curString;    break;
00664         default: warn("Warning: Unexpected tag `title' found\n"); break; 
00665       }
00666     }
00667 
00668     void endSubgroup()
00669     {
00670       if (m_state==InGroup)
00671       {
00672         m_curGroup->subgroupList.append(m_curString);
00673       }
00674       else
00675       {
00676         warn("Warning: Unexpected tag `subgroup' found\n");
00677       }
00678     }
00679 
00680     void startIgnoreElement(const QXmlAttributes& )
00681     {
00682     }
00683 
00684     void endIgnoreElement()
00685     {
00686     }
00687 
00688     bool startDocument()
00689     {
00690       m_state = Invalid;
00691 
00692       m_curClass=0;
00693       m_curNamespace=0;
00694       m_curFile=0;
00695       m_curGroup=0;
00696       m_curPage=0;
00697       m_curPackage=0;
00698       m_curDir=0;
00699 
00700       m_stateStack.setAutoDelete(TRUE);
00701       m_tagFileClasses.setAutoDelete(TRUE);
00702       m_tagFileFiles.setAutoDelete(TRUE);
00703       m_tagFileNamespaces.setAutoDelete(TRUE);
00704       m_tagFileGroups.setAutoDelete(TRUE);
00705       m_tagFilePages.setAutoDelete(TRUE);
00706       m_tagFilePackages.setAutoDelete(TRUE);
00707       m_tagFileDirs.setAutoDelete(TRUE);
00708 
00709       m_startElementHandlers.insert("compound",    new StartElementHandler(this,&TagFileParser::startCompound));
00710       m_startElementHandlers.insert("member",      new StartElementHandler(this,&TagFileParser::startMember));
00711       m_startElementHandlers.insert("name",        new StartElementHandler(this,&TagFileParser::startStringValue));
00712       m_startElementHandlers.insert("base",        new StartElementHandler(this,&TagFileParser::startBase));
00713       m_startElementHandlers.insert("filename",    new StartElementHandler(this,&TagFileParser::startStringValue));
00714       m_startElementHandlers.insert("includes",    new StartElementHandler(this,&TagFileParser::startIncludes));
00715       m_startElementHandlers.insert("path",        new StartElementHandler(this,&TagFileParser::startStringValue));
00716       m_startElementHandlers.insert("anchorfile",  new StartElementHandler(this,&TagFileParser::startStringValue));
00717       m_startElementHandlers.insert("anchor",      new StartElementHandler(this,&TagFileParser::startStringValue));
00718       m_startElementHandlers.insert("arglist",     new StartElementHandler(this,&TagFileParser::startStringValue));
00719       m_startElementHandlers.insert("title",       new StartElementHandler(this,&TagFileParser::startStringValue));
00720       m_startElementHandlers.insert("subgroup",    new StartElementHandler(this,&TagFileParser::startStringValue));
00721       m_startElementHandlers.insert("class",       new StartElementHandler(this,&TagFileParser::startStringValue));
00722       m_startElementHandlers.insert("namespace",   new StartElementHandler(this,&TagFileParser::startStringValue));
00723       m_startElementHandlers.insert("file",        new StartElementHandler(this,&TagFileParser::startStringValue));
00724       m_startElementHandlers.insert("dir",         new StartElementHandler(this,&TagFileParser::startStringValue));
00725       m_startElementHandlers.insert("page",        new StartElementHandler(this,&TagFileParser::startStringValue));
00726       m_startElementHandlers.insert("docanchor",   new StartElementHandler(this,&TagFileParser::startDocAnchor));
00727       m_startElementHandlers.insert("tagfile",     new StartElementHandler(this,&TagFileParser::startIgnoreElement));
00728       m_startElementHandlers.insert("templarg",    new StartElementHandler(this,&TagFileParser::startStringValue));
00729       m_startElementHandlers.insert("type",        new StartElementHandler(this,&TagFileParser::startStringValue));
00730 
00731       m_endElementHandlers.insert("compound",    new EndElementHandler(this,&TagFileParser::endCompound));
00732       m_endElementHandlers.insert("member",      new EndElementHandler(this,&TagFileParser::endMember));
00733       m_endElementHandlers.insert("name",        new EndElementHandler(this,&TagFileParser::endName));
00734       m_endElementHandlers.insert("base",        new EndElementHandler(this,&TagFileParser::endBase));
00735       m_endElementHandlers.insert("filename",    new EndElementHandler(this,&TagFileParser::endFilename));
00736       m_endElementHandlers.insert("includes",    new EndElementHandler(this,&TagFileParser::endIncludes));
00737       m_endElementHandlers.insert("path",        new EndElementHandler(this,&TagFileParser::endPath));
00738       m_endElementHandlers.insert("anchorfile",  new EndElementHandler(this,&TagFileParser::endAnchorFile));
00739       m_endElementHandlers.insert("anchor",      new EndElementHandler(this,&TagFileParser::endAnchor));
00740       m_endElementHandlers.insert("arglist",     new EndElementHandler(this,&TagFileParser::endArglist));
00741       m_endElementHandlers.insert("title",       new EndElementHandler(this,&TagFileParser::endTitle));
00742       m_endElementHandlers.insert("subgroup",    new EndElementHandler(this,&TagFileParser::endSubgroup));
00743       m_endElementHandlers.insert("class"   ,    new EndElementHandler(this,&TagFileParser::endClass));
00744       m_endElementHandlers.insert("namespace",   new EndElementHandler(this,&TagFileParser::endNamespace));
00745       m_endElementHandlers.insert("file",        new EndElementHandler(this,&TagFileParser::endFile));
00746       m_endElementHandlers.insert("dir",         new EndElementHandler(this,&TagFileParser::endDir));
00747       m_endElementHandlers.insert("page",        new EndElementHandler(this,&TagFileParser::endPage));
00748       m_endElementHandlers.insert("docanchor",   new EndElementHandler(this,&TagFileParser::endDocAnchor));
00749       m_endElementHandlers.insert("tagfile",     new EndElementHandler(this,&TagFileParser::endIgnoreElement));
00750       m_endElementHandlers.insert("templarg",    new EndElementHandler(this,&TagFileParser::endTemplateArg));
00751       m_endElementHandlers.insert("type",        new EndElementHandler(this,&TagFileParser::endType));
00752 
00753       return TRUE;
00754     }
00755 
00756     bool startElement( const QString&, const QString&, 
00757                        const QString&name, const QXmlAttributes& attrib )
00758     {
00759       //printf("startElement `%s'\n",name.data());
00760       StartElementHandler *handler = m_startElementHandlers[name];
00761       if (handler)
00762       {
00763         (*handler)(attrib);
00764       }
00765       else 
00766       {
00767         warn("Warning: Unknown tag `%s' found!\n",name.data());
00768       }
00769       return TRUE;
00770     }
00771 
00772     bool endElement( const QString&, const QString&, const QString& name )
00773     {
00774       //printf("endElement `%s'\n",name.data());
00775       EndElementHandler *handler = m_endElementHandlers[name];
00776       if (handler)
00777       {
00778         (*handler)();
00779       }
00780       else 
00781       {
00782         warn("Warning: Unknown tag `%s' found!\n",name.data());
00783       }
00784       return TRUE;
00785     }
00786 
00787     bool characters ( const QString & ch ) 
00788     {
00789       m_curString+=ch;
00790       return TRUE;
00791     }
00792 
00793     void dump();
00794     void buildLists(Entry *root);
00795     void addIncludes();
00796     
00797   private:
00798     void buildMemberList(Entry *ce,QList<TagMemberInfo> &members);
00799     void addDocAnchors(Entry *e,const TagAnchorInfoList &l);
00800     QList<TagClassInfo>        m_tagFileClasses;
00801     QList<TagFileInfo>         m_tagFileFiles;
00802     QList<TagNamespaceInfo>    m_tagFileNamespaces;
00803     QList<TagGroupInfo>        m_tagFileGroups;
00804     QList<TagPageInfo>         m_tagFilePages;
00805     QList<TagPackageInfo>      m_tagFilePackages;
00806     QList<TagDirInfo>          m_tagFileDirs;
00807     QDict<StartElementHandler> m_startElementHandlers;
00808     QDict<EndElementHandler>   m_endElementHandlers;
00809     TagClassInfo              *m_curClass;
00810     TagFileInfo               *m_curFile;
00811     TagNamespaceInfo          *m_curNamespace;
00812     TagPackageInfo            *m_curPackage;
00813     TagGroupInfo              *m_curGroup;
00814     TagPageInfo               *m_curPage;
00815     TagDirInfo                *m_curDir;
00816     TagMemberInfo             *m_curMember;
00817     TagIncludeInfo            *m_curIncludes;
00818     QCString                   m_curString;
00819     QString                    m_tagName;
00820     QString                    m_fileName;
00821     State                      m_state;
00822     QStack<State>              m_stateStack;
00823     QXmlLocator               *m_locator;
00824     QString                    m_inputFileName;
00825 };
00826 
00830 class TagFileErrorHandler : public QXmlErrorHandler
00831 {
00832   public:
00833     virtual ~TagFileErrorHandler() {}
00834     bool warning( const QXmlParseException & )
00835     {
00836       return FALSE;
00837     }
00838     bool error( const QXmlParseException & )
00839     {
00840       return FALSE;
00841     }
00842     bool fatalError( const QXmlParseException &exception )
00843     {
00844       err("Fatal error at line %d column %d: %s\n",
00845           exception.lineNumber(),exception.columnNumber(),
00846           exception.message().data());
00847       return FALSE;
00848     }
00849     QString errorString() { return ""; }
00850 
00851   private:
00852     QString errorMsg;
00853 };
00854 
00856 void TagFileParser::dump()
00857 {
00858   msg("Result:\n");
00859   QListIterator<TagClassInfo> lci(m_tagFileClasses);
00860 
00861   //============== CLASSES
00862   TagClassInfo *cd;
00863   for (;(cd=lci.current());++lci)
00864   {
00865     msg("class `%s'\n",cd->name.data());
00866     msg("  filename `%s'\n",cd->filename.data());
00867     if (cd->bases)
00868     {
00869       QListIterator<BaseInfo> bii(*cd->bases);
00870       BaseInfo *bi;
00871       for ( bii.toFirst() ; (bi=bii.current()) ; ++bii) 
00872       {
00873         msg( "  base: %s \n", bi->name.data() );
00874       }
00875     }
00876 
00877     QListIterator<TagMemberInfo> mci(cd->members);
00878     TagMemberInfo *md;
00879     for (;(md=mci.current());++mci)
00880     {
00881       msg("  member:\n");
00882       msg("    kind: `%s'\n",md->kind.data());
00883       msg("    name: `%s'\n",md->name.data());
00884       msg("    anchor: `%s'\n",md->anchor.data());
00885       msg("    arglist: `%s'\n",md->arglist.data());
00886     }
00887   }
00888   //============== NAMESPACES
00889   QListIterator<TagNamespaceInfo> lni(m_tagFileNamespaces);
00890   TagNamespaceInfo *nd;
00891   for (;(nd=lni.current());++lni)
00892   {
00893     msg("namespace `%s'\n",nd->name.data());
00894     msg("  filename `%s'\n",nd->filename.data());
00895     QStringList::Iterator it;
00896     for ( it = nd->classList.begin(); 
00897         it != nd->classList.end(); ++it ) 
00898     {
00899       msg( "  class: %s \n", (*it).latin1() );
00900     }
00901 
00902     QListIterator<TagMemberInfo> mci(nd->members);
00903     TagMemberInfo *md;
00904     for (;(md=mci.current());++mci)
00905     {
00906       msg("  member:\n");
00907       msg("    kind: `%s'\n",md->kind.data());
00908       msg("    name: `%s'\n",md->name.data());
00909       msg("    anchor: `%s'\n",md->anchor.data());
00910       msg("    arglist: `%s'\n",md->arglist.data());
00911     }
00912   }
00913   //============== FILES
00914   QListIterator<TagFileInfo> lfi(m_tagFileFiles);
00915   TagFileInfo *fd;
00916   for (;(fd=lfi.current());++lfi)
00917   {
00918     msg("file `%s'\n",fd->name.data());
00919     msg("  filename `%s'\n",fd->filename.data());
00920     QStringList::Iterator it;
00921     for ( it = fd->namespaceList.begin(); 
00922         it != fd->namespaceList.end(); ++it ) 
00923     {
00924       msg( "  namespace: %s \n", (*it).latin1() );
00925     }
00926     for ( it = fd->classList.begin(); 
00927         it != fd->classList.end(); ++it ) 
00928     {
00929       msg( "  class: %s \n", (*it).latin1() );
00930     }
00931 
00932     QListIterator<TagMemberInfo> mci(fd->members);
00933     TagMemberInfo *md;
00934     for (;(md=mci.current());++mci)
00935     {
00936       msg("  member:\n");
00937       msg("    kind: `%s'\n",md->kind.data());
00938       msg("    name: `%s'\n",md->name.data());
00939       msg("    anchor: `%s'\n",md->anchor.data());
00940       msg("    arglist: `%s'\n",md->arglist.data());
00941     }
00942 
00943     QListIterator<TagIncludeInfo> mii(fd->includes);
00944     TagIncludeInfo *ii;
00945     for (;(ii=mii.current());++mii)
00946     {
00947       msg("  includes id: %s name: %s\n",ii->id.data(),ii->name.data());
00948     }
00949   }
00950 
00951   //============== GROUPS
00952   QListIterator<TagGroupInfo> lgi(m_tagFileGroups);
00953   TagGroupInfo *gd;
00954   for (;(gd=lgi.current());++lgi)
00955   {
00956     msg("group `%s'\n",gd->name.data());
00957     msg("  filename `%s'\n",gd->filename.data());
00958     QStringList::Iterator it;
00959     for ( it = gd->namespaceList.begin(); 
00960         it != gd->namespaceList.end(); ++it ) 
00961     {
00962       msg( "  namespace: %s \n", (*it).latin1() );
00963     }
00964     for ( it = gd->classList.begin(); 
00965         it != gd->classList.end(); ++it ) 
00966     {
00967       msg( "  class: %s \n", (*it).latin1() );
00968     }
00969     for ( it = gd->fileList.begin(); 
00970         it != gd->fileList.end(); ++it ) 
00971     {
00972       msg( "  file: %s \n", (*it).latin1() );
00973     }
00974     for ( it = gd->subgroupList.begin(); 
00975         it != gd->subgroupList.end(); ++it ) 
00976     {
00977       msg( "  subgroup: %s \n", (*it).latin1() );
00978     }
00979     for ( it = gd->pageList.begin(); 
00980         it != gd->pageList.end(); ++it ) 
00981     {
00982       msg( "  page: %s \n", (*it).latin1() );
00983     }
00984 
00985     QListIterator<TagMemberInfo> mci(gd->members);
00986     TagMemberInfo *md;
00987     for (;(md=mci.current());++mci)
00988     {
00989       msg("  member:\n");
00990       msg("    kind: `%s'\n",md->kind.data());
00991       msg("    name: `%s'\n",md->name.data());
00992       msg("    anchor: `%s'\n",md->anchor.data());
00993       msg("    arglist: `%s'\n",md->arglist.data());
00994     }
00995   }
00996   //============== PAGES
00997   QListIterator<TagPageInfo> lpi(m_tagFilePages);
00998   TagPageInfo *pd;
00999   for (;(pd=lpi.current());++lpi)
01000   {
01001     msg("page `%s'\n",pd->name.data());
01002     msg("  title `%s'\n",pd->title.data());
01003     msg("  filename `%s'\n",pd->filename.data());
01004   }
01005   //============== DIRS
01006   QListIterator<TagDirInfo> ldi(m_tagFileDirs);
01007   TagDirInfo *dd;
01008   for (;(dd=ldi.current());++ldi)
01009   {
01010     msg("dir `%s'\n",dd->name.data());
01011     msg("  path `%s'\n",dd->path.data());
01012     QStringList::Iterator it;
01013     for ( it = dd->fileList.begin(); 
01014         it != dd->fileList.end(); ++it ) 
01015     {
01016       msg( "  file: %s \n", (*it).latin1() );
01017     }
01018     for ( it = dd->subdirList.begin(); 
01019         it != dd->subdirList.end(); ++it ) 
01020     {
01021       msg( "  subdir: %s \n", (*it).latin1() );
01022     }
01023   }
01024 }
01025 
01026 void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l)
01027 {
01028   QListIterator<TagAnchorInfo> tli(l);
01029   TagAnchorInfo *ta;
01030   for (tli.toFirst();(ta=tli.current());++tli)
01031   {
01032     if (Doxygen::sectionDict.find(ta->label)==0)
01033     {
01034       //printf("New sectionInfo file=%s anchor=%s\n",
01035       //    ta->fileName.data(),ta->label.data());
01036       SectionInfo *si=new SectionInfo(ta->fileName,ta->label,ta->label,
01037           SectionInfo::Anchor,m_tagName);
01038       Doxygen::sectionDict.insert(ta->label,si);
01039       e->anchors->append(si);
01040     }
01041     else
01042     {
01043       warn("Duplicate anchor %s found\n",ta->label.data());
01044     }
01045   }
01046 }
01047 
01048 void TagFileParser::buildMemberList(Entry *ce,QList<TagMemberInfo> &members)
01049 {
01050   QListIterator<TagMemberInfo> mii(members);
01051   TagMemberInfo *tmi;
01052   for (;(tmi=mii.current());++mii)
01053   {
01054     Entry *me      = new Entry;
01055     me->type       = tmi->type;
01056     me->name       = tmi->name;
01057     me->args       = tmi->arglist;
01058     if (!me->args.isEmpty())
01059     {
01060       delete me->argList;
01061       me->argList = new ArgumentList;
01062       stringToArgumentList(me->args,me->argList);
01063     }
01064     me->protection = tmi->prot;
01065     me->virt       = tmi->virt;
01066     me->stat       = tmi->isStatic;
01067     me->fileName   = ce->fileName;
01068     if (ce->section == Entry::GROUPDOC_SEC)
01069     {
01070       me->groups->append(new Grouping(ce->name,Grouping::GROUPING_INGROUP));
01071     }
01072     addDocAnchors(me,tmi->docAnchors);
01073     TagInfo *ti    = new TagInfo;
01074     ti->tagName    = m_tagName;
01075     ti->anchor     = tmi->anchor;
01076     ti->fileName   = tmi->anchorFile;
01077     me->tagInfo    = ti;
01078     if (tmi->kind=="define")
01079     {
01080       me->type="#define";
01081       me->section = Entry::DEFINE_SEC;
01082     }
01083     else if (tmi->kind=="enumvalue")
01084     {
01085       me->section = Entry::VARIABLE_SEC;
01086       me->mtype = Method;
01087     }
01088     else if (tmi->kind=="property")
01089     {
01090       me->section = Entry::VARIABLE_SEC;
01091       me->mtype = Property;
01092     }
01093     else if (tmi->kind=="event")
01094     {
01095       me->section = Entry::VARIABLE_SEC;
01096       me->mtype = Event;
01097     }
01098     else if (tmi->kind=="variable")
01099     {
01100       me->section = Entry::VARIABLE_SEC;
01101       me->mtype = Method;
01102     }
01103     else if (tmi->kind=="typedef")
01104     {
01105       me->section = Entry::VARIABLE_SEC; //Entry::TYPEDEF_SEC;
01106       me->type.prepend("typedef ");
01107       me->mtype = Method;
01108     }
01109     else if (tmi->kind=="enumeration")
01110     {
01111       me->section = Entry::ENUM_SEC;
01112       me->mtype = Method;
01113     }
01114     else if (tmi->kind=="function")
01115     {
01116       me->section = Entry::FUNCTION_SEC;
01117       me->mtype = Method;
01118     }
01119     else if (tmi->kind=="signal")
01120     {
01121       me->section = Entry::FUNCTION_SEC;
01122       me->mtype = Signal;
01123     }
01124     else if (tmi->kind=="prototype")
01125     {
01126       me->section = Entry::FUNCTION_SEC;
01127       me->mtype = Method;
01128     }
01129     else if (tmi->kind=="friend")
01130     {
01131       me->section = Entry::FUNCTION_SEC;
01132       me->type.prepend("friend ");
01133       me->mtype = Method;
01134     }
01135     else if (tmi->kind=="dcop")
01136     {
01137       me->section = Entry::FUNCTION_SEC;
01138       me->mtype = DCOP;
01139     }
01140     else if (tmi->kind=="slot")
01141     {
01142       me->section = Entry::FUNCTION_SEC;
01143       me->mtype = Slot;
01144     }
01145     ce->addSubEntry(me);
01146   }
01147 }
01148 
01149 static QString stripPath(const QString &s)
01150 {
01151   int i=s.findRev('/');
01152   if (i!=-1)
01153   {
01154     return s.right(s.length()-i-1);
01155   }
01156   else
01157   {
01158     return s;
01159   }
01160 }
01161 
01166 void TagFileParser::buildLists(Entry *root)
01167 {
01168   // build class list
01169   TagClassInfo *tci = m_tagFileClasses.first();
01170   while (tci)
01171   {
01172     Entry *ce = new Entry;
01173     ce->section = Entry::CLASS_SEC;
01174     switch (tci->kind)
01175     {
01176       case TagClassInfo::Class:     break;
01177       case TagClassInfo::Struct:    ce->spec = Entry::Struct;    break;
01178       case TagClassInfo::Union:     ce->spec = Entry::Union;     break;
01179       case TagClassInfo::Interface: ce->spec = Entry::Interface; break;
01180       case TagClassInfo::Exception: ce->spec = Entry::Exception; break;
01181       case TagClassInfo::Protocol:  ce->spec = Entry::Protocol;  break;
01182       case TagClassInfo::Category:  ce->spec = Entry::Category;  break;
01183     }
01184     ce->name     = tci->name;
01185     addDocAnchors(ce,tci->docAnchors);
01186     TagInfo *ti  = new TagInfo;
01187     ti->tagName  = m_tagName;
01188     ti->fileName = tci->filename;
01189     ce->tagInfo = ti;
01190     ce->objc = tci->isObjC;
01191     // transfer base class list
01192     if (tci->bases)
01193     {
01194       delete ce->extends;
01195       ce->extends = tci->bases; tci->bases = 0;
01196     }
01197     if (tci->templateArguments)
01198     {
01199       if (ce->tArgLists==0) 
01200       {
01201         ce->tArgLists = new QList<ArgumentList>;
01202         ce->tArgLists->setAutoDelete(TRUE);
01203       }
01204       ArgumentList *al = new ArgumentList;
01205       ce->tArgLists->append(al);
01206       
01207       QListIterator<QString> sli(*tci->templateArguments);
01208       QString *argName;
01209       for (;(argName=sli.current());++sli)
01210       {
01211         Argument *a = new Argument;
01212         a->type = "class";
01213         a->name = *argName;
01214         al->append(a);
01215       }
01216     }
01217 
01218     buildMemberList(ce,tci->members);
01219     root->addSubEntry(ce);
01220     tci = m_tagFileClasses.next();
01221   }
01222 
01223   // build file list
01224   TagFileInfo *tfi = m_tagFileFiles.first();
01225   while (tfi)
01226   {
01227     Entry *fe = new Entry;
01228     fe->section = guessSection(tfi->name);
01229     fe->name     = tfi->name;
01230     addDocAnchors(fe,tfi->docAnchors);
01231     TagInfo *ti  = new TagInfo;
01232     ti->tagName  = m_tagName;
01233     ti->fileName = tfi->filename;
01234     fe->tagInfo  = ti;
01235     
01236     QString fullName = m_tagName+":"+tfi->path+stripPath(tfi->name);
01237     fe->fileName = fullName;
01238     //printf("new FileDef() filename=%s\n",tfi->filename.data());
01239     FileDef *fd = new FileDef(m_tagName+":"+tfi->path,
01240                               tfi->name,m_tagName,
01241                               tfi->filename
01242                              );
01243     FileName *mn;
01244     if ((mn=Doxygen::inputNameDict->find(tfi->name)))
01245     {
01246       mn->append(fd);
01247     }
01248     else
01249     {
01250       mn = new FileName(fullName,tfi->name);
01251       mn->append(fd);
01252       Doxygen::inputNameList->inSort(mn);
01253       Doxygen::inputNameDict->insert(tfi->name,mn);
01254     }
01255     buildMemberList(fe,tfi->members);
01256     root->addSubEntry(fe);
01257     tfi = m_tagFileFiles.next();
01258   }
01259 
01260   // build namespace list
01261   TagNamespaceInfo *tni = m_tagFileNamespaces.first();
01262   while (tni)
01263   {
01264     Entry *ne    = new Entry;
01265     ne->section  = Entry::NAMESPACE_SEC;
01266     ne->name     = tni->name;
01267     addDocAnchors(ne,tni->docAnchors);
01268     TagInfo *ti  = new TagInfo;
01269     ti->tagName  = m_tagName;
01270     ti->fileName = tni->filename;
01271     ne->tagInfo  = ti;
01272 
01273     buildMemberList(ne,tni->members);
01274     root->addSubEntry(ne);
01275     tni = m_tagFileNamespaces.next();
01276   }
01277 
01278   // build package list
01279   TagPackageInfo *tpgi = m_tagFilePackages.first();
01280   while (tpgi)
01281   {
01282     Entry *pe    = new Entry;
01283     pe->section  = Entry::PACKAGE_SEC;
01284     pe->name     = tpgi->name;
01285     addDocAnchors(pe,tpgi->docAnchors);
01286     TagInfo *ti  = new TagInfo;
01287     ti->tagName  = m_tagName;
01288     ti->fileName = tpgi->filename;
01289     pe->tagInfo  = ti;
01290 
01291     buildMemberList(pe,tpgi->members);
01292     root->addSubEntry(pe);
01293     tpgi = m_tagFilePackages.next();
01294   }
01295 
01296   // build group list, but only if config file says to include it
01297   //if (Config_getBool("EXTERNAL_GROUPS")) 
01298   //{
01299     TagGroupInfo *tgi = m_tagFileGroups.first();
01300     while (tgi)
01301     {
01302       Entry *ge    = new Entry;
01303       ge->section  = Entry::GROUPDOC_SEC;
01304       ge->name     = tgi->name;
01305       ge->type     = tgi->title;
01306       addDocAnchors(ge,tgi->docAnchors);
01307       TagInfo *ti  = new TagInfo;
01308       ti->tagName  = m_tagName;
01309       ti->fileName = tgi->filename;
01310       ge->tagInfo  = ti;
01311       
01312       buildMemberList(ge,tgi->members);
01313       root->addSubEntry(ge);
01314       tgi = m_tagFileGroups.next();
01315     }
01316   //}
01317 
01318   // build page list
01319   TagPageInfo *tpi = m_tagFilePages.first();
01320   while (tpi)
01321   {
01322     Entry *pe    = new Entry;
01323     pe->section  = Entry::PAGEDOC_SEC;
01324     pe->name     = tpi->name;
01325     pe->args     = tpi->title;
01326     addDocAnchors(pe,tpi->docAnchors);
01327     TagInfo *ti  = new TagInfo;
01328     ti->tagName  = m_tagName;
01329     ti->fileName = tpi->filename;
01330     pe->tagInfo  = ti;
01331 
01332     root->addSubEntry(pe);
01333     tpi = m_tagFilePages.next();
01334   }
01335 }
01336 
01337 void TagFileParser::addIncludes()
01338 {
01339   TagFileInfo *tfi = m_tagFileFiles.first();
01340   while (tfi)
01341   {
01342     //printf("tag file tagName=%s path=%s name=%s\n",m_tagName.data(),tfi->path.data(),tfi->name.data());
01343     FileName *fn = Doxygen::inputNameDict->find(tfi->name);
01344     if (fn)
01345     {
01346       //printf("found\n");
01347       FileNameIterator fni(*fn);
01348       FileDef *fd;
01349       for (;(fd=fni.current());++fni)
01350       {
01351         //printf("input file path=%s name=%s\n",fd->getPath().data(),fd->name().data());
01352         if (fd->getPath()==QCString(m_tagName+":"+tfi->path))
01353         {
01354           //printf("found\n");
01355           QListIterator<TagIncludeInfo> mii(tfi->includes);
01356           TagIncludeInfo *ii;
01357           for (;(ii=mii.current());++mii)
01358           {
01359             //printf("ii->name=`%s'\n",ii->name.data());
01360             FileName *ifn = Doxygen::inputNameDict->find(ii->name);
01361             ASSERT(ifn!=0);
01362             if (ifn)
01363             {
01364               FileNameIterator ifni(*ifn);
01365               FileDef *ifd;
01366               for (;(ifd=ifni.current());++ifni)
01367               {
01368                 //printf("ifd->getOutputFileBase()=%s ii->id=%s\n",
01369                 //        ifd->getOutputFileBase().data(),ii->id.data());
01370                 if (ifd->getOutputFileBase()==QCString(ii->id))
01371                 {
01372                   fd->addIncludeDependency(ifd,ii->text,ii->isLocal,ii->isImported);
01373                 }
01374               }
01375             }
01376           }
01377         }
01378       } 
01379     }
01380     tfi = m_tagFileFiles.next();
01381   }
01382 }
01383 
01384 void parseTagFile(Entry *root,const char *fullName,const char *tagName)
01385 {
01386   QFileInfo fi(fullName);
01387   if (!fi.exists()) return;
01388   TagFileParser handler( tagName );
01389   handler.setFileName(fullName);
01390   TagFileErrorHandler errorHandler;
01391   QFile xmlFile( fullName );
01392   QXmlInputSource source( xmlFile );
01393   QXmlSimpleReader reader;
01394   reader.setContentHandler( &handler );
01395   reader.setErrorHandler( &errorHandler );
01396   reader.parse( source );
01397   handler.buildLists(root);
01398   handler.addIncludes();
01399   //handler.dump();
01400 }
01401 
01402 



Generated on Mon Mar 31 10:58:44 2008 by  doxygen 1.5.1