filedef.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * $Id: filedef.cpp,v 1.55 2001/03/19 19:27:40 root Exp $
00004  *
00005  * Copyright (C) 1997-2008 by Dimitri van Heesch.
00006  *
00007  * Permission to use, copy, modify, and distribute this software and its
00008  * documentation under the terms of the GNU General Public License is hereby 
00009  * granted. No representations are made about the suitability of this software 
00010  * for any purpose. It is provided "as is" without express or implied warranty.
00011  * See the GNU General Public License for more details.
00012  *
00013  * Documents produced by Doxygen are derivative works derived from the
00014  * input used in their production; they are not affected by this license.
00015  *
00016  */
00017 
00018 #include "qtbc.h"
00019 #include "memberlist.h"
00020 #include "classlist.h"
00021 #include "filedef.h"
00022 #include "doxygen.h"
00023 #include "memberdef.h"
00024 #include "classdef.h"
00025 #include "namespacedef.h"
00026 #include "util.h"
00027 #include "language.h"
00028 #include "outputlist.h"
00029 #include "dot.h"
00030 #include "message.h"
00031 #include "docparser.h"
00032 #include "searchindex.h"
00033 #include "htags.h"
00034 #include "parserintf.h"
00035 #include "portable.h"
00036 #include "vhdldocgen.h"
00037 #include "debug.h"
00038 
00039 class DevNullCodeDocInterface : public CodeOutputInterface
00040 {
00041   public:
00042     virtual void codify(const char *) {}
00043     virtual void writeCodeLink(const char *,const char *,
00044                                const char *,const char *,
00045                                const char *) {}
00046     virtual void writeLineNumber(const char *,const char *,
00047                                  const char *,int) {}
00048     virtual void startCodeLine() {}
00049     virtual void endCodeLine() {}
00050     virtual void startCodeAnchor(const char *) {}
00051     virtual void endCodeAnchor() {}
00052     virtual void startFontClass(const char *) {}
00053     virtual void endFontClass() {}
00054     virtual void writeCodeAnchor(const char *) {}
00055     virtual void linkableSymbol(int, const char *,Definition *,Definition *) {}
00056 };
00057 
00062 FileDef::FileDef(const char *p,const char *nm,
00063                  const char *lref,const char *dn)
00064    : Definition((QCString)p+nm,1,nm)
00065 {
00066   path=p;
00067   filepath=path+nm;
00068   filename=nm;
00069   diskname=dn;
00070   if (diskname.isEmpty()) diskname=nm;
00071   setReference(lref);
00072   classSDict        = 0;
00073   includeList       = 0;
00074   includeDict       = 0; 
00075   includedByList    = 0;
00076   includedByDict    = 0; 
00077   namespaceSDict    = 0; 
00078   srcDefDict        = 0;
00079   srcMemberDict     = 0;
00080   usingDirList      = 0;
00081   usingDeclList     = 0;
00082   package           = 0;
00083   isSource          = FALSE; 
00084   docname           = nm;
00085   dir               = 0;
00086   if (Config_getBool("FULL_PATH_NAMES"))
00087   {
00088     docname.prepend(stripFromPath(path.copy()));
00089   }
00090   m_isJava          = name().right(5)==".java";
00091   memberGroupSDict = 0;
00092   acquireFileVersion();
00093   m_subGrouping=Config_getBool("SUBGROUPING");
00094 }
00095 
00097 FileDef::~FileDef()
00098 {
00099   delete classSDict;
00100   delete includeDict;
00101   delete includeList;
00102   delete includedByDict;
00103   delete includedByList;
00104   delete namespaceSDict;
00105   delete srcDefDict;
00106   delete srcMemberDict;
00107   delete usingDirList;
00108   delete usingDeclList;
00109   delete memberGroupSDict;
00110 }
00111 
00113 void FileDef::computeAnchors()
00114 {
00115   MemberList *ml = getMemberList(MemberList::allMembersList);
00116   if (ml) setAnchors(0,'a',ml);
00117 }
00118 
00119 void FileDef::distributeMemberGroupDocumentation()
00120 {
00121   //printf("FileDef::distributeMemberGroupDocumentation()\n");
00122   if (memberGroupSDict)
00123   {
00124     MemberGroupSDict::Iterator mgli(*memberGroupSDict);
00125     MemberGroup *mg;
00126     for (;(mg=mgli.current());++mgli)
00127     {
00128       mg->distributeMemberGroupDocumentation();
00129     }
00130   }
00131 }
00132 
00133 void FileDef::findSectionsInDocumentation()
00134 {
00135   docFindSections(documentation(),this,0,docFile());
00136   if (memberGroupSDict)
00137   {
00138     MemberGroupSDict::Iterator mgli(*memberGroupSDict);
00139     MemberGroup *mg;
00140     for (;(mg=mgli.current());++mgli)
00141     {
00142       mg->findSectionsInDocumentation();
00143     }
00144   }
00145 
00146   QListIterator<MemberList> mli(m_memberLists);
00147   MemberList *ml;
00148   for (mli.toFirst();(ml=mli.current());++mli)
00149   {
00150     if (ml->listType()&MemberList::declarationLists)
00151     {
00152       ml->findSectionsInDocumentation();
00153     }
00154   }
00155 }
00156 
00157 void FileDef::writeDetailedDocumentation(OutputList &ol)
00158 {
00159   if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) || 
00160       !documentation().isEmpty() 
00161      )
00162   {
00163     ol.writeRuler();
00164     ol.pushGeneratorState();
00165     ol.disable(OutputGenerator::Latex);
00166     ol.disable(OutputGenerator::RTF);
00167     ol.writeAnchor(0,"_details"); 
00168     ol.popGeneratorState();
00169     ol.startGroupHeader();
00170     ol.parseText(theTranslator->trDetailedDescription());
00171     ol.endGroupHeader();
00172     ol.startTextBlock();
00173     if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
00174     {
00175       ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
00176     }
00177     if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") && 
00178         !documentation().isEmpty())
00179     {
00180       ol.pushGeneratorState();
00181         ol.disable(OutputGenerator::Man);
00182         ol.newParagraph();
00183         ol.enableAll();
00184         ol.disableAllBut(OutputGenerator::Man);
00185         ol.writeString("\n\n");
00186       ol.popGeneratorState();
00187     }
00188     if (!documentation().isEmpty())
00189     {
00190       //if (doc.at(dl-1)!='.' && doc.at(dl-1)!='!' && doc.at(dl-1)!='?') 
00191       //  doc+='.';
00192       ol.parseDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
00193     }
00194     //printf("Writing source ref for file %s\n",name().data());
00195     if (Config_getBool("SOURCE_BROWSER")) 
00196     {
00197       ol.startParagraph();
00198       QCString refText = theTranslator->trDefinedInSourceFile();
00199       int fileMarkerPos = refText.find("@0");
00200       if (fileMarkerPos!=-1) // should always pass this.
00201       {
00202         ol.parseText(refText.left(fileMarkerPos)); //text left from marker 1
00203         ol.writeObjectLink(0,getSourceFileBase(),
00204             0,name());
00205         ol.parseText(refText.right(
00206               refText.length()-fileMarkerPos-2)); // text right from marker 2
00207       }
00208       ol.endParagraph();
00209     }
00210     ol.endTextBlock();
00211   }
00212 }
00213 
00217 void FileDef::writeDocumentation(OutputList &ol)
00218 {
00219   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
00220   bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
00221   //funcList->countDecMembers();
00222   
00223   //QCString fn = name();
00224   //if (Config_getBool("FULL_PATH_NAMES"))
00225   //{
00226   //  fn.prepend(stripFromPath(getPath().copy()));
00227   //}
00228 
00229   //printf("WriteDocumentation diskname=%s\n",diskname.data());
00230   
00231   QCString versionTitle;
00232   if (!fileVersion.isEmpty())
00233   {
00234     versionTitle=("("+fileVersion+")");
00235   }
00236   QCString title = docname+versionTitle;
00237   QCString pageTitle=theTranslator->trFileReference(docname);
00238 
00239   if (Config_getBool("SHOW_DIRECTORIES") && getDirDef())
00240   {
00241     startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_FileVisible,TRUE);
00242     getDirDef()->writeNavigationPath(ol);
00243     ol.endQuickIndices();
00244     ol.startContents();
00245     QCString pageTitleShort=theTranslator->trFileReference(name());
00246     startTitle(ol,getOutputFileBase());
00247     ol.pushGeneratorState();
00248       ol.disableAllBut(OutputGenerator::Html);
00249       ol.parseText(pageTitleShort); // Html only
00250       ol.enableAll();
00251       ol.disable(OutputGenerator::Html);
00252       ol.parseText(pageTitle); // other output formats
00253     ol.popGeneratorState();
00254     addGroupListToTitle(ol,this);
00255     endTitle(ol,getOutputFileBase(),title);
00256   }
00257   else
00258   {
00259     startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_FileVisible);
00260     startTitle(ol,getOutputFileBase());
00261     ol.parseText(pageTitle);
00262     addGroupListToTitle(ol,this);
00263     endTitle(ol,getOutputFileBase(),title);
00264   }
00265   if (!fileVersion.isEmpty())
00266   {
00267     ol.disableAllBut(OutputGenerator::Html);
00268     ol.startProjectNumber();
00269     ol.docify(versionTitle);
00270     ol.endProjectNumber();
00271     ol.enableAll();
00272   }
00273   
00274   if (Config_getBool("SEARCHENGINE"))
00275   {
00276     Doxygen::searchIndex->setCurrentDoc(pageTitle,getOutputFileBase());
00277     Doxygen::searchIndex->addWord(localName(),TRUE);
00278   }
00279   
00280   if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
00281   {
00282     Doxygen::tagFile << "  <compound kind=\"file\">" << endl;
00283     Doxygen::tagFile << "    <name>" << convertToXML(name()) << "</name>" << endl;
00284     Doxygen::tagFile << "    <path>" << convertToXML(getPath()) << "</path>" << endl;
00285     Doxygen::tagFile << "    <filename>" 
00286                      << convertToXML(getOutputFileBase()) 
00287                      << "</filename>" << endl;
00288   }
00289   
00290   if (Config_getBool("DETAILS_AT_TOP"))
00291   {
00292     ol.startTextBlock(); 
00293     writeDetailedDocumentation(ol);
00294     ol.endTextBlock();
00295 
00296     ol.pushGeneratorState();
00297     ol.disable(OutputGenerator::Man);
00298     ol.disable(OutputGenerator::RTF);
00299     ol.newParagraph();
00300     ol.popGeneratorState();
00301   }
00302   else if (!briefDescription().isEmpty()) 
00303   {
00304     ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),TRUE,FALSE);
00305     //ol.writeString(" \n");
00306     ol.disableAllBut(OutputGenerator::Html);
00307     ol.startTextLink(0,"_details");
00308     ol.parseText(theTranslator->trMore());
00309     ol.endTextLink();
00310     ol.enableAll();
00311 
00312     ol.pushGeneratorState();
00313     ol.disable(OutputGenerator::Man);
00314     ol.disable(OutputGenerator::RTF);
00315     ol.newParagraph();
00316     ol.popGeneratorState();
00317   }
00318   ol.writeSynopsis();
00319  
00320   if (Config_getBool("SHOW_INCLUDE_FILES") && includeList && 
00321       includeList->count()>0)
00322   {
00323     ol.startTextBlock(TRUE);
00324     QListIterator<IncludeInfo> ili(*includeList);
00325     IncludeInfo *ii;
00326     for (;(ii=ili.current());++ili)
00327     {
00328       FileDef *fd=ii->fileDef;
00329       bool isIDLorJava = FALSE;
00330       if (fd)
00331       {
00332         isIDLorJava = fd->name().right(4)==".idl" ||   // M$ or Corba IDL
00333                       fd->name().right(5)==".pidl" ||
00334                       fd->name().right(5)==".java" ||  // Sun's Java
00335                       fd->name().right(4)==".jsl";     // M$ J#
00336       }
00337       ol.startTypewriter();
00338       if (isIDLorJava) // IDL/Java include
00339       {
00340         ol.docify("import ");
00341       }
00342       else if (ii->imported) // Objective-C include
00343       {
00344         ol.docify("#import ");
00345       }
00346       else // C/C++ include
00347       {
00348         ol.docify("#include ");
00349       }
00350       if (ii->local || isIDLorJava)
00351         ol.docify("\"");
00352       else
00353         ol.docify("<");
00354       ol.disable(OutputGenerator::Html);
00355       ol.docify(ii->includeName);
00356       ol.enableAll();
00357       ol.disableAllBut(OutputGenerator::Html);
00358       
00359       // Here we use the include file name as it appears in the file.
00360       // we could also we the name as it is used within doxygen,
00361       // then we should have used fd->docName() instead of ii->includeName
00362       if (fd && fd->isLinkable())
00363       {
00364         ol.writeObjectLink(fd->getReference(),
00365             fd->generateSourceFile() ? fd->includeName() : fd->getOutputFileBase(),
00366             0,ii->includeName);
00367         if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !fd->isReference()) 
00368         {
00369           const char *locStr = (ii->local    || isIDLorJava) ? "yes" : "no";
00370           const char *impStr = (ii->imported || isIDLorJava) ? "yes" : "no";
00371           Doxygen::tagFile << "    <includes id=\"" 
00372                            << convertToXML(fd->getOutputFileBase()) << "\" "
00373                            << "name=\"" << convertToXML(fd->name()) << "\" "
00374                            << "local=\"" << locStr << "\" "
00375                            << "imported=\"" << impStr << "\">"
00376                            << convertToXML(ii->includeName)
00377                            << "</includes>" 
00378                            << endl;
00379         }
00380       }
00381       else
00382       {
00383         ol.docify(ii->includeName);
00384       }
00385       
00386       ol.enableAll();
00387       if (ii->local || isIDLorJava)
00388         ol.docify("\"");
00389       else
00390         ol.docify(">");
00391       if (isIDLorJava) 
00392         ol.docify(";");
00393       ol.endTypewriter();
00394       ol.lineBreak();
00395     }
00396     ol.endTextBlock();
00397   }
00398   
00399   if (Config_getBool("HAVE_DOT") && Config_getBool("INCLUDE_GRAPH"))
00400   {
00401     //printf("Graph for file %s\n",name().data());
00402     DotInclDepGraph incDepGraph(this,FALSE);
00403     if (!incDepGraph.isTrivial() && !incDepGraph.isTooBig())
00404     {
00405       ol.startTextBlock(); 
00406       ol.disable(OutputGenerator::Man);
00407       ol.newParagraph();
00408       ol.startInclDepGraph();
00409       ol.parseText(theTranslator->trInclDepGraph(name()));
00410       ol.endInclDepGraph(incDepGraph);
00411       ol.enableAll();
00412       ol.endTextBlock(TRUE);
00413     }
00414     //incDepGraph.writeGraph(Config_getString("HTML_OUTPUT"),fd->getOutputFileBase());
00415   }
00416 
00417   if (Config_getBool("HAVE_DOT") && Config_getBool("INCLUDED_BY_GRAPH"))
00418   {
00419     //printf("Graph for file %s\n",name().data());
00420     DotInclDepGraph incDepGraph(this,TRUE);
00421     if (!incDepGraph.isTrivial() && !incDepGraph.isTooBig())
00422     {
00423       ol.startTextBlock(); 
00424       ol.disable(OutputGenerator::Man);
00425       ol.newParagraph();
00426       ol.startInclDepGraph();
00427       ol.parseText(theTranslator->trInclByDepGraph());
00428       ol.endInclDepGraph(incDepGraph);
00429       ol.enableAll();
00430       ol.endTextBlock(TRUE);
00431     }
00432     //incDepGraph.writeGraph(Config_getString("HTML_OUTPUT"),fd->getOutputFileBase());
00433   }
00434 
00435   //printf("%s: generateSourceFile()=%d\n",name().data(),generateSourceFile());
00436   if (generateSourceFile())
00437   {
00438     ol.disableAllBut(OutputGenerator::Html);
00439     ol.newParagraph();
00440     ol.startTextLink(includeName(),0);
00441     ol.parseText(theTranslator->trGotoSourceCode());
00442     ol.endTextLink();
00443     ol.enableAll();
00444   }
00445   
00446   ol.startMemberSections();
00447 
00448   if (namespaceSDict && namespaceSDict->count()>0)
00449   {
00450     NamespaceSDict::Iterator ndi(*namespaceSDict);
00451     NamespaceDef *nd;
00452     bool found=FALSE;
00453     for (ndi.toFirst();(nd=ndi.current());++ndi)
00454     {
00455       if (nd->name().find('@')==-1 && !nd->isArtificial())
00456       {
00457         if (!found)
00458         {
00459           ol.startMemberHeader();
00460           if (fortranOpt)
00461           {
00462             ol.parseText(theTranslator->trModules());
00463           }
00464           else
00465           {
00466             ol.parseText(theTranslator->trNamespaces());
00467           }
00468           ol.endMemberHeader();
00469           ol.startMemberList();
00470           found=TRUE;
00471         }
00472         ol.startMemberItem(0);
00473         if (fortranOpt) 
00474         {
00475           ol.writeString("module ");
00476         }
00477         else
00478         {
00479           ol.writeString("namespace ");
00480         }
00481         ol.insertMemberAlign();
00482         if (nd->isLinkable()) 
00483         {
00484           ol.writeObjectLink(nd->getReference(),
00485               nd->getOutputFileBase(),
00486               0,
00487               nd->displayName()
00488           );
00489           if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
00490           {
00491             Doxygen::tagFile << "    <namespace>" << convertToXML(nd->name()) << "</namespace>" << endl;
00492           }
00493         }
00494         else
00495         {
00496           ol.startBold();
00497           ol.docify(nd->displayName());
00498           ol.endBold();
00499         }
00500         ol.endMemberItem();
00501       }
00502     }
00503     if (found) ol.endMemberList();
00504   }
00505 
00506   if (classSDict) classSDict->writeDeclaration(ol);
00507   
00508   /* write user defined member groups */
00509   if (memberGroupSDict)
00510   {
00511     MemberGroupSDict::Iterator mgli(*memberGroupSDict);
00512     MemberGroup *mg;
00513     for (;(mg=mgli.current());++mgli)
00514     {
00515       if ((!mg->allMembersInSameSection() || !m_subGrouping) 
00516           && mg->header()!="[NOHEADER]")
00517       {
00518         mg->writeDeclarations(ol,0,0,this,0);
00519       }
00520     }
00521   }
00522 
00523   //allMemberList.writeDeclarations(ol,0,0,this,0,0,0);
00524   writeMemberDeclarations(ol,MemberList::decDefineMembers,theTranslator->trDefines());
00525   writeMemberDeclarations(ol,MemberList::decProtoMembers,theTranslator->trFuncProtos());
00526   writeMemberDeclarations(ol,MemberList::decTypedefMembers,theTranslator->trTypedefs());
00527   writeMemberDeclarations(ol,MemberList::decEnumMembers,theTranslator->trEnumerations());
00528   writeMemberDeclarations(ol,MemberList::decFuncMembers,
00529       fortranOpt ? theTranslator->trSubprograms()  : 
00530       vhdlOpt    ? VhdlDocGen::trFunctionAndProc() :
00531                    theTranslator->trFunctions())   ;
00532   writeMemberDeclarations(ol,MemberList::decVarMembers,theTranslator->trVariables());
00533   ol.endMemberSections();
00534 
00535   if (!Config_getBool("DETAILS_AT_TOP"))
00536   {
00537     writeDetailedDocumentation(ol);
00538   }
00539 
00540   writeMemberDocumentation(ol);
00541   
00542   // write Author section (Man only)
00543   ol.disableAllBut(OutputGenerator::Man);
00544   ol.startGroupHeader();
00545   ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
00546   ol.endGroupHeader();
00547   ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
00548   ol.enableAll();
00549 
00550   if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
00551   {
00552     writeDocAnchorsToTagFile();
00553     Doxygen::tagFile << "  </compound>" << endl;
00554   }
00555 
00556   endFile(ol);
00557 
00558   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
00559   {
00560     MemberList *ml = getMemberList(MemberList::allMembersList);
00561     if (ml) ml->sort();
00562     writeMemberPages(ol);
00563   }
00564 }
00565 
00566 void FileDef::writeMemberDocumentation(OutputList &ol)
00567 {
00568   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
00569   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
00570   {
00571     ol.disable(OutputGenerator::Html);
00572   }
00573 
00574   writeMemberDocumentation(ol,MemberList::docDefineMembers,theTranslator->trDefineDocumentation());
00575   writeMemberDocumentation(ol,MemberList::docProtoMembers,fortranOpt?theTranslator->trSubprogramDocumentation():theTranslator->trFunctionPrototypeDocumentation());
00576   writeMemberDocumentation(ol,MemberList::docTypedefMembers,theTranslator->trTypedefDocumentation());
00577   writeMemberDocumentation(ol,MemberList::docEnumMembers,theTranslator->trEnumerationTypeDocumentation());
00578   writeMemberDocumentation(ol,MemberList::docFuncMembers,theTranslator->trFunctionDocumentation());
00579   writeMemberDocumentation(ol,MemberList::docVarMembers,theTranslator->trVariableDocumentation());
00580 
00581   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
00582   {
00583     ol.enable(OutputGenerator::Html);
00584   }
00585 }
00586 
00587 void FileDef::writeMemberPages(OutputList &ol)
00588 {
00589   ol.pushGeneratorState();
00590   ol.disableAllBut(OutputGenerator::Html);
00591   
00592   QListIterator<MemberList> mli(m_memberLists);
00593   MemberList *ml;
00594   for (mli.toFirst();(ml=mli.current());++mli)
00595   {
00596     if (ml->listType()&MemberList::documentationLists)
00597     {
00598       ml->writeDocumentationPage(ol,name(),this);
00599     }
00600   }
00601 
00602   ol.popGeneratorState();
00603 }
00604 
00605 void FileDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
00606 {
00607   static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
00608 
00609   ol.writeString("      <div class=\"navtab\">\n");
00610   ol.writeString("        <table>\n");
00611 
00612   MemberList *allMemberList = getMemberList(MemberList::allMembersList);
00613   if (allMemberList)
00614   {
00615     MemberListIterator mli(*allMemberList);
00616     MemberDef *md;
00617     for (mli.toFirst();(md=mli.current());++mli)
00618     {
00619       if (md->getFileDef()==this && md->getNamespaceDef()==0 && md->isLinkable())
00620       {
00621         ol.writeString("          <tr><td class=\"navtab\">");
00622         if (md->isLinkableInProject())
00623         {
00624           if (md==currentMd) // selected item => highlight
00625           {
00626             ol.writeString("<a class=\"qindexHL\" ");
00627           }
00628           else
00629           {
00630             ol.writeString("<a class=\"qindex\" ");
00631           }
00632           ol.writeString("href=\"");
00633           if (createSubDirs) ol.writeString("../../");
00634           ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
00635           ol.writeString("\">");
00636           ol.writeString(md->localName());
00637           ol.writeString("</a>");
00638         }
00639         ol.writeString("</td></tr>\n");
00640       }
00641     }
00642   }
00643 
00644   ol.writeString("        </table>\n");
00645   ol.writeString("      </div>\n");
00646 }
00647 
00649 void FileDef::writeSource(OutputList &ol)
00650 {
00651   static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
00652   QCString title = docname;
00653   if (!fileVersion.isEmpty())
00654   {
00655     title+=(" ("+fileVersion+")");
00656   }
00657   QCString pageTitle = theTranslator->trSourceFile(title);
00658   ol.disableAllBut(OutputGenerator::Html);
00659 
00660   if (Config_getBool("SHOW_DIRECTORIES") && getDirDef())
00661   {
00662     startFile(ol,getSourceFileBase(),0,pageTitle,HLI_FileVisible,TRUE);
00663     getDirDef()->writeNavigationPath(ol);
00664     ol.endQuickIndices();
00665     ol.endContents();
00666     startTitle(ol,getOutputFileBase());
00667     ol.parseText(name());
00668     endTitle(ol,getOutputFileBase(),title);
00669   }
00670   else
00671   {
00672     startFile(ol,getSourceFileBase(),0,pageTitle,HLI_FileVisible,TRUE);
00673     startTitle(ol,0);
00674     ol.parseText(title);
00675     endTitle(ol,0,0);
00676   }
00677 
00678   if (isLinkable())
00679   {
00680     ol.startTextLink(getOutputFileBase(),0);
00681     ol.parseText(theTranslator->trGotoDocumentation());
00682     ol.endTextLink();
00683   }
00684 
00685   ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
00686   pIntf->resetCodeParserState();
00687   ol.startCodeFragment();
00688   pIntf->parseCode(ol,0,
00689             fileToString(absFilePath(),filterSourceFiles),
00690             FALSE,0,this
00691            );
00692   ol.endCodeFragment();
00693   endFile(ol);
00694   ol.enableAll();
00695 }
00696 
00697 void FileDef::parseSource()
00698 {
00699   static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
00700   DevNullCodeDocInterface devNullIntf;
00701   ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
00702   pIntf->resetCodeParserState();
00703   pIntf->parseCode(
00704             devNullIntf,0,
00705             fileToString(absFilePath(),filterSourceFiles),
00706             FALSE,0,this
00707            );
00708 }
00709 
00710 void FileDef::addMembersToMemberGroup()
00711 {
00712   QListIterator<MemberList> mli(m_memberLists);
00713   MemberList *ml;
00714   for (mli.toFirst();(ml=mli.current());++mli)
00715   {
00716     if (ml->listType()&MemberList::declarationLists)
00717     {
00718       ::addMembersToMemberGroup(ml,&memberGroupSDict,this);
00719     }
00720   }
00721 
00722   // add members inside sections to their groups
00723   if (memberGroupSDict)
00724   {
00725     MemberGroupSDict::Iterator mgli(*memberGroupSDict);
00726     MemberGroup *mg;
00727     for (;(mg=mgli.current());++mgli)
00728     {
00729       if (mg->allMembersInSameSection() && m_subGrouping)
00730       {
00731         //printf("----> addToDeclarationSection(%s)\n",mg->header().data());
00732         mg->addToDeclarationSection();
00733       }
00734     }
00735   }
00736 }
00737 
00739 void FileDef::insertMember(MemberDef *md)
00740 {
00741   if (md->isHidden()) return;
00742   //printf("%s:FileDef::insertMember(%s (=%p) list has %d elements)\n",
00743   //    name().data(),md->name().data(),md,allMemberList.count());
00744   MemberList *allMemberList = getMemberList(MemberList::allMembersList);
00745   if (allMemberList && allMemberList->findRef(md)!=-1)  // TODO optimize the findRef!
00746   { 
00747     return;
00748   }
00749 
00750   if (allMemberList==0)
00751   {
00752     allMemberList = new MemberList(MemberList::allMembersList);;
00753     m_memberLists.append(allMemberList);
00754   }
00755   allMemberList->append(md); 
00756   //::addFileMemberNameToIndex(md);
00757   switch (md->memberType())
00758   {
00759     case MemberDef::Variable:     
00760     case MemberDef::Property:     
00761       addMemberToList(MemberList::decVarMembers,md);
00762       addMemberToList(MemberList::docVarMembers,md);
00763       break;
00764     case MemberDef::Function: 
00765       addMemberToList(MemberList::decFuncMembers,md);
00766       addMemberToList(MemberList::docFuncMembers,md);
00767       break;
00768     case MemberDef::Typedef:      
00769       addMemberToList(MemberList::decTypedefMembers,md);
00770       addMemberToList(MemberList::docTypedefMembers,md);
00771       break;
00772     case MemberDef::Enumeration:  
00773       addMemberToList(MemberList::decEnumMembers,md);
00774       addMemberToList(MemberList::docEnumMembers,md);
00775       break;
00776     case MemberDef::EnumValue:    // enum values are shown inside their enums
00777       break;
00778     case MemberDef::Prototype:    
00779       addMemberToList(MemberList::decProtoMembers,md);
00780       addMemberToList(MemberList::docProtoMembers,md);
00781       break;
00782     case MemberDef::Define:       
00783       addMemberToList(MemberList::decDefineMembers,md);
00784       addMemberToList(MemberList::docDefineMembers,md);
00785       break;
00786     default:
00787        err("FileDef::insertMembers(): "
00788            "member `%s' with class scope `%s' inserted in file scope `%s'!\n",
00789            md->name().data(),
00790            md->getClassDef() ? md->getClassDef()->name().data() : "<global>",
00791            name().data());
00792   }
00793   //addMemberToGroup(md,groupId);
00794 }
00795 
00797 void FileDef::insertClass(ClassDef *cd)
00798 {
00799   if (cd->isHidden()) return;
00800   if (classSDict==0)
00801   {
00802     classSDict = new ClassSDict(17);
00803   }
00804   if (Config_getBool("SORT_BRIEF_DOCS"))
00805     classSDict->inSort(cd->name(),cd);
00806   else
00807     classSDict->append(cd->name(),cd);
00808 }
00809 
00811 void FileDef::insertNamespace(NamespaceDef *nd)
00812 {
00813   if (nd->isHidden()) return;
00814   if (!nd->name().isEmpty() && 
00815       (namespaceSDict==0 || namespaceSDict->find(nd->name())==0))
00816   {
00817     if (namespaceSDict==0)
00818     {
00819       namespaceSDict = new NamespaceSDict;
00820     }
00821     if (Config_getBool("SORT_BRIEF_DOCS"))
00822       namespaceSDict->inSort(nd->name(),nd);
00823     else
00824       namespaceSDict->append(nd->name(),nd);
00825   }
00826 }
00827 
00828 void FileDef::addSourceRef(int line,Definition *d,MemberDef *md)
00829 {
00830   //printf("FileDef::addSourceDef(%d,%p,%p)\n",line,d,md);
00831   if (d)
00832   {
00833     if (srcDefDict==0)    srcDefDict    = new QIntDict<Definition>(257);
00834     if (srcMemberDict==0) srcMemberDict = new QIntDict<MemberDef>(257);
00835     srcDefDict->insert(line,d);
00836     if (md) srcMemberDict->insert(line,md);
00837     //printf("Adding member %s with anchor %s at line %d to file %s\n",
00838     //    md->name().data(),md->anchor().data(),line,name().data());
00839   }
00840 }
00841 
00842 Definition *FileDef::getSourceDefinition(int lineNr)
00843 {
00844   Definition *result=0;
00845   if (srcDefDict)
00846   {
00847     result = srcDefDict->find(lineNr);
00848   }
00849   return result;
00850 }
00851 
00852 MemberDef *FileDef::getSourceMember(int lineNr)
00853 {
00854   MemberDef *result=0;
00855   if (srcMemberDict)
00856   {
00857     result = srcMemberDict->find(lineNr);
00858   }
00859   return result;
00860 }
00861 
00862 
00863 void FileDef::addUsingDirective(NamespaceDef *nd)
00864 {
00865   if (usingDirList==0)
00866   {
00867     usingDirList = new NamespaceSDict;
00868   }
00869   if (usingDirList->find(nd->qualifiedName())==0)
00870   {
00871     usingDirList->append(nd->qualifiedName(),nd);
00872   }
00873   //printf("%p: FileDef::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count());
00874 }
00875 
00876 NamespaceSDict *FileDef::getUsedNamespaces() const 
00877 { 
00878   //printf("%p: FileDef::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0);
00879   return usingDirList; 
00880 }
00881 
00882 void FileDef::addUsingDeclaration(Definition *d)
00883 {
00884   if (usingDeclList==0)
00885   {
00886     usingDeclList = new SDict<Definition>(17);
00887   }
00888   if (usingDeclList->find(d->qualifiedName())==0)
00889   {
00890     usingDeclList->append(d->qualifiedName(),d);
00891   }
00892 }
00893 
00894 void FileDef::addIncludeDependency(FileDef *fd,const char *incName,bool local,
00895                                    bool imported)
00896 {
00897   //printf("FileDef::addIncludeDependency(%p,%s,%d)\n",fd,incName,local);
00898   QCString iName = fd ? fd->absFilePath().data() : incName;
00899   if (!iName.isEmpty() && (!includeDict || includeDict->find(iName)==0))
00900   {
00901     if (includeDict==0)
00902     {
00903       includeDict   = new QDict<IncludeInfo>(61);
00904       includeList   = new QList<IncludeInfo>;
00905       includeList->setAutoDelete(TRUE);
00906     }
00907     IncludeInfo *ii = new IncludeInfo;
00908     ii->fileDef     = fd;
00909     ii->includeName = incName;
00910     ii->local       = local;
00911     ii->imported    = imported;
00912     includeList->append(ii);
00913     includeDict->insert(iName,ii);
00914   }
00915 }
00916 
00917 void FileDef::addIncludedUsingDirectives()
00918 {
00919   if (visited) return;
00920   visited=TRUE;
00921   //printf("( FileDef::addIncludedUsingDirectives for file %s\n",name().data());
00922 
00923   NamespaceList nl;
00924   if (includeList) // file contains #includes
00925   {
00926     {
00927       QListIterator<IncludeInfo> iii(*includeList);
00928       IncludeInfo *ii;
00929       for (iii.toFirst();(ii=iii.current());++iii) // foreach #include...
00930       {
00931         if (ii->fileDef && !ii->fileDef->visited) // ...that is a known file
00932         {
00933           // recurse into this file
00934           ii->fileDef->addIncludedUsingDirectives();
00935         }
00936       }
00937     }
00938     {
00939       QListIterator<IncludeInfo> iii(*includeList);
00940       IncludeInfo *ii;
00941       // iterate through list from last to first
00942       for (iii.toLast();(ii=iii.current());--iii)
00943       {
00944         if (ii->fileDef && ii->fileDef!=this)
00945         {
00946           NamespaceSDict *unl = ii->fileDef->usingDirList;
00947           if (unl)
00948           {
00949             NamespaceSDict::Iterator nli(*unl);
00950             NamespaceDef *nd;
00951             for (nli.toLast();(nd=nli.current());--nli)
00952             {
00953               // append each using directive found in a #include file
00954               if (usingDirList==0) usingDirList = new NamespaceSDict;
00955               //printf("Prepending used namespace %s to the list of file %s\n",
00956               //    nd->name().data(),name().data());
00957               if (usingDirList->find(nd->qualifiedName())==0) // not yet added
00958               {
00959                 usingDirList->prepend(nd->qualifiedName(),nd);
00960               }
00961             }
00962           }
00963         }
00964       }
00965     }
00966   }
00967   //printf(") end FileDef::addIncludedUsingDirectives for file %s\n",name().data());
00968 }
00969 
00970 
00971 void FileDef::addIncludedByDependency(FileDef *fd,const char *incName,
00972                                       bool local,bool imported)
00973 {
00974   //printf("FileDef::addIncludedByDependency(%p,%s,%d)\n",fd,incName,local);
00975   QCString iName = fd ? fd->absFilePath().data() : incName;
00976   if (!iName.isEmpty() && (includedByDict==0 || includedByDict->find(iName)==0))
00977   {
00978     if (includedByDict==0)
00979     {
00980       includedByDict = new QDict<IncludeInfo>(61);
00981       includedByList = new QList<IncludeInfo>;
00982       includedByList->setAutoDelete(TRUE);
00983     }
00984     IncludeInfo *ii = new IncludeInfo;
00985     ii->fileDef     = fd;
00986     ii->includeName = incName;
00987     ii->local       = local;
00988     ii->imported    = imported;
00989     includedByList->append(ii);
00990     includedByDict->insert(iName,ii);
00991   }
00992 }
00993 
00994 bool FileDef::isIncluded(const QCString &name) const
00995 {
00996   if (name.isEmpty()) return FALSE;
00997   return includeDict!=0 && includeDict->find(name)!=0;
00998 }
00999 
01000 bool FileDef::generateSourceFile() const 
01001 { 
01002   QCString extension = name().right(4);
01003   return !isReference() && 
01004          (Config_getBool("SOURCE_BROWSER") || 
01005            (Config_getBool("VERBATIM_HEADERS") && guessSection(name())==Entry::HEADER_SEC) 
01006          ) &&
01007          extension!=".doc" && extension!=".txt" && extension!=".dox"; 
01008 }
01009 
01010 
01011 void FileDef::addListReferences()
01012 {
01013   {
01014     LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();
01015     addRefItem(xrefItems.pointer(),
01016                theTranslator->trFile(TRUE,TRUE),
01017                getOutputFileBase(),name()
01018               );
01019   }
01020   if (memberGroupSDict)
01021   {
01022     MemberGroupSDict::Iterator mgli(*memberGroupSDict);
01023     MemberGroup *mg;
01024     for (;(mg=mgli.current());++mgli)
01025     {
01026       mg->addListReferences(this);
01027     }
01028   }
01029   QListIterator<MemberList> mli(m_memberLists);
01030   MemberList *ml;
01031   for (mli.toFirst();(ml=mli.current());++mli)
01032   {
01033     if (ml->listType()&MemberList::documentationLists)
01034     {
01035       ml->addListReferences(this);
01036     }
01037   }
01038 }
01039 
01040 //-------------------------------------------------------------------
01041 
01042 static int findMatchingPart(const QCString &path,const QCString dir)
01043 {
01044   int si1;
01045   int pos1=0,pos2=0;
01046   while ((si1=path.find('/',pos1))!=-1)
01047   {
01048     int si2=dir.find('/',pos2);
01049     //printf("  found slash at pos %d in path %d: %s<->%s\n",si1,si2,
01050     //    path.mid(pos1,si1-pos2).data(),dir.mid(pos2).data());
01051     if (si2==-1 && path.mid(pos1,si1-pos2)==dir.mid(pos2)) // match at end
01052     {
01053       return dir.length();
01054     }
01055     if (si1!=si2 || path.mid(pos1,si1-pos2)!=dir.mid(pos2,si2-pos2)) // no match in middle
01056     {
01057       return QMAX(pos1-1,0);
01058     }
01059     pos1=si1+1;
01060     pos2=si2+1;
01061   }
01062   return 0;
01063 }
01064 
01065 static Directory *findDirNode(Directory *root,const QCString &name)
01066 {
01067   QListIterator<DirEntry> dli(root->children());
01068   DirEntry *de;
01069   for (dli.toFirst();(de=dli.current());++dli)
01070   {
01071     if (de->kind()==DirEntry::Dir)
01072     {
01073       Directory *dir = (Directory *)de;
01074       QCString dirName=dir->name();
01075       int sp=findMatchingPart(name,dirName);
01076       //printf("findMatchingPart(%s,%s)=%d\n",name.data(),dirName.data(),sp);
01077       if (sp>0) // match found
01078       {
01079         if ((uint)sp==dirName.length()) // whole directory matches
01080         {
01081           // recurse into the directory
01082           return findDirNode(dir,name.mid(dirName.length()+1));
01083         } 
01084         else // partial match => we need to split the path into three parts
01085         {
01086           QCString baseName     =dirName.left(sp);
01087           QCString oldBranchName=dirName.mid(sp+1);
01088           QCString newBranchName=name.mid(sp+1);
01089           // strip file name from path
01090           int newIndex=newBranchName.findRev('/');
01091           if (newIndex>0) newBranchName=newBranchName.left(newIndex);
01092 
01093           //printf("Splitting off part in new branch \n"
01094           //    "base=%s old=%s new=%s\n",
01095           //    baseName.data(),
01096           //    oldBranchName.data(),
01097           //    newBranchName.data()
01098           //      );
01099           Directory *base = new Directory(root,baseName);
01100           Directory *newBranch = new Directory(base,newBranchName);
01101           dir->reParent(base);
01102           dir->rename(oldBranchName);
01103           base->addChild(dir);
01104           base->addChild(newBranch);
01105           dir->setLast(FALSE);
01106           // remove DirEntry container from list (without deleting it)
01107           root->children().setAutoDelete(FALSE);
01108           root->children().removeRef(dir);
01109           root->children().setAutoDelete(TRUE);
01110           // add new branch to the root
01111           if (!root->children().isEmpty())
01112           {
01113             root->children().last()->setLast(FALSE); 
01114           }
01115           root->addChild(base);
01116           return newBranch;
01117         }
01118       }
01119     }
01120   }
01121   int si=name.findRev('/');
01122   if (si==-1) // no subdir
01123   {
01124     return root; // put the file under the root node.
01125   }
01126   else // need to create a subdir 
01127   {
01128     QCString baseName = name.left(si);
01129     //printf("new subdir %s\n",baseName.data());
01130     Directory *newBranch = new Directory(root,baseName);
01131     if (!root->children().isEmpty())
01132     {
01133       root->children().last()->setLast(FALSE); 
01134     }
01135     root->addChild(newBranch);
01136     return newBranch;
01137   }
01138 }
01139 
01140 static void mergeFileDef(Directory *root,FileDef *fd)
01141 {
01142   QCString rootPath = root->name();
01143   QCString filePath = fd->absFilePath();
01144   //printf("merging %s\n",filePath.data());
01145   Directory *dirNode = findDirNode(root,filePath);
01146   if (!dirNode->children().isEmpty())
01147   {
01148     dirNode->children().last()->setLast(FALSE); 
01149   }
01150   DirEntry *e=new DirEntry(dirNode,fd);
01151   dirNode->addChild(e);
01152 }
01153 
01154 #if 0
01155 static void generateIndent(QTextStream &t,DirEntry *de,int level)
01156 {
01157   if (de->parent())
01158   {
01159     generateIndent(t,de->parent(),level+1);
01160   }
01161   // from the root up to node n do...
01162   if (level==0) // item before a dir or document
01163   {
01164     if (de->isLast())
01165     {
01166       if (de->kind()==DirEntry::Dir)
01167       {
01168         t << "<img " << FTV_IMGATTRIBS(plastnode) << "/>";
01169       }
01170       else
01171       {
01172         t << "<img " << FTV_IMGATTRIBS(lastnode) << "/>";
01173       }
01174     }
01175     else
01176     {
01177       if (de->kind()==DirEntry::Dir)
01178       {
01179         t << "<img " << FTV_IMGATTRIBS(pnode) << "/>";
01180       }
01181       else
01182       {
01183         t << "<img " << FTV_IMGATTRIBS(node) << "/>";
01184       }
01185     }
01186   }
01187   else // item at another level
01188   {
01189     if (de->isLast())
01190     {
01191       t << "<img " << FTV_IMGATTRIBS(blank) << "/>";
01192     }
01193     else
01194     {
01195       t << "<img " << FTV_IMGATTRIBS(vertline) << "/>";
01196     }
01197   }
01198 }
01199 
01200 static void writeDirTreeNode(QTextStream &t,Directory *root,int level)
01201 {
01202   QCString indent;
01203   indent.fill(' ',level*2);
01204   QListIterator<DirEntry> dli(root->children());
01205   DirEntry *de;
01206   for (dli.toFirst();(de=dli.current());++dli)
01207   {
01208     t << indent << "<p>";
01209     generateIndent(t,de,0);
01210     if (de->kind()==DirEntry::Dir)
01211     {
01212       Directory *dir=(Directory *)de;
01213       //printf("%s [dir]: %s (last=%d,dir=%d)\n",indent.data(),dir->name().data(),dir->isLast(),dir->kind()==DirEntry::Dir);
01214       t << "<img " << FTV_IMGATTRIBS(folderclosed) << "/>";
01215       t << dir->name();
01216       t << "</p>\n";
01217       t << indent << "<div>\n";
01218       writeDirTreeNode(t,dir,level+1);
01219       t << indent << "</div>\n";
01220     }
01221     else
01222     {
01223       //printf("%s [file]: %s (last=%d,dir=%d)\n",indent.data(),de->file()->name().data(),de->isLast(),de->kind()==DirEntry::Dir);
01224       t << "<img " << FTV_IMGATTRIBS(doc) << "/>";
01225       t << de->file()->name();
01226       t << "</p>\n";
01227     }
01228   }
01229 }
01230 #endif
01231 
01232 static void addDirsAsGroups(Directory *root,GroupDef *parent,int level)
01233 {
01234   GroupDef *gd=0;
01235   if (root->kind()==DirEntry::Dir)
01236   {
01237     gd = new GroupDef("[generated]",
01238                       1,
01239                       root->path(), // name
01240                       root->name()  // title
01241                      );
01242     if (parent) 
01243     {
01244       parent->addGroup(gd);
01245       gd->makePartOfGroup(parent);
01246     }
01247     else
01248     {
01249       Doxygen::groupSDict->append(root->path(),gd);
01250     }
01251   }
01252   QListIterator<DirEntry> dli(root->children());
01253   DirEntry *de;
01254   for (dli.toFirst();(de=dli.current());++dli)
01255   {
01256     if (de->kind()==DirEntry::Dir)
01257     {
01258       addDirsAsGroups((Directory *)de,gd,level+1);
01259     }
01260   }
01261 }
01262 
01263 void generateFileTree()
01264 {
01265   Directory *root=new Directory(0,"root");
01266   root->setLast(TRUE);
01267   FileNameListIterator fnli(*Doxygen::inputNameList); 
01268   FileName *fn;
01269   for (fnli.toFirst();(fn=fnli.current());++fnli)
01270   {
01271     FileNameIterator fni(*fn);
01272     FileDef *fd;
01273     for (;(fd=fni.current());++fni)
01274     {
01275       mergeFileDef(root,fd);
01276     }
01277   }
01278   //t << "<div class=\"directory\">\n";
01279   //writeDirTreeNode(t,root,0);
01280   //t << "</div>\n";
01281   addDirsAsGroups(root,0,0);
01282   delete root;
01283 }
01284 
01285 //-------------------------------------------------------------------
01286 
01287 void FileDef::combineUsingRelations()
01288 {
01289   if (visited) return; // already done
01290   visited=TRUE;
01291   if (usingDirList)
01292   {
01293     NamespaceSDict::Iterator nli(*usingDirList);
01294     NamespaceDef *nd;
01295     for (nli.toFirst();(nd=nli.current());++nli)
01296     {
01297       nd->combineUsingRelations();
01298     }
01299     for (nli.toFirst();(nd=nli.current());++nli)
01300     {
01301       // add used namespaces of namespace nd to this namespace
01302       if (nd->getUsedNamespaces())
01303       {
01304         NamespaceSDict::Iterator unli(*nd->getUsedNamespaces());
01305         NamespaceDef *und;
01306         for (unli.toFirst();(und=unli.current());++unli)
01307         {
01308           //printf("Adding namespace %s to the using list of %s\n",und->qualifiedName().data(),qualifiedName().data());
01309           addUsingDirective(und);
01310         }
01311       }
01312       // add used classes of namespace nd to this namespace
01313       if (nd->getUsedClasses())
01314       {
01315         SDict<Definition>::Iterator cli(*nd->getUsedClasses());
01316         Definition *ucd;
01317         for (cli.toFirst();(ucd=cli.current());++cli)
01318         {
01319           //printf("Adding class %s to the using list of %s\n",cd->qualifiedName().data(),qualifiedName().data());
01320           addUsingDeclaration(ucd);
01321         }
01322       }
01323     }
01324   }
01325 }
01326 
01327 bool FileDef::isDocumentationFile() const
01328 {
01329   return name().right(4)==".doc" ||
01330          name().right(4)==".txt" ||
01331          name().right(4)==".dox";
01332 }
01333 
01334 void FileDef::acquireFileVersion()
01335 {
01336   QCString vercmd = Config_getString("FILE_VERSION_FILTER");
01337   if (!vercmd.isEmpty()) 
01338   {
01339     msg("Version of %s : ",filepath.data());
01340     QCString cmd = vercmd+" \""+filepath+"\"";
01341     Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",cmd.data());
01342     FILE *f=portable_popen(cmd,"r");
01343     if (!f)
01344     {
01345       err("Error: could not execute %s\n",vercmd.data());
01346       return;
01347     }
01348     const int bufSize=1024;
01349     char buf[bufSize];
01350     int numRead = fread(buf,1,bufSize,f);
01351     portable_pclose(f);
01352     if (numRead > 0) 
01353     {
01354       fileVersion = QCString(buf,numRead).stripWhiteSpace();
01355       msg("%s\n",fileVersion.data());
01356     }
01357     else 
01358     {
01359       msg("no version available\n");
01360     }
01361   }
01362 }
01363 
01364 
01365 QCString FileDef::getSourceFileBase() const
01366 { 
01367   if (Htags::useHtags)
01368   {
01369     return Htags::path2URL(filepath);
01370   }
01371   else
01372   {
01373     return convertNameToFile(diskname+"-source"); 
01374   }
01375 }
01376 
01378 QCString FileDef::includeName() const 
01379 { 
01380   if (Htags::useHtags)
01381   {
01382     return Htags::path2URL(filepath);
01383   }
01384   else
01385   {
01386     return convertNameToFile(diskname+"-source"); 
01387   }
01388 }
01389 
01390 MemberList *FileDef::createMemberList(MemberList::ListType lt)
01391 {
01392   m_memberLists.setAutoDelete(TRUE);
01393   QListIterator<MemberList> mli(m_memberLists);
01394   MemberList *ml;
01395   for (mli.toFirst();(ml=mli.current());++mli)
01396   {
01397     if (ml->listType()==lt)
01398     {
01399       return ml;
01400     }
01401   }
01402   // not found, create a new member list
01403   ml = new MemberList(lt);
01404   m_memberLists.append(ml);
01405   return ml;
01406 }
01407 
01408 void FileDef::addMemberToList(MemberList::ListType lt,MemberDef *md)
01409 {
01410   static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
01411   static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
01412   MemberList *ml = createMemberList(lt);
01413   if (((ml->listType()&MemberList::declarationLists) && sortBriefDocs) ||
01414       ((ml->listType()&MemberList::documentationLists) && sortMemberDocs)
01415      )
01416     ml->inSort(md);
01417   else
01418     ml->append(md);
01419   if (lt&MemberList::documentationLists)
01420   {
01421     ml->setInFile(TRUE);
01422   }
01423   if (ml->listType()&MemberList::declarationLists) md->setSectionList(this,ml);
01424 }
01425 
01426 MemberList *FileDef::getMemberList(MemberList::ListType lt) const
01427 {
01428   FileDef *that = (FileDef*)this;
01429   MemberList *ml = that->m_memberLists.first();
01430   while (ml)
01431   {
01432     if (ml->listType()==lt)
01433     {
01434       return ml;
01435     }
01436     ml = that->m_memberLists.next();
01437   }
01438   return 0;
01439 }
01440 
01441 void FileDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,const QCString &title)
01442 {
01443   MemberList * ml = getMemberList(lt);
01444   if (ml) ml->writeDeclarations(ol,0,0,this,0,title,0);
01445 }
01446 
01447 void FileDef::writeMemberDocumentation(OutputList &ol,MemberList::ListType lt,const QCString &title)
01448 {
01449   MemberList * ml = getMemberList(lt);
01450   if (ml) ml->writeDocumentation(ol,name(),this,title);
01451 }



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