diff options
41 files changed, 815 insertions, 822 deletions
diff --git a/addon/doxyparse/doxyparse.cpp b/addon/doxyparse/doxyparse.cpp index db05d89..7ec37f7 100644 --- a/addon/doxyparse/doxyparse.cpp +++ b/addon/doxyparse/doxyparse.cpp @@ -49,7 +49,7 @@ class Doxyparse : public CodeOutputInterface { public: - Doxyparse(FileDef *fd) : m_fd(fd) {} + Doxyparse(const FileDef *fd) : m_fd(fd) {} ~Doxyparse() {} // these are just null functions, they can be used to produce a syntax highlighted @@ -84,7 +84,7 @@ class Doxyparse : public CodeOutputInterface } private: - FileDef *m_fd; + const FileDef *m_fd; }; static bool is_c_code = true; @@ -110,7 +110,7 @@ static void findXRefSymbols(FileDef *fd) delete parse; } -static bool ignoreStaticExternalCall(MemberDef *context, MemberDef *md) { +static bool ignoreStaticExternalCall(const MemberDef *context, const MemberDef *md) { if (md->isStatic()) { if(md->getFileDef() && context->getFileDef()) { if(md->getFileDef()->getOutputFileBase() == context->getFileDef()->getOutputFileBase()) @@ -163,8 +163,8 @@ static void printPrototypeYes() { static void printNumberOfLines(int lines) { printf(" lines_of_code: %d\n", lines); } -static void printNumberOfArguments(int arguments) { - printf(" parameters: %d\n", arguments); +static void printNumberOfArguments(size_t arguments) { + printf(" parameters: %zu\n", arguments); } static void printUses() { printf(" uses:\n"); @@ -174,11 +174,11 @@ static void printReferenceTo(std::string type, std::string signature, std::strin printf(" type: %s\n", type.c_str()); printf(" defined_in: \"%s\"\n", unescapeCharsInString(defined_in.c_str()).data()); } -static void printNumberOfConditionalPaths(MemberDef* md) { +static void printNumberOfConditionalPaths(const MemberDef* md) { printf(" conditional_paths: %d\n", md->numberOfFlowKeyWords()); } -static int isPartOfCStruct(MemberDef * md) { +static int isPartOfCStruct(const MemberDef * md) { return is_c_code && md->getClassDef() != NULL; } @@ -198,7 +198,7 @@ std::string argumentData(const Argument &argument) { return data; } -std::string functionSignature(MemberDef* md) { +std::string functionSignature(const MemberDef* md) { std::string signature = sanitizeString(md->name().data()); if(md->isFunction()){ const ArgumentList &argList = md->argumentList(); @@ -215,7 +215,7 @@ std::string functionSignature(MemberDef* md) { return signature; } -static void referenceTo(MemberDef* md) { +static void referenceTo(const MemberDef* md) { std::string type = md->memberTypeName().data(); std::string defined_in = ""; std::string signature = ""; @@ -253,17 +253,17 @@ void protectionInformation(Protection protection) { } } -void cModule(ClassDef* cd) { - MemberList* ml = cd->getMemberList(MemberListType_variableMembers); +void cModule(const ClassDef* cd) { + const MemberList* ml = cd->getMemberList(MemberListType_variableMembers); if (ml) { - FileDef *fd = cd->getFileDef(); - MemberList *fd_ml = fd->getMemberList(MemberListType_allMembersList); + const FileDef *fd = cd->getFileDef(); + const MemberList *fd_ml = fd->getMemberList(MemberListType_allMembersList); if (!fd_ml || fd_ml->count() == 0) { printModule(fd->getOutputFileBase().data()); printDefines(); } MemberListIterator mli(*ml); - MemberDef* md; + const MemberDef* md; for (mli.toFirst(); (md=mli.current()); ++mli) { printDefinition("variable", cd->name().data() + std::string("::") + md->name().data(), md->getDefLine()); protectionInformation(md->protection()); @@ -271,7 +271,7 @@ void cModule(ClassDef* cd) { } } -static bool checkOverrideArg(const ArgumentList &argList, MemberDef *md) { +static bool checkOverrideArg(const ArgumentList &argList, const MemberDef *md) { if(!md->isFunction() || argList.empty()){ return false; } @@ -285,7 +285,7 @@ static bool checkOverrideArg(const ArgumentList &argList, MemberDef *md) { return false; } -void functionInformation(MemberDef* md) { +void functionInformation(const MemberDef* md) { std::string temp = ""; int size = md->getEndBodyLine() - md->getStartBodyLine() + 1; printNumberOfLines(size); @@ -301,12 +301,10 @@ void functionInformation(MemberDef* md) { } printNumberOfConditionalPaths(md); - MemberSDict *defDict = md->getReferencesMembers(); - if (defDict) { - MemberSDict::Iterator msdi(*defDict); - MemberDef *rmd; + auto refList = md->getReferencesMembers(); + if (!refList.empty()) { printUses(); - for (msdi.toFirst(); (rmd=msdi.current()); ++msdi) { + for (const auto &rmd : refList) { if (rmd->definitionType() == Definition::TypeMember && !ignoreStaticExternalCall(md, rmd) && !checkOverrideArg(argList, rmd)) { referenceTo(rmd); } @@ -314,15 +312,15 @@ void functionInformation(MemberDef* md) { } } -void prototypeInformation(MemberDef* md) { +void prototypeInformation(const MemberDef* md) { printPrototypeYes(); const ArgumentList &argList = md->argumentList(); printNumberOfArguments(argList.size()); } -static void lookupSymbol(Definition *d) { +static void lookupSymbol(const Definition *d) { if (d->definitionType() == Definition::TypeMember) { - MemberDef *md = dynamic_cast<MemberDef*>(d); + const MemberDef *md = dynamic_cast<const MemberDef*>(d); std::string type = md->memberTypeName().data(); std::string signature = functionSignature(md); printDefinition(type, signature, md->getDefLine()); @@ -336,17 +334,17 @@ static void lookupSymbol(Definition *d) { } } -void listMembers(MemberList *ml) { +void listMembers(const MemberList *ml) { if (ml) { MemberListIterator mli(*ml); - MemberDef *md; + const MemberDef *md; for (mli.toFirst(); (md=mli.current()); ++mli) { lookupSymbol((Definition*) md); } } } -void listAllMembers(ClassDef* cd) { +void listAllMembers(const ClassDef* cd) { // methods listMembers(cd->getMemberList(MemberListType_functionMembers)); // constructors @@ -355,7 +353,7 @@ void listAllMembers(ClassDef* cd) { listMembers(cd->getMemberList(MemberListType_variableMembers)); } -static void classInformation(ClassDef* cd) { +static void classInformation(const ClassDef* cd) { if (is_c_code) { cModule(cd); } else { @@ -418,7 +416,7 @@ static void listSymbols() { ClassSDict *classes = fd->getClassSDict(); if (classes) { ClassSDict::Iterator cli(*classes); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst(); (cd = cli.current()); ++cli) { if (!cd->isVisited()) { classInformation(cd); diff --git a/doc/doxygen_manual.tex b/doc/doxygen_manual.tex index aacb573..3354801 100644 --- a/doc/doxygen_manual.tex +++ b/doc/doxygen_manual.tex @@ -122,6 +122,7 @@ \usepackage{etoc} \etocsettocstyle{\doxytocparskip}{\doxynormalparskip} \begin{document} +\raggedbottom \pagenumbering{alph} \begin{titlepage} \includegraphics[width=\textwidth]{doxygen_logo} diff --git a/doc/manual.sty b/doc/manual.sty index fd9fd0e..2e85012 100644 --- a/doc/manual.sty +++ b/doc/manual.sty @@ -40,10 +40,3 @@ \usepackage{xpatch} \xpatchcmd{\part}{plain}{empty}{}{} -% Define caption that is also suitable in a table -\makeatletter -\def\doxyfigcaption{% -\refstepcounter{figure}% -\@dblarg{\@caption{figure}}} -\makeatother - diff --git a/src/clangparser.cpp b/src/clangparser.cpp index 1a91b8f..d17ed91 100644 --- a/src/clangparser.cpp +++ b/src/clangparser.cpp @@ -133,6 +133,7 @@ class ClangTUParser::Private CXToken *tokens = 0; uint numTokens = 0; StringVector filesInSameTU; + TooltipManager tooltipManager; // state while parsing sources MemberDef *currentMemberDef=0; @@ -572,7 +573,7 @@ void ClangTUParser::writeMultiLineCodeLink(CodeOutputInterface &ol, const char *text) { static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); - TooltipManager::instance()->addTooltip(d); + p->tooltipManager.addTooltip(d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); diff --git a/src/classdef.cpp b/src/classdef.cpp index e797b05e..91730a0 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -82,9 +82,9 @@ class ClassDefImpl : public DefinitionImpl, public ClassDef virtual CompoundType compoundType() const; virtual QCString compoundTypeString() const; virtual BaseClassList baseClasses() const; - virtual void updateBaseClasses(BaseClassList bcd); + virtual void updateBaseClasses(const BaseClassList &bcd); virtual BaseClassList subClasses() const; - virtual void updateSubClasses(BaseClassList bcd); + virtual void updateSubClasses(const BaseClassList &bcd); virtual const MemberNameInfoLinkedMap &memberNameInfoLinkedMap() const; virtual Protection protection() const; virtual bool isLinkableInProject() const; @@ -512,8 +512,8 @@ class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef virtual void addGroupedInheritedMembers(OutputList &,MemberListType, const ClassDef *,const QCString &) const {} virtual void writeTagFile(FTextStream &) {} - virtual void updateBaseClasses(BaseClassList) {} - virtual void updateSubClasses(BaseClassList) {} + virtual void updateBaseClasses(const BaseClassList &) {} + virtual void updateSubClasses(const BaseClassList &) {} virtual void setVisited(bool visited) const { m_visited = visited; } virtual bool isVisited() const { return m_visited; } @@ -3420,16 +3420,14 @@ bool ClassDefImpl::isLinkable() const /*! the class is visible in a class diagram, or class hierarchy */ bool ClassDefImpl::isVisibleInHierarchy() const { - static bool allExternals = Config_getBool(ALLEXTERNALS); - static bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES); - static bool extractStatic = Config_getBool(EXTRACT_STATIC); + bool allExternals = Config_getBool(ALLEXTERNALS); + bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES); + bool extractStatic = Config_getBool(EXTRACT_STATIC); return // show all classes or a subclass is visible - (allExternals || hasNonReferenceSuperClass()) && + ((allExternals && !isArtificial()) || hasNonReferenceSuperClass()) && // and not an anonymous compound !isAnonymous() && - // not an artificially introduced class - /*!isArtificial() &&*/ // 1.8.2: allowed these to appear // and not privately inherited protectionLevelVisible(m_impl->prot) && // documented or shown anyway or documentation is external @@ -4752,7 +4750,7 @@ BaseClassList ClassDefImpl::baseClasses() const return m_impl->inherits; } -void ClassDefImpl::updateBaseClasses(BaseClassList bcd) +void ClassDefImpl::updateBaseClasses(const BaseClassList &bcd) { m_impl->inherits = bcd; } @@ -4762,7 +4760,7 @@ BaseClassList ClassDefImpl::subClasses() const return m_impl->inheritedBy; } -void ClassDefImpl::updateSubClasses(BaseClassList bcd) +void ClassDefImpl::updateSubClasses(const BaseClassList &bcd) { m_impl->inheritedBy = bcd; } diff --git a/src/classdef.h b/src/classdef.h index bd06323..faaf0f6 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -160,14 +160,14 @@ class ClassDef : virtual public Definition virtual BaseClassList baseClasses() const = 0; /** Update the list of base classes to the one passed */ - virtual void updateBaseClasses(BaseClassList bcd) = 0; + virtual void updateBaseClasses(const BaseClassList &bcd) = 0; /** Returns the list of sub classes that directly derive from this class */ virtual BaseClassList subClasses() const = 0; /** Update the list of sub classes to the one passed */ - virtual void updateSubClasses(BaseClassList bcd) = 0; + virtual void updateSubClasses(const BaseClassList &bcd) = 0; /** Returns a dictionary of all members. This includes any inherited * members. Members are sorted alphabetically. @@ -175,6 +175,7 @@ struct codeYY_state QCString forceTagReference; VariableContext theVarContext; CallContext theCallContext; + TooltipManager tooltipManager; }; static bool isCastKeyword(const QCString &s); @@ -241,7 +242,7 @@ static void addVariable(yyscan_t yyscanner,QCString type,QCString name); //------------------------------------------------------------------- static std::mutex g_searchIndexMutex; -static std::mutex g_tooltipMutex; +static std::mutex g_docCrossReferenceMutex; /* ----------------------------------------------------------------- */ @@ -1810,6 +1811,14 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} yyextra->type.resize(0); yyextra->name.resize(0); BEGIN( Body ); } +<SkipInits>{ID}{B}*"{" { + QCString text = yytext; + int bracketPos = text.find('{'); + int spacePos = text.find(' '); + int len = spacePos==-1 ? bracketPos : spacePos; + generateClassOrGlobalLink(yyscanner,*yyextra->code,text.left(len)); + yyextra->code->codify(yytext+len); + } <SkipInits>{ID} { generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); } @@ -2463,10 +2472,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); - { - std::lock_guard<std::mutex> lock(g_tooltipMutex); - TooltipManager::instance()->addTooltip(d); - } + yyextra->tooltipManager.addTooltip(d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); @@ -2756,6 +2762,7 @@ static bool getLinkInScope(yyscan_t yyscanner, if (yyextra->currentDefinition && yyextra->currentMemberDef && md!=yyextra->currentMemberDef && yyextra->insideBody && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); } //printf("d->getReference()='%s' d->getOutputBase()='%s' name='%s' member name='%s'\n",d->getReference().data(),d->getOutputFileBase().data(),d->name().data(),md->name().data()); @@ -2916,6 +2923,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, if (d && d->isLinkable() && md->isLinkable() && yyextra->currentMemberDef && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); } } @@ -2970,6 +2978,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, addToSearchIndex(yyscanner,clName); if (yyextra->currentMemberDef && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); } return; @@ -3030,6 +3039,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner, if (yyextra->currentDefinition && yyextra->currentMemberDef && /*xmd!=yyextra->currentMemberDef &&*/ yyextra->insideBody && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,xmd); } @@ -3449,6 +3459,7 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->method,name); if (yyextra->currentMemberDef && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(ctx->method)); } } @@ -3523,6 +3534,7 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->objectVar,object); if (yyextra->currentMemberDef && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(ctx->objectVar)); } } @@ -3895,6 +3907,8 @@ void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const delete yyextra->sourceFileDef; yyextra->sourceFileDef=0; } + // write the tooltips + yyextra->tooltipManager.writeTooltips(od); printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL); return; diff --git a/src/config.xml b/src/config.xml index 39e83ad..793b7d1 100644 --- a/src/config.xml +++ b/src/config.xml @@ -660,7 +660,8 @@ Go to the <a href="commands.html">next</a> section or return to the <br>Note: For files without extension you can use `no_extension` as a placeholder. <br>Note that for custom extensions you also need to set \ref cfg_file_patterns "FILE_PATTERNS" otherwise the - files are not read by doxygen. + files are not read by doxygen. When specifying `no_extension` you should add `*` + to the \ref cfg_file_patterns "FILE_PATTERNS". ]]> </docs> </option> @@ -1739,10 +1740,10 @@ to disable this feature. <docs> <![CDATA[ If clang assisted parsing is enabled you can provide the clang parser with the - path to the directory containing a file called compile_commands.json. + path to the directory containing a file called `compile_commands.json`. This file is the <a href="http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html"> compilation database</a> containing the options used when the source files were built. - This is equivalent to specifying the "-p" option to a clang tool, such as clang-check. + This is equivalent to specifying the `-p` option to a clang tool, such as `clang-check`. These options will then be passed to the parser. Any options specified with \ref cfg_clang_options "CLANG_OPTIONS" will be added as well. diff --git a/src/configgen.py b/src/configgen.py index 4ffa8f8..063c1f4 100755 --- a/src/configgen.py +++ b/src/configgen.py @@ -62,7 +62,7 @@ def transformDocs(doc): # fallback for not handled doc = re.sub('\\\\ref', '', doc) #<a href="address">description</a> -> description (see: address) - doc = re.sub('<a +href="([^"]*)" *>([^<]*)</a>', '\\2 (see: \\1)', doc) + doc = re.sub('<a +href="([^"]*)" *>([^<]*)</a>', '\\2 (see: \n\\1)', doc) # LaTeX name as formula -> LaTeX doc = doc.replace("\\f$\\mbox{\\LaTeX}\\f$", "LaTeX") # Other formula's (now just 2) so explicitly mentioned. diff --git a/src/context.cpp b/src/context.cpp index 614cc2d..394e857 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -4943,7 +4943,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> Cachable &cache = getCache(); if (!cache.sourceRefs) { - cache.sourceRefs.reset(MemberListContext::alloc(m_memberDef->getReferencesMembers(),TRUE)); + cache.sourceRefs.reset(MemberListContext::alloc(m_memberDef->getReferencesMembers())); } return cache.sourceRefs.get(); } @@ -4952,7 +4952,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> Cachable &cache = getCache(); if (!cache.sourceRefBys) { - cache.sourceRefBys.reset(MemberListContext::alloc(m_memberDef->getReferencedByMembers(),TRUE)); + cache.sourceRefBys.reset(MemberListContext::alloc(m_memberDef->getReferencedByMembers())); } return cache.sourceRefBys.get(); } @@ -6541,7 +6541,7 @@ class NestingContext::Private : public GenericNodeListContext if (!nd->isAnonymous() && (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) { - bool hasChildren = namespaceHasVisibleChild(nd,addClasses,false,ClassDef::Class); + bool hasChildren = namespaceHasNestedNamespace(nd); bool isLinkable = nd->isLinkableInProject(); if (isLinkable || hasChildren) { @@ -6670,7 +6670,7 @@ class NestingContext::Private : public GenericNodeListContext } } } - void addDerivedClasses(BaseClassList bcl,bool hideSuper) + void addDerivedClasses(const BaseClassList &bcl,bool hideSuper) { for (const auto &bcd : bcl) { @@ -6812,7 +6812,7 @@ void NestingContext::addClassHierarchy(const ClassSDict &classSDict,bool rootOnl p->addClassHierarchy(classSDict,rootOnly); } -void NestingContext::addDerivedClasses(BaseClassList bcl,bool hideSuper) +void NestingContext::addDerivedClasses(const BaseClassList &bcl,bool hideSuper) { p->addDerivedClasses(bcl,hideSuper); } @@ -8533,7 +8533,7 @@ class InheritanceListContext::Private : public GenericNodeListContext } }; -InheritanceListContext::InheritanceListContext(BaseClassList list, bool baseClasses) : RefCountedContext("InheritanceListContext") +InheritanceListContext::InheritanceListContext(const BaseClassList &list, bool baseClasses) : RefCountedContext("InheritanceListContext") { p = new Private; for (const auto &bcd : list) @@ -8581,7 +8581,7 @@ TemplateListIntf::ConstIterator *InheritanceListContext::createIterator() const class MemberListContext::Private : public GenericNodeListContext { public: - void addMember(MemberDef *md) + void addMember(const MemberDef *md) { append(MemberContext::alloc(md)); } @@ -8630,6 +8630,16 @@ MemberListContext::MemberListContext(MemberSDict *list,bool doSort) : RefCounted } } +MemberListContext::MemberListContext(std::vector<const MemberDef *> &&ml) : RefCountedContext("MemberListContext") +{ + p = new Private; + for (const auto &md : ml) + { + p->addMember(md); + } + ml.clear(); +} + MemberListContext::~MemberListContext() { delete p; diff --git a/src/context.h b/src/context.h index 473c72f..240e8fd 100644 --- a/src/context.h +++ b/src/context.h @@ -452,7 +452,7 @@ class ClassInheritanceNodeContext : public RefCountedContext, public TemplateStr virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } - void addChildren(BaseClassList bcl,bool hideSuper); + void addChildren(const BaseClassList &bcl,bool hideSuper); private: ClassInheritanceNodeContext(const ClassDef *); @@ -550,7 +550,7 @@ class NestingContext : public RefCountedContext, public TemplateListIntf void addModules(const GroupSDict &modules); void addModules(const GroupList &modules); void addClassHierarchy(const ClassSDict &clDict,bool rootOnly); - void addDerivedClasses(BaseClassList bcl,bool hideSuper); + void addDerivedClasses(const BaseClassList &bcl,bool hideSuper); private: NestingContext(const NestingNodeContext *parent,int level); @@ -926,7 +926,7 @@ class InheritanceNodeContext : public RefCountedContext, public TemplateStructIn class InheritanceListContext : public RefCountedContext, public TemplateListIntf { public: - static InheritanceListContext *alloc(BaseClassList list,bool baseClasses) + static InheritanceListContext *alloc(const BaseClassList &list,bool baseClasses) { return new InheritanceListContext(list,baseClasses); } // TemplateListIntf @@ -937,7 +937,7 @@ class InheritanceListContext : public RefCountedContext, public TemplateListIntf virtual int release() { return RefCountedContext::release(); } private: - InheritanceListContext(BaseClassList list,bool baseClasses); + InheritanceListContext(const BaseClassList &list,bool baseClasses); ~InheritanceListContext(); class Private; Private *p; @@ -954,6 +954,8 @@ class MemberListContext : public RefCountedContext, public TemplateListIntf { return new MemberListContext(ml); } static MemberListContext *alloc(MemberSDict *ml,bool doSort) { return new MemberListContext(ml,doSort); } + static MemberListContext *alloc(std::vector<const MemberDef *> &&ml) + { return new MemberListContext(std::move(ml)); } // TemplateListIntf virtual uint count() const; @@ -966,6 +968,7 @@ class MemberListContext : public RefCountedContext, public TemplateListIntf MemberListContext(); MemberListContext(const MemberList *ml); MemberListContext(MemberSDict *ml,bool doSort); + MemberListContext(std::vector<const MemberDef *> &&ml); ~MemberListContext(); class Private; Private *p; diff --git a/src/defargs.l b/src/defargs.l index 6ecc7ff..e25c1fe 100644 --- a/src/defargs.l +++ b/src/defargs.l @@ -511,6 +511,8 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <FuncQual>"volatile" { yyextra->argList->setVolatileSpecifier(TRUE); } +<FuncQual>"override" { + } <FuncQual>"&" { yyextra->argList->setRefQualifier(RefQualifierLValue); } @@ -790,7 +792,7 @@ std::unique_ptr<ArgumentList> stringToArgumentList(SrcLangExt lang, const char * yyextra->argList->setNoParameters(TRUE); } if (extraTypeChars) *extraTypeChars=yyextra->extraTypeChars; - //printf("stringToArgumentList(%s) result=%s\n",argsString,argListToString(al).data()); + //printf("stringToArgumentList(%s) result=%s\n",argsString,argListToString(*al).data()); printlex(yy_flex_debug, FALSE, __FILE__, NULL); defargsYYlex_destroy(yyscanner); return al; diff --git a/src/defgen.cpp b/src/defgen.cpp index b01d438..82f7c26 100644 --- a/src/defgen.cpp +++ b/src/defgen.cpp @@ -243,71 +243,58 @@ void generateDEFForMember(MemberDef *md, //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers()); - MemberSDict *mdict = md->getReferencesMembers(); - if (mdict) + QCString refPrefix = " " + memPrefix + "ref-"; + auto refList = md->getReferencesMembers(); + for (const auto &rmd : refList) { - MemberSDict::Iterator mdi(*mdict); - MemberDef *rmd; - QCString refPrefix = " " + memPrefix + "ref-"; - - for (mdi.toFirst();(rmd=mdi.current());++mdi) + if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef()) { - if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef()) + t << memPrefix << "referenceto = {" << endl; + t << refPrefix << "id = '" + << rmd->getBodyDef()->getOutputFileBase() + << "_1" // encoded ':' character (see util.cpp:convertNameToFile) + << rmd->anchor() << "';" << endl; + + t << refPrefix << "line = '" + << rmd->getStartBodyLine() << "';" << endl; + + QCString scope = rmd->getScopeString(); + QCString name = rmd->name(); + if (!scope.isEmpty() && scope!=def->name()) { - t << memPrefix << "referenceto = {" << endl; - t << refPrefix << "id = '" - << rmd->getBodyDef()->getOutputFileBase() - << "_1" // encoded ':' character (see util.cpp:convertNameToFile) - << rmd->anchor() << "';" << endl; - - t << refPrefix << "line = '" - << rmd->getStartBodyLine() << "';" << endl; - - QCString scope = rmd->getScopeString(); - QCString name = rmd->name(); - if (!scope.isEmpty() && scope!=def->name()) - { - name.prepend(scope+"::"); - } - - t << refPrefix << "name = "; - writeDEFString(t,name); - t << ';' << endl << " };" << endl; + name.prepend(scope+"::"); } - } /* for (mdi.toFirst...) */ + + t << refPrefix << "name = "; + writeDEFString(t,name); + t << ';' << endl << " };" << endl; + } } - mdict = md->getReferencedByMembers(); - if (mdict) + auto refByList = md->getReferencedByMembers(); + for (const auto &rmd : refByList) { - MemberSDict::Iterator mdi(*mdict); - MemberDef *rmd; - QCString refPrefix = " " + memPrefix + "ref-"; - - for (mdi.toFirst();(rmd=mdi.current());++mdi) + if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef()) { - if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef()) + t << memPrefix << "referencedby = {" << endl; + t << refPrefix << "id = '" + << rmd->getBodyDef()->getOutputFileBase() + << "_1" // encoded ':' character (see util.cpp:convertNameToFile) + << rmd->anchor() << "';" << endl; + + t << refPrefix << "line = '" + << rmd->getStartBodyLine() << "';" << endl; + + QCString scope = rmd->getScopeString(); + QCString name = rmd->name(); + if (!scope.isEmpty() && scope!=def->name()) { - t << memPrefix << "referencedby = {" << endl; - t << refPrefix << "id = '" - << rmd->getBodyDef()->getOutputFileBase() - << "_1" // encoded ':' character (see util.cpp:convertNameToFile) - << rmd->anchor() << "';" << endl; - - t << refPrefix << "line = '" - << rmd->getStartBodyLine() << "';" << endl; - - QCString scope = rmd->getScopeString(); - QCString name = rmd->name(); - if (!scope.isEmpty() && scope!=def->name()) - { - name.prepend(scope+"::"); - } - - t << refPrefix << "name = "; - writeDEFString(t,name); - t << ';' << endl << " };" << endl; + name.prepend(scope+"::"); } - } /* for (mdi.toFirst...) */ + + t << refPrefix << "name = "; + writeDEFString(t,name); + t << ';' << endl << " };" << endl; + } } t << " }; /* " << Prefix << "-member */" << endl; diff --git a/src/definition.cpp b/src/definition.cpp index 9e78b74..355ef82 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -16,6 +16,10 @@ */ #include <algorithm> +#include <iterator> +#include <unordered_map> +#include <string> + #include <ctype.h> #include <qregexp.h> #include "md5.h" @@ -58,8 +62,8 @@ class DefinitionImpl::IMPL SectionRefs sectionRefs; - MemberSDict *sourceRefByDict = 0; - MemberSDict *sourceRefsDict = 0; + std::unordered_map<std::string,const MemberDef *> sourceRefByDict; + std::unordered_map<std::string,const MemberDef *> sourceRefsDict; RefItemVector xrefListItems; GroupList *partOfGroups = 0; @@ -100,8 +104,6 @@ class DefinitionImpl::IMPL DefinitionImpl::IMPL::~IMPL() { - delete sourceRefByDict; - delete sourceRefsDict; delete partOfGroups; delete brief; delete details; @@ -138,8 +140,8 @@ void DefinitionImpl::IMPL::init(const char *df, const char *n) details = 0; body = 0; inbodyDocs = 0; - sourceRefByDict = 0; - sourceRefsDict = 0; + sourceRefByDict.clear(); + sourceRefsDict.clear(); outerScope = Doxygen::globalScope; partOfGroups = 0; hidden = FALSE; @@ -314,33 +316,11 @@ DefinitionImpl::DefinitionImpl(const DefinitionImpl &d) { m_impl = new DefinitionImpl::IMPL; *m_impl = *d.m_impl; - m_impl->sourceRefByDict = 0; - m_impl->sourceRefsDict = 0; m_impl->partOfGroups = 0; m_impl->brief = 0; m_impl->details = 0; m_impl->body = 0; m_impl->inbodyDocs = 0; - if (d.m_impl->sourceRefByDict) - { - m_impl->sourceRefByDict = new MemberSDict; - MemberSDict::IteratorDict it(*d.m_impl->sourceRefByDict); - MemberDef *md; - for (it.toFirst();(md=it.current());++it) - { - m_impl->sourceRefByDict->append(it.currentKey(),md); - } - } - if (d.m_impl->sourceRefsDict) - { - m_impl->sourceRefsDict = new MemberSDict; - MemberSDict::IteratorDict it(*d.m_impl->sourceRefsDict); - MemberDef *md; - for (it.toFirst();(md=it.current());++it) - { - m_impl->sourceRefsDict->append(it.currentKey(),md); - } - } if (d.m_impl->partOfGroups) { GroupListIterator it(*d.m_impl->partOfGroups); @@ -1262,11 +1242,27 @@ void DefinitionImpl::writeInlineCode(OutputList &ol,const char *scopeName) const ol.popGeneratorState(); } +static inline std::vector<const MemberDef*> refMapToVector(const std::unordered_map<std::string,const MemberDef *> &map) +{ + // convert map to a vector of values + std::vector<const MemberDef *> result; + std::transform(map.begin(),map.end(), // iterate over map + std::back_inserter(result), // add results to vector + [](const auto &item) + { return item.second; } // extract value to add from map Key,Value pair + ); + // and sort it + std::sort(result.begin(),result.end(), + [](const auto &m1,const auto &m2) { return genericCompareMembers(m1,m2)<0; }); + return result; +} + /*! Write a reference to the source code fragments in which this * definition is used. */ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, - const QCString &text,MemberSDict *members,bool /*funcOnly*/) const + const QCString &text,const std::unordered_map<std::string,const MemberDef *> &membersMap, + bool /*funcOnly*/) const { static bool latexSourceCode = Config_getBool(LATEX_SOURCE_CODE); static bool docbookSourceCode = Config_getBool(DOCBOOK_PROGRAMLISTING); @@ -1274,15 +1270,15 @@ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); static bool refLinkSource = Config_getBool(REFERENCES_LINK_SOURCE); ol.pushGeneratorState(); - if (members) + if (!membersMap.empty()) { - members->sort(); + auto members = refMapToVector(membersMap); ol.startParagraph("reference"); ol.parseText(text); ol.docify(" "); - QCString ldefLine=theTranslator->trWriteList((int)members->count()); + QCString ldefLine=theTranslator->trWriteList((int)members.size()); QRegExp marker("@[0-9]+"); uint index=0; @@ -1294,7 +1290,7 @@ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, bool ok; ol.parseText(ldefLine.mid(index,(uint)newIndex-index)); uint entryIndex = ldefLine.mid(newIndex+1,matchLen-1).toUInt(&ok); - MemberDef *md=members->at(entryIndex); + const MemberDef *md=members.at(entryIndex); if (ok && md) { QCString scope=md->getScopeString(); @@ -1466,14 +1462,7 @@ void DefinitionImpl::addSourceReferencedBy(const MemberDef *md) name.prepend(scope+"::"); } - if (m_impl->sourceRefByDict==0) - { - m_impl->sourceRefByDict = new MemberSDict; - } - if (m_impl->sourceRefByDict->find(name)==0) - { - m_impl->sourceRefByDict->append(name,md); - } + m_impl->sourceRefByDict.insert({name.str(),md}); } } @@ -1489,14 +1478,7 @@ void DefinitionImpl::addSourceReferences(const MemberDef *md) name.prepend(scope+"::"); } - if (m_impl->sourceRefsDict==0) - { - m_impl->sourceRefsDict = new MemberSDict; - } - if (m_impl->sourceRefsDict->find(name)==0) - { - m_impl->sourceRefsDict->append(name,md); - } + m_impl->sourceRefsDict.insert({name.str(),md}); } } @@ -1960,29 +1942,20 @@ QCString DefinitionImpl::briefDescription(bool abbr) const QCString(""); } -QCString DefinitionImpl::briefDescriptionAsTooltip() const +void DefinitionImpl::computeTooltip() { - if (m_impl->brief) + if (m_impl->brief && m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty()) { - if (m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty()) - { - static bool reentering=FALSE; - if (!reentering) - { - const MemberDef *md = definitionType()==TypeMember ? dynamic_cast<const MemberDef*>(this) : 0; - const Definition *scope = definitionType()==TypeMember ? getOuterScope() : this; - reentering=TRUE; // prevent requests for tooltips while parsing a tooltip - m_impl->brief->tooltip = parseCommentAsText( - scope,md, - m_impl->brief->doc, - m_impl->brief->file, - m_impl->brief->line); - reentering=FALSE; - } - } - return m_impl->brief->tooltip; + const MemberDef *md = definitionType()==TypeMember ? dynamic_cast<const MemberDef*>(this) : 0; + const Definition *scope = definitionType()==TypeMember ? getOuterScope() : this; + m_impl->brief->tooltip = parseCommentAsText(scope,md, + m_impl->brief->doc, m_impl->brief->file, m_impl->brief->line); } - return QCString(""); +} + +QCString DefinitionImpl::briefDescriptionAsTooltip() const +{ + return m_impl->brief ? m_impl->brief->tooltip : QCString(); } int DefinitionImpl::briefLine() const @@ -2100,16 +2073,49 @@ Definition *DefinitionImpl::getOuterScope() const return m_impl->outerScope; } -MemberSDict *DefinitionImpl::getReferencesMembers() const +std::vector<const MemberDef*> DefinitionImpl::getReferencesMembers() const +{ + return refMapToVector(m_impl->sourceRefsDict); +} + +std::vector<const MemberDef*> DefinitionImpl::getReferencedByMembers() const +{ + return refMapToVector(m_impl->sourceRefByDict); +} + +void DefinitionImpl::mergeReferences(const Definition *other) { - return m_impl->sourceRefsDict; + const DefinitionImpl *defImpl = dynamic_cast<const DefinitionImpl*>(other); + if (defImpl) + { + for (const auto &kv : defImpl->m_impl->sourceRefsDict) + { + auto it = m_impl->sourceRefsDict.find(kv.first); + if (it != m_impl->sourceRefsDict.end()) + { + m_impl->sourceRefsDict.insert(kv); + } + } + } } -MemberSDict *DefinitionImpl::getReferencedByMembers() const +void DefinitionImpl::mergeReferencedBy(const Definition *other) { - return m_impl->sourceRefByDict; + const DefinitionImpl *defImpl = dynamic_cast<const DefinitionImpl*>(other); + if (defImpl) + { + for (const auto &kv : defImpl->m_impl->sourceRefByDict) + { + auto it = m_impl->sourceRefByDict.find(kv.first); + if (it != m_impl->sourceRefByDict.end()) + { + m_impl->sourceRefByDict.insert({kv.first,kv.second}); + } + } + } } + void DefinitionImpl::setReference(const char *r) { m_impl->ref=r; diff --git a/src/definition.h b/src/definition.h index 8ad15b2..b3d7853 100644 --- a/src/definition.h +++ b/src/definition.h @@ -272,8 +272,8 @@ class Definition : public DefinitionIntf virtual Definition *findInnerCompound(const char *name) const = 0; virtual Definition *getOuterScope() const = 0; - virtual MemberSDict *getReferencesMembers() const = 0; - virtual MemberSDict *getReferencedByMembers() const = 0; + virtual std::vector<const MemberDef *> getReferencesMembers() const = 0; + virtual std::vector<const MemberDef *> getReferencedByMembers() const = 0; virtual bool hasSections() const = 0; virtual bool hasSources() const = 0; @@ -347,6 +347,9 @@ class Definition : public DefinitionIntf virtual void mergeRefItems(Definition *d) = 0; virtual void addInnerCompound(const Definition *d) = 0; virtual void addSectionsToIndex() = 0; + virtual void mergeReferences(const Definition *other) = 0; + virtual void mergeReferencedBy(const Definition *other) = 0; + virtual void computeTooltip() = 0; //----------------------------------------------------------------------------------- // --- writing output ---- diff --git a/src/definitionimpl.h b/src/definitionimpl.h index e91d989..c4e6e2a 100644 --- a/src/definitionimpl.h +++ b/src/definitionimpl.h @@ -18,6 +18,9 @@ #ifndef DEFINITIONIMPL_H #define DEFINITIONIMPL_H +#include <unordered_map> +#include <string> + #include "definition.h" class DefinitionImpl : virtual public Definition @@ -71,8 +74,8 @@ class DefinitionImpl : virtual public Definition virtual const RefItemVector &xrefListItems() const; virtual Definition *findInnerCompound(const char *name) const; virtual Definition *getOuterScope() const; - virtual MemberSDict *getReferencesMembers() const; - virtual MemberSDict *getReferencedByMembers() const; + virtual std::vector<const MemberDef *> getReferencesMembers() const; + virtual std::vector<const MemberDef *> getReferencedByMembers() const; virtual bool hasSections() const; virtual bool hasSources() const; virtual bool hasBriefDescription() const; @@ -92,6 +95,8 @@ class DefinitionImpl : virtual public Definition virtual void addSourceReferences(const MemberDef *d); virtual void setRefItems(const RefItemVector &sli); virtual void mergeRefItems(Definition *d); + virtual void mergeReferences(const Definition *other); + virtual void mergeReferencedBy(const Definition *other); virtual void addInnerCompound(const Definition *d); virtual void setOuterScope(Definition *d); virtual void setHidden(bool b); @@ -113,6 +118,7 @@ class DefinitionImpl : virtual public Definition virtual void writeToc(OutputList &ol, const LocalToc <) const; virtual void setCookie(Cookie *cookie) const; virtual Cookie *cookie() const; + virtual void computeTooltip(); protected: @@ -123,8 +129,8 @@ class DefinitionImpl : virtual public Definition virtual QCString _symbolName() const ; int _getXRefListId(const char *listName) const; - void _writeSourceRefList(OutputList &ol,const char *scopeName, - const QCString &text,MemberSDict *members,bool) const; + void _writeSourceRefList(OutputList &ol,const char *scopeName,const QCString &text, + const std::unordered_map<std::string,const MemberDef *> &members,bool) const; void _setBriefDescription(const char *b,const char *briefFile,int briefLine); void _setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace,bool atTop); void _setInbodyDocumentation(const char *d,const char *docFile,int docLine); @@ -222,9 +228,9 @@ class DefinitionAliasImpl : virtual public Definition { return m_def->findInnerCompound(name); } virtual Definition *getOuterScope() const { return const_cast<Definition*>(m_scope); } - virtual MemberSDict *getReferencesMembers() const + virtual std::vector<const MemberDef *> getReferencesMembers() const { return m_def->getReferencesMembers(); } - virtual MemberSDict *getReferencedByMembers() const + virtual std::vector<const MemberDef *> getReferencedByMembers() const { return m_def->getReferencedByMembers(); } virtual bool hasSections() const { return m_def->hasSections(); } @@ -254,6 +260,8 @@ class DefinitionAliasImpl : virtual public Definition virtual void addSourceReferences(const MemberDef *) {} virtual void setRefItems(const RefItemVector &) {} virtual void mergeRefItems(Definition *) {} + virtual void mergeReferences(const Definition *) {} + virtual void mergeReferencedBy(const Definition *) {} virtual void addInnerCompound(const Definition *) {} virtual void setOuterScope(Definition *) {} virtual void setHidden(bool) {} @@ -273,6 +281,7 @@ class DefinitionAliasImpl : virtual public Definition virtual void writeToc(OutputList &, const LocalToc &) const {} virtual void setCookie(Cookie *cookie) const { delete m_cookie; m_cookie = cookie; } virtual Cookie *cookie() const { return m_cookie; } + virtual void computeTooltip() {} protected: const Definition *getAlias() const { return m_def; } const Definition *getScope() const { return m_scope; } diff --git a/src/doctokenizer.l b/src/doctokenizer.l index 1774788..5b72b77 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -568,7 +568,6 @@ RCSID "$"("Author"|"Date"|"Header"|"Id"|"Locker"|"Log"|"Name"|"RCSfile"|"Revisio } } <St_Para>{BLANK}*(\n|"\\ilinebr"){OLISTITEM} { /* list item on next line */ - lineCount(yytext,yyleng); if (!g_markdownSupport || g_insidePre) { REJECT; diff --git a/src/dotcallgraph.cpp b/src/dotcallgraph.cpp index 5e13f8e..ef89627 100644 --- a/src/dotcallgraph.cpp +++ b/src/dotcallgraph.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * -* Copyright (C) 1997-2019 by Dimitri van Heesch. +* Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby @@ -34,51 +34,45 @@ static QCString getUniqueId(const MemberDef *md) void DotCallGraph::buildGraph(DotNode *n,const MemberDef *md,int distance) { - MemberSDict *refs = m_inverse ? md->getReferencedByMembers() : md->getReferencesMembers(); - if (refs) + auto refs = m_inverse ? md->getReferencedByMembers() : md->getReferencesMembers(); + for (const auto &rmd : refs) { - refs->sort(); - MemberSDict::Iterator mri(*refs); - MemberDef *rmd; - for (;(rmd=mri.current());++mri) + if (rmd->showInCallGraph()) { - if (rmd->showInCallGraph()) + QCString uniqueId = getUniqueId(rmd); + DotNode *bn = m_usedNodes->find(uniqueId); + if (bn) // file is already a node in the graph { - QCString uniqueId = getUniqueId(rmd); - DotNode *bn = m_usedNodes->find(uniqueId); - if (bn) // file is already a node in the graph + n->addChild(bn,0,0,0); + bn->addParent(n); + bn->setDistance(distance); + } + else + { + QCString name; + if (HIDE_SCOPE_NAMES) { - n->addChild(bn,0,0,0); - bn->addParent(n); - bn->setDistance(distance); + name = rmd->getOuterScope()==m_scope ? + rmd->name() : rmd->qualifiedName(); } else { - QCString name; - if (HIDE_SCOPE_NAMES) - { - name = rmd->getOuterScope()==m_scope ? - rmd->name() : rmd->qualifiedName(); - } - else - { - name = rmd->qualifiedName(); - } - QCString tooltip = rmd->briefDescriptionAsTooltip(); - bn = new DotNode( + name = rmd->qualifiedName(); + } + QCString tooltip = rmd->briefDescriptionAsTooltip(); + bn = new DotNode( getNextNodeNumber(), linkToText(rmd->getLanguage(),name,FALSE), tooltip, uniqueId, 0 //distance - ); - n->addChild(bn,0,0,0); - bn->addParent(n); - bn->setDistance(distance); - m_usedNodes->insert(uniqueId,bn); + ); + n->addChild(bn,0,0,0); + bn->addParent(n); + bn->setDistance(distance); + m_usedNodes->insert(uniqueId,bn); - buildGraph(bn,rmd,distance+1); - } + buildGraph(bn,rmd,distance+1); } } } @@ -121,9 +115,9 @@ void DotCallGraph::determineTruncatedNodes(QList<DotNode> &queue) const DotNode *dn; for (li.toFirst();(dn=li.current());++li) { - if (!dn->isVisible()) + if (!dn->isVisible()) truncated = TRUE; - else + else queue.append(dn); } } @@ -198,7 +192,7 @@ QCString DotCallGraph::getMapLabel() const } QCString DotCallGraph::writeGraph( - FTextStream &out, + FTextStream &out, GraphOutputFormat graphFormat, EmbeddedOutputFormat textFormat, const char *path, diff --git a/src/dotgraph.cpp b/src/dotgraph.cpp index 1ad85e1..287793e 100644 --- a/src/dotgraph.cpp +++ b/src/dotgraph.cpp @@ -239,7 +239,7 @@ void DotGraph::generateCode(FTextStream &t) t << "<img src=\"" << relImgName() << "\" border=\"0\" usemap=\"#" << correctId(getMapLabel()) << "\" alt=\"" << getImgAltText() << "\"/>"; if (!m_noDivTag) t << "</div>"; t << endl; - if (m_regenerate || !insertMapFile(t, absMapName(), m_relPath, getMapLabel())) + if (m_regenerate || !insertMapFile(t, absMapName(), m_relPath, correctId(getMapLabel()))) { int mapId = DotManager::instance()-> createFilePatcher(m_fileName.data())-> diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 73c4b02..1a70e61 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -3709,59 +3709,10 @@ static void transferFunctionReferences() ) ) /* match found */ { - MemberSDict *defDict = mdef->getReferencesMembers(); - MemberSDict *decDict = mdec->getReferencesMembers(); - if (defDict!=0) - { - MemberSDict::IteratorDict msdi(*defDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) - { - if (decDict==0 || decDict->find(rmd->name())==0) - { - mdec->addSourceReferences(rmd); - } - } - } - if (decDict!=0) - { - MemberSDict::IteratorDict msdi(*decDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) - { - if (defDict==0 || defDict->find(rmd->name())==0) - { - mdef->addSourceReferences(rmd); - } - } - } - - defDict = mdef->getReferencedByMembers(); - decDict = mdec->getReferencedByMembers(); - if (defDict!=0) - { - MemberSDict::IteratorDict msdi(*defDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) - { - if (decDict==0 || decDict->find(rmd->name())==0) - { - mdec->addSourceReferencedBy(rmd); - } - } - } - if (decDict!=0) - { - MemberSDict::IteratorDict msdi(*decDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) - { - if (defDict==0 || defDict->find(rmd->name())==0) - { - mdef->addSourceReferencedBy(rmd); - } - } - } + mdef->mergeReferences(mdec); + mdec->mergeReferences(mdef); + mdef->mergeReferencedBy(mdec); + mdec->mergeReferencedBy(mdef); } } } @@ -4111,7 +4062,7 @@ static bool findTemplateInstanceRelation(const Entry *root, //printf("\n"); bool existingClass = (templSpec == - tempArgListToString(templateClass->templateArguments(),root->lang) + tempArgListToString(templateClass->templateArguments(),root->lang,false) ); if (existingClass) return TRUE; @@ -4382,7 +4333,7 @@ static bool findClassRelation( // instance (for instance if a class // derived from a template argument) { - //printf("baseClass=%p templSpec=%s\n",baseClass,templSpec.data()); + //printf("baseClass=%s templSpec=%s\n",baseClass->name().data(),templSpec.data()); ClassDef *templClass=getClass(baseClass->name()+templSpec); if (templClass) { @@ -4469,7 +4420,7 @@ static bool findClassRelation( if (baseClassTypeDef==0) { //printf(" => findTemplateInstanceRelation: %p\n",baseClassTypeDef); - findTemplateInstanceRelation(root,context,baseClass,templSpec,templateNames,isArtificial); + findTemplateInstanceRelation(root,context,baseClass,templSpec,templateNames,baseClass->isArtificial()); } } else if (mode==DocumentedOnly || mode==Undocumented) @@ -7352,14 +7303,13 @@ static void computeMemberRelations() { const ClassDef *bmcd = bmd->getClassDef(); //printf("Check relation between '%s'::'%s' (%p) and '%s'::'%s' (%p)\n", - // mcd->name().data(),md->name().data(),md, - // bmcd->name().data(),bmd->name().data(),bmd + // mcd->name().data(),md->name().data(),md.get(), + // bmcd->name().data(),bmd->name().data(),bmd.get() // ); if (bmcd && mcd && bmcd!=mcd && - (bmd->virtualness()!=Normal || bmd->getLanguage()==SrcLangExt_Python || - bmd->getLanguage()==SrcLangExt_Java || bmd->getLanguage()==SrcLangExt_PHP || - bmcd->compoundType()==ClassDef::Interface || - bmcd->compoundType()==ClassDef::Protocol + (bmd->virtualness()!=Normal || + bmd->getLanguage()==SrcLangExt_Python || bmd->getLanguage()==SrcLangExt_Java || bmd->getLanguage()==SrcLangExt_PHP || + bmcd->compoundType()==ClassDef::Interface || bmcd->compoundType()==ClassDef::Protocol ) && md->isFunction() && mcd->isLinkable() && @@ -7370,8 +7320,8 @@ static void computeMemberRelations() const ArgumentList &bmdAl = bmd->argumentList(); const ArgumentList &mdAl = md->argumentList(); //printf(" Base argList='%s'\n Super argList='%s'\n", - // argListToString(bmdAl.pointer()).data(), - // argListToString(mdAl.pointer()).data() + // argListToString(bmdAl).data(), + // argListToString(mdAl).data() // ); if ( matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),&bmdAl, @@ -7380,6 +7330,7 @@ static void computeMemberRelations() ) ) { + //printf("match!\n"); MemberDef *rmd; if ((rmd=md->reimplements())==0 || minClassDistance(mcd,bmcd)<minClassDistance(mcd,rmd->getClassDef()) @@ -7391,6 +7342,10 @@ static void computeMemberRelations() //printf("%s: add reimplementedBy member %s\n",bmcd->name().data(),mcd->name().data()); bmd->insertReimplementedBy(md.get()); } + else + { + //printf("no match!\n"); + } } } } @@ -7647,7 +7602,6 @@ static void generateFileSources() results.emplace_back(threadPool.queue(processFile)); } } - // first wait until all files are processed for (auto &f : results) { auto ctx = f.get(); @@ -7856,6 +7810,32 @@ static void sortMemberLists() //---------------------------------------------------------------------------- +void computeTooltipTexts() +{ + QDictIterator<DefinitionIntf> di(*Doxygen::symbolMap); + DefinitionIntf *intf; + for (;(intf=di.current());++di) + { + if (intf->definitionType()==DefinitionIntf::TypeSymbolList) // list of symbols + { + DefinitionListIterator dli(*(DefinitionList*)intf); + Definition *d; + // for each symbol + for (dli.toFirst();(d=dli.current());++dli) + { + d->computeTooltip(); + } + } + else // single symbol + { + Definition *d = (Definition *)intf; + if (d!=Doxygen::globalScope) d->computeTooltip(); + } + } +} + +//---------------------------------------------------------------------------- + static void setAnonymousEnumType() { ClassSDict::Iterator cli(*Doxygen::classSDict); @@ -7947,7 +7927,8 @@ static void inheritDocumentation() { for (const auto &md : *mn) { - //printf("%04d Member '%s'\n",count++,md->name().data()); + //static int count=0; + //printf("%04d Member '%s'\n",count++,md->qualifiedName().data()); if (md->documentation().isEmpty() && md->briefDescription().isEmpty()) { // no documentation yet MemberDef *bmd = md->reimplements(); @@ -10528,7 +10509,7 @@ void adjustConfiguration() } else { - msg("Adding custom extension mapping: .%s will be treated as language %s\n", + msg("Adding custom extension mapping: '%s' will be treated as language '%s'\n", ext.data(),language.data()); } } @@ -11438,6 +11419,10 @@ void parseInput() vhdlCorrectMemberProperties(); g_s.end(); + g_s.begin("Computing tooltip texts...\n"); + computeTooltipTexts(); + g_s.end(); + if (Config_getBool(SORT_GROUP_NAMES)) { Doxygen::groupSDict->sort(); diff --git a/src/formula.cpp b/src/formula.cpp index ca50c9c..8ba9729 100644 --- a/src/formula.cpp +++ b/src/formula.cpp @@ -148,7 +148,7 @@ void FormulaManager::generateImages(const char *path,Format format,HighDPI hd) c // store the original directory if (!d.exists()) { - term("Output dir %s does not exist!\n",path); + term("Output directory '%s' does not exist!\n",path); } QCString oldDir = QDir::currentDirPath().utf8(); QCString macroFile = Config_getString(FORMULA_MACROFILE); @@ -167,7 +167,6 @@ void FormulaManager::generateImages(const char *path,Format format,HighDPI hd) c QCString texName="_formulas.tex"; IntVector formulasToGenerate; QFile f(texName); - bool formulaError=FALSE; if (f.open(IO_WriteOnly)) { FTextStream t(&f); @@ -214,8 +213,9 @@ void FormulaManager::generateImages(const char *path,Format format,HighDPI hd) c { err("Problems running latex. Check your installation or look " "for typos in _formulas.tex and check _formulas.log!\n"); - formulaError=TRUE; - //return; + Portable::sysTimerStop(); + QDir::setCurrent(oldDir); + return; } Portable::sysTimerStop(); //printf("Running dvips...\n"); @@ -439,12 +439,12 @@ void FormulaManager::generateImages(const char *path,Format format,HighDPI hd) c if (RM_TMP_FILES) { thisDir.remove("_formulas.dvi"); - if (!formulaError) thisDir.remove("_formulas.log"); // keep file in case of errors + thisDir.remove("_formulas.log"); // keep file in case of errors thisDir.remove("_formulas.aux"); } } // remove the latex file itself - if (RM_TMP_FILES && !formulaError) thisDir.remove("_formulas.tex"); + if (RM_TMP_FILES) thisDir.remove("_formulas.tex"); // write/update the formula repository so we know what text the // generated images represent (we use this next time to avoid regeneration diff --git a/src/fortrancode.l b/src/fortrancode.l index f2b0ee8..6b278cc 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -172,6 +172,7 @@ struct fortrancodeYY_state int inTypeDecl = 0; bool endComment = false; + TooltipManager tooltipManager; }; #if USE_STATE2STRING @@ -1012,7 +1013,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); - TooltipManager::instance()->addTooltip(d); + yyextra->tooltipManager.addTooltip(d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); @@ -1514,6 +1515,10 @@ void FortranCodeParser::parseCode(CodeOutputInterface & codeOutIntf, } if (yyextra->hasContLine) free(yyextra->hasContLine); yyextra->hasContLine = NULL; + + // write the tooltips + yyextra->tooltipManager.writeTooltips(codeOutIntf); + printlex(yy_flex_debug, FALSE, __FILE__, fileDef ? fileDef->fileName().data(): NULL); } diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp index 6fc14bf..b34f644 100644 --- a/src/ftvhelp.cpp +++ b/src/ftvhelp.cpp @@ -167,7 +167,7 @@ void FTVHelp::finalize() */ void FTVHelp::incContentsDepth() { - //printf("incContentsDepth() indent=%d\n",m_indent); + //printf("%p: incContentsDepth() indent=%d\n",this,m_indent); m_indent++; ASSERT(m_indent<MAX_INDENT); } @@ -178,7 +178,7 @@ void FTVHelp::incContentsDepth() */ void FTVHelp::decContentsDepth() { - //printf("decContentsDepth() indent=%d\n",m_indent); + //printf("%p: decContentsDepth() indent=%d\n",this,m_indent); ASSERT(m_indent>0); if (m_indent>0) { diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index ea4d895..e1358a7 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -1231,9 +1231,6 @@ void HtmlGenerator::writePageFooter(FTextStream &t,const QCString &lastTitle, void HtmlGenerator::writeFooter(const char *navPath) { - // Currently only tooltips in HTML - TooltipManager::instance()->writeTooltips(m_codeGen); - writePageFooter(t,m_lastTitle,m_relPath,navPath); } diff --git a/src/index.cpp b/src/index.cpp index e46a578..c4fda05 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -307,7 +307,6 @@ void endFile(OutputList &ol,bool skipNavIndex,bool skipEndContents, ol.writeFooter(navPath); // write the footer ol.popGeneratorState(); ol.endFile(); - TooltipManager::instance()->clearTooltips(); // Only clear after the last is written } void endFileWithNavPath(const Definition *d,OutputList &ol) @@ -326,6 +325,66 @@ void endFileWithNavPath(const Definition *d,OutputList &ol) } //---------------------------------------------------------------------- + +static bool memberVisibleInIndex(const MemberDef *md) +{ + bool isAnonymous = md->isAnonymous(); + bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); + bool extractStatic = Config_getBool(EXTRACT_STATIC); + return (!isAnonymous && + (!hideUndocMembers || md->hasDocumentation()) && + (!md->isStatic() || extractStatic) + ); +} + +static void writeMemberToIndex(const Definition *def,const MemberDef *md,bool addToIndex) +{ + bool isAnonymous = md->isAnonymous(); + bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); + const MemberList *enumList = md->enumFieldList(); + bool isDir = enumList!=0 && md->isEnumerate(); + if (md->getOuterScope()==def || md->getOuterScope()==Doxygen::globalScope) + { + Doxygen::indexList->addContentsItem(isDir, + md->name(),md->getReference(),md->getOutputFileBase(),md->anchor(),FALSE,addToIndex); + } + else // inherited member + { + Doxygen::indexList->addContentsItem(isDir, + md->name(),def->getReference(),def->getOutputFileBase(),md->anchor(),FALSE,addToIndex); + } + if (isDir) + { + if (!isAnonymous) + { + Doxygen::indexList->incContentsDepth(); + } + MemberListIterator emli(*enumList); + MemberDef *emd; + for (emli.toFirst();(emd=emli.current());++emli) + { + if (!hideUndocMembers || emd->hasDocumentation()) + { + if (emd->getOuterScope()==def || emd->getOuterScope()==Doxygen::globalScope) + { + Doxygen::indexList->addContentsItem(FALSE, + emd->name(),emd->getReference(),emd->getOutputFileBase(),emd->anchor(),FALSE,addToIndex); + } + else // inherited member + { + Doxygen::indexList->addContentsItem(FALSE, + emd->name(),def->getReference(),def->getOutputFileBase(),emd->anchor(),FALSE,addToIndex); + } + } + } + if (!isAnonymous) + { + Doxygen::indexList->decContentsDepth(); + } + } +} + +//---------------------------------------------------------------------- template<class T> void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, const QCString &name,const QCString &anchor, @@ -366,55 +425,9 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, MemberDef *md; for (mi.toFirst();(md=mi.current());++mi) { - const MemberList *enumList = md->enumFieldList(); - bool isDir = enumList!=0 && md->isEnumerate(); - bool isAnonymous = md->isAnonymous(); - static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); - static bool extractStatic = Config_getBool(EXTRACT_STATIC); - if (!isAnonymous && - (!hideUndocMembers || md->hasDocumentation()) && - (!md->isStatic() || extractStatic) - ) + if (memberVisibleInIndex(md)) { - if (md->getOuterScope()==def || md->getOuterScope()==Doxygen::globalScope) - { - Doxygen::indexList->addContentsItem(isDir, - md->name(),md->getReference(),md->getOutputFileBase(),md->anchor(),FALSE,addToIndex); - } - else // inherited member - { - Doxygen::indexList->addContentsItem(isDir, - md->name(),def->getReference(),def->getOutputFileBase(),md->anchor(),FALSE,addToIndex); - } - } - if (isDir) - { - if (!isAnonymous) - { - Doxygen::indexList->incContentsDepth(); - } - MemberListIterator emli(*enumList); - MemberDef *emd; - for (emli.toFirst();(emd=emli.current());++emli) - { - if (!hideUndocMembers || emd->hasDocumentation()) - { - if (emd->getOuterScope()==def || emd->getOuterScope()==Doxygen::globalScope) - { - Doxygen::indexList->addContentsItem(FALSE, - emd->name(),emd->getReference(),emd->getOutputFileBase(),emd->anchor(),FALSE,addToIndex); - } - else // inherited member - { - Doxygen::indexList->addContentsItem(FALSE, - emd->name(),def->getReference(),def->getOutputFileBase(),emd->anchor(),FALSE,addToIndex); - } - } - } - if (!isAnonymous) - { - Doxygen::indexList->decContentsDepth(); - } + writeMemberToIndex(def,md,addToIndex); } } } @@ -451,7 +464,7 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, //---------------------------------------------------------------------------- /*! Generates HTML Help tree of classes */ -static void writeClassTree(OutputList &ol,BaseClassList bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex) +static void writeClassTree(OutputList &ol,const BaseClassList &bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex) { if (bcl.empty()) return; bool started=FALSE; @@ -1554,7 +1567,7 @@ static int countNamespaces() //---------------------------------------------------------------------------- -void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly,ClassDef::CompoundType ct) +static void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly,ClassDef::CompoundType ct) { static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); if (clDict) @@ -1605,9 +1618,7 @@ void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalO { ftv->addContentsItem(count>0,cd->displayName(FALSE),cd->getReference(), cd->getOutputFileBase(),cd->anchor(),FALSE,TRUE,cd); - if (addToIndex && - /*cd->partOfGroups()==0 &&*/ - (cd->getOuterScope()==0 || + if ((cd->getOuterScope()==0 || cd->getOuterScope()->definitionType()!=Definition::TypeClass ) ) @@ -1615,7 +1626,7 @@ void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalO addMembersToIndex(cd,LayoutDocManager::Class, cd->displayName(FALSE), cd->anchor(), - cd->partOfGroups()==0 && !cd->isSimple()); + addToIndex && cd->partOfGroups()==0 && !cd->isSimple()); } if (count>0) { @@ -1629,10 +1640,64 @@ void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalO } } +static int countVisibleMembers(const NamespaceDef *nd) +{ + int count=0; + QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace)); + LayoutDocEntry *lde; + for (eli.toFirst();(lde=eli.current());++eli) + { + if (lde->kind()==LayoutDocEntry::MemberDef) + { + LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; + MemberList *ml = nd->getMemberList(lmd->type); + if (ml) + { + MemberListIterator mi(*ml); + MemberDef *md; + for (mi.toFirst();(md=mi.current());++mi) + { + if (memberVisibleInIndex(md)) + { + count++; + } + } + } + } + } + return count; +} + +static void writeNamespaceMembers(const NamespaceDef *nd,bool addToIndex) +{ + QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace)); + LayoutDocEntry *lde; + for (eli.toFirst();(lde=eli.current());++eli) + { + if (lde->kind()==LayoutDocEntry::MemberDef) + { + LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; + MemberList *ml = nd->getMemberList(lmd->type); + if (ml) + { + MemberListIterator mi(*ml); + MemberDef *md; + for (mi.toFirst();(md=mi.current());++mi) + { + //printf(" member %s visible=%d\n",md->name().data(),memberVisibleInIndex(md)); + if (memberVisibleInIndex(md)) + { + writeMemberToIndex(nd,md,addToIndex); + } + } + } + } + } +} + static void writeNamespaceTree(const NamespaceSDict *nsDict,FTVHelp *ftv, - bool rootOnly,bool showClasses,bool addToIndex,ClassDef::CompoundType ct) + bool rootOnly,bool addToIndex) { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); if (nsDict) { NamespaceSDict::Iterator nli(*nsDict); @@ -1643,8 +1708,12 @@ static void writeNamespaceTree(const NamespaceSDict *nsDict,FTVHelp *ftv, (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) { - bool hasChildren = namespaceHasVisibleChild(nd,showClasses,sliceOpt,ct); + bool hasChildren = namespaceHasNestedNamespace(nd) || + namespaceHasNestedClass(nd,false,ClassDef::Class); bool isLinkable = nd->isLinkableInProject(); + int visibleMembers = countVisibleMembers(nd); + + //printf("namespace %s hasChildren=%d visibleMembers=%d\n",nd->name().data(),hasChildren,visibleMembers); QCString ref; QCString file; @@ -1658,45 +1727,114 @@ static void writeNamespaceTree(const NamespaceSDict *nsDict,FTVHelp *ftv, } } - if ((isLinkable && !showClasses) || hasChildren) + bool isDir = hasChildren || visibleMembers>0; + if ((isLinkable) || isDir) { ftv->addContentsItem(hasChildren,nd->localName(),ref,file,0,FALSE,TRUE,nd); if (addToIndex) { - Doxygen::indexList->addContentsItem(hasChildren,nd->localName(),ref,file,QCString(), + Doxygen::indexList->addContentsItem(isDir,nd->localName(),ref,file,QCString(), hasChildren && !file.isEmpty(),addToIndex); } + if (addToIndex && isDir) + { + Doxygen::indexList->incContentsDepth(); + } - //printf("*** writeNamespaceTree count=%d addToIndex=%d showClasses=%d classCount=%d\n", - // count,addToIndex,showClasses,classCount); - if (hasChildren) + //printf("*** writeNamespaceTree count=%d addToIndex=%d false=%d classCount=%d\n", + // count,addToIndex,false,classCount); + if (isDir) { - if (addToIndex) Doxygen::indexList->incContentsDepth(); ftv->incContentsDepth(); - writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,showClasses,addToIndex,ct); - if (showClasses) + writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,addToIndex); + writeClassTree(nd->getClassSDict(),ftv,FALSE,FALSE,ClassDef::Class); + writeNamespaceMembers(nd,addToIndex); + ftv->decContentsDepth(); + } + if (addToIndex && isDir) + { + Doxygen::indexList->decContentsDepth(); + } + } + } + } + } +} + +static void writeClassTreeInsideNamespace(const NamespaceSDict *nsDict,FTVHelp *ftv, + bool rootOnly,bool addToIndex,ClassDef::CompoundType ct) +{ + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + if (nsDict) + { + NamespaceSDict::Iterator nli(*nsDict); + const NamespaceDef *nd; + for (nli.toFirst();(nd=nli.current());++nli) + { + if (!nd->isAnonymous() && + (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) + { + bool isDir = namespaceHasNestedClass(nd,sliceOpt,ct); + bool isLinkable = nd->isLinkableInProject(); + + //printf("namespace %s isDir=%d\n",nd->name().data(),isDir); + + QCString ref; + QCString file; + if (isLinkable) + { + ref = nd->getReference(); + file = nd->getOutputFileBase(); + if (nd->getLanguage()==SrcLangExt_VHDL) // UGLY HACK + { + file=file.replace(0,qstrlen("namespace"),"class"); + } + } + + if (isDir) + { + ftv->addContentsItem(isDir,nd->localName(),ref,file,0,FALSE,TRUE,nd); + + if (addToIndex) + { + // the namespace entry is already shown under the namespace list so don't + // add it to the nav index and don't create a separate index file for it otherwise + // it will overwrite the one written for the namespace list. + Doxygen::indexList->addContentsItem(isDir,nd->localName(),ref,file,QCString(), + false, // separateIndex + false // addToNavIndex + ); + } + if (addToIndex) + { + Doxygen::indexList->incContentsDepth(); + } + + ftv->incContentsDepth(); + writeClassTreeInsideNamespace(nd->getNamespaceSDict(),ftv,FALSE,addToIndex,ct); + ClassSDict *d = nd->getClassSDict(); + if (sliceOpt) + { + if (ct == ClassDef::Interface) { - ClassSDict *d = nd->getClassSDict(); - if (sliceOpt) - { - if (ct == ClassDef::Interface) - { - d = nd->getInterfaceSDict(); - } - else if (ct == ClassDef::Struct) - { - d = nd->getStructSDict(); - } - else if (ct == ClassDef::Exception) - { - d = nd->getExceptionSDict(); - } - } - writeClassTree(d,ftv,addToIndex,FALSE,ct); + d = nd->getInterfaceSDict(); + } + else if (ct == ClassDef::Struct) + { + d = nd->getStructSDict(); + } + else if (ct == ClassDef::Exception) + { + d = nd->getExceptionSDict(); } - ftv->decContentsDepth(); - if (addToIndex) Doxygen::indexList->decContentsDepth(); + } + writeClassTree(d,ftv,addToIndex,FALSE,ct); + ftv->decContentsDepth(); + + if (addToIndex) + { + Doxygen::indexList->decContentsDepth(); } } } @@ -1794,7 +1932,7 @@ static void writeNamespaceIndex(OutputList &ol) Doxygen::indexList->incContentsDepth(); } FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,FALSE,addToIndex,ClassDef::Class); + writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,addToIndex); QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); @@ -2424,26 +2562,50 @@ static void writeAlphabeticalExceptionIndex(OutputList &ol) //---------------------------------------------------------------------------- -static void writeAnnotatedIndex(OutputList &ol) +struct AnnotatedIndexContext +{ + AnnotatedIndexContext(int numAnno,int numPrint, + LayoutNavEntry::Kind lk,LayoutNavEntry::Kind fk, + const QCString &title,const QCString &intro, + ClassDef::CompoundType ct, + const QCString &fn, + HighlightedItem hi) : + numAnnotated(numAnno), numPrinted(numPrint), + listKind(lk), fallbackKind(fk), + listDefaultTitleText(title), listDefaultIntroText(intro), + compoundType(ct),fileBaseName(fn), + hiItem(hi) { } + + const int numAnnotated; + const int numPrinted; + const LayoutNavEntry::Kind listKind; + const LayoutNavEntry::Kind fallbackKind; + const QCString listDefaultTitleText; + const QCString listDefaultIntroText; + const ClassDef::CompoundType compoundType; + const QCString fileBaseName; + const HighlightedItem hiItem; +}; + +static void writeAnnotatedIndexGeneric(OutputList &ol,const AnnotatedIndexContext ctx) { //printf("writeAnnotatedIndex: count=%d printed=%d\n", // annotatedClasses,annotatedClassesPrinted); - if (annotatedClasses==0) return; + if (ctx.numAnnotated==0) return; ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); - if (annotatedClassesPrinted==0) + if (ctx.numPrinted==0) { ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); } - LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList); - if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes); // fall back - QCString title = lne ? lne->title() : theTranslator->trCompoundList(); + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(ctx.listKind); + if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(ctx.fallbackKind); // fall back + QCString title = lne ? lne->title() : ctx.listDefaultTitleText; bool addToIndex = lne==0 || lne->visible(); - - startFile(ol,"annotated",0,title,HLI_AnnotatedClasses); + startFile(ol,ctx.fileBaseName,0,title,ctx.hiItem); startTitle(ol,0); ol.parseText(title); @@ -2452,7 +2614,7 @@ static void writeAnnotatedIndex(OutputList &ol) ol.startContents(); ol.startTextBlock(); - ol.parseText(lne ? lne->intro() : theTranslator->trCompoundListDescription()); + ol.parseText(lne ? lne->intro() : ctx.listDefaultIntroText); ol.endTextBlock(); // --------------- @@ -2462,7 +2624,7 @@ static void writeAnnotatedIndex(OutputList &ol) ol.disable(OutputGenerator::Html); Doxygen::indexList->disable(); - writeAnnotatedClassList(ol, ClassDef::Class); + writeAnnotatedClassList(ol, ctx.compoundType); Doxygen::indexList->enable(); ol.popGeneratorState(); @@ -2476,17 +2638,16 @@ static void writeAnnotatedIndex(OutputList &ol) { if (addToIndex) { - Doxygen::indexList->addContentsItem(TRUE,title,0,"annotated",0,TRUE,TRUE); + Doxygen::indexList->addContentsItem(TRUE,title,0,ctx.fileBaseName,0,TRUE,TRUE); Doxygen::indexList->incContentsDepth(); } - FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Class); - writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Class); + FTVHelp ftv(false); + writeClassTreeInsideNamespace(Doxygen::namespaceSDict,&ftv,TRUE,addToIndex,ctx.compoundType); + writeClassTree(Doxygen::classSDict,&ftv,addToIndex,TRUE,ctx.compoundType); QGString outStr; FTextStream t(&outStr); - ftv->generateTreeViewInline(t); + ftv.generateTreeViewInline(t); ol.writeString(outStr); - delete ftv; if (addToIndex) { Doxygen::indexList->decContentsDepth(); @@ -2502,233 +2663,58 @@ static void writeAnnotatedIndex(OutputList &ol) //---------------------------------------------------------------------------- -static void writeAnnotatedInterfaceIndex(OutputList &ol) +static void writeAnnotatedIndex(OutputList &ol) { - //printf("writeAnnotatedInterfaceIndex: count=%d printed=%d\n", - // annotatedInterfaces,annotatedInterfacesPrinted); - if (annotatedInterfaces==0) return; + writeAnnotatedIndexGeneric(ol, + AnnotatedIndexContext(annotatedClasses,annotatedClassesPrinted, + LayoutNavEntry::ClassList,LayoutNavEntry::Classes, + theTranslator->trCompoundList(),theTranslator->trCompoundListDescription(), + ClassDef::Class, + "annotated", + HLI_AnnotatedClasses)); - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Man); - if (annotatedInterfacesPrinted==0) - { - ol.disable(OutputGenerator::Latex); - ol.disable(OutputGenerator::RTF); - } - LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::InterfaceList); - if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Interfaces); // fall back - QCString title = lne ? lne->title() : theTranslator->trInterfaceList(); - bool addToIndex = lne==0 || lne->visible(); - - startFile(ol,"annotatedinterfaces",0,title,HLI_AnnotatedInterfaces); - - startTitle(ol,0); - ol.parseText(title); - endTitle(ol,0,0); - - ol.startContents(); - - ol.startTextBlock(); - ol.parseText(lne ? lne->intro() : theTranslator->trInterfaceListDescription()); - ol.endTextBlock(); - - // --------------- - // Linear interface index for Latex/RTF - // --------------- - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Html); - Doxygen::indexList->disable(); - - writeAnnotatedClassList(ol, ClassDef::Interface); - - Doxygen::indexList->enable(); - ol.popGeneratorState(); - - // --------------- - // Hierarchical interface index for HTML - // --------------- - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::Html); +} - { - if (addToIndex) - { - Doxygen::indexList->addContentsItem(TRUE,title,0,"annotatedinterfaces",0,TRUE,TRUE); - Doxygen::indexList->incContentsDepth(); - } - FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Interface); - writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Interface); - QGString outStr; - FTextStream t(&outStr); - ftv->generateTreeViewInline(t); - ol.writeString(outStr); - delete ftv; - if (addToIndex) - { - Doxygen::indexList->decContentsDepth(); - } - } +//---------------------------------------------------------------------------- - ol.popGeneratorState(); - // ------ +static void writeAnnotatedInterfaceIndex(OutputList &ol) +{ + writeAnnotatedIndexGeneric(ol, + AnnotatedIndexContext(annotatedInterfaces,annotatedInterfacesPrinted, + LayoutNavEntry::InterfaceList,LayoutNavEntry::Interfaces, + theTranslator->trInterfaceList(),theTranslator->trInterfaceListDescription(), + ClassDef::Interface, + "annotatedinterfaces", + HLI_AnnotatedInterfaces)); - endFile(ol); // contains ol.endContents() - ol.popGeneratorState(); } //---------------------------------------------------------------------------- static void writeAnnotatedStructIndex(OutputList &ol) { - //printf("writeAnnotatedStructIndex: count=%d printed=%d\n", - // annotatedStructs,annotatedStructsPrinted); - if (annotatedStructs==0) return; - - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Man); - if (annotatedStructsPrinted==0) - { - ol.disable(OutputGenerator::Latex); - ol.disable(OutputGenerator::RTF); - } - LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::StructList); - if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Structs); // fall back - QCString title = lne ? lne->title() : theTranslator->trStructList(); - bool addToIndex = lne==0 || lne->visible(); - - startFile(ol,"annotatedstructs",0,title,HLI_AnnotatedStructs); - - startTitle(ol,0); - ol.parseText(title); - endTitle(ol,0,0); - - ol.startContents(); - - ol.startTextBlock(); - ol.parseText(lne ? lne->intro() : theTranslator->trStructListDescription()); - ol.endTextBlock(); - - // --------------- - // Linear struct index for Latex/RTF - // --------------- - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Html); - Doxygen::indexList->disable(); - - writeAnnotatedClassList(ol, ClassDef::Struct); - - Doxygen::indexList->enable(); - ol.popGeneratorState(); - - // --------------- - // Hierarchical struct index for HTML - // --------------- - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::Html); - - { - if (addToIndex) - { - Doxygen::indexList->addContentsItem(TRUE,title,0,"annotatedstructs",0,TRUE,TRUE); - Doxygen::indexList->incContentsDepth(); - } - FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Struct); - writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Struct); - QGString outStr; - FTextStream t(&outStr); - ftv->generateTreeViewInline(t); - ol.writeString(outStr); - delete ftv; - if (addToIndex) - { - Doxygen::indexList->decContentsDepth(); - } - } + writeAnnotatedIndexGeneric(ol, + AnnotatedIndexContext(annotatedStructs,annotatedStructsPrinted, + LayoutNavEntry::StructList,LayoutNavEntry::Structs, + theTranslator->trStructList(),theTranslator->trStructListDescription(), + ClassDef::Struct, + "annotatedstructs", + HLI_AnnotatedStructs)); - ol.popGeneratorState(); - // ------ - - endFile(ol); // contains ol.endContents() - ol.popGeneratorState(); } //---------------------------------------------------------------------------- static void writeAnnotatedExceptionIndex(OutputList &ol) { - //printf("writeAnnotatedExceptionIndex: count=%d printed=%d\n", - // annotatedExceptions,annotatedExceptionsPrinted); - if (annotatedExceptions==0) return; - - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Man); - if (annotatedExceptionsPrinted==0) - { - ol.disable(OutputGenerator::Latex); - ol.disable(OutputGenerator::RTF); - } - LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ExceptionList); - if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Exceptions); // fall back - QCString title = lne ? lne->title() : theTranslator->trExceptionList(); - bool addToIndex = lne==0 || lne->visible(); - - startFile(ol,"annotatedexceptions",0,title,HLI_AnnotatedExceptions); - - startTitle(ol,0); - ol.parseText(title); - endTitle(ol,0,0); - - ol.startContents(); - - ol.startTextBlock(); - ol.parseText(lne ? lne->intro() : theTranslator->trExceptionListDescription()); - ol.endTextBlock(); - - // --------------- - // Linear interface index for Latex/RTF - // --------------- - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Html); - Doxygen::indexList->disable(); - - writeAnnotatedClassList(ol, ClassDef::Exception); + writeAnnotatedIndexGeneric(ol, + AnnotatedIndexContext(annotatedExceptions,annotatedExceptionsPrinted, + LayoutNavEntry::ExceptionList,LayoutNavEntry::Exceptions, + theTranslator->trExceptionList(),theTranslator->trExceptionListDescription(), + ClassDef::Exception, + "annotatedexceptions", + HLI_AnnotatedExceptions)); - Doxygen::indexList->enable(); - ol.popGeneratorState(); - - // --------------- - // Hierarchical interface index for HTML - // --------------- - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::Html); - - { - if (addToIndex) - { - Doxygen::indexList->addContentsItem(TRUE,title,0,"annotatedexceptions",0,TRUE,TRUE); - Doxygen::indexList->incContentsDepth(); - } - FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Exception); - writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Exception); - QGString outStr; - FTextStream t(&outStr); - ftv->generateTreeViewInline(t); - ol.writeString(outStr); - delete ftv; - if (addToIndex) - { - Doxygen::indexList->decContentsDepth(); - } - } - - ol.popGeneratorState(); - // ------ - - endFile(ol); // contains ol.endContents() - ol.popGeneratorState(); } //---------------------------------------------------------------------------- diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 1d55dd6..418afa7 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -774,7 +774,8 @@ static void writeDefaultHeaderPart1(FTextStream &t) // End of preamble, now comes the document contents t << "%===== C O N T E N T S =====\n" "\n" - "\\begin{document}\n"; + "\\begin{document}\n" + "\\raggedbottom\n"; QCString documentPre = theTranslator->latexDocumentPre(); if (!documentPre.isEmpty()) { diff --git a/src/markdown.cpp b/src/markdown.cpp index 15e18bc..930efd6 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -808,6 +808,7 @@ int Markdown::processLink(const char *data,int,int size) } contentStart=i; int level=1; + int nlTotal=0; int nl=0; // find the matching ] while (i<size) @@ -831,6 +832,8 @@ int Markdown::processLink(const char *data,int,int size) } i++; } + nlTotal += nl; + nl = 0; if (i>=size) return 0; // premature end of comment -> no link contentEnd=i; convertStringFragment(content,data+contentStart,contentEnd-contentStart); @@ -843,9 +846,12 @@ int Markdown::processLink(const char *data,int,int size) if (i<size && data[i]=='\n') // one newline allowed here { i++; + nl++; // skip more whitespace while (i<size && data[i]==' ') i++; } + nlTotal += nl; + nl = 0; bool explicitTitle=FALSE; if (i<size && data[i]=='(') // inline link @@ -854,7 +860,6 @@ int Markdown::processLink(const char *data,int,int size) while (i<size && data[i]==' ') i++; if (i<size && data[i]=='<') i++; linkStart=i; - nl=0; int braceCount=1; while (i<size && data[i]!='\'' && data[i]!='"' && braceCount>0) { @@ -876,6 +881,8 @@ int Markdown::processLink(const char *data,int,int size) i++; } } + nlTotal += nl; + nl = 0; if (i>=size || data[i]=='\n') return 0; convertStringFragment(link,data+linkStart,i-linkStart); link = link.stripWhiteSpace(); @@ -985,6 +992,8 @@ int Markdown::processLink(const char *data,int,int size) { return 0; } + nlTotal += nl; + nl = 0; if (isToc) // special case for [TOC] { int toc_level = Config_getInt(TOC_INCLUDE_HEADINGS); @@ -1066,6 +1075,7 @@ int Markdown::processLink(const char *data,int,int size) m_out.addStr("<a href=\""); m_out.addStr(link); m_out.addStr("\""); + for (int ii = 0; ii < nlTotal; ii++) m_out.addStr("\n"); if (!title.isEmpty()) { m_out.addStr(" title=\""); diff --git a/src/memberdef.cpp b/src/memberdef.cpp index c3c420a..cae209c 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -4343,11 +4343,9 @@ MemberDef *MemberDefImpl::createTemplateInstanceMember( const ArgumentList &formalArgs,const std::unique_ptr<ArgumentList> &actualArgs) const { //printf(" Member %s %s %s\n",typeString(),name().data(),argsString()); - std::unique_ptr<ArgumentList> actualArgList; + std::unique_ptr<ArgumentList> actualArgList = std::make_unique<ArgumentList>(m_impl->defArgList); if (!m_impl->defArgList.empty()) { - actualArgList = std::make_unique<ArgumentList>(m_impl->defArgList); - // replace formal arguments with actuals for (Argument &arg : *actualArgList) { @@ -4356,10 +4354,6 @@ MemberDef *MemberDefImpl::createTemplateInstanceMember( actualArgList->setTrailingReturnType( substituteTemplateArgumentsInString(actualArgList->trailingReturnType(),formalArgs,actualArgs)); } - else - { - actualArgList = std::make_unique<ArgumentList>(); - } QCString methodName=name(); if (methodName.left(9)=="operator ") // conversion operator diff --git a/src/memberlist.cpp b/src/memberlist.cpp index b8e5e89..0c608ff 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -63,7 +63,7 @@ MemberList::~MemberList() delete memberGroupList; } -static int genericCompareMembers(const MemberDef *c1,const MemberDef *c2) +int genericCompareMembers(const MemberDef *c1,const MemberDef *c2) { bool sortConstructorsFirst = Config_getBool(SORT_MEMBERS_CTORS_1ST); if (sortConstructorsFirst) diff --git a/src/memberlist.h b/src/memberlist.h index 4038453..b8c723b 100644 --- a/src/memberlist.h +++ b/src/memberlist.h @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -105,7 +105,7 @@ class MemberList : private QList<MemberDef> int m_dictCnt; int m_protoCnt; int m_defCnt; - int m_friendCnt; + int m_friendCnt; */ int m_numDecMembers; // number of members in the brief part of the memberlist int m_numDecEnumValues; @@ -145,5 +145,6 @@ class MemberSDict : public SDict<MemberDef> int compareValues(const MemberDef *item1,const MemberDef *item2) const; }; +int genericCompareMembers(const MemberDef *c1,const MemberDef *c2); #endif @@ -2416,6 +2416,10 @@ static bool expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in expanded = expandExpression(yyscanner,resultExpr,&restExpr,0,level+1); state->expandedDict.erase(toStdString(macroName)); } + else if (def && def->nonRecursive) + { + expanded = true; + } if (expanded) { expr=expr.left(p)+resultExpr+restExpr; diff --git a/src/pycode.l b/src/pycode.l index ea314da..bcba42f 100644 --- a/src/pycode.l +++ b/src/pycode.l @@ -106,6 +106,7 @@ struct pycodeYY_state bool endComment = FALSE; VariableContext theVarContext; CallContext theCallContext; + TooltipManager tooltipManager; }; @@ -147,7 +148,6 @@ static void addVariable(yyscan_t yyscanner, QCString type, QCString name); //------------------------------------------------------------------- static std::mutex g_searchIndexMutex; -static std::mutex g_tooltipMutex; //------------------------------------------------------------------- @@ -168,6 +168,8 @@ EXPCHAR [#(){}\[\],:.%/\\=`*~|&<>!;+-] NONEMPTYEXP [^ \t\n:] PARAMNONEMPTY [^ \t\n():] IDENTIFIER ({LETTER}|"_")({LETTER}|{DIGIT}|"_")* +SCOPE {IDENTIFIER}("."{IDENTIFIER})* +CALLANY "("[^)]*")" BORDER ([^A-Za-z0-9]) POUNDCOMMENT "##" @@ -341,6 +343,11 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU codify(yyscanner,"cls."); findMemberLink(yyscanner,*yyextra->code,&yytext[4]); } + "@"{SCOPE}{CALLANY}? { // decorator + startFontClass(yyscanner,"preprocessor"); + codify(yyscanner,yytext); + endFontClass(yyscanner); + } } <ClassDec>{IDENTIFIER} { @@ -1080,10 +1087,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner, { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); - { - std::lock_guard<std::mutex> lock(g_tooltipMutex); - TooltipManager::instance()->addTooltip(d); - } + yyextra->tooltipManager.addTooltip(d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); @@ -1622,6 +1626,8 @@ void PythonCodeParser::parseCode(CodeOutputInterface &codeOutIntf, delete yyextra->sourceFileDef; yyextra->sourceFileDef=0; } + // write the tooltips + yyextra->tooltipManager.writeTooltips(codeOutIntf); printlex(yy_flex_debug, FALSE, __FILE__, fileDef ? fileDef->fileName().data(): NULL); } diff --git a/src/pyscanner.l b/src/pyscanner.l index a136b52..4a9552e 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -113,6 +113,7 @@ struct pyscannerYY_state int search_count = 0; QCString argType; bool funcParamsEnd = FALSE; + std::vector<QCString> decorators; }; //----------------------------------------------------------------------------- @@ -175,6 +176,7 @@ NONEMPTYEXP [^ \t\n:] PARAMNONEMPTY [^ \t\n():] IDENTIFIER ({LETTER}|"_")({LETTER}|{DIGIT}|"_")* SCOPE {IDENTIFIER}("."{IDENTIFIER})* +CALL "("[^)]*")" BORDER ([^A-Za-z0-9]) TRISINGLEQUOTE {STRINGPREFIX}?"'''"(!)? @@ -335,6 +337,8 @@ STARTDOCSYMS "##" "@staticmethod" { yyextra->stat=TRUE; } + "@"{SCOPE}{CALL}? { // decorator + } {SCRIPTCOMMENT} { // Unix type script comment if (yyextra->yyLineNr != 1) REJECT; } diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp index 235479d..76ac77d 100644 --- a/src/sqlite3gen.cpp +++ b/src/sqlite3gen.cpp @@ -1619,26 +1619,16 @@ static void generateSqlite3ForMember(const MemberDef *md, struct Refid scope_ref // + source references // The cross-references in initializers only work when both the src and dst // are defined. - MemberSDict *mdict = md->getReferencesMembers(); - if (mdict!=0) + auto refList = md->getReferencesMembers(); + for (const auto &rmd : refList) { - MemberSDict::IteratorDict mdi(*mdict); - const MemberDef *rmd; - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - insertMemberReference(md,rmd, "inline"); - } + insertMemberReference(md,rmd, "inline"); } // + source referenced by - mdict = md->getReferencedByMembers(); - if (mdict!=0) + auto refByList = md->getReferencedByMembers(); + for (const auto &rmd : refByList) { - MemberSDict::IteratorDict mdi(*mdict); - const MemberDef *rmd; - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - insertMemberReference(rmd,md, "inline"); - } + insertMemberReference(rmd,md, "inline"); } return; } @@ -1856,24 +1846,16 @@ static void generateSqlite3ForMember(const MemberDef *md, struct Refid scope_ref // + source references // The cross-references in initializers only work when both the src and dst // are defined. - MemberSDict *mdict = md->getReferencesMembers(); - if (mdict!=0) + auto refList = md->getReferencesMembers(); + for (const auto &refmd : refList) { - MemberSDict::IteratorDict mdi(*mdict); - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - insertMemberReference(md,rmd, "inline"); - } + insertMemberReference(md,refmd, "inline"); } // + source referenced by - mdict = md->getReferencedByMembers(); - if (mdict!=0) + auto refByList = md->getReferencedByMembers(); + for (const auto &refmd : refByList) { - MemberSDict::IteratorDict mdi(*mdict); - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - insertMemberReference(rmd,md, "inline"); - } + insertMemberReference(refmd,md, "inline"); } } diff --git a/src/tooltip.cpp b/src/tooltip.cpp index 8cc1f87..32b43fa 100644 --- a/src/tooltip.cpp +++ b/src/tooltip.cpp @@ -1,10 +1,10 @@ /****************************************************************************** * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -13,7 +13,8 @@ * */ -#include <qdict.h> +#include <map> +#include <string> #include "tooltip.h" #include "definition.h" @@ -26,34 +27,15 @@ class TooltipManager::Private { public: - Private() : tooltipInfo(10007) {} - QDict<Definition> tooltipInfo; + std::map<std::string,const Definition*> tooltipInfo; }; -TooltipManager *TooltipManager::s_theInstance = 0; - -TooltipManager::TooltipManager() +TooltipManager::TooltipManager() : p(std::make_unique<Private>()) { - p = new Private; } TooltipManager::~TooltipManager() { - delete p; -} - -TooltipManager *TooltipManager::instance() -{ - if (!s_theInstance) - { - s_theInstance = new TooltipManager; - } - return s_theInstance; -} - -void TooltipManager::clearTooltips() -{ - p->tooltipInfo.clear(); } static QCString escapeId(const char *s) @@ -70,7 +52,7 @@ static QCString escapeId(const char *s) void TooltipManager::addTooltip(const Definition *d) { - static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); + bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); if (!sourceTooltips) return; QCString id = d->getOutputFileBase(); int i=id.findRev('/'); @@ -85,18 +67,14 @@ void TooltipManager::addTooltip(const Definition *d) id+="_"+anc; } id = "a" + id; - if (p->tooltipInfo.find(id)==0) - { - p->tooltipInfo.insert(id,d); - } + p->tooltipInfo.insert({id.str(),d}); } void TooltipManager::writeTooltips(CodeOutputInterface &ol) { - QDictIterator<Definition> di(p->tooltipInfo); - Definition *d; - for (di.toFirst();(d=di.current());++di) + for (const auto &kv : p->tooltipInfo) { + const Definition *d = kv.second; DocLinkInfo docInfo; docInfo.name = d->qualifiedName(); docInfo.ref = d->getReference(); @@ -114,13 +92,13 @@ void TooltipManager::writeTooltips(CodeOutputInterface &ol) QCString decl; if (d->definitionType()==Definition::TypeMember) { - MemberDef *md = dynamic_cast<MemberDef*>(d); + const MemberDef *md = dynamic_cast<const MemberDef*>(d); if (!md->isAnonymous()) { decl = md->declaration(); } } - ol.writeTooltip(di.currentKey(), // id + ol.writeTooltip(kv.first.c_str(), // id docInfo, // symName decl, // decl d->briefDescriptionAsTooltip(), // desc diff --git a/src/tooltip.h b/src/tooltip.h index 170ea3c..3517b5d 100644 --- a/src/tooltip.h +++ b/src/tooltip.h @@ -1,10 +1,10 @@ /****************************************************************************** * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -15,23 +15,27 @@ #ifndef TOOLTIP_H #define TOOLTIP_H +#include <memory> + class Definition; class CodeOutputInterface; +//! Class that manages the tooltips for a source file class TooltipManager { public: - static TooltipManager *instance(); - void clearTooltips(); + TooltipManager(); + ~TooltipManager(); + + /** add a tooltip for a given symbol definition */ void addTooltip(const Definition *d); + + /** write the list of all collected tooltip to the given outputs */ void writeTooltips(CodeOutputInterface &ol); private: class Private; - Private *p; - TooltipManager(); - ~TooltipManager(); - static TooltipManager *s_theInstance; + std::unique_ptr<Private> p; }; #endif diff --git a/src/util.cpp b/src/util.cpp index 41fcffa..dd25284 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -2200,55 +2200,57 @@ QCString argListToString(const ArgumentList &al,bool useCanonicalType,bool showD return removeRedundantWhiteSpace(result); } -QCString tempArgListToString(const ArgumentList &al,SrcLangExt lang) +QCString tempArgListToString(const ArgumentList &al,SrcLangExt lang,bool includeDefault) { QCString result; if (al.empty()) return result; result="<"; - auto it = al.begin(); - while (it!=al.end()) + bool first=true; + for (const auto &a : al) { - Argument a = *it; - if (!a.name.isEmpty()) // add template argument name + if (a.defval.isEmpty() || includeDefault) { - if (a.type.left(4)=="out") // C# covariance - { - result+="out "; - } - else if (a.type.left(3)=="in") // C# contravariance + if (!first) result+=", "; + if (!a.name.isEmpty()) // add template argument name { - result+="in "; - } - if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp) - { - result+=a.type+" "; + if (a.type.left(4)=="out") // C# covariance + { + result+="out "; + } + else if (a.type.left(3)=="in") // C# contravariance + { + result+="in "; + } + if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp) + { + result+=a.type+" "; + } + result+=a.name; } - result+=a.name; - } - else // extract name from type - { - int i=a.type.length()-1; - while (i>=0 && isId(a.type.at(i))) i--; - if (i>0) + else // extract name from type { - result+=a.type.right(a.type.length()-i-1); - if (a.type.find("...")!=-1) + int i=a.type.length()-1; + while (i>=0 && isId(a.type.at(i))) i--; + if (i>0) { - result+="..."; + result+=a.type.right(a.type.length()-i-1); + if (a.type.find("...")!=-1) + { + result+="..."; + } + } + else // nothing found -> take whole name + { + result+=a.type; } } - else // nothing found -> take whole name + if (!a.typeConstraint.isEmpty() && lang==SrcLangExt_Java) { - result+=a.type; + result+=" extends "; // TODO: now Java specific, C# has where... + result+=a.typeConstraint; } + first=false; } - if (!a.typeConstraint.isEmpty() && lang==SrcLangExt_Java) - { - result+=" extends "; // TODO: now Java specific, C# has where... - result+=a.typeConstraint; - } - ++it; - if (it!=al.end()) result+=", "; } result+=">"; return removeRedundantWhiteSpace(result); @@ -2593,7 +2595,7 @@ exit: return prot; } -void trimBaseClassScope(BaseClassList bcl,QCString &s,int level=0) +void trimBaseClassScope(const BaseClassList &bcl,QCString &s,int level=0) { //printf("trimBaseClassScope level=%d '%s'\n",level,s.data()); for (const auto &bcd : bcl) @@ -2814,8 +2816,10 @@ static QCString getCanonicalTypeForIdentifier( { symName=word; } - //printf("getCanonicalTypeForIdentifier(%s,[%s->%s]) start\n", - // word.data(),tSpec?tSpec->data():"<none>",templSpec.data()); + //printf("getCanonicalTypeForIdentifier(%s d=%s fs=%s ,[%s->%s]) start\n", + // word.data(), + // d ? d->name().data() : "<null>",fs ? fs->name().data() : "<null>", + // tSpec?tSpec->data():"<none>",templSpec.data()); const ClassDef *cd = 0; const MemberDef *mType = 0; @@ -2908,7 +2912,13 @@ static QCString getCanonicalTypeForIdentifier( //printf("word=%s typeString=%s\n",word.data(),mType->typeString()); if (word!=mType->typeString()) { - result = getCanonicalTypeForIdentifier(d,fs,mType->typeString(),tSpec,count+1); + QCString type = mType->typeString(); + if (type.startsWith("typename ")) + { + type.stripPrefix("typename "); + type = stripTemplateSpecifiersFromScope(type,FALSE); + } + result = getCanonicalTypeForIdentifier(d,fs,type,tSpec,count+1); } else { @@ -2961,7 +2971,6 @@ static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCStr //printf(" i=%d p=%d\n",i,p); if (i>pp) canType += type.mid(pp,i-pp); - QCString ct = getCanonicalTypeForIdentifier(d,fs,word,&templSpec); // in case the ct is empty it means that "word" represents scope "d" @@ -3032,9 +3041,9 @@ static bool matchArgument2( { //printf(">> match argument: %s::'%s|%s' (%s) <-> %s::'%s|%s' (%s)\n", // srcScope ? srcScope->name().data() : "", - // srcA->type.data(),srcA->name.data(),srcA->canType.data(), + // srcA.type.data(),srcA.name.data(),srcA.canType.data(), // dstScope ? dstScope->name().data() : "", - // dstA->type.data(),dstA->name.data(),dstA->canType.data()); + // dstA.type.data(),dstA.name.data(),dstA.canType.data()); //if (srcA->array!=dstA->array) // nomatch for char[] against char //{ @@ -4572,7 +4581,7 @@ int getPrefixIndex(const QCString &name) //---------------------------------------------------------------------------- -static void initBaseClassHierarchy(BaseClassList bcl) +static void initBaseClassHierarchy(const BaseClassList &bcl) { for (const auto &bcd : bcl) { @@ -4627,7 +4636,7 @@ void initClassHierarchy(ClassSDict *cl) //---------------------------------------------------------------------------- -bool hasVisibleRoot(BaseClassList bcl) +bool hasVisibleRoot(const BaseClassList &bcl) { for (const auto &bcd : bcl) { @@ -8022,54 +8031,65 @@ uint getUtf8CodeToUpper( const QCString& s, int idx ) } //-------------------------------------------------------------------------------------- +// +bool namespaceHasNestedNamespace(const NamespaceDef *nd) +{ + NamespaceSDict::Iterator cnli(*nd->getNamespaceSDict()); + const NamespaceDef *cnd; + for (cnli.toFirst();(cnd=cnli.current());++cnli) + { + if (cnd->isLinkableInProject() && !cnd->isAnonymous()) + { + return true; + } + } + return false; +} -bool namespaceHasVisibleChild(const NamespaceDef *nd,bool includeClasses,bool filterClasses,ClassDef::CompoundType ct) +bool namespaceHasNestedClass(const NamespaceDef *nd,bool filterClasses,ClassDef::CompoundType ct) { + //printf(">namespaceHasVisibleChild(%s,includeClasses=%d)\n",nd->name().data(),includeClasses); if (nd->getNamespaceSDict()) { NamespaceSDict::Iterator cnli(*nd->getNamespaceSDict()); const NamespaceDef *cnd; for (cnli.toFirst();(cnd=cnli.current());++cnli) { - if (cnd->isLinkableInProject() && !cnd->isAnonymous()) - { - return TRUE; - } - else if (namespaceHasVisibleChild(cnd,includeClasses,filterClasses,ct)) + if (namespaceHasNestedClass(cnd,filterClasses,ct)) { + //printf("<namespaceHasVisibleChild(%s,includeClasses=%d): case2\n",nd->name().data(),includeClasses); return TRUE; } } } - if (includeClasses) + + const ClassSDict *d = nd->getClassSDict(); + if (filterClasses) { - const ClassSDict *d = nd->getClassSDict(); - if (filterClasses) + if (ct == ClassDef::Interface) { - if (ct == ClassDef::Interface) - { - d = nd->getInterfaceSDict(); - } - else if (ct == ClassDef::Struct) - { - d = nd->getStructSDict(); - } - else if (ct == ClassDef::Exception) - { - d = nd->getExceptionSDict(); - } + d = nd->getInterfaceSDict(); + } + else if (ct == ClassDef::Struct) + { + d = nd->getStructSDict(); + } + else if (ct == ClassDef::Exception) + { + d = nd->getExceptionSDict(); } + } - if (d) + if (d) + { + ClassSDict::Iterator cli(*d); + const ClassDef *cd; + for (;(cd=cli.current());++cli) { - ClassSDict::Iterator cli(*d); - const ClassDef *cd; - for (;(cd=cli.current());++cli) + if (cd->isLinkableInProject() && cd->templateMaster()==0) { - if (cd->isLinkableInProject() && cd->templateMaster()==0) - { - return TRUE; - } + //printf("<namespaceHasVisibleChild(%s,includeClasses=%d): case3\n",nd->name().data(),includeClasses); + return TRUE; } } } @@ -283,7 +283,7 @@ QCString removeRedundantWhiteSpace(const QCString &s); QCString argListToString(const ArgumentList &al,bool useCanonicalType=FALSE,bool showDefVals=TRUE); -QCString tempArgListToString(const ArgumentList &al,SrcLangExt lang); +QCString tempArgListToString(const ArgumentList &al,SrcLangExt lang,bool includeDefaults=true); QCString generateMarker(int id); @@ -310,9 +310,10 @@ QCString replaceAnonymousScopes(const QCString &s,const char *replacement=0); void initClassHierarchy(ClassSDict *cl); -bool hasVisibleRoot(BaseClassList bcl); +bool hasVisibleRoot(const BaseClassList &bcl); bool classHasVisibleChildren(const ClassDef *cd); -bool namespaceHasVisibleChild(const NamespaceDef *nd,bool includeClasses,bool filterClasses,ClassDef::CompoundType ct); +bool namespaceHasNestedNamespace(const NamespaceDef *nd); +bool namespaceHasNestedClass(const NamespaceDef *nd,bool filterClasses,ClassDef::CompoundType ct); bool classVisibleInIndex(const ClassDef *cd); int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level=0); diff --git a/src/vhdlcode.l b/src/vhdlcode.l index cecf9fb..7610c9a 100644 --- a/src/vhdlcode.l +++ b/src/vhdlcode.l @@ -109,6 +109,7 @@ struct vhdlcodeYY_state bool lexInit = false; int braceCount = 0; + TooltipManager tooltipManager; }; @@ -1229,7 +1230,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); - TooltipManager::instance()->addTooltip(d); + yyextra->tooltipManager.addTooltip(d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); @@ -1656,6 +1657,10 @@ void VHDLCodeParser::parseCode(CodeOutputInterface &od, yyextra->sourceFileDef=0; } yyextra->startCode=false; + + // write the tooltips + yyextra->tooltipManager.writeTooltips(od); + printlex(yy_flex_debug, false, __FILE__, fd ? fd->fileName().data(): NULL); } diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index a842841..1993c1e 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -1021,23 +1021,15 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream } //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers()); - MemberSDict *mdict = md->getReferencesMembers(); - if (mdict) + auto refList = md->getReferencesMembers(); + for (const auto &refmd : refList) { - MemberSDict::Iterator mdi(*mdict); - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - writeMemberReference(t,def,rmd,"references"); - } + writeMemberReference(t,def,refmd,"references"); } - mdict = md->getReferencedByMembers(); - if (mdict) + auto refByList = md->getReferencedByMembers(); + for (const auto &refmd : refByList) { - MemberSDict::Iterator mdi(*mdict); - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - writeMemberReference(t,def,rmd,"referencedby"); - } + writeMemberReference(t,def,refmd,"referencedby"); } t << " </memberdef>" << endl; diff --git a/templates/latex/doxygen.sty b/templates/latex/doxygen.sty index 78a5254..6c42b2f 100644 --- a/templates/latex/doxygen.sty +++ b/templates/latex/doxygen.sty @@ -186,9 +186,8 @@ % (only if caption is specified) \newenvironment{DoxyImage}{% \begin{figure}[H]% - \begin{center}% + \centering% }{% - \end{center}% \end{figure}% } @@ -571,6 +570,6 @@ % Define caption that is also suitable in a table \makeatletter \def\doxyfigcaption{% -\refstepcounter{figure}% +\H@refstepcounter{figure}% \@dblarg{\@caption{figure}}} \makeatother |