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(); |
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 |