Orb/Doxygen/src/doxygen.cpp
changeset 4 468f4c8d3d5b
parent 3 d8fccb2cd802
equal deleted inserted replaced
3:d8fccb2cd802 4:468f4c8d3d5b
     1 /******************************************************************************
     1 /******************************************************************************
     2  *
     2  *
     3  * Copyright (C) 1997-2008 by Dimitri van Heesch.
     3  * Copyright (C) 1997-2010 by Dimitri van Heesch.
     4  *
     4  *
     5  * Permission to use, copy, modify, and distribute this software and its
     5  * Permission to use, copy, modify, and distribute this software and its
     6  * documentation under the terms of the GNU General Public License is hereby 
     6  * documentation under the terms of the GNU General Public License is hereby 
     7  * granted. No representations are made about the suitability of this software 
     7  * granted. No representations are made about the suitability of this software 
     8  * for any purpose. It is provided "as is" without express or implied warranty.
     8  * for any purpose. It is provided "as is" without express or implied warranty.
   152 static QDict<FileDef>   g_usingDeclarations(1009); // used classes
   152 static QDict<FileDef>   g_usingDeclarations(1009); // used classes
   153 static FileStorage     *g_storage = 0;
   153 static FileStorage     *g_storage = 0;
   154 static bool             g_successfulRun = FALSE;
   154 static bool             g_successfulRun = FALSE;
   155 static bool             g_dumpSymbolMap = FALSE;
   155 static bool             g_dumpSymbolMap = FALSE;
   156 static bool             g_dumpConfigAsXML = FALSE;
   156 static bool             g_dumpConfigAsXML = FALSE;
       
   157 
       
   158 
   157 
   159 
   158 void clearAll()
   160 void clearAll()
   159 {
   161 {
   160   g_inputFiles.clear();      
   162   g_inputFiles.clear();      
   161   //g_excludeNameDict.clear();  
   163   //g_excludeNameDict.clear();  
  2308   }
  2310   }
  2309   else
  2311   else
  2310   {
  2312   {
  2311     mn = new MemberName(name);
  2313     mn = new MemberName(name);
  2312     mn->append(md);
  2314     mn->append(md);
  2313 	// PaulRoss: This first line looks wrong to me but links to typedef's don't work without it!
       
  2314     Doxygen::functionNameSDict->append(name,mn);
  2315     Doxygen::functionNameSDict->append(name,mn);
  2315     //Doxygen::memberNameSDict->append(name,mn);
       
  2316   }
  2316   }
  2317   rootNav->changeSection(Entry::EMPTY_SEC);
  2317   rootNav->changeSection(Entry::EMPTY_SEC);
  2318   return md;
  2318   return md;
  2319 }
  2319 }
  2320 
  2320 
  2481                    root->name.data(),
  2481                    root->name.data(),
  2482                    root->args.data(),
  2482                    root->args.data(),
  2483                    root->bodyLine,
  2483                    root->bodyLine,
  2484                    root->mGrpId
  2484                    root->mGrpId
  2485                 );
  2485                 );
  2486 	//Entry *pParent = root->parent();
  2486     //printf("root->parent->name=%s\n",root->parent->name.data());
  2487 	//if (pParent) {
  2487 
  2488 	//	printf("root->parent->name=%s\n",root->parent()->name.data());
       
  2489 	//} else {
       
  2490 	//	printf("NO Parent\n");
       
  2491 	//}
       
  2492     if (root->type.isEmpty() && root->name.find("operator")==-1 &&
  2488     if (root->type.isEmpty() && root->name.find("operator")==-1 &&
  2493         (root->name.find('*')!=-1 || root->name.find('&')!=-1))
  2489         (root->name.find('*')!=-1 || root->name.find('&')!=-1))
  2494     {
  2490     {
  2495       // recover from parse error caused by redundant braces 
  2491       // recover from parse error caused by redundant braces 
  2496       // like in "int *(var[10]);", which is parsed as
  2492       // like in "int *(var[10]);", which is parsed as
  2689       rootNav->section()==Entry::VARIABLE_SEC &&
  2685       rootNav->section()==Entry::VARIABLE_SEC &&
  2690       rootNav->type().find("typedef ")!=-1 // its a typedef
  2686       rootNav->type().find("typedef ")!=-1 // its a typedef
  2691      ) 
  2687      ) 
  2692   {
  2688   {
  2693     addVariable(rootNav);
  2689     addVariable(rootNav);
  2694 	//printf("addVariable() done\n");
       
  2695   }
  2690   }
  2696   if (rootNav->children())
  2691   if (rootNav->children())
  2697   {
  2692   {
  2698     EntryNavListIterator eli(*rootNav->children());
  2693     EntryNavListIterator eli(*rootNav->children());
  2699     EntryNav *e;
  2694     EntryNav *e;
  5833             }
  5828             }
  5834           }
  5829           }
  5835         }
  5830         }
  5836         else if (cd) // member specialization
  5831         else if (cd) // member specialization
  5837         {
  5832         {
       
  5833           MemberNameIterator mni(*mn);
       
  5834           MemberDef *declMd=0;
       
  5835           MemberDef *md=0;
       
  5836           for (mni.toFirst();(md=mni.current());++mni)
       
  5837           {
       
  5838             if (md->getClassDef()==cd) 
       
  5839             {
       
  5840               // TODO: we should probably also check for matching arguments
       
  5841               declMd = md;
       
  5842               break;
       
  5843             }
       
  5844           }
  5838           MemberDef::MemberType mtype=MemberDef::Function;
  5845           MemberDef::MemberType mtype=MemberDef::Function;
  5839           ArgumentList *tArgList = new ArgumentList;
  5846           ArgumentList *tArgList = new ArgumentList;
  5840           //  getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
  5847           //  getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
  5841           MemberDef *md=new MemberDef(
  5848           md=new MemberDef(
  5842               root->fileName,root->startLine,
  5849               root->fileName,root->startLine,
  5843               funcType,funcName,funcArgs,exceptions,
  5850               funcType,funcName,funcArgs,exceptions,
  5844               root->protection,root->virt,root->stat,Member,
  5851               declMd ? declMd->protection() : root->protection,
       
  5852               root->virt,root->stat,Member,
  5845               mtype,tArgList,root->argList);
  5853               mtype,tArgList,root->argList);
  5846           //printf("new specialized member %s args=`%s'\n",md->name().data(),funcArgs.data());
  5854           //printf("new specialized member %s args=`%s'\n",md->name().data(),funcArgs.data());
  5847           md->setTagInfo(rootNav->tagInfo());
  5855           md->setTagInfo(rootNav->tagInfo());
  5848           md->setMemberClass(cd);
  5856           md->setMemberClass(cd);
  5849           md->setTemplateSpecialization(TRUE);
  5857           md->setTemplateSpecialization(TRUE);
  6763                   fmd->addSectionsToDefinition(root->anchors);
  6771                   fmd->addSectionsToDefinition(root->anchors);
  6764                   fmd->setInitializer(root->initializer);
  6772                   fmd->setInitializer(root->initializer);
  6765                   fmd->setMaxInitLines(root->initLines);
  6773                   fmd->setMaxInitLines(root->initLines);
  6766                   fmd->setMemberGroupId(root->mGrpId);
  6774                   fmd->setMemberGroupId(root->mGrpId);
  6767                   fmd->setExplicitExternal(root->explicitExternal);
  6775                   fmd->setExplicitExternal(root->explicitExternal);
       
  6776                   fmd->setRefItems(root->sli);
  6768                   if (fmd)
  6777                   if (fmd)
  6769                   {
  6778                   {
  6770                     md->insertEnumField(fmd);
  6779                     md->insertEnumField(fmd);
  6771                     fmd->setEnumScope(md);
  6780                     fmd->setEnumScope(md);
  6772                   }
  6781                   }
  7883     rootNav->loadEntry(g_storage);
  7892     rootNav->loadEntry(g_storage);
  7884     Entry *root = rootNav->entry();
  7893     Entry *root = rootNav->entry();
  7885 
  7894 
  7886     QCString normalizedName = root->name;
  7895     QCString normalizedName = root->name;
  7887     normalizedName = substitute(normalizedName,"\\","/");
  7896     normalizedName = substitute(normalizedName,"\\","/");
       
  7897     //printf("root->docFile=%s normalizedName=%s\n",
       
  7898     //    root->docFile.data(),normalizedName.data());
       
  7899     if (root->docFile==normalizedName) // current dir?
       
  7900     {
       
  7901       int lastSlashPos=normalizedName.findRev('/'); 
       
  7902       if (lastSlashPos!=-1) // strip file name
       
  7903       {
       
  7904         normalizedName=normalizedName.left(lastSlashPos);
       
  7905       }
       
  7906     }
  7888     if (normalizedName.at(normalizedName.length()-1)!='/')
  7907     if (normalizedName.at(normalizedName.length()-1)!='/')
  7889     {
  7908     {
  7890       normalizedName+='/';
  7909       normalizedName+='/';
  7891     }
  7910     }
  7892     DirDef *dir,*matchingDir=0;
  7911     DirDef *dir,*matchingDir=0;
  7920       addDirToGroups(root,matchingDir);
  7939       addDirToGroups(root,matchingDir);
  7921     }
  7940     }
  7922     else
  7941     else
  7923     {
  7942     {
  7924       warn(root->fileName,root->startLine,"Warning: No matching "
  7943       warn(root->fileName,root->startLine,"Warning: No matching "
  7925           "directory found for command \\dir %s\n",root->name.data());
  7944           "directory found for command \\dir %s\n",normalizedName.data());
  7926     }
  7945     }
  7927     rootNav->releaseEntry();
  7946     rootNav->releaseEntry();
  7928   }
  7947   }
  7929   RECURSE_ENTRYTREE(findDirDocumentation,rootNav);
  7948   RECURSE_ENTRYTREE(findDirDocumentation,rootNav);
  7930 }
  7949 }
  8225     QCString n=pd->getOutputFileBase();
  8244     QCString n=pd->getOutputFileBase();
  8226     startFile(*g_outputList,n,n,pd->name());
  8245     startFile(*g_outputList,n,n,pd->name());
  8227     startTitle(*g_outputList,n);
  8246     startTitle(*g_outputList,n);
  8228     g_outputList->docify(pd->name());
  8247     g_outputList->docify(pd->name());
  8229     endTitle(*g_outputList,n,0);
  8248     endTitle(*g_outputList,n,0);
       
  8249     g_outputList->startContents();
  8230     g_outputList->parseDoc(pd->docFile(),                            // file
  8250     g_outputList->parseDoc(pd->docFile(),                            // file
  8231                          pd->docLine(),                            // startLine
  8251                          pd->docLine(),                            // startLine
  8232                          pd,                                       // context
  8252                          pd,                                       // context
  8233                          0,                                        // memberDef
  8253                          0,                                        // memberDef
  8234                          pd->documentation()+"\n\n\\include "+pd->name(),          // docs
  8254                          pd->documentation()+"\n\n\\include "+pd->name(),          // docs
  8235                          TRUE,                                     // index words
  8255                          TRUE,                                     // index words
  8236                          TRUE,                                     // is example
  8256                          TRUE,                                     // is example
  8237                          pd->name()
  8257                          pd->name()
  8238                         );
  8258                         );
       
  8259     g_outputList->endContents();
  8239     endFile(*g_outputList);
  8260     endFile(*g_outputList);
  8240   }
  8261   }
  8241   g_outputList->enable(OutputGenerator::Man);
  8262   g_outputList->enable(OutputGenerator::Man);
  8242 }
  8263 }
  8243 
  8264 
  8566   parseTagFile(root,fi.absFilePath(),fi.fileName());
  8587   parseTagFile(root,fi.absFilePath(),fi.fileName());
  8567 
  8588 
  8568 }
  8589 }
  8569 
  8590 
  8570 //----------------------------------------------------------------------------
  8591 //----------------------------------------------------------------------------
  8571 // returns TRUE if the name of the file represented by `fi' matches
       
  8572 // one of the file patterns in the `patList' list.
       
  8573 
       
  8574 static bool patternMatch(QFileInfo *fi,QStrList *patList)
       
  8575 {
       
  8576   bool found=FALSE;
       
  8577   if (patList)
       
  8578   { 
       
  8579     QCString pattern=patList->first();
       
  8580     while (!pattern.isEmpty() && !found)
       
  8581     {
       
  8582       int i=pattern.find('=');
       
  8583       if (i!=-1) pattern=pattern.left(i); // strip of the extension specific filter name
       
  8584 
       
  8585 #if defined(_WIN32) // windows
       
  8586       QRegExp re(pattern,FALSE,TRUE); // case insensitive match 
       
  8587 #else                // unix
       
  8588       QRegExp re(pattern,TRUE,TRUE);  // case sensitive match
       
  8589 #endif
       
  8590       found = found || re.match(fi->fileName())!=-1 || 
       
  8591                        re.match(fi->filePath())!=-1 ||
       
  8592                        re.match(fi->absFilePath())!=-1;
       
  8593       //printf("Matching `%s' against pattern `%s' found=%d\n",
       
  8594       //    fi->fileName().data(),pattern.data(),found);
       
  8595       pattern=patList->next();
       
  8596     }
       
  8597   }
       
  8598   return found;
       
  8599 }
       
  8600 
       
  8601 //----------------------------------------------------------------------------
       
  8602 static void copyStyleSheet()
  8592 static void copyStyleSheet()
  8603 {
  8593 {
  8604   QCString &htmlStyleSheet = Config_getString("HTML_STYLESHEET");
  8594   QCString &htmlStyleSheet = Config_getString("HTML_STYLESHEET");
  8605   if (!htmlStyleSheet.isEmpty())
  8595   if (!htmlStyleSheet.isEmpty())
  8606   {
  8596   {
  8828             err("Warning: source %s is not a readable file or directory... skipping.\n",cfi->absFilePath().data());
  8818             err("Warning: source %s is not a readable file or directory... skipping.\n",cfi->absFilePath().data());
  8829           }
  8819           }
  8830         }
  8820         }
  8831         else if (cfi->isFile() && 
  8821         else if (cfi->isFile() && 
  8832             (!Config_getBool("EXCLUDE_SYMLINKS") || !cfi->isSymLink()) &&
  8822             (!Config_getBool("EXCLUDE_SYMLINKS") || !cfi->isSymLink()) &&
  8833             (patList==0 || patternMatch(cfi,patList)) && 
  8823             (patList==0 || patternMatch(*cfi,patList)) && 
  8834             !patternMatch(cfi,exclPatList) &&
  8824             !patternMatch(*cfi,exclPatList) &&
  8835             (killDict==0 || killDict->find(cfi->absFilePath())==0)
  8825             (killDict==0 || killDict->find(cfi->absFilePath())==0)
  8836             )
  8826             )
  8837         {
  8827         {
  8838           totalSize+=cfi->size()+cfi->absFilePath().length()+4;
  8828           totalSize+=cfi->size()+cfi->absFilePath().length()+4;
  8839           QCString name=convertToQCString(cfi->fileName());
  8829           QCString name=convertToQCString(cfi->fileName());
  8864           if (killDict) killDict->insert(cfi->absFilePath(),(void *)0x8);
  8854           if (killDict) killDict->insert(cfi->absFilePath(),(void *)0x8);
  8865         }
  8855         }
  8866         else if (recursive &&
  8856         else if (recursive &&
  8867             (!Config_getBool("EXCLUDE_SYMLINKS") || !cfi->isSymLink()) &&
  8857             (!Config_getBool("EXCLUDE_SYMLINKS") || !cfi->isSymLink()) &&
  8868             cfi->isDir() && cfi->fileName()!="." && 
  8858             cfi->isDir() && cfi->fileName()!="." && 
  8869             !patternMatch(cfi,exclPatList) &&
  8859             !patternMatch(*cfi,exclPatList) &&
  8870             cfi->fileName()!="..")
  8860             cfi->fileName()!="..")
  8871         {
  8861         {
  8872           cfi->setFile(cfi->absFilePath());
  8862           cfi->setFile(cfi->absFilePath());
  8873           totalSize+=readDir(cfi,fnList,fnDict,exclDict,
  8863           totalSize+=readDir(cfi,fnList,fnDict,exclDict,
  8874               patList,exclPatList,resultList,resultDict,errorIfNotExist,
  8864               patList,exclPatList,resultList,resultDict,errorIfNotExist,
  9155 //----------------------------------------------------------------------------
  9145 //----------------------------------------------------------------------------
  9156 // print the usage of doxygen
  9146 // print the usage of doxygen
  9157 
  9147 
  9158 static void usage(const char *name)
  9148 static void usage(const char *name)
  9159 {
  9149 {
  9160   msg("Doxygen version %s\nCopyright Dimitri van Heesch 1997-2008\n\n",versionString);
  9150   msg("Doxygen version %s\nCopyright Dimitri van Heesch 1997-2010\n\n",versionString);
  9161   msg("You can use doxygen in a number of ways:\n\n");
  9151   msg("You can use doxygen in a number of ways:\n\n");
  9162   msg("1) Use doxygen to generate a template configuration file:\n");
  9152   msg("1) Use doxygen to generate a template configuration file:\n");
  9163   msg("    %s [-s] -g [configName]\n\n",name);
  9153   msg("    %s [-s] -g [configName]\n\n",name);
  9164   msg("    If - is used for configName doxygen will write to standard output.\n\n");
  9154   msg("    If - is used for configName doxygen will write to standard output.\n\n");
  9165   msg("2) Use doxygen to update an old configuration file:\n");
  9155   msg("2) Use doxygen to update an old configuration file:\n");
 10220   createTemplateInstanceMembers();
 10210   createTemplateInstanceMembers();
 10221 
 10211 
 10222   msg("Computing class relations...\n");
 10212   msg("Computing class relations...\n");
 10223   computeTemplateClassRelations(); 
 10213   computeTemplateClassRelations(); 
 10224   flushUnresolvedRelations();
 10214   flushUnresolvedRelations();
       
 10215 
       
 10216   computeClassRelations();        
       
 10217 
 10225   if (Config_getBool("OPTIMIZE_OUTPUT_VHDL"))
 10218   if (Config_getBool("OPTIMIZE_OUTPUT_VHDL"))
 10226   {
       
 10227     VhdlDocGen::computeVhdlComponentRelations();
 10219     VhdlDocGen::computeVhdlComponentRelations();
 10228   }
 10220 
 10229   else
       
 10230   {
       
 10231     computeClassRelations();        
       
 10232   }
       
 10233   g_classEntries.clear();          
 10221   g_classEntries.clear();          
 10234 
 10222 
 10235   msg("Add enum values to enums...\n");
 10223   msg("Add enum values to enums...\n");
 10236   addEnumValuesToEnums(rootNav);
 10224   addEnumValuesToEnums(rootNav);
 10237   findEnumDocumentation(rootNav);
 10225   findEnumDocumentation(rootNav);
 10273   
 10261   
 10274   msg("Determining which enums are documented\n");
 10262   msg("Determining which enums are documented\n");
 10275   findDocumentedEnumValues();
 10263   findDocumentedEnumValues();
 10276 
 10264 
 10277   msg("Computing member relations...\n");
 10265   msg("Computing member relations...\n");
 10278   // TODO: This seems to generate an infinite loop
       
 10279   computeMemberRelations();
 10266   computeMemberRelations();
 10280 
 10267 
 10281   msg("Building full member lists recursively...\n");
 10268   msg("Building full member lists recursively...\n");
 10282   buildCompleteMemberLists();
 10269   buildCompleteMemberLists();
 10283   
 10270   
 10386     Doxygen::indexList.addImageFile("tab_r.gif");
 10373     Doxygen::indexList.addImageFile("tab_r.gif");
 10387     Doxygen::indexList.addImageFile("tab_l.gif");
 10374     Doxygen::indexList.addImageFile("tab_l.gif");
 10388     Doxygen::indexList.addImageFile("tab_b.gif");
 10375     Doxygen::indexList.addImageFile("tab_b.gif");
 10389     Doxygen::indexList.addStyleSheetFile("tabs.css");
 10376     Doxygen::indexList.addStyleSheetFile("tabs.css");
 10390     Doxygen::indexList.addImageFile("doxygen.png");
 10377     Doxygen::indexList.addImageFile("doxygen.png");
 10391     if (Config_getBool("HTML_DYNAMIC_SECTIONS")) HtmlGenerator::generateSectionImages();
 10378     //if (Config_getBool("HTML_DYNAMIC_SECTIONS")) HtmlGenerator::generateSectionImages();
 10392     copyStyleSheet();
 10379     copyStyleSheet();
 10393   }
 10380   }
 10394   if (Config_getBool("GENERATE_LATEX")) 
 10381   if (Config_getBool("GENERATE_LATEX")) 
 10395   {
 10382   {
 10396     g_outputList->add(new LatexGenerator);
 10383     g_outputList->add(new LatexGenerator);
 10464   static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
 10451   static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
 10465 
 10452 
 10466   // generate search indices (need to do this before writing other HTML
 10453   // generate search indices (need to do this before writing other HTML
 10467   // pages as these contain a drop down menu with options depending on
 10454   // pages as these contain a drop down menu with options depending on
 10468   // what categories we find in this function.
 10455   // what categories we find in this function.
 10469   if (searchEngine)
 10456   if (Config_getBool("GENERATE_HTML") && searchEngine)
 10470   {
 10457   {
 10471     QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search";
 10458     QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search";
 10472     QDir searchDir(searchDirName);
 10459     QDir searchDir(searchDirName);
 10473     if (!searchDir.exists() && !searchDir.mkdir(searchDirName))
 10460     if (!searchDir.exists() && !searchDir.mkdir(searchDirName))
 10474     {
 10461     {
 10475       err("Could not create search results directory '%s/search'\n",searchDirName.data());
 10462       err("Error: Could not create search results directory '%s' $PWD='%s'\n",
 10476       return;
 10463           searchDirName.data(),QDir::currentDirPath().data());
       
 10464       exit(1);
 10477     }
 10465     }
 10478     HtmlGenerator::writeSearchData(searchDirName);
 10466     HtmlGenerator::writeSearchData(searchDirName);
 10479     writeSearchStyleSheet();
 10467     if (!serverBasedSearch) // client side search index
 10480     if (serverBasedSearch)
       
 10481     {
       
 10482     }
       
 10483     else
       
 10484     {
 10468     {
 10485       writeJavascriptSearchIndex();
 10469       writeJavascriptSearchIndex();
 10486     }
 10470     }
 10487   }
 10471   }
 10488 
 10472