Skip to main content

The doxygen.h File Reference

Included Headers

#include <mutex> #include "containers.h" #include "membergroup.h" #include "dirdef.h" #include "memberlist.h" #include "define.h" #include "cache.h" #include "symbolmap.h" #include "searchindex.h"

Classes Index

structLookupInfo
structInputFileEncoding
structNamespaceAliasInfo
classDoxygen

This class serves as a namespace for global variables used by doxygen. More...

Typedefs Index

usingInputFileEncodingList = std::vector< InputFileEncoding >
usingClangUsrMap = std::unordered_map< std::string, const Definition * >
usingStaticInitMap = std::unordered_map< std::string, BodyInfo >
usingNamespaceAliasInfoMap = std::unordered_map< std::string, NamespaceAliasInfo >

Functions Index

voidinitDoxygen ()
voidreadConfiguration (int argc, char **argv)
voidcheckConfiguration ()

check and resolve config options More...

voidadjustConfiguration ()

adjust globals that depend on configuration settings. More...

voidparseInput ()
voidgenerateOutput ()
voidcleanUpDoxygen ()
voidreadFileOrDirectory (const QCString &s, FileNameLinkedMap *fnDict, StringUnorderedSet *exclSet, const StringVector *patList, const StringVector *exclPatList, StringVector *resultList, StringUnorderedSet *resultSet, bool recursive, bool errorIfNotExist=TRUE, StringUnorderedSet *killSet=nullptr, StringUnorderedSet *paths=nullptr)

Macro Definitions Index

#defineTHREAD_LOCAL   thread_local
#defineAtomicInt   std::atomic_int

Typedefs

ClangUsrMap

using ClangUsrMap = std::unordered_map<std::string,const Definition *>

Definition at line 83 of file doxygen.h.

83using ClangUsrMap = std::unordered_map<std::string,const Definition *>;

InputFileEncodingList

using InputFileEncodingList = std::vector<InputFileEncoding>

Definition at line 81 of file doxygen.h.

81using InputFileEncodingList = std::vector<InputFileEncoding>;

NamespaceAliasInfoMap

using NamespaceAliasInfoMap = std::unordered_map<std::string,NamespaceAliasInfo>

Definition at line 87 of file doxygen.h.

87using NamespaceAliasInfoMap = std::unordered_map<std::string,NamespaceAliasInfo>;

StaticInitMap

using StaticInitMap = std::unordered_map<std::string,BodyInfo>

Definition at line 85 of file doxygen.h.

85using StaticInitMap = std::unordered_map<std::string,BodyInfo>;

Functions

adjustConfiguration()

void adjustConfiguration ()

adjust globals that depend on configuration settings.

Declaration at line 149 of file doxygen.h, definition at line 11858 of file doxygen.cpp.

11859{
11860 AUTO_TRACE();
11861 Doxygen::globalNamespaceDef = createNamespaceDef("<globalScope>",1,1,"<globalScope>");
11871
11872 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11873
11874 /* Set the global html file extension. */
11875 Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION);
11876
11877
11879 Config_getBool(CALLER_GRAPH) ||
11880 Config_getBool(REFERENCES_RELATION) ||
11881 Config_getBool(REFERENCED_BY_RELATION);
11882
11883 /**************************************************************************
11884 * Add custom extension mappings
11885 **************************************************************************/
11886
11887 const StringVector &extMaps = Config_getList(EXTENSION_MAPPING);
11888 for (const auto &mapping : extMaps)
11889 {
11890 QCString mapStr = mapping.c_str();
11891 int i=mapStr.find('=');
11892 if (i==-1)
11893 {
11894 continue;
11895 }
11896 else
11897 {
11898 QCString ext = mapStr.left(i).stripWhiteSpace().lower();
11899 QCString language = mapStr.mid(i+1).stripWhiteSpace().lower();
11900 if (ext.isEmpty() || language.isEmpty())
11901 {
11902 continue;
11903 }
11904
11905 if (!updateLanguageMapping(ext,language))
11906 {
11907 err("Failed to map file extension '{}' to unsupported language '{}'.\n"
11908 "Check the EXTENSION_MAPPING setting in the config file.\n",
11909 ext,language);
11910 }
11911 else
11912 {
11913 msg("Adding custom extension mapping: '{}' will be treated as language '{}'\n",
11914 ext,language);
11915 }
11916 }
11917 }
11918 // create input file exncodings
11919
11920 // check INPUT_ENCODING
11921 void *cd = portable_iconv_open("UTF-8",Config_getString(INPUT_ENCODING).data());
11922 if (cd==reinterpret_cast<void *>(-1))
11923 {
11924 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
11925 "Check the 'INPUT_ENCODING' setting in the config file!\n",
11926 Config_getString(INPUT_ENCODING),strerror(errno));
11927 }
11928 else
11929 {
11931 }
11932
11933 // check and split INPUT_FILE_ENCODING
11934 const StringVector &fileEncod = Config_getList(INPUT_FILE_ENCODING);
11935 for (const auto &mapping : fileEncod)
11936 {
11937 QCString mapStr = mapping.c_str();
11938 int i=mapStr.find('=');
11939 if (i==-1)
11940 {
11941 continue;
11942 }
11943 else
11944 {
11945 QCString pattern = mapStr.left(i).stripWhiteSpace().lower();
11946 QCString encoding = mapStr.mid(i+1).stripWhiteSpace().lower();
11947 if (pattern.isEmpty() || encoding.isEmpty())
11948 {
11949 continue;
11950 }
11951 cd = portable_iconv_open("UTF-8",encoding.data());
11952 if (cd==reinterpret_cast<void *>(-1))
11953 {
11954 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
11955 "Check the 'INPUT_FILE_ENCODING' setting in the config file!\n",
11956 encoding,strerror(errno));
11957 }
11958 else
11959 {
11961 }
11962
11963 Doxygen::inputFileEncodingList.emplace_back(pattern, encoding);
11964 }
11965 }
11966
11967 // add predefined macro name to a dictionary
11968 const StringVector &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED);
11969 for (const auto &s : expandAsDefinedList)
11970 {
11971 Doxygen::expandAsDefinedSet.insert(s.c_str());
11972 }
11973
11974 // read aliases and store them in a dictionary
11975 readAliases();
11976
11977 // store number of spaces in a tab into Doxygen::spaces
11978 int tabSize = Config_getInt(TAB_SIZE);
11979 Doxygen::spaces.resize(tabSize);
11980 for (int sp=0; sp<tabSize; sp++) Doxygen::spaces.at(sp)=' ';
11981 Doxygen::spaces.at(tabSize)='\0';
11982}

References AUTO_TRACE, Config_getBool, Config_getEnum, Config_getInt, Config_getList, Config_getString, createNamespaceDef, QCString::data, Doxygen::diaFileNameLinkedMap, Doxygen::dotFileNameLinkedMap, err, Doxygen::exampleNameLinkedMap, Doxygen::expandAsDefinedSet, QCString::find, Doxygen::globalNamespaceDef, Doxygen::globalScope, Doxygen::htmlFileExtension, Doxygen::imageNameLinkedMap, Doxygen::includeNameLinkedMap, Doxygen::inputFileEncodingList, Doxygen::inputNameLinkedMap, QCString::isEmpty, QCString::left, QCString::lower, QCString::mid, Doxygen::mscFileNameLinkedMap, msg, Doxygen::parseSourcesNeeded, Doxygen::plantUmlFileNameLinkedMap, portable_iconv_close, portable_iconv_open, readAliases, setTranslator, Doxygen::spaces, QCString::stripWhiteSpace, term, toNamespaceDefMutable and updateLanguageMapping.

Referenced by main.

checkConfiguration()

void checkConfiguration ()

check and resolve config options

Declaration at line 148 of file doxygen.h, definition at line 11847 of file doxygen.cpp.

11848{
11849 AUTO_TRACE();
11850
11855}

References AUTO_TRACE, Config::checkAndCorrect, Config_getBool, FALSE, initWarningFormat, Config::postProcess and Config::updateObsolete.

Referenced by main.

cleanUpDoxygen()

void cleanUpDoxygen ()

Declaration at line 152 of file doxygen.h, definition at line 11373 of file doxygen.cpp.

References FormulaManager::clear, LinkedMap< T, Hash, KeyEqual, Map >::clear, ModuleManager::clear, Doxygen::diaFileNameLinkedMap, Doxygen::dirLinkedMap, Doxygen::dotFileNameLinkedMap, Doxygen::exampleLinkedMap, Doxygen::exampleNameLinkedMap, Doxygen::functionNameLinkedMap, g_outputList, Doxygen::globalNamespaceDef, Doxygen::globalScope, Doxygen::groupLinkedMap, Doxygen::imageNameLinkedMap, Doxygen::includeNameLinkedMap, Doxygen::indexList, Doxygen::inputNameLinkedMap, FormulaManager::instance, ModuleManager::instance, SectionManager::instance, Doxygen::mainPage, Doxygen::memberNameLinkedMap, Doxygen::mscFileNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Doxygen::parserManager, Doxygen::plantUmlFileNameLinkedMap, Doxygen::symbolMap and theTranslator.

Referenced by generateOutput, parseInput, readConfiguration and stopDoxygen.

generateOutput()

void generateOutput ()

Declaration at line 151 of file doxygen.h, definition at line 13018 of file doxygen.cpp.

13019{
13020 AUTO_TRACE();
13021 /**************************************************************************
13022 * Initialize output generators *
13023 **************************************************************************/
13024
13025 /// add extra languages for which we can only produce syntax highlighted code
13027
13028 //// dump all symbols
13029 if (g_dumpSymbolMap)
13030 {
13031 dumpSymbolMap();
13032 exit(0);
13033 }
13034
13035 bool generateHtml = Config_getBool(GENERATE_HTML);
13036 bool generateLatex = Config_getBool(GENERATE_LATEX);
13037 bool generateMan = Config_getBool(GENERATE_MAN);
13038 bool generateRtf = Config_getBool(GENERATE_RTF);
13039 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13040
13041
13043 if (generateHtml)
13044 {
13048 }
13049 if (generateLatex)
13050 {
13053 }
13054 if (generateDocbook)
13055 {
13058 }
13059 if (generateMan)
13060 {
13061 g_outputList->add<ManGenerator>();
13063 }
13064 if (generateRtf)
13065 {
13066 g_outputList->add<RTFGenerator>();
13068 }
13069 if (Config_getBool(USE_HTAGS))
13070 {
13072 QCString htmldir = Config_getString(HTML_OUTPUT);
13073 if (!Htags::execute(htmldir))
13074 err("USE_HTAGS is YES but htags(1) failed. \n");
13075 else if (!Htags::loadFilemap(htmldir))
13076 err("htags(1) ended normally but failed to load the filemap. \n");
13077 }
13078
13079 /**************************************************************************
13080 * Generate documentation *
13081 **************************************************************************/
13082
13083 g_s.begin("Generating style sheet...\n");
13084 //printf("writing style info\n");
13085 g_outputList->writeStyleInfo(0); // write first part
13086 g_s.end();
13087
13088 bool searchEngine = Config_getBool(SEARCHENGINE);
13089 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13090
13091 g_s.begin("Generating search indices...\n");
13092 if (searchEngine && !serverBasedSearch && generateHtml)
13093 {
13095 }
13096
13097 // generate search indices (need to do this before writing other HTML
13098 // pages as these contain a drop down menu with options depending on
13099 // what categories we find in this function.
13100 if (generateHtml && searchEngine)
13101 {
13102 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13103 Dir searchDir(searchDirName.str());
13104 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13105 {
13106 term("Could not create search results directory '{}' $PWD='{}'\n",
13107 searchDirName,Dir::currentDirPath());
13108 }
13109 HtmlGenerator::writeSearchData(searchDirName);
13110 if (!serverBasedSearch) // client side search index
13111 {
13113 }
13114 }
13115 g_s.end();
13116
13117 // copy static stuff
13118 if (generateHtml)
13119 {
13121 copyLogo(Config_getString(HTML_OUTPUT));
13122 copyIcon(Config_getString(HTML_OUTPUT));
13123 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT));
13124 }
13125 if (generateLatex)
13126 {
13128 copyLogo(Config_getString(LATEX_OUTPUT));
13129 copyIcon(Config_getString(LATEX_OUTPUT));
13130 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT));
13131 }
13132 if (generateDocbook)
13133 {
13134 copyLogo(Config_getString(DOCBOOK_OUTPUT));
13135 copyIcon(Config_getString(DOCBOOK_OUTPUT));
13136 }
13137 if (generateRtf)
13138 {
13139 copyLogo(Config_getString(RTF_OUTPUT));
13140 copyIcon(Config_getString(RTF_OUTPUT));
13141 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT));
13142 }
13143
13145 if (fm.hasFormulas() && generateHtml
13146 && !Config_getBool(USE_MATHJAX))
13147 {
13148 g_s.begin("Generating images for formulas in HTML...\n");
13149 fm.generateImages(Config_getString(HTML_OUTPUT), Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13151 g_s.end();
13152 }
13153 if (fm.hasFormulas() && generateRtf)
13154 {
13155 g_s.begin("Generating images for formulas in RTF...\n");
13157 g_s.end();
13158 }
13159
13160 if (fm.hasFormulas() && generateDocbook)
13161 {
13162 g_s.begin("Generating images for formulas in Docbook...\n");
13164 g_s.end();
13165 }
13166
13167 g_s.begin("Generating example documentation...\n");
13169 g_s.end();
13170
13171 g_s.begin("Generating file sources...\n");
13173 g_s.end();
13174
13175 g_s.begin("Generating file documentation...\n");
13177 g_s.end();
13178
13179 g_s.begin("Generating page documentation...\n");
13181 g_s.end();
13182
13183 g_s.begin("Generating group documentation...\n");
13185 g_s.end();
13186
13187 g_s.begin("Generating class documentation...\n");
13189 g_s.end();
13190
13191 g_s.begin("Generating concept documentation...\n");
13193 g_s.end();
13194
13195 g_s.begin("Generating module documentation...\n");
13197 g_s.end();
13198
13199 g_s.begin("Generating namespace documentation...\n");
13201 g_s.end();
13202
13203 if (Config_getBool(GENERATE_LEGEND))
13204 {
13205 g_s.begin("Generating graph info page...\n");
13207 g_s.end();
13208 }
13209
13210 g_s.begin("Generating directory documentation...\n");
13212 g_s.end();
13213
13214 if (g_outputList->size()>0)
13215 {
13217 }
13218
13219 g_s.begin("finalizing index lists...\n");
13220 Doxygen::indexList->finalize();
13221 g_s.end();
13222
13223 g_s.begin("writing tag file...\n");
13224 writeTagFile();
13225 g_s.end();
13226
13227 if (Config_getBool(GENERATE_XML))
13228 {
13229 g_s.begin("Generating XML output...\n");
13231 generateXML();
13233 g_s.end();
13234 }
13235 if (Config_getBool(GENERATE_SQLITE3))
13236 {
13237 g_s.begin("Generating SQLITE3 output...\n");
13239 g_s.end();
13240 }
13241
13242 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13243 {
13244 g_s.begin("Generating AutoGen DEF output...\n");
13245 generateDEF();
13246 g_s.end();
13247 }
13248 if (Config_getBool(GENERATE_PERLMOD))
13249 {
13250 g_s.begin("Generating Perl module output...\n");
13252 g_s.end();
13253 }
13254 if (generateHtml && searchEngine && serverBasedSearch)
13255 {
13256 g_s.begin("Generating search index\n");
13257 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13258 {
13260 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13261 }
13262 else // write data for external search index
13263 {
13265 QCString searchDataFile = Config_getString(SEARCHDATA_FILE);
13266 if (searchDataFile.isEmpty())
13267 {
13268 searchDataFile="searchdata.xml";
13269 }
13270 if (!Portable::isAbsolutePath(searchDataFile.data()))
13271 {
13272 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13273 }
13274 Doxygen::searchIndex.write(searchDataFile);
13275 }
13276 g_s.end();
13277 }
13278
13279 if (generateRtf)
13280 {
13281 g_s.begin("Combining RTF output...\n");
13282 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13283 {
13284 err("An error occurred during post-processing the RTF files!\n");
13285 }
13286 g_s.end();
13287 }
13288
13289 g_s.begin("Running plantuml with JAVA...\n");
13291 g_s.end();
13292
13293 if (Config_getBool(HAVE_DOT))
13294 {
13295 g_s.begin("Running dot...\n");
13297 g_s.end();
13298 }
13299
13300 if (generateHtml &&
13301 Config_getBool(GENERATE_HTMLHELP) &&
13302 !Config_getString(HHC_LOCATION).isEmpty())
13303 {
13304 g_s.begin("Running html help compiler...\n");
13306 g_s.end();
13307 }
13308
13309 if ( generateHtml &&
13310 Config_getBool(GENERATE_QHP) &&
13311 !Config_getString(QHG_LOCATION).isEmpty())
13312 {
13313 g_s.begin("Running qhelpgenerator...\n");
13315 g_s.end();
13316 }
13317
13318 g_outputList->cleanup();
13319
13320 msg("type lookup cache used {}/{} hits={} misses={}\n",
13322 Doxygen::typeLookupCache->capacity(),
13324 Doxygen::typeLookupCache->misses());
13325 msg("symbol lookup cache used {}/{} hits={} misses={}\n",
13327 Doxygen::symbolLookupCache->capacity(),
13329 Doxygen::symbolLookupCache->misses());
13330 int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::typeLookupCache->misses()*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
13331 int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::symbolLookupCache->misses()));
13332 int cacheParam = std::max(typeCacheParam,symbolCacheParam);
13333 if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
13334 {
13335 msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is {} at the cost of higher memory usage.\n",cacheParam);
13336 }
13337
13339 {
13340
13341 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13342 if (numThreads<1) numThreads=1;
13343 msg("Total elapsed time: {:.6f} seconds\n(of which an average of {:.6f} seconds per thread waiting for external tools to finish)\n",
13344 (static_cast<double>(Debug::elapsedTime())),
13345 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13346 );
13347 g_s.print();
13348
13350 msg("finished...\n");
13352 }
13353 else
13354 {
13355 msg("finished...\n");
13356 }
13357
13358
13359 /**************************************************************************
13360 * Start cleaning up *
13361 **************************************************************************/
13362
13364
13366 Dir thisDir;
13367 thisDir.remove(Doxygen::filterDBFileName.str());
13369 exitTracing();
13371 delete Doxygen::clangUsrMap;
13373
13374 //dumpDocNodeSizes();
13375}

References addCodeOnlyMappings, AUTO_TRACE, FormulaManager::Bitmap, Doxygen::clangUsrMap, cleanUpDoxygen, Debug::clearFlag, computeIdealCacheParam, Config_getBool, Config_getEnum, Config_getInt, Config_getList, Config_getString, copyExtraFiles, copyIcon, copyLatexStyleSheet, copyLogo, copyStyleSheet, createJavaScriptSearchIndex, Dir::currentDirPath, QCString::data, Config::deinit, dumpSymbolMap, Debug::elapsedTime, err, Htags::execute, Dir::exists, exitTracing, FALSE, Doxygen::filterDBFileName, finalizeSearchIndexer, finishWarnExit, g_dumpSymbolMap, g_outputList, g_s, g_successfulRun, generateClassDocs, generateConceptDocs, generateDEF, generateDirDocs, generateExampleDocs, generateFileDocs, generateFileSources, generateGroupDocs, FormulaManager::generateImages, generateNamespaceDocs, generatePageDocs, generatePerlMod, generateSqlite3, generateXML, Doxygen::generatingXmlOutput, Portable::getSysElapsedTime, FormulaManager::hasFormulas, Doxygen::indexList, DocbookGenerator::init, HtmlGenerator::init, LatexGenerator::init, ManGenerator::init, RTFGenerator::init, DotManager::instance, FormulaManager::instance, ModuleManager::instance, PlantumlManager::instance, SearchIndexIntf::Internal, Portable::isAbsolutePath, QCString::isEmpty, Debug::isFlagSet, Htags::loadFilemap, Dir::mkdir, msg, FormulaManager::On, QCString::prepend, RTFGenerator::preProcessFileInplace, Dir::remove, DotManager::run, PlantumlManager::run, runHtmlHelpCompiler, runQHelpGenerator, Doxygen::searchIndex, Debug::setFlag, QCString::str, Doxygen::symbolLookupCache, term, Debug::Time, TRUE, Doxygen::typeLookupCache, Htags::useHtags, FormulaManager::Vector, ModuleManager::writeDocumentation, HtmlGenerator::writeExternalSearchPage, writeGraphInfo, writeIndexHierarchy, writeJavaScriptSearchIndex, HtmlGenerator::writeSearchData, HtmlGenerator::writeSearchPage, HtmlGenerator::writeTabData and writeTagFile.

Referenced by main.

initDoxygen()

void initDoxygen ()

Declaration at line 146 of file doxygen.h, definition at line 11304 of file doxygen.cpp.

11305{
11306 initResources();
11307 QCString lang = Portable::getenv("LC_ALL");
11308 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
11309 std::setlocale(LC_ALL,"");
11310 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11311 std::setlocale(LC_NUMERIC,"C");
11312
11314
11338
11339 // register any additional parsers here...
11340
11342
11343#if USE_LIBCLANG
11345#endif
11354 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11355 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11356 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
11358
11359 // initialization of these globals depends on
11360 // configuration switches so we need to postpone these
11361 Doxygen::globalScope = nullptr;
11370
11371}

References Doxygen::clangUsrMap, Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Doxygen::diaFileNameLinkedMap, Doxygen::dirLinkedMap, Doxygen::dotFileNameLinkedMap, Doxygen::exampleLinkedMap, Doxygen::exampleNameLinkedMap, Doxygen::functionNameLinkedMap, Portable::getenv, Doxygen::globalScope, Doxygen::groupLinkedMap, Doxygen::hiddenClassLinkedMap, Doxygen::imageNameLinkedMap, Doxygen::includeNameLinkedMap, Doxygen::indexList, initDefaultExtensionMapping, initResources, Doxygen::inputNameLinkedMap, QCString::isEmpty, make_parser_factory, Doxygen::memberNameLinkedMap, Doxygen::mscFileNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Doxygen::parserManager, Doxygen::plantUmlFileNameLinkedMap, Portable::setenv, Debug::startTimer and Doxygen::symbolMap.

Referenced by main.

parseInput()

void parseInput ()

Declaration at line 150 of file doxygen.h, definition at line 12343 of file doxygen.cpp.

12344{
12345 AUTO_TRACE();
12346 std::atexit(exitDoxygen);
12347
12348 Portable::correctPath(Config_getList(EXTERNAL_TOOL_PATH));
12349
12350#if USE_LIBCLANG
12351 Doxygen::clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
12352#endif
12353
12354 // we would like to show the versionString earlier, but we first have to handle the configuration file
12355 // to know the value of the QUIET setting.
12356 QCString versionString = getFullVersion();
12357 msg("Doxygen version used: {}\n",versionString);
12358
12360
12361 /**************************************************************************
12362 * Make sure the output directory exists
12363 **************************************************************************/
12364 QCString outputDirectory = Config_getString(OUTPUT_DIRECTORY);
12365 if (!g_singleComment)
12366 {
12367 if (outputDirectory.isEmpty())
12368 {
12369 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,Dir::currentDirPath().c_str());
12370 }
12371 else
12372 {
12373 Dir dir(outputDirectory.str());
12374 if (!dir.exists())
12375 {
12377 if (!dir.mkdir(outputDirectory.str()))
12378 {
12379 term("tag OUTPUT_DIRECTORY: Output directory '{}' does not "
12380 "exist and cannot be created\n",outputDirectory);
12381 }
12382 else
12383 {
12384 msg("Notice: Output directory '{}' does not exist. "
12385 "I have created it for you.\n", outputDirectory);
12386 }
12387 dir.setPath(outputDirectory.str());
12388 }
12389 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,dir.absPath().c_str());
12390 }
12391 }
12392 AUTO_TRACE_ADD("outputDirectory={}",outputDirectory);
12393
12394 /**************************************************************************
12395 * Initialize global lists and dictionaries
12396 **************************************************************************/
12397
12398 // also scale lookup cache with SYMBOL_CACHE_SIZE
12399 int cacheSize = Config_getInt(LOOKUP_CACHE_SIZE);
12400 if (cacheSize<0) cacheSize=0;
12401 if (cacheSize>9) cacheSize=9;
12402 uint32_t lookupSize = 65536 << cacheSize;
12405
12406#ifdef HAS_SIGNALS
12407 signal(SIGINT, stopDoxygen);
12408#endif
12409
12410 uint32_t pid = Portable::pid();
12411 Doxygen::filterDBFileName.sprintf("doxygen_filterdb_%d.tmp",pid);
12412 Doxygen::filterDBFileName.prepend(outputDirectory+"/");
12413
12414 /**************************************************************************
12415 * Check/create output directories *
12416 **************************************************************************/
12417
12418 bool generateHtml = Config_getBool(GENERATE_HTML);
12419 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
12420 bool generateXml = Config_getBool(GENERATE_XML);
12421 bool generateLatex = Config_getBool(GENERATE_LATEX);
12422 bool generateRtf = Config_getBool(GENERATE_RTF);
12423 bool generateMan = Config_getBool(GENERATE_MAN);
12424 bool generateSql = Config_getBool(GENERATE_SQLITE3);
12425 QCString htmlOutput;
12426 QCString docbookOutput;
12427 QCString xmlOutput;
12428 QCString latexOutput;
12429 QCString rtfOutput;
12430 QCString manOutput;
12431 QCString sqlOutput;
12432
12433 if (!g_singleComment)
12434 {
12435 if (generateHtml)
12436 {
12437 htmlOutput = createOutputDirectory(outputDirectory,Config_getString(HTML_OUTPUT),"/html");
12438 Config_updateString(HTML_OUTPUT,htmlOutput);
12439
12440 QCString sitemapUrl = Config_getString(SITEMAP_URL);
12441 bool generateSitemap = !sitemapUrl.isEmpty();
12442 if (generateSitemap && !sitemapUrl.endsWith("/"))
12443 {
12444 Config_updateString(SITEMAP_URL,sitemapUrl+"/");
12445 }
12446
12447 // add HTML indexers that are enabled
12448 bool generateHtmlHelp = Config_getBool(GENERATE_HTMLHELP);
12449 bool generateEclipseHelp = Config_getBool(GENERATE_ECLIPSEHELP);
12450 bool generateQhp = Config_getBool(GENERATE_QHP);
12451 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
12452 bool generateDocSet = Config_getBool(GENERATE_DOCSET);
12453 if (generateEclipseHelp) Doxygen::indexList->addIndex<EclipseHelp>();
12454 if (generateHtmlHelp) Doxygen::indexList->addIndex<HtmlHelp>();
12455 if (generateQhp) Doxygen::indexList->addIndex<Qhp>();
12456 if (generateSitemap) Doxygen::indexList->addIndex<Sitemap>();
12457 if (generateTreeView) Doxygen::indexList->addIndex<FTVHelp>(TRUE);
12458 if (generateDocSet) Doxygen::indexList->addIndex<DocSets>();
12459 Doxygen::indexList->addIndex<Crawlmap>();
12460 Doxygen::indexList->initialize();
12461 }
12462
12463 if (generateDocbook)
12464 {
12465 docbookOutput = createOutputDirectory(outputDirectory,Config_getString(DOCBOOK_OUTPUT),"/docbook");
12466 Config_updateString(DOCBOOK_OUTPUT,docbookOutput);
12467 }
12468
12469 if (generateXml)
12470 {
12471 xmlOutput = createOutputDirectory(outputDirectory,Config_getString(XML_OUTPUT),"/xml");
12472 Config_updateString(XML_OUTPUT,xmlOutput);
12473 }
12474
12475 if (generateLatex)
12476 {
12477 latexOutput = createOutputDirectory(outputDirectory,Config_getString(LATEX_OUTPUT), "/latex");
12478 Config_updateString(LATEX_OUTPUT,latexOutput);
12479 }
12480
12481 if (generateRtf)
12482 {
12483 rtfOutput = createOutputDirectory(outputDirectory,Config_getString(RTF_OUTPUT),"/rtf");
12484 Config_updateString(RTF_OUTPUT,rtfOutput);
12485 }
12486
12487 if (generateMan)
12488 {
12489 manOutput = createOutputDirectory(outputDirectory,Config_getString(MAN_OUTPUT),"/man");
12490 Config_updateString(MAN_OUTPUT,manOutput);
12491 }
12492
12493 if (generateSql)
12494 {
12495 sqlOutput = createOutputDirectory(outputDirectory,Config_getString(SQLITE3_OUTPUT),"/sqlite3");
12496 Config_updateString(SQLITE3_OUTPUT,sqlOutput);
12497 }
12498 }
12499
12500 if (Config_getBool(HAVE_DOT))
12501 {
12502 QCString curFontPath = Config_getString(DOT_FONTPATH);
12503 if (curFontPath.isEmpty())
12504 {
12505 Portable::getenv("DOTFONTPATH");
12506 QCString newFontPath = ".";
12507 if (!curFontPath.isEmpty())
12508 {
12509 newFontPath+=Portable::pathListSeparator();
12510 newFontPath+=curFontPath;
12511 }
12512 Portable::setenv("DOTFONTPATH",qPrint(newFontPath));
12513 }
12514 else
12515 {
12516 Portable::setenv("DOTFONTPATH",qPrint(curFontPath));
12517 }
12518 }
12519
12520 /**************************************************************************
12521 * Handle layout file *
12522 **************************************************************************/
12523
12525 QCString layoutFileName = Config_getString(LAYOUT_FILE);
12526 bool defaultLayoutUsed = FALSE;
12527 if (layoutFileName.isEmpty())
12528 {
12529 layoutFileName = Config_updateString(LAYOUT_FILE,"DoxygenLayout.xml");
12530 defaultLayoutUsed = TRUE;
12531 }
12532 AUTO_TRACE_ADD("defaultLayoutUsed={}, layoutFileName={}",defaultLayoutUsed,layoutFileName);
12533
12534 FileInfo fi(layoutFileName.str());
12535 if (fi.exists())
12536 {
12537 msg("Parsing layout file {}...\n",layoutFileName);
12538 LayoutDocManager::instance().parse(layoutFileName);
12539 }
12540 else if (!defaultLayoutUsed)
12541 {
12542 warn_uncond("failed to open layout file '{}' for reading! Using default settings.\n",layoutFileName);
12543 }
12544 printLayout();
12545
12546 /**************************************************************************
12547 * Read and preprocess input *
12548 **************************************************************************/
12549
12550 // prevent search in the output directories
12551 StringVector exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12552 if (generateHtml) exclPatterns.push_back(htmlOutput.str());
12553 if (generateDocbook) exclPatterns.push_back(docbookOutput.str());
12554 if (generateXml) exclPatterns.push_back(xmlOutput.str());
12555 if (generateLatex) exclPatterns.push_back(latexOutput.str());
12556 if (generateRtf) exclPatterns.push_back(rtfOutput.str());
12557 if (generateMan) exclPatterns.push_back(manOutput.str());
12558 Config_updateList(EXCLUDE_PATTERNS,exclPatterns);
12559
12560 if (!g_singleComment)
12561 {
12563
12565 }
12566
12567 // Notice: the order of the function calls below is very important!
12568
12569 if (generateHtml && !Config_getBool(USE_MATHJAX))
12570 {
12572 }
12573 if (generateRtf)
12574 {
12576 }
12577 if (generateDocbook)
12578 {
12580 }
12581
12583
12584 /**************************************************************************
12585 * Handle Tag Files *
12586 **************************************************************************/
12587
12588 std::shared_ptr<Entry> root = std::make_shared<Entry>();
12589
12590 if (!g_singleComment)
12591 {
12592 msg("Reading and parsing tag files\n");
12593 const StringVector &tagFileList = Config_getList(TAGFILES);
12594 for (const auto &s : tagFileList)
12595 {
12596 readTagFile(root,s.c_str());
12597 }
12598 }
12599
12600 /**************************************************************************
12601 * Parse source files *
12602 **************************************************************************/
12603
12604 addSTLSupport(root);
12605
12606 g_s.begin("Parsing files\n");
12607 if (g_singleComment)
12608 {
12609 //printf("Parsing comment %s\n",qPrint(g_commentFileName));
12610 if (g_commentFileName=="-")
12611 {
12612 std::string text = fileToString(g_commentFileName).str();
12613 addTerminalCharIfMissing(text,'\n');
12614 generateHtmlForComment("stdin.md",text);
12615 }
12616 else if (FileInfo(g_commentFileName.str()).isFile())
12617 {
12618 std::string text;
12620 addTerminalCharIfMissing(text,'\n');
12622 }
12623 else
12624 {
12625 }
12627 exit(0);
12628 }
12629 else
12630 {
12631 if (Config_getInt(NUM_PROC_THREADS)==1)
12632 {
12634 }
12635 else
12636 {
12638 }
12639 }
12640 g_s.end();
12641
12642 /**************************************************************************
12643 * Gather information *
12644 **************************************************************************/
12645
12646 g_s.begin("Building macro definition list...\n");
12648 g_s.end();
12649
12650 g_s.begin("Building group list...\n");
12651 buildGroupList(root.get());
12652 organizeSubGroups(root.get());
12653 g_s.end();
12654
12655 g_s.begin("Building directory list...\n");
12657 findDirDocumentation(root.get());
12658 g_s.end();
12659
12660 g_s.begin("Building namespace list...\n");
12661 buildNamespaceList(root.get());
12662 findUsingDirectives(root.get());
12663 g_s.end();
12664
12665 g_s.begin("Building file list...\n");
12666 buildFileList(root.get());
12667 g_s.end();
12668
12669 g_s.begin("Building class list...\n");
12670 buildClassList(root.get());
12671 g_s.end();
12672
12673 g_s.begin("Building concept list...\n");
12674 buildConceptList(root.get());
12675 g_s.end();
12676
12677 // build list of using declarations here (global list)
12678 buildListOfUsingDecls(root.get());
12679 g_s.end();
12680
12681 g_s.begin("Computing nesting relations for classes...\n");
12683 g_s.end();
12684 // 1.8.2-20121111: no longer add nested classes to the group as well
12685 //distributeClassGroupRelations();
12686
12687 // calling buildClassList may result in cached relations that
12688 // become invalid after resolveClassNestingRelations(), that's why
12689 // we need to clear the cache here
12690 Doxygen::typeLookupCache->clear();
12691 // we don't need the list of using declaration anymore
12692 g_usingDeclarations.clear();
12693
12694 g_s.begin("Associating documentation with classes...\n");
12695 buildClassDocList(root.get());
12696 g_s.end();
12697
12698 g_s.begin("Associating documentation with concepts...\n");
12699 buildConceptDocList(root.get());
12701 g_s.end();
12702
12703 g_s.begin("Associating documentation with modules...\n");
12704 findModuleDocumentation(root.get());
12705 g_s.end();
12706
12707 g_s.begin("Building example list...\n");
12708 buildExampleList(root.get());
12709 g_s.end();
12710
12711 g_s.begin("Searching for enumerations...\n");
12712 findEnums(root.get());
12713 g_s.end();
12714
12715 // Since buildVarList calls isVarWithConstructor
12716 // and this calls getResolvedClass we need to process
12717 // typedefs first so the relations between classes via typedefs
12718 // are properly resolved. See bug 536385 for an example.
12719 g_s.begin("Searching for documented typedefs...\n");
12720 buildTypedefList(root.get());
12721 g_s.end();
12722
12723 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
12724 {
12725 g_s.begin("Searching for documented sequences...\n");
12726 buildSequenceList(root.get());
12727 g_s.end();
12728
12729 g_s.begin("Searching for documented dictionaries...\n");
12730 buildDictionaryList(root.get());
12731 g_s.end();
12732 }
12733
12734 g_s.begin("Searching for members imported via using declarations...\n");
12735 // this should be after buildTypedefList in order to properly import
12736 // used typedefs
12737 findUsingDeclarations(root.get(),TRUE); // do for python packages first
12738 findUsingDeclarations(root.get(),FALSE); // then the rest
12739 g_s.end();
12740
12741 g_s.begin("Searching for included using directives...\n");
12743 g_s.end();
12744
12745 g_s.begin("Searching for documented variables...\n");
12746 buildVarList(root.get());
12747 g_s.end();
12748
12749 g_s.begin("Building interface member list...\n");
12750 buildInterfaceAndServiceList(root.get()); // UNO IDL
12751
12752 g_s.begin("Building member list...\n"); // using class info only !
12753 buildFunctionList(root.get());
12754 g_s.end();
12755
12756 g_s.begin("Searching for friends...\n");
12757 findFriends();
12758 g_s.end();
12759
12760 g_s.begin("Searching for documented defines...\n");
12761 findDefineDocumentation(root.get());
12762 g_s.end();
12763
12764 g_s.begin("Computing class inheritance relations...\n");
12765 findClassEntries(root.get());
12767 g_s.end();
12768
12769 g_s.begin("Computing class usage relations...\n");
12771 g_s.end();
12772
12773 if (Config_getBool(INLINE_SIMPLE_STRUCTS))
12774 {
12775 g_s.begin("Searching for tag less structs...\n");
12777 g_s.end();
12778 }
12779
12780 g_s.begin("Flushing cached template relations that have become invalid...\n");
12782 g_s.end();
12783
12784 g_s.begin("Warn for undocumented namespaces...\n");
12786 g_s.end();
12787
12788 g_s.begin("Computing class relations...\n");
12791 if (Config_getBool(OPTIMIZE_OUTPUT_VHDL))
12792 {
12794 }
12796 g_classEntries.clear();
12797 g_s.end();
12798
12799 g_s.begin("Add enum values to enums...\n");
12800 addEnumValuesToEnums(root.get());
12801 findEnumDocumentation(root.get());
12802 g_s.end();
12803
12804 g_s.begin("Searching for member function documentation...\n");
12805 findObjCMethodDefinitions(root.get());
12806 findMemberDocumentation(root.get()); // may introduce new members !
12807 findUsingDeclImports(root.get()); // may introduce new members !
12808 g_usingClassMap.clear();
12812 g_s.end();
12813
12814 // moved to after finding and copying documentation,
12815 // as this introduces new members see bug 722654
12816 g_s.begin("Creating members for template instances...\n");
12818 g_s.end();
12819
12820 g_s.begin("Building page list...\n");
12821 buildPageList(root.get());
12822 g_s.end();
12823
12824 g_s.begin("Search for main page...\n");
12825 findMainPage(root.get());
12826 findMainPageTagFiles(root.get());
12827 g_s.end();
12828
12829 g_s.begin("Computing page relations...\n");
12830 computePageRelations(root.get());
12832 g_s.end();
12833
12834 g_s.begin("Determining the scope of groups...\n");
12835 findGroupScope(root.get());
12836 g_s.end();
12837
12838 g_s.begin("Computing module relations...\n");
12839 auto &mm = ModuleManager::instance();
12840 mm.resolvePartitions();
12841 mm.resolveImports();
12842 mm.collectExportedSymbols();
12843 g_s.end();
12844
12845 auto memberNameComp = [](const MemberNameLinkedMap::Ptr &n1,const MemberNameLinkedMap::Ptr &n2)
12846 {
12847 return qstricmp_sort(n1->memberName().data()+getPrefixIndex(n1->memberName()),
12848 n2->memberName().data()+getPrefixIndex(n2->memberName())
12849 )<0;
12850 };
12851
12852 auto classComp = [](const ClassLinkedMap::Ptr &c1,const ClassLinkedMap::Ptr &c2)
12853 {
12854 if (Config_getBool(SORT_BY_SCOPE_NAME))
12855 {
12856 return qstricmp_sort(c1->name(), c2->name())<0;
12857 }
12858 else
12859 {
12860 int i = qstricmp_sort(c1->className(), c2->className());
12861 return i==0 ? qstricmp_sort(c1->name(), c2->name())<0 : i<0;
12862 }
12863 };
12864
12865 auto namespaceComp = [](const NamespaceLinkedMap::Ptr &n1,const NamespaceLinkedMap::Ptr &n2)
12866 {
12867 return qstricmp_sort(n1->name(),n2->name())<0;
12868 };
12869
12870 auto conceptComp = [](const ConceptLinkedMap::Ptr &c1,const ConceptLinkedMap::Ptr &c2)
12871 {
12872 return qstricmp_sort(c1->name(),c2->name())<0;
12873 };
12874
12875 g_s.begin("Sorting lists...\n");
12876 std::stable_sort(Doxygen::memberNameLinkedMap->begin(),
12878 memberNameComp);
12879 std::stable_sort(Doxygen::functionNameLinkedMap->begin(),
12881 memberNameComp);
12882 std::stable_sort(Doxygen::hiddenClassLinkedMap->begin(),
12884 classComp);
12885 std::stable_sort(Doxygen::classLinkedMap->begin(),
12887 classComp);
12888 std::stable_sort(Doxygen::conceptLinkedMap->begin(),
12890 conceptComp);
12891 std::stable_sort(Doxygen::namespaceLinkedMap->begin(),
12893 namespaceComp);
12894 g_s.end();
12895
12896 g_s.begin("Determining which enums are documented\n");
12898 g_s.end();
12899
12900 g_s.begin("Computing member relations...\n");
12903 g_s.end();
12904
12905 g_s.begin("Building full member lists recursively...\n");
12907 g_s.end();
12908
12909 g_s.begin("Adding members to member groups.\n");
12911 g_s.end();
12912
12913 if (Config_getBool(DISTRIBUTE_GROUP_DOC))
12914 {
12915 g_s.begin("Distributing member group documentation.\n");
12917 g_s.end();
12918 }
12919
12920 g_s.begin("Computing member references...\n");
12922 g_s.end();
12923
12924 if (Config_getBool(INHERIT_DOCS))
12925 {
12926 g_s.begin("Inheriting documentation...\n");
12928 g_s.end();
12929 }
12930
12931
12932 // compute the shortest possible names of all files
12933 // without losing the uniqueness of the file names.
12934 g_s.begin("Generating disk names...\n");
12936 g_s.end();
12937
12938 g_s.begin("Adding source references...\n");
12940 g_s.end();
12941
12942 g_s.begin("Adding xrefitems...\n");
12945 g_s.end();
12946
12947 g_s.begin("Sorting member lists...\n");
12949 g_s.end();
12950
12951 g_s.begin("Setting anonymous enum type...\n");
12953 g_s.end();
12954
12955 g_s.begin("Computing dependencies between directories...\n");
12957 g_s.end();
12958
12959 g_s.begin("Generating citations page...\n");
12961 g_s.end();
12962
12963 g_s.begin("Counting members...\n");
12964 countMembers();
12965 g_s.end();
12966
12967 g_s.begin("Counting data structures...\n");
12969 g_s.end();
12970
12971 g_s.begin("Resolving user defined references...\n");
12973 g_s.end();
12974
12975 g_s.begin("Finding anchors and sections in the documentation...\n");
12977 g_s.end();
12978
12979 g_s.begin("Transferring function references...\n");
12981 g_s.end();
12982
12983 g_s.begin("Combining using relations...\n");
12985 g_s.end();
12986
12988 g_s.begin("Adding members to index pages...\n");
12990 addToIndices();
12991 g_s.end();
12992
12993 g_s.begin("Correcting members for VHDL...\n");
12995 g_s.end();
12996
12997 g_s.begin("Computing tooltip texts...\n");
12999 g_s.end();
13000
13001 if (Config_getBool(SORT_GROUP_NAMES))
13002 {
13003 std::stable_sort(Doxygen::groupLinkedMap->begin(),
13005 [](const auto &g1,const auto &g2)
13006 { return g1->groupTitle() < g2->groupTitle(); });
13007
13008 for (const auto &gd : *Doxygen::groupLinkedMap)
13009 {
13010 gd->sortSubGroups();
13011 }
13012 }
13013
13014 printNavTree(root.get(),0);
13016}

References Dir::absPath, addEnumValuesToEnums, addListReferences, addMembersToIndex, addMembersToMemberGroup, addSourceReferences, addSTLSupport, addTerminalCharIfMissing, addToIndices, AUTO_TRACE, AUTO_TRACE_ADD, begin, buildClassDocList, buildClassList, buildCompleteMemberLists, buildConceptDocList, buildConceptList, buildDefineList, buildDictionaryList, buildDirectories, buildExampleList, buildFileList, buildFunctionList, buildGroupList, buildInterfaceAndServiceList, buildListOfUsingDecls, buildNamespaceList, buildPageList, buildSequenceList, buildTypedefList, buildVarList, checkMarkdownMainfile, checkPageRelations, FormulaManager::checkRepositories, Doxygen::clangAssistedParsing, Doxygen::classLinkedMap, cleanUpDoxygen, combineUsingRelations, computeClassRelations, computeDirDependencies, computeMemberReferences, computeMemberRelations, computePageRelations, computeTemplateClassRelations, computeTooltipTexts, computeVerifiedDotPath, VhdlDocGen::computeVhdlComponentRelations, Doxygen::conceptLinkedMap, Config_getBool, Config_getInt, Config_getList, Config_getString, Config_updateList, Config_updateString, Portable::correctPath, Index::countDataStructures, countMembers, createOutputDirectory, createTemplateInstanceMembers, Dir::currentDirPath, distributeConceptGroups, distributeMemberGroupDocumentation, end, QCString::endsWith, Dir::exists, FileInfo::exists, exitDoxygen, FALSE, fileToString, Doxygen::filterDBFileName, findClassEntries, findDefineDocumentation, findDirDocumentation, findDocumentedEnumValues, findEnumDocumentation, findEnums, findFriends, findGroupScope, findIncludedUsingDirectives, findInheritedTemplateInstances, findMainPage, findMainPageTagFiles, findMemberDocumentation, findModuleDocumentation, findObjCMethodDefinitions, findSectionsInDocumentation, findTagLessClasses, findUsedTemplateInstances, findUsingDeclarations, findUsingDeclImports, findUsingDirectives, flushCachedTemplateRelations, flushUnresolvedRelations, Doxygen::functionNameLinkedMap, g_classEntries, g_commentFileName, g_s, g_singleComment, g_usingClassMap, g_usingDeclarations, generateDiskNames, generateHtmlForComment, CitationManager::generatePage, generateXRefPages, Portable::getenv, getPrefixIndex, Doxygen::groupLinkedMap, Doxygen::hiddenClassLinkedMap, Doxygen::indexList, inheritDocumentation, LayoutDocManager::init, FormulaManager::initFromRepository, initSearchIndexer, CitationManager::instance, FormulaManager::instance, Index::instance, LayoutDocManager::instance, ModuleManager::instance, QCString::isEmpty, FileInfo::isFile, Doxygen::memberNameLinkedMap, mergeCategories, Dir::mkdir, msg, Doxygen::namespaceLinkedMap, organizeSubGroups, LayoutDocManager::parse, parseFilesMultiThreading, parseFilesSingleThreading, Portable::pathListSeparator, Portable::pid, printLayout, printNavTree, printSectionsTree, qPrint, qstricmp_sort, readInputFile, readTagFile, resolveClassNestingRelations, resolveUserReferences, searchInputFiles, setAnonymousEnumType, Portable::setenv, Dir::setPath, sortMemberLists, stopDoxygen, QCString::str, Doxygen::symbolLookupCache, term, transferFunctionDocumentation, transferFunctionReferences, transferRelatedFunctionDocumentation, transferStaticInstanceInitializers, TRUE, Doxygen::typeLookupCache, vhdlCorrectMemberProperties, warn_uncond and warnUndocumentedNamespaces.

Referenced by main.

readConfiguration()

void readConfiguration (int argc, char ** argv)

Declaration at line 147 of file doxygen.h, definition at line 11417 of file doxygen.cpp.

11417void readConfiguration(int argc, char **argv)
11418{
11419 QCString versionString = getFullVersion();
11420
11421 // helper that calls \a func to write to file \a fileName via a TextStream
11422 auto writeFile = [](const char *fileName,std::function<void(TextStream&)> func) -> bool
11423 {
11424 std::ofstream f;
11425 if (openOutputFile(fileName,f))
11426 {
11427 TextStream t(&f);
11428 func(t);
11429 return true;
11430 }
11431 return false;
11432 };
11433
11434
11435 /**************************************************************************
11436 * Handle arguments *
11437 **************************************************************************/
11438
11439 int optInd=1;
11440 QCString configName;
11441 QCString traceName;
11442 bool genConfig=false;
11443 bool shortList=false;
11444 bool traceTiming=false;
11446 bool updateConfig=false;
11447 bool quiet = false;
11448 while (optInd<argc && argv[optInd][0]=='-' &&
11449 (isalpha(argv[optInd][1]) || argv[optInd][1]=='?' ||
11450 argv[optInd][1]=='-')
11451 )
11452 {
11453 switch(argv[optInd][1])
11454 {
11455 case 'g':
11456 {
11457 genConfig=TRUE;
11458 }
11459 break;
11460 case 'l':
11461 {
11462 QCString layoutName;
11463 if (optInd+1>=argc)
11464 {
11465 layoutName="DoxygenLayout.xml";
11466 }
11467 else
11468 {
11469 layoutName=argv[optInd+1];
11470 }
11471 writeDefaultLayoutFile(layoutName);
11473 exit(0);
11474 }
11475 break;
11476 case 'c':
11477 if (optInd+1>=argc) // no file name given
11478 {
11479 msg("option \"-c\" is missing the file name to read\n");
11480 devUsage();
11482 exit(1);
11483 }
11484 else
11485 {
11486 g_commentFileName=argv[optInd+1];
11487 optInd++;
11488 }
11489 g_singleComment=true;
11490 quiet=true;
11491 break;
11492 case 'd':
11493 {
11494 QCString debugLabel=getArg(argc,argv,optInd);
11495 if (debugLabel.isEmpty())
11496 {
11497 devUsage();
11499 exit(0);
11500 }
11501 int retVal = Debug::setFlagStr(debugLabel);
11502 if (!retVal)
11503 {
11504 msg("option \"-d\" has unknown debug specifier: \"{}\".\n",debugLabel);
11505 devUsage();
11507 exit(1);
11508 }
11509 }
11510 break;
11511 case 't':
11512 {
11513#if ENABLE_TRACING
11514 if (!strcmp(argv[optInd]+1,"t_time"))
11515 {
11516 traceTiming = true;
11517 }
11518 else if (!strcmp(argv[optInd]+1,"t"))
11519 {
11520 traceTiming = false;
11521 }
11522 else
11523 {
11524 err("option should be \"-t\" or \"-t_time\", found: \"{}\".\n",argv[optInd]);
11526 exit(1);
11527 }
11528 if (optInd+1>=argc || argv[optInd+1][0] == '-') // no file name given
11529 {
11530 traceName="stdout";
11531 }
11532 else
11533 {
11534 traceName=argv[optInd+1];
11535 optInd++;
11536 }
11537#else
11538 err("support for option \"-t\" has not been compiled in (use a debug build or a release build with tracing enabled).\n");
11540 exit(1);
11541#endif
11542 }
11543 break;
11544 case 'x':
11545 if (!strcmp(argv[optInd]+1,"x_noenv")) diffList=Config::CompareMode::CompressedNoEnv;
11546 else if (!strcmp(argv[optInd]+1,"x")) diffList=Config::CompareMode::Compressed;
11547 else
11548 {
11549 err("option should be \"-x\" or \"-x_noenv\", found: \"{}\".\n",argv[optInd]);
11551 exit(1);
11552 }
11553 break;
11554 case 's':
11555 shortList=TRUE;
11556 break;
11557 case 'u':
11558 updateConfig=TRUE;
11559 break;
11560 case 'e':
11561 {
11562 QCString formatName=getArg(argc,argv,optInd);
11563 if (formatName.isEmpty())
11564 {
11565 err("option \"-e\" is missing format specifier rtf.\n");
11567 exit(1);
11568 }
11569 if (qstricmp(formatName.data(),"rtf")==0)
11570 {
11571 if (optInd+1>=argc)
11572 {
11573 err("option \"-e rtf\" is missing an extensions file name\n");
11575 exit(1);
11576 }
11577 writeFile(argv[optInd+1],RTFGenerator::writeExtensionsFile);
11579 exit(0);
11580 }
11581 err("option \"-e\" has invalid format specifier.\n");
11583 exit(1);
11584 }
11585 break;
11586 case 'f':
11587 {
11588 QCString listName=getArg(argc,argv,optInd);
11589 if (listName.isEmpty())
11590 {
11591 err("option \"-f\" is missing list specifier.\n");
11593 exit(1);
11594 }
11595 if (qstricmp(listName.data(),"emoji")==0)
11596 {
11597 if (optInd+1>=argc)
11598 {
11599 err("option \"-f emoji\" is missing an output file name\n");
11601 exit(1);
11602 }
11603 writeFile(argv[optInd+1],[](TextStream &t) { EmojiEntityMapper::instance().writeEmojiFile(t); });
11605 exit(0);
11606 }
11607 err("option \"-f\" has invalid list specifier.\n");
11609 exit(1);
11610 }
11611 break;
11612 case 'w':
11613 {
11614 QCString formatName=getArg(argc,argv,optInd);
11615 if (formatName.isEmpty())
11616 {
11617 err("option \"-w\" is missing format specifier rtf, html or latex\n");
11619 exit(1);
11620 }
11621 if (qstricmp(formatName.data(),"rtf")==0)
11622 {
11623 if (optInd+1>=argc)
11624 {
11625 err("option \"-w rtf\" is missing a style sheet file name\n");
11627 exit(1);
11628 }
11629 if (!writeFile(argv[optInd+1],RTFGenerator::writeStyleSheetFile))
11630 {
11631 err("error opening RTF style sheet file {}!\n",argv[optInd+1]);
11633 exit(1);
11634 }
11636 exit(0);
11637 }
11638 else if (qstricmp(formatName.data(),"html")==0)
11639 {
11640 Config::init();
11641 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11642 // explicit config file mentioned or default found on disk
11643 {
11644 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11645 if (!Config::parse(df)) // parse the config file
11646 {
11647 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11649 exit(1);
11650 }
11651 }
11652 if (optInd+3>=argc)
11653 {
11654 err("option \"-w html\" does not have enough arguments\n");
11656 exit(1);
11657 }
11661 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11662 writeFile(argv[optInd+1],[&](TextStream &t) { HtmlGenerator::writeHeaderFile(t,argv[optInd+3]); });
11663 writeFile(argv[optInd+2],HtmlGenerator::writeFooterFile);
11664 writeFile(argv[optInd+3],HtmlGenerator::writeStyleSheetFile);
11666 exit(0);
11667 }
11668 else if (qstricmp(formatName.data(),"latex")==0)
11669 {
11670 Config::init();
11671 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11672 {
11673 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11674 if (!Config::parse(df))
11675 {
11676 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11678 exit(1);
11679 }
11680 }
11681 if (optInd+3>=argc)
11682 {
11683 err("option \"-w latex\" does not have enough arguments\n");
11685 exit(1);
11686 }
11690 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11691 writeFile(argv[optInd+1],LatexGenerator::writeHeaderFile);
11692 writeFile(argv[optInd+2],LatexGenerator::writeFooterFile);
11693 writeFile(argv[optInd+3],LatexGenerator::writeStyleSheetFile);
11695 exit(0);
11696 }
11697 else
11698 {
11699 err("Illegal format specifier \"{}\": should be one of rtf, html or latex\n",formatName);
11701 exit(1);
11702 }
11703 }
11704 break;
11705 case 'm':
11707 break;
11708 case 'v':
11709 version(false);
11711 exit(0);
11712 break;
11713 case 'V':
11714 version(true);
11716 exit(0);
11717 break;
11718 case '-':
11719 if (qstrcmp(&argv[optInd][2],"help")==0)
11720 {
11721 usage(argv[0],versionString);
11722 exit(0);
11723 }
11724 else if (qstrcmp(&argv[optInd][2],"version")==0)
11725 {
11726 version(false);
11728 exit(0);
11729 }
11730 else if ((qstrcmp(&argv[optInd][2],"Version")==0) ||
11731 (qstrcmp(&argv[optInd][2],"VERSION")==0))
11732 {
11733 version(true);
11735 exit(0);
11736 }
11737 else
11738 {
11739 err("Unknown option \"-{}\"\n",&argv[optInd][1]);
11740 usage(argv[0],versionString);
11741 exit(1);
11742 }
11743 break;
11744 case 'b':
11745 setvbuf(stdout,nullptr,_IONBF,0);
11746 break;
11747 case 'q':
11748 quiet = true;
11749 break;
11750 case 'h':
11751 case '?':
11752 usage(argv[0],versionString);
11753 exit(0);
11754 break;
11755 default:
11756 err("Unknown option \"-{:c}\"\n",argv[optInd][1]);
11757 usage(argv[0],versionString);
11758 exit(1);
11759 }
11760 optInd++;
11761 }
11762
11763 /**************************************************************************
11764 * Parse or generate the config file *
11765 **************************************************************************/
11766
11767 initTracing(traceName.data(),traceTiming);
11768 TRACE("Doxygen version used: {}",getFullVersion());
11769 Config::init();
11770
11771 FileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile");
11772 if (optInd>=argc)
11773 {
11774 if (configFileInfo1.exists())
11775 {
11776 configName="Doxyfile";
11777 }
11778 else if (configFileInfo2.exists())
11779 {
11780 configName="doxyfile";
11781 }
11782 else if (genConfig)
11783 {
11784 configName="Doxyfile";
11785 }
11786 else
11787 {
11788 err("Doxyfile not found and no input file specified!\n");
11789 usage(argv[0],versionString);
11790 exit(1);
11791 }
11792 }
11793 else
11794 {
11795 FileInfo fi(argv[optInd]);
11796 if (fi.exists() || qstrcmp(argv[optInd],"-")==0 || genConfig)
11797 {
11798 configName=argv[optInd];
11799 }
11800 else
11801 {
11802 err("configuration file {} not found!\n",argv[optInd]);
11803 usage(argv[0],versionString);
11804 exit(1);
11805 }
11806 }
11807
11808 if (genConfig)
11809 {
11810 generateConfigFile(configName,shortList);
11812 exit(0);
11813 }
11814
11815 if (!Config::parse(configName,updateConfig,diffList))
11816 {
11817 err("could not open or read configuration file {}!\n",configName);
11819 exit(1);
11820 }
11821
11822 if (diffList!=Config::CompareMode::Full)
11823 {
11825 compareDoxyfile(diffList);
11827 exit(0);
11828 }
11829
11830 if (updateConfig)
11831 {
11833 generateConfigFile(configName,shortList,TRUE);
11835 exit(0);
11836 }
11837
11838 /* Perlmod wants to know the path to the config file.*/
11839 FileInfo configFileInfo(configName.str());
11840 setPerlModDoxyfile(configFileInfo.absFilePath());
11841
11842 /* handle -q option */
11843 if (quiet) Config_updateBool(QUIET,TRUE);
11844}

References FileInfo::absFilePath, Config::checkAndCorrect, cleanUpDoxygen, compareDoxyfile, Config::Compressed, Config::CompressedNoEnv, Config_getBool, Config_getEnum, Config_updateBool, QCString::data, devUsage, err, FileInfo::exists, Config::Full, g_commentFileName, g_dumpSymbolMap, g_singleComment, generateConfigFile, getArg, Config::init, initTracing, EmojiEntityMapper::instance, QCString::isEmpty, msg, openOutputFile, Config::parse, Config::postProcess, qstrcmp, qstricmp, Debug::setFlagStr, setPerlModDoxyfile, setTranslator, QCString::str, TRACE, TRUE, Config::updateObsolete, usage, version, writeDefaultLayoutFile, EmojiEntityMapper::writeEmojiFile, RTFGenerator::writeExtensionsFile, HtmlGenerator::writeFooterFile, LatexGenerator::writeFooterFile, HtmlGenerator::writeHeaderFile, LatexGenerator::writeHeaderFile, HtmlGenerator::writeStyleSheetFile, LatexGenerator::writeStyleSheetFile and RTFGenerator::writeStyleSheetFile.

Referenced by main.

readFileOrDirectory()

void readFileOrDirectory (const QCString & s, FileNameLinkedMap * fnDict, StringUnorderedSet * exclSet, const StringVector * patList, const StringVector * exclPatList, StringVector * resultList, StringUnorderedSet * resultSet, bool recursive, bool errorIfNotExist=TRUE, StringUnorderedSet * killSet=nullptr, StringUnorderedSet * paths=nullptr)

Declaration at line 153 of file doxygen.h, definition at line 11067 of file doxygen.cpp.

11068 FileNameLinkedMap *fnMap,
11069 StringUnorderedSet *exclSet,
11070 const StringVector *patList,
11071 const StringVector *exclPatList,
11072 StringVector *resultList,
11073 StringUnorderedSet *resultSet,
11074 bool recursive,
11075 bool errorIfNotExist,
11076 StringUnorderedSet *killSet,
11077 StringUnorderedSet *paths
11078 )
11079{
11080 //printf("killSet count=%d\n",killSet ? (int)killSet->size() : -1);
11081 // strip trailing slashes
11082 if (s.isEmpty()) return;
11083
11084 g_pathsVisited.clear();
11085
11086 FileInfo fi(s.str());
11087 //printf("readFileOrDirectory(%s)\n",s);
11088 {
11089 if (exclSet==nullptr || exclSet->find(fi.absFilePath())==exclSet->end())
11090 {
11091 if (Config_getBool(EXCLUDE_SYMLINKS) && fi.isSymLink())
11092 {
11093 }
11094 else if (!fi.exists() || !fi.isReadable())
11095 {
11096 if (errorIfNotExist)
11097 {
11098 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",s);
11099 }
11100 }
11101 else if (fi.isFile())
11102 {
11103 std::string dirPath = fi.dirPath(true);
11104 std::string filePath = fi.absFilePath();
11105 if (paths && !dirPath.empty())
11106 {
11107 paths->insert(dirPath);
11108 }
11109 //printf("killSet.find(%s)=%d\n",qPrint(fi.absFilePath()),killSet.find(fi.absFilePath())!=killSet.end());
11110 if (killSet==nullptr || killSet->find(filePath)==killSet->end())
11111 {
11112 std::string name=fi.fileName();
11113 if (fnMap)
11114 {
11115 auto fd = createFileDef(QCString(dirPath+"/"),QCString(name));
11116 if (!name.empty())
11117 {
11118 FileName *fn = fnMap->add(QCString(name),QCString(filePath));
11119 fn->push_back(std::move(fd));
11120 }
11121 }
11122 if (resultList || resultSet)
11123 {
11124 if (resultList) resultList->push_back(filePath);
11125 if (resultSet) resultSet->insert(filePath);
11126 }
11127
11128 if (killSet) killSet->insert(fi.absFilePath());
11129 }
11130 }
11131 else if (fi.isDir()) // readable dir
11132 {
11133 readDir(&fi,fnMap,exclSet,patList,
11134 exclPatList,resultList,resultSet,errorIfNotExist,
11135 recursive,killSet,paths);
11136 }
11137 }
11138 }
11139}

References FileInfo::absFilePath, LinkedMap< T, Hash, KeyEqual, Map >::add, Config_getBool, createFileDef, FileInfo::dirPath, FileInfo::exists, FileInfo::fileName, g_pathsVisited, FileInfo::isDir, QCString::isEmpty, FileInfo::isFile, FileInfo::isReadable, FileInfo::isSymLink, readDir, QCString::str and warn_uncond.

Referenced by searchInputFiles.

Macro Definitions

AtomicInt

#define AtomicInt   std::atomic_int

Definition at line 31 of file doxygen.h.

31#define AtomicInt std::atomic_int

THREAD_LOCAL

#define THREAD_LOCAL   thread_local

Definition at line 30 of file doxygen.h.

30#define THREAD_LOCAL thread_local

Referenced by LatexCodeGenerator::codify and removeRedundantWhiteSpace.


Generated via doxygen2docusaurus by Doxygen 1.14.0.