diff options
Diffstat (limited to 'src/doxygen.cpp')
-rw-r--r-- | src/doxygen.cpp | 185 |
1 files changed, 105 insertions, 80 deletions
diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 4f4d13b..4c489d2 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -75,10 +75,12 @@ #include "searchindex.h" #include "parserintf.h" #include "htags.h" +#include "pycode.h" #include "pyscanner.h" +#include "fortrancode.h" #include "fortranscanner.h" -#include "xmlscanner.h" -#include "sqlscanner.h" +#include "xmlcode.h" +#include "sqlcode.h" #include "tclscanner.h" #include "code.h" #include "objcache.h" @@ -171,6 +173,7 @@ bool Doxygen::generatingXmlOutput = FALSE; bool Doxygen::markdownSupport = TRUE; GenericsSDict *Doxygen::genericsDict; DocGroup Doxygen::docGroup; +Preprocessor *Doxygen::preprocessor = 0; // locally accessible globals static std::unordered_map< std::string, const Entry* > g_classEntries; @@ -419,9 +422,9 @@ static STLInfo g_stlinfo[] = { 0, 0, 0, 0, 0, 0, 0, FALSE, FALSE } }; -static void addSTLMember(const std::unique_ptr<Entry> &root,const char *type,const char *name) +static void addSTLMember(const std::shared_ptr<Entry> &root,const char *type,const char *name) { - std::unique_ptr<Entry> memEntry = std::make_unique<Entry>(); + std::shared_ptr<Entry> memEntry = std::make_shared<Entry>(); memEntry->name = name; memEntry->type = type; memEntry->protection = Public; @@ -432,9 +435,9 @@ static void addSTLMember(const std::unique_ptr<Entry> &root,const char *type,con root->moveToSubEntryAndKeep(memEntry); } -static void addSTLIterator(const std::unique_ptr<Entry> &classEntry,const char *name) +static void addSTLIterator(const std::shared_ptr<Entry> &classEntry,const char *name) { - std::unique_ptr<Entry> iteratorClassEntry = std::make_unique<Entry>(); + std::shared_ptr<Entry> iteratorClassEntry = std::make_shared<Entry>(); iteratorClassEntry->fileName = "[STL]"; iteratorClassEntry->startLine = 1; iteratorClassEntry->name = name; @@ -445,14 +448,14 @@ static void addSTLIterator(const std::unique_ptr<Entry> &classEntry,const char * classEntry->moveToSubEntryAndKeep(iteratorClassEntry); } -static void addSTLClass(const std::unique_ptr<Entry> &root,const STLInfo *info) +static void addSTLClass(const std::shared_ptr<Entry> &root,const STLInfo *info) { //printf("Adding STL class %s\n",info->className); QCString fullName = info->className; fullName.prepend("std::"); // add fake Entry for the class - std::unique_ptr<Entry> classEntry = std::make_unique<Entry>(); + std::shared_ptr<Entry> classEntry = std::make_shared<Entry>(); classEntry->fileName = "[STL]"; classEntry->startLine = 1; classEntry->name = fullName; @@ -487,9 +490,9 @@ static void addSTLClass(const std::unique_ptr<Entry> &root,const STLInfo *info) addSTLMember(classEntry,info->templType2,info->templName2); } if (fullName=="std::auto_ptr" || fullName=="std::smart_ptr" || fullName=="std::shared_ptr" || - fullName=="std::unique_ptr" || fullName=="std::weak_ptr") + fullName=="std::shared_ptr" || fullName=="std::weak_ptr") { - std::unique_ptr<Entry> memEntry = std::make_unique<Entry>(); + std::shared_ptr<Entry> memEntry = std::make_shared<Entry>(); memEntry->name = "operator->"; memEntry->args = "()"; memEntry->type = "T*"; @@ -520,9 +523,9 @@ static void addSTLClass(const std::unique_ptr<Entry> &root,const STLInfo *info) } -static void addSTLClasses(const std::unique_ptr<Entry> &root) +static void addSTLClasses(const std::shared_ptr<Entry> &root) { - std::unique_ptr<Entry> namespaceEntry = std::make_unique<Entry>(); + std::shared_ptr<Entry> namespaceEntry = std::make_shared<Entry>(); namespaceEntry->fileName = "[STL]"; namespaceEntry->startLine = 1; namespaceEntry->name = "std"; @@ -1317,7 +1320,7 @@ static void addClassToContext(const Entry *root) //printf("ClassDict.insert(%s)\n",fullName.data()); Doxygen::classSDict->append(fullName,cd); - if (cd->isGeneric()) // generics are also stored in a separate dictionary for fast lookup of instantions + if (cd->isGeneric()) // generics are also stored in a separate dictionary for fast lookup of instances { //printf("inserting generic '%s' cd=%p\n",fullName.data(),cd); Doxygen::genericsDict->insert(fullName,cd); @@ -1604,7 +1607,7 @@ static void processTagLessClasses(ClassDef *rootCd, if (type.find(icd->name())!=-1) // matching tag less struct/union { QCString name = md->name(); - if (name.at(0)=='@') name = "__unnamed__"; + if (md->isAnonymous()) name = "__unnamed__"; if (!prefix.isEmpty()) name.prepend(prefix+"."); //printf(" found %s for class %s\n",name.data(),cd->name().data()); ClassDef *ncd = createTagLessInstance(rootCd,icd,name); @@ -2461,7 +2464,7 @@ static MemberDef *addVariableToFile( QCString def; // determine the definition of the global variable - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@' && + if (nd && !nd->isAnonymous() && !Config_getBool(HIDE_SCOPE_NAMES) ) // variable is inside a namespace, so put the scope before the name @@ -2616,7 +2619,7 @@ static MemberDef *addVariableToFile( addMemberToGroups(root,md); md->setRefItems(root->sli); - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') + if (nd && !nd->isAnonymous()) { md->setNamespace(nd); nd->insertMember(md); @@ -6540,7 +6543,7 @@ static void findMember(const Entry *root, // first note that we pass: // (root->tArgLists ? root->tArgLists->last() : 0) - // for the template arguments fo the new "member." + // for the template arguments for the new "member." // this accurately reflects the template arguments of // the related function, which don't have to do with // those of the related class. @@ -7027,7 +7030,7 @@ static void findEnums(const Entry *root) mnsd=Doxygen::memberNameSDict; isGlobal=FALSE; } - else if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') // found enum inside namespace + else if (nd) // found enum inside namespace { mnsd=Doxygen::functionNameSDict; isGlobal=TRUE; @@ -7076,7 +7079,7 @@ static void findEnums(const Entry *root) baseType.prepend(" : "); } - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') + if (nd) { if (isRelated || Config_getBool(HIDE_SCOPE_NAMES)) { @@ -7095,7 +7098,7 @@ static void findEnums(const Entry *root) // even if we have already added the enum to a namespace, we still // also want to add it to other appropriate places such as file // or class. - if (isGlobal) + if (isGlobal && (nd==0 || !nd->isAnonymous())) { if (!defSet) md->setDefinition(name+baseType); if (fd==0 && root->parent()) @@ -7204,7 +7207,7 @@ static void addEnumValuesToEnums(const Entry *root) mnsd=Doxygen::memberNameSDict; isGlobal=FALSE; } - else if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') // found enum inside namespace + else if (nd && !nd->isAnonymous()) // found enum inside namespace { //printf("Enum in namespace '%s'::'%s'\n",nd->name().data(),name.data()); mnsd=Doxygen::functionNameSDict; @@ -7312,7 +7315,7 @@ static void addEnumValuesToEnums(const Entry *root) { //printf("found enum value with same name %s in scope %s\n", // fmd->name().data(),fmd->getOuterScope()->name().data()); - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') + if (nd && !nd->isAnonymous()) { const NamespaceDef *fnd=fmd->getNamespaceDef(); if (fnd==nd) // enum value is inside a namespace @@ -8991,7 +8994,8 @@ static void generateExampleDocs() for (pdi.toFirst();(pd=pdi.current());++pdi) { msg("Generating docs for example %s...\n",pd->name().data()); - resetCCodeParserState(); + CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(".c"); // TODO: do this on code type + intf.resetCodeParserState(); QCString n=pd->getOutputFileBase(); startFile(*g_outputList,n,n,pd->name()); startTitle(*g_outputList,n); @@ -9197,7 +9201,7 @@ static void compareDoxyfile() //---------------------------------------------------------------------------- -static void readTagFile(const std::unique_ptr<Entry> &root,const char *tl) +static void readTagFile(const std::shared_ptr<Entry> &root,const char *tl) { QCString tagLine = tl; QCString fileName; @@ -9347,7 +9351,7 @@ static void copyExtraFiles(QStrList files,const QCString &filesOption,const QCSt //---------------------------------------------------------------------------- -static ParserInterface *getParserForFile(const char *fn) +static OutlineParserInterface &getParserForFile(const char *fn) { QCString fileName=fn; QCString extension; @@ -9362,11 +9366,11 @@ static ParserInterface *getParserForFile(const char *fn) extension = ".no_extension"; } - return Doxygen::parserManager->getParser(extension); + return Doxygen::parserManager->getOutlineParser(extension); } -static void parseFile(ParserInterface *parser, - const std::unique_ptr<Entry> &root,FileDef *fd,const char *fn, +static void parseFile(OutlineParserInterface &parser, + const std::shared_ptr<Entry> &root,FileDef *fd,const char *fn, bool sameTu,QStrList &filesInSameTu) { #if USE_LIBCLANG @@ -9390,12 +9394,12 @@ static void parseFile(ParserInterface *parser, BufStr preBuf(fi.size()+4096); if (Config_getBool(ENABLE_PREPROCESSING) && - parser->needsPreprocessing(extension)) + parser.needsPreprocessing(extension)) { BufStr inBuf(fi.size()+4096); msg("Preprocessing %s...\n",fn); readInputFile(fileName,inBuf); - preprocessFile(fileName,inBuf,preBuf); + Doxygen::preprocessor->processFile(fileName,inBuf,preBuf); } else // no preprocessing { @@ -9419,15 +9423,15 @@ static void parseFile(ParserInterface *parser, fd->getAllIncludeFilesRecursively(filesInSameTu); } - std::unique_ptr<Entry> fileRoot = std::make_unique<Entry>(); + std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>(); // use language parse to parse the file - parser->parseInput(fileName,convBuf.data(),fileRoot,sameTu,filesInSameTu); + parser.parseInput(fileName,convBuf.data(),fileRoot,sameTu,filesInSameTu); fileRoot->setFileDef(fd); root->moveToSubEntryAndKeep(fileRoot); } //! parse the list of input files -static void parseFiles(const std::unique_ptr<Entry> &root) +static void parseFiles(const std::shared_ptr<Entry> &root) { #if USE_LIBCLANG static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); @@ -9453,8 +9457,8 @@ static void parseFiles(const std::unique_ptr<Entry> &root) if (fd->isSource() && !fd->isReference()) // this is a source file { QStrList filesInSameTu; - ParserInterface * parser = getParserForFile(s->data()); - parser->startTranslationUnit(s->data()); + OutlineParserInterface &parser = getParserForFile(s->data()); + parser.startTranslationUnit(s->data()); parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); //printf(" got %d extra files in tu\n",filesInSameTu.count()); @@ -9476,7 +9480,7 @@ static void parseFiles(const std::unique_ptr<Entry> &root) } incFile = filesInSameTu.next(); } - parser->finishTranslationUnit(); + parser.finishTranslationUnit(); g_processedFiles.insert(*s,(void*)0x8); } } @@ -9489,15 +9493,15 @@ static void parseFiles(const std::unique_ptr<Entry> &root) QStrList filesInSameTu; FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig); ASSERT(fd!=0); - ParserInterface * parser = getParserForFile(s->data()); - parser->startTranslationUnit(s->data()); + OutlineParserInterface &parser = getParserForFile(s->data()); + parser.startTranslationUnit(s->data()); parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); - parser->finishTranslationUnit(); + parser.finishTranslationUnit(); g_processedFiles.insert(*s,(void*)0x8); } } } - else // normal pocessing + else // normal processing #endif { StringListIterator it(g_inputFiles); @@ -9508,8 +9512,8 @@ static void parseFiles(const std::unique_ptr<Entry> &root) QStrList filesInSameTu; FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig); ASSERT(fd!=0); - ParserInterface * parser = getParserForFile(s->data()); - parser->startTranslationUnit(s->data()); + OutlineParserInterface &parser = getParserForFile(s->data()); + parser.startTranslationUnit(s->data()); parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); } } @@ -9588,7 +9592,7 @@ static QDict<void> g_pathsVisited(1009); //---------------------------------------------------------------------------- // Read all files matching at least one pattern in 'patList' in the // directory represented by 'fi'. -// The directory is read iff the recusiveFlag is set. +// The directory is read iff the recursiveFlag is set. // The contents of all files is append to the input string int readDir(QFileInfo *fi, @@ -10066,32 +10070,55 @@ static const char *getArg(int argc,char **argv,int &optind) //---------------------------------------------------------------------------- +/** @brief /dev/null outline parser */ +class NullOutlineParser : public OutlineParserInterface +{ + public: + void startTranslationUnit(const char *) {} + void finishTranslationUnit() {} + void parseInput(const char *, const char *,const std::shared_ptr<Entry> &, bool, QStrList &) {} + bool needsPreprocessing(const QCString &) const { return FALSE; } + void parsePrototype(const char *) {} +}; + + + void initDoxygen() { initResources(); - const char *lang = portable_getenv("LC_ALL"); - if (lang) portable_setenv("LANG",lang); + const char *lang = Portable::getenv("LC_ALL"); + if (lang) Portable::setenv("LANG",lang); setlocale(LC_ALL,""); setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8 setlocale(LC_NUMERIC,"C"); - portable_correct_path(); + Portable::correct_path(); Doxygen::runningTime.start(); - initPreprocessor(); - - Doxygen::parserManager = new ParserManager; - Doxygen::parserManager->registerDefaultParser( new FileParser); - Doxygen::parserManager->registerParser("c", new CLanguageScanner); - Doxygen::parserManager->registerParser("python", new PythonLanguageScanner); - Doxygen::parserManager->registerParser("fortran", new FortranLanguageScanner); - Doxygen::parserManager->registerParser("fortranfree", new FortranLanguageScannerFree); - Doxygen::parserManager->registerParser("fortranfixed", new FortranLanguageScannerFixed); - Doxygen::parserManager->registerParser("vhdl", new VHDLLanguageScanner); - Doxygen::parserManager->registerParser("xml", new XMLScanner); - Doxygen::parserManager->registerParser("sql", new SQLScanner); - Doxygen::parserManager->registerParser("tcl", new TclLanguageScanner); - Doxygen::parserManager->registerParser("md", new MarkdownFileParser); + Doxygen::preprocessor = new Preprocessor(); + + Doxygen::parserManager = new ParserManager( std::make_unique<NullOutlineParser>(), + std::make_unique<FileCodeParser>()); + Doxygen::parserManager->registerParser("c", std::make_unique<COutlineParser>(), + std::make_unique<CCodeParser>()); + Doxygen::parserManager->registerParser("python", std::make_unique<PythonOutlineParser>(), + std::make_unique<PythonCodeParser>()); + Doxygen::parserManager->registerParser("fortran", std::make_unique<FortranOutlineParser>(), + std::make_unique<FortranCodeParser>()); + Doxygen::parserManager->registerParser("fortranfree", std::make_unique<FortranOutlineParserFree>(), + std::make_unique<FortranCodeParserFree>()); + Doxygen::parserManager->registerParser("fortranfixed", std::make_unique<FortranOutlineParserFixed>(), + std::make_unique<FortranCodeParserFixed>()); + Doxygen::parserManager->registerParser("vhdl", std::make_unique<VHDLOutlineParser>(), + std::make_unique<VHDLCodeParser>()); + Doxygen::parserManager->registerParser("xml", std::make_unique<NullOutlineParser>(), + std::make_unique<XMLCodeParser>()); + Doxygen::parserManager->registerParser("sql", std::make_unique<NullOutlineParser>(), + std::make_unique<SQLCodeParser>()); + Doxygen::parserManager->registerParser("tcl", std::make_unique<TclOutlineParser>(), + std::make_unique<TclCodeParser>()); + Doxygen::parserManager->registerParser("md", std::make_unique<MarkdownOutlineParser>(), + std::make_unique<FileCodeParser>()); // register any additional parsers here... @@ -10182,11 +10209,10 @@ void cleanUpDoxygen() delete Doxygen::globalScope; delete Doxygen::xrefLists; delete Doxygen::parserManager; - cleanUpPreprocessor(); + delete Doxygen::preprocessor; delete theTranslator; delete g_outputList; Mappers::freeMappers(); - codeFreeScanner(); if (Doxygen::symbolMap) { @@ -10662,7 +10688,7 @@ void adjustConfiguration() while (s) { QFileInfo fi(s); - addSearchDir(fi.absFilePath().utf8()); + Doxygen::preprocessor->addSearchDir(fi.absFilePath().utf8()); s=includePath.next(); } @@ -11102,7 +11128,7 @@ void parseInput() signal(SIGINT, stopDoxygen); #endif - uint pid = portable_pid(); + uint pid = Portable::pid(); Doxygen::objDBFileName.sprintf("doxygen_objdb_%d.tmp",pid); Doxygen::objDBFileName.prepend(outputDirectory+"/"); Doxygen::entryDBFileName.sprintf("doxygen_entrydb_%d.tmp",pid); @@ -11162,18 +11188,18 @@ void parseInput() QCString curFontPath = Config_getString(DOT_FONTPATH); if (curFontPath.isEmpty()) { - portable_getenv("DOTFONTPATH"); + Portable::getenv("DOTFONTPATH"); QCString newFontPath = "."; if (!curFontPath.isEmpty()) { - newFontPath+=portable_pathListSeparator(); + newFontPath+=Portable::pathListSeparator(); newFontPath+=curFontPath; } - portable_setenv("DOTFONTPATH",newFontPath); + Portable::setenv("DOTFONTPATH",newFontPath); } else { - portable_setenv("DOTFONTPATH",curFontPath); + Portable::setenv("DOTFONTPATH",curFontPath); } } @@ -11240,7 +11266,7 @@ void parseInput() * Handle Tag Files * **************************************************************************/ - std::unique_ptr<Entry> root = std::make_unique<Entry>(); + std::shared_ptr<Entry> root = std::make_shared<Entry>(); msg("Reading and parsing tag files\n"); QStrList &tagFileList = Config_getList(TAGFILES); @@ -11266,8 +11292,6 @@ void parseInput() // we are done with input scanning now, so free up the buffers used by flex // (can be around 4MB) - preFreeScanner(); - scanFreeScanner(); pyscanFreeScanner(); /************************************************************************** @@ -11800,7 +11824,7 @@ void generateOutput() { searchDataFile="searchdata.xml"; } - if (!portable_isAbsolutePath(searchDataFile)) + if (!Portable::isAbsolutePath(searchDataFile)) { searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/"); } @@ -11862,12 +11886,13 @@ void generateOutput() g_s.begin("Running html help compiler...\n"); QString oldDir = QDir::currentDirPath(); QDir::setCurrent(Config_getString(HTML_OUTPUT)); - portable_sysTimerStart(); - if (portable_system(Config_getString(HHC_LOCATION), "index.hhp", Debug::isFlagSet(Debug::ExtCmd))!=1) + Portable::setShortDir(); + Portable::sysTimerStart(); + if (Portable::system(Config_getString(HHC_LOCATION), "index.hhp", Debug::isFlagSet(Debug::ExtCmd))!=1) { err("failed to run html help compiler on index.hhp\n"); } - portable_sysTimerStop(); + Portable::sysTimerStop(); QDir::setCurrent(oldDir); g_s.end(); } @@ -11882,12 +11907,12 @@ void generateOutput() QCString const args = QCString().sprintf("%s -o \"%s\"", qhpFileName.data(), qchFileName.data()); QString const oldDir = QDir::currentDirPath(); QDir::setCurrent(Config_getString(HTML_OUTPUT)); - portable_sysTimerStart(); - if (portable_system(Config_getString(QHG_LOCATION), args.data(), FALSE)) + Portable::sysTimerStart(); + if (Portable::system(Config_getString(QHG_LOCATION), args.data(), FALSE)) { err("failed to run qhelpgenerator on index.qhp\n"); } - portable_sysTimerStop(); + Portable::sysTimerStop(); QDir::setCurrent(oldDir); g_s.end(); } @@ -11908,7 +11933,7 @@ void generateOutput() { msg("Total elapsed time: %.3f seconds\n(of which %.3f seconds waiting for external tools to finish)\n", ((double)Doxygen::runningTime.elapsed())/1000.0, - portable_getSysElapsedTime() + Portable::getSysElapsedTime() ); g_s.print(); } @@ -11924,7 +11949,7 @@ void generateOutput() cleanUpDoxygen(); - finializeSearchIndexer(); + finalizeSearchIndexer(); // Doxygen::symbolStorage->close(); QDir thisDir; thisDir.remove(Doxygen::objDBFileName); |