From 9b9c2c6101be61baefb73b0c414e93381070e21b Mon Sep 17 00:00:00 2001 From: "luz.paz" Date: Sat, 28 Sep 2019 11:14:28 -0400 Subject: Fix typos Found via ``` codespell -q 3 -S *.js,*.po,./src/translator*,*.eps,./doc/changelog.doc -L ang,ans,attribs,ba,behaviour,classe,colour,german,iff,initialise,nam,nd,que,russian,statics,te,tim,uint ``` --- src/context.cpp | 2 +- src/dotgraph.cpp | 2 +- src/doxygen.cpp | 2 +- src/fortrancode.l | 2 +- src/fortranscanner.l | 2 +- src/memberdef.h | 2 +- src/portable.cpp | 2 +- src/pycode.l | 4 ++-- src/pyscanner.l | 6 +++--- src/scanner.l | 2 +- src/sortdict.h | 12 ++++++------ src/vhdljjparser.cpp | 4 ++-- templates/latex/tabu_doxygen.sty | 10 +++++----- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/context.cpp b/src/context.cpp index 1933d43..8b7643a 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -8446,7 +8446,7 @@ TemplateVariant NamespaceMembersIndexContext::get(const char *name) const //------------------------------------------------------------------------ -//%% struct InheritanceGraph: a connected graph reprenting part of the overall interitance tree +//%% struct InheritanceGraph: a connected graph reprenting part of the overall inheritance tree //%% { class InheritanceGraphContext::Private { diff --git a/src/dotgraph.cpp b/src/dotgraph.cpp index df64d66..bbffaf0 100644 --- a/src/dotgraph.cpp +++ b/src/dotgraph.cpp @@ -289,7 +289,7 @@ void DotGraph::writeGraphHeader(FTextStream &t,const QCString &title) { t << " // INTERACTIVE_SVG=YES\n"; } - t << " // LATEX_PDF_SIZE\n"; // write placeholder for LaTeX PDF bounding box size repacement + t << " // LATEX_PDF_SIZE\n"; // write placeholder for LaTeX PDF bounding box size replacement if (Config_getBool(DOT_TRANSPARENT)) { t << " bgcolor=\"transparent\";" << endl; diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 953a5de..7fec2b6 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -2588,7 +2588,7 @@ static MemberDef *addVariableToFile( addMemberDocs(root,md,def,0,FALSE); md->setRefItems(root->sli); // if md is a variable forward declaration and root is the definition that - // turn md into the defintion + // turn md into the definition if (!root->explicitExternal && md->isExternal()) { md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn()); diff --git a/src/fortrancode.l b/src/fortrancode.l index d372299..303bbfb 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -521,7 +521,7 @@ static bool getGenericProcedureLink(const ClassDef *cd, return FALSE; } -static bool getLink(UseSDict *usedict, // dictonary with used modules +static bool getLink(UseSDict *usedict, // dictionary with used modules const char *memberText, // exact member text CodeOutputInterface &ol, const char *text) diff --git a/src/fortranscanner.l b/src/fortranscanner.l index d75134a..eb798c9 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -1840,7 +1840,7 @@ static QCString extractFromParens(const QCString name) return extracted; } -/*! remove non usefull spaces from bind statement */ +/*! remove unuseful spaces from bind statement */ static QCString extractBind(const QCString name) { QCString parensPart = extractFromParens(name); diff --git a/src/memberdef.h b/src/memberdef.h index b200833..97bf819 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -239,7 +239,7 @@ class MemberDef : virtual public Definition virtual bool hasCallGraph() const = 0; virtual bool hasCallerGraph() const = 0; virtual bool visibleMemberGroup(bool hideNoHeader) const = 0; - // refrenced related members + // referenced related members virtual bool hasReferencesRelation() const = 0; virtual bool hasReferencedByRelation() const = 0; diff --git a/src/portable.cpp b/src/portable.cpp index 3d64638..c6e829d 100644 --- a/src/portable.cpp +++ b/src/portable.cpp @@ -457,7 +457,7 @@ bool portable_isAbsolutePath(const char *fileName) /** * Correct a possible wrong PATH variable * - * This routine was inspired by the cause for bug 766059 was that in the Windows path there were forward slahes. + * This routine was inspired by the cause for bug 766059 was that in the Windows path there were forward slashes. */ void portable_correct_path(void) { diff --git a/src/pycode.l b/src/pycode.l index a76129d..8cae0e2 100644 --- a/src/pycode.l +++ b/src/pycode.l @@ -1316,7 +1316,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT \\{B}\n { // line continuation codifyLines(yytext); } - \\. { // espaced char + \\. { // escaped char codify(yytext); } {STRINGPREFIX}?{TRIDOUBLEQUOTE} { // triple double quotes @@ -1339,7 +1339,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT \\{B}\n { // line continuation codifyLines(yytext); } - \\. { // espaced char + \\. { // escaped char codify(yytext); } {STRINGPREFIX}?{TRISINGLEQUOTE} { // triple single quotes diff --git a/src/pyscanner.l b/src/pyscanner.l index 2320bca..33e6867 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -1619,7 +1619,7 @@ STARTDOCSYMS "##" incLineNr(); docBlock += yytext; } - \\. { // espaced char + \\. { // escaped char docBlock += yytext; } . { @@ -1654,7 +1654,7 @@ STARTDOCSYMS "##" addToString(yytext); incLineNr(); } - \\. { // espaced char + \\. { // escaped char addToString(yytext); } "\"\"\"" { // triple double quotes @@ -1677,7 +1677,7 @@ STARTDOCSYMS "##" addToString(yytext); incLineNr(); } - \\. { // espaced char + \\. { // escaped char addToString(yytext); } "'''" { // triple single quotes diff --git a/src/scanner.l b/src/scanner.l index 07d5c71..1db7320 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -2001,7 +2001,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name=removeRedundantWhiteSpace(substitute(yytext,"\\","::")); //printf("PHP: adding use relation: %s\n",current->name.data()); current->fileName = yyFileName; - // add a using declaraton + // add a using declaration current->section=Entry::USINGDECL_SEC; current_root->addSubEntry(current); current = new Entry(*current); diff --git a/src/sortdict.h b/src/sortdict.h index 52eccd3..0e0b5c1 100644 --- a/src/sortdict.h +++ b/src/sortdict.h @@ -128,7 +128,7 @@ class SDict /*! Appends an element to the dictionary. The element is owned by the * dictionary. - * \param key The unique key to use to quicky find the item later on. + * \param key The unique key to use to quickly find the item later on. * \param d The compound to add. * \sa find() */ @@ -146,7 +146,7 @@ class SDict /*! Prepends an element to the dictionary. The element is owned by the * dictionary. - * \param key The unique key to use to quicky find the item later on. + * \param key The unique key to use to quickly find the item later on. * \param d The compound to add. * \sa find() */ @@ -190,7 +190,7 @@ class SDict m_list->sort(); } /*! Inserts a compound into the dictionary in a sorted way. - * \param key The unique key to use to quicky find the item later on. + * \param key The unique key to use to quickly find the item later on. * \param d The compound to add. * \sa find() */ @@ -470,7 +470,7 @@ class SIntDict /*! Appends a compound to the dictionary. The element is owned by the * dictionary. - * \param key The unique key to use to quicky find the item later on. + * \param key The unique key to use to quickly find the item later on. * \param d The compound to add. * \sa find() */ @@ -488,7 +488,7 @@ class SIntDict /*! Prepend a compound to the dictionary. The element is owned by the * dictionary. - * \param key The unique key to use to quicky find the item later on. + * \param key The unique key to use to quickly find the item later on. * \param d The compound to add. * \sa find() */ @@ -521,7 +521,7 @@ class SIntDict } /*! Inserts a compound into the dictionary in a sorted way. - * \param key The unique key to use to quicky find the item later on. + * \param key The unique key to use to quickly find the item later on. * \param d The compound to add. * \sa find() */ diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp index aeed048..47772f6 100644 --- a/src/vhdljjparser.cpp +++ b/src/vhdljjparser.cpp @@ -343,7 +343,7 @@ void VhdlParser::addCompInst(const char *n, const char* instName, const char* co { current->args=lastCompound->name; // architecture name } - current->includeName=comp; // component/enity/configuration + current->includeName=comp; // component/entity/configuration int u=genLabels.find("|",1); if (u>0) { @@ -584,7 +584,7 @@ void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, * ..... * library * package - * enity zzz + * entity zzz * ..... * and so on.. */ diff --git a/templates/latex/tabu_doxygen.sty b/templates/latex/tabu_doxygen.sty index 3efcaf3..a5ab3dc 100755 --- a/templates/latex/tabu_doxygen.sty +++ b/templates/latex/tabu_doxygen.sty @@ -78,7 +78,7 @@ \TMP@EnsureCode 58 = 12 % : (for siunitx) \TMP@EnsureCode124 = 12 % | \TMP@EnsureCode 36 = 3 % $ = math shift -\TMP@EnsureCode 38 = 4 % & = tab alignmment character +\TMP@EnsureCode 38 = 4 % & = tab alignment character \TMP@EnsureCode 32 = 10 % space \TMP@EnsureCode 94 = 7 % ^ \TMP@EnsureCode 95 = 8 % _ @@ -840,7 +840,7 @@ }% \tabu@reset \def\tabu@setsave #1{\expandafter\tabu@sets@ve #1\@nil{#1}} \long\def\tabu@sets@ve #1\@nil #2{\@temptokena\expandafter{\the\@temptokena \def#2{#1}}} -%% The Rewritting Process ------------------------------------------- +%% The Rewriting Process ------------------------------------------- \def\tabu@newcolumntype #1{% \expandafter\tabu@new@columntype \csname NC@find@\string#1\expandafter\endcsname @@ -1056,7 +1056,7 @@ \else #2\tabucolX \fi }% \tabu@hsize -%% \usetabu and \preamble: rewritting process --------------------- +%% \usetabu and \preamble: rewriting process --------------------- \tabu@privatecolumntype \usetabu [1]{% \ifx\\#1\\\tabu@saveerr{}\else \@ifundefined{tabu@saved@\string#1} @@ -1072,7 +1072,7 @@ {\csname tabu@saved@\string#1\expandafter\endcsname\expandafter\z@}% \fi }% \NC@rewrite@\preamble -%% Controlling the rewritting process ------------------------------- +%% Controlling the rewriting process ------------------------------- \tabu@newcolumntype \tabu@rewritefirst{% \iftabu@long \aftergroup \tabu@longpream % \else \aftergroup \tabu@pream @@ -2388,7 +2388,7 @@ \PackageWarning{tabu} {\string\@arrayright\space is missing from the \MessageBreak definition of \string\endarray. - \MessageBreak Comptability with delarray.sty is broken.}% + \MessageBreak Compatibility with delarray.sty is broken.}% \fi\fi }% \tabu@fix@arrayright \def\tabu@adl@xarraydashrule #1#2#3{% -- cgit v0.12 From a872ee137c88b98c4d5ce2391c60e304d68faccb Mon Sep 17 00:00:00 2001 From: albert-github Date: Wed, 2 Oct 2019 17:44:32 +0200 Subject: issue #7285 git executable required Test showed that the REQUIRED is not necessary for the doxygen build process. The git version available will not be available. --- cmake/git_watcher.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/git_watcher.cmake b/cmake/git_watcher.cmake index 6447b86..6a50476 100644 --- a/cmake/git_watcher.cmake +++ b/cmake/git_watcher.cmake @@ -69,7 +69,7 @@ CHECK_OPTIONAL_VARIABLE(GIT_WORKING_DIR "${CMAKE_SOURCE_DIR}") # Check the optional git variable. # If it's not set, we'll try to find it using the CMake packaging system. if(NOT DEFINED GIT_EXECUTABLE) - find_package(Git QUIET REQUIRED) + find_package(Git QUIET) endif() CHECK_REQUIRED_VARIABLE(GIT_EXECUTABLE) -- cgit v0.12 From d269f239d7af8d3bd762abfd6a8557cd2d898eab Mon Sep 17 00:00:00 2001 From: albert-github Date: Sat, 5 Oct 2019 13:08:50 +0200 Subject: Incorrect warning for ALIASES In case we have an alias in the form: `mine_err(1)=\1` we get the warning: ``` error: Illegal alias format 'mine_err(1)=\1'. Use "name=value" or "name(n)=value", where n is the number of arguments ``` Note the round brackets in the explanation., these have to be curly brackets. --- src/configimpl.l | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/configimpl.l b/src/configimpl.l index e657745..0cc5c88 100644 --- a/src/configimpl.l +++ b/src/configimpl.l @@ -1495,7 +1495,7 @@ void Config::checkAndCorrect() alias=alias.stripWhiteSpace(); if (alias.find(re1)!=0 && alias.find(re2)!=0) { - err("Illegal alias format '%s'. Use \"name=value\" or \"name(n)=value\", where n is the number of arguments\n", + err("Illegal alias format '%s'. Use \"name=value\" or \"name{n}=value\", where n is the number of arguments\n", alias.data()); } s=aliasList.next(); -- cgit v0.12 From 3367058c49f85c3d8a86377db08e90ec9e601c60 Mon Sep 17 00:00:00 2001 From: albert-github Date: Sun, 6 Oct 2019 18:02:00 +0200 Subject: Bug 570798 - \\\< does not work for php constants Handle comment for define analogous to a normal php variable, the closing part is automatically done when the comment is finished (rule: `";"`). --- src/scanner.l | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scanner.l b/src/scanner.l index 07d5c71..316bb81 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -2770,7 +2770,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name += yytext ; addType( current ); } -";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { +";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { if (current->bodyLine==-1) { current->bodyLine=yyLineNr; -- cgit v0.12 From ae0a5ec2a10371adbcdb0df4f3ce536ed6b43840 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Mon, 7 Oct 2019 21:01:10 +0200 Subject: Use smartpointers to manage the lifetime of Entry objects --- src/commentscan.l | 18 +- src/docgroup.cpp | 15 + src/doxygen.cpp | 969 +++++++++++++++++++++++------------------------ src/entry.cpp | 82 ++-- src/entry.h | 38 +- src/fileparser.h | 2 +- src/fortranscanner.h | 2 +- src/fortranscanner.l | 240 +++++------- src/groupdef.cpp | 12 +- src/groupdef.h | 16 +- src/markdown.cpp | 11 +- src/markdown.h | 2 +- src/parserintf.h | 4 +- src/pyscanner.h | 2 +- src/pyscanner.l | 108 ++---- src/scanner.h | 2 +- src/scanner.l | 317 +++++++--------- src/sqlscanner.h | 2 +- src/tagreader.cpp | 63 +-- src/tagreader.h | 4 +- src/tclscanner.h | 2 +- src/tclscanner.l | 38 +- src/vhdldocgen.cpp | 24 +- src/vhdljjparser.cpp | 105 +++-- src/vhdljjparser.h | 9 +- src/xmlscanner.h | 2 +- vhdlparser/VhdlParser.cc | 22 +- vhdlparser/VhdlParser.h | 2 +- vhdlparser/vhdlparser.jj | 22 +- 29 files changed, 1021 insertions(+), 1114 deletions(-) diff --git a/src/commentscan.l b/src/commentscan.l index 7c9929c..23a1fc2 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -415,11 +415,8 @@ static GuardType guardType; // kind of guard for conditional se static bool enabledSectionFound; static QCString functionProto; // function prototype static QStack guards; // tracks nested conditional sections (if,ifnot,..) -static Entry* current = 0 ; // working entry -//static Entry* current_root = 0 ; // parent of working entry +static Entry *current = 0; // working entry - -//static Entry* previous = 0 ; // TODO: remove need for this static bool needNewEntry; static QCString g_sectionLabel; @@ -533,7 +530,6 @@ static QCString stripQuotes(const char *s) static void addXRefItem(const char *listName,const char *itemTitle, const char *listTitle,bool append) { - Entry *docEntry = current; // inBody && previous ? previous : current; if (listName==0) return; //printf("addXRefItem(%s,%s,%s,%d)\n",listName,itemTitle,listTitle,append); @@ -545,9 +541,9 @@ static void addXRefItem(const char *listName,const char *itemTitle, Doxygen::xrefLists->insert(listName,refList); //printf("new list!\n"); } - if (docEntry->sli) + if (current->sli) { - QListIterator slii(*docEntry->sli); + QListIterator slii(*current->sli); for (slii.toLast();(lii=slii.current());--slii) { if (qstrcmp(lii->type,listName)==0) @@ -580,16 +576,16 @@ static void addXRefItem(const char *listName,const char *itemTitle, ASSERT(item!=0); item->text = outputXRef; item->listAnchor = anchorLabel; - docEntry->addSpecialListItem(listName,itemId); + current->addSpecialListItem(listName,itemId); QCString cmdString; cmdString.sprintf(" \\xrefitem %s %d.",listName,itemId); if (inBody) { - docEntry->inbodyDocs += cmdString; + current->inbodyDocs += cmdString; } else { - docEntry->doc += cmdString; + current->doc += cmdString; } SectionInfo *si = Doxygen::sectionDict->find(anchorLabel); if (si) @@ -609,7 +605,7 @@ static void addXRefItem(const char *listName,const char *itemTitle, g_sectionTitle,SectionInfo::Anchor, g_sectionLevel); Doxygen::sectionDict->append(anchorLabel,si); - docEntry->anchors->append(si); + current->anchors->append(si); } } outputXRef.resize(0); diff --git a/src/docgroup.cpp b/src/docgroup.cpp index 1f4fb6d..ecaa1af 100644 --- a/src/docgroup.cpp +++ b/src/docgroup.cpp @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2019 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 + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + #include "doxygen.h" #include "util.h" #include "entry.h" diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 953a5de..798418f 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -33,6 +33,9 @@ #include #include +#include +#include + #include "version.h" #include "doxygen.h" #include "scanner.h" @@ -105,13 +108,6 @@ // provided by the generated file resources.cpp extern void initResources(); -#define RECURSE_ENTRYTREE(func,var) \ - do { if (var->children()) { \ - EntryListIterator eli(*var->children()); \ - for (;eli.current();++eli) func(eli.current()); \ - } } while(0) - - #if !defined(_WIN32) || defined(__CYGWIN__) #include #define HAS_SIGNALS @@ -177,7 +173,7 @@ GenericsSDict *Doxygen::genericsDict; DocGroup Doxygen::docGroup; // locally accessible globals -static QDict g_classEntries(1009); +static std::unordered_map< std::string, const Entry* > g_classEntries; static StringList g_inputFiles; static QDict g_compoundKeywordDict(7); // keywords recognised as compounds static OutputList *g_outputList = 0; // list of output generating objects @@ -297,9 +293,12 @@ void statistics() -static void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl, - ArgumentList *al,bool over_load,NamespaceSDict *nl=0); -static void findMember(Entry *root, +static void addMemberDocs(const Entry *root,MemberDef *md, const char *funcDecl, + ArgumentList *al,bool over_load,uint64 spec); +static void findMember(const Entry *root, + const QCString &relates, + const QCString &type, + const QCString &args, QCString funcDecl, bool overloaded, bool isFunc @@ -313,7 +312,7 @@ enum FindBaseClassRelation_Mode }; static bool findClassRelation( - Entry *root, + const Entry *root, Definition *context, ClassDef *cd, BaseInfo *bi, @@ -420,9 +419,9 @@ static STLInfo g_stlinfo[] = { 0, 0, 0, 0, 0, 0, 0, FALSE, FALSE } }; -static void addSTLMember(Entry *root,const char *type,const char *name) +static void addSTLMember(const std::unique_ptr &root,const char *type,const char *name) { - Entry *memEntry = new Entry; + std::unique_ptr memEntry = std::make_unique(); memEntry->name = name; memEntry->type = type; memEntry->protection = Public; @@ -430,16 +429,12 @@ static void addSTLMember(Entry *root,const char *type,const char *name) memEntry->brief = "STL member"; memEntry->hidden = FALSE; memEntry->artificial = TRUE; - //memEntry->parent = root; - root->addSubEntry(memEntry); - //EntryNav *memEntryNav = new EntryNav(root,memEntry); - //memEntryNav->setEntry(memEntry); - //rootNav->addChild(memEntryNav); + root->moveToSubEntryAndKeep(memEntry); } -static void addSTLIterator(Entry *classEntry,const char *name) +static void addSTLIterator(const std::unique_ptr &classEntry,const char *name) { - Entry *iteratorClassEntry = new Entry; + std::unique_ptr iteratorClassEntry = std::make_unique(); iteratorClassEntry->fileName = "[STL]"; iteratorClassEntry->startLine = 1; iteratorClassEntry->name = name; @@ -447,113 +442,106 @@ static void addSTLIterator(Entry *classEntry,const char *name) iteratorClassEntry->brief = "STL iterator class"; iteratorClassEntry->hidden = FALSE; iteratorClassEntry->artificial= TRUE; - classEntry->addSubEntry(iteratorClassEntry); - //EntryNav *iteratorClassEntryNav = new EntryNav(classEntryNav,iteratorClassEntry); - //iteratorClassEntryNav->setEntry(iteratorClassEntry); - //classEntryNav->addChild(iteratorClassEntryNav); + classEntry->moveToSubEntryAndKeep(iteratorClassEntry); +} + +static void addSTLClass(const std::unique_ptr &root,const STLInfo *info) +{ + //printf("Adding STL class %s\n",info->className); + QCString fullName = info->className; + fullName.prepend("std::"); + + // add fake Entry for the class + std::unique_ptr classEntry = std::make_unique(); + classEntry->fileName = "[STL]"; + classEntry->startLine = 1; + classEntry->name = fullName; + classEntry->section = Entry::CLASS_SEC; + classEntry->brief = "STL class"; + classEntry->hidden = FALSE; + classEntry->artificial= TRUE; + + // add template arguments to class + if (info->templType1) + { + ArgumentList *al = new ArgumentList; + Argument *a=new Argument; + a->type="typename"; + a->name=info->templType1; + al->append(a); + if (info->templType2) // another template argument + { + a=new Argument; + a->type="typename"; + a->name=info->templType2; + al->append(a); + } + classEntry->tArgLists = new QList; + classEntry->tArgLists->setAutoDelete(TRUE); + classEntry->tArgLists->append(al); + } + // add member variables + if (info->templName1) + { + addSTLMember(classEntry,info->templType1,info->templName1); + } + if (info->templName2) + { + addSTLMember(classEntry,info->templType2,info->templName2); + } + if (fullName=="std::auto_ptr" || fullName=="std::smart_ptr" || fullName=="std::shared_ptr" || + fullName=="std::unique_ptr" || fullName=="std::weak_ptr") + { + std::unique_ptr memEntry = std::make_unique(); + memEntry->name = "operator->"; + memEntry->args = "()"; + memEntry->type = "T*"; + memEntry->protection = Public; + memEntry->section = Entry::FUNCTION_SEC; + memEntry->brief = "STL member"; + memEntry->hidden = FALSE; + memEntry->artificial = FALSE; + classEntry->moveToSubEntryAndKeep(memEntry); + } + if (info->baseClass1) + { + classEntry->extends->append(new BaseInfo(info->baseClass1,Public,info->virtualInheritance?Virtual:Normal)); + } + if (info->baseClass2) + { + classEntry->extends->append(new BaseInfo(info->baseClass2,Public,info->virtualInheritance?Virtual:Normal)); + } + if (info->iterators) + { + // add iterator class + addSTLIterator(classEntry,fullName+"::iterator"); + addSTLIterator(classEntry,fullName+"::const_iterator"); + addSTLIterator(classEntry,fullName+"::reverse_iterator"); + addSTLIterator(classEntry,fullName+"::const_reverse_iterator"); + } + root->moveToSubEntryAndKeep(classEntry); } -static void addSTLClasses(Entry *root) +static void addSTLClasses(const std::unique_ptr &root) { - Entry *namespaceEntry = new Entry; + std::unique_ptr namespaceEntry = std::make_unique(); namespaceEntry->fileName = "[STL]"; namespaceEntry->startLine = 1; - //namespaceEntry->parent = rootNav->entry(); namespaceEntry->name = "std"; namespaceEntry->section = Entry::NAMESPACE_SEC; namespaceEntry->brief = "STL namespace"; namespaceEntry->hidden = FALSE; namespaceEntry->artificial= TRUE; - root->addSubEntry(namespaceEntry); - //EntryNav *namespaceEntryNav = new EntryNav(rootNav,namespaceEntry); - //namespaceEntryNav->setEntry(namespaceEntry); - //rootNav->addChild(namespaceEntryNav); STLInfo *info = g_stlinfo; while (info->className) { - //printf("Adding STL class %s\n",info->className); - QCString fullName = info->className; - fullName.prepend("std::"); - - // add fake Entry for the class - Entry *classEntry = new Entry; - classEntry->fileName = "[STL]"; - classEntry->startLine = 1; - classEntry->name = fullName; - classEntry->section = Entry::CLASS_SEC; - classEntry->brief = "STL class"; - classEntry->hidden = FALSE; - classEntry->artificial= TRUE; - namespaceEntry->addSubEntry(classEntry); - //EntryNav *classEntryNav = new EntryNav(namespaceEntryNav,classEntry); - //classEntryNav->setEntry(classEntry); - //namespaceEntryNav->addChild(classEntryNav); - - // add template arguments to class - if (info->templType1) - { - ArgumentList *al = new ArgumentList; - Argument *a=new Argument; - a->type="typename"; - a->name=info->templType1; - al->append(a); - if (info->templType2) // another template argument - { - a=new Argument; - a->type="typename"; - a->name=info->templType2; - al->append(a); - } - classEntry->tArgLists = new QList; - classEntry->tArgLists->setAutoDelete(TRUE); - classEntry->tArgLists->append(al); - } - // add member variables - if (info->templName1) - { - addSTLMember(classEntry,info->templType1,info->templName1); - } - if (info->templName2) - { - addSTLMember(classEntry,info->templType2,info->templName2); - } - if (fullName=="std::auto_ptr" || fullName=="std::smart_ptr" || fullName=="std::shared_ptr" || - fullName=="std::unique_ptr" || fullName=="std::weak_ptr") - { - Entry *memEntry = new Entry; - memEntry->name = "operator->"; - memEntry->args = "()"; - memEntry->type = "T*"; - memEntry->protection = Public; - memEntry->section = Entry::FUNCTION_SEC; - memEntry->brief = "STL member"; - memEntry->hidden = FALSE; - memEntry->artificial = FALSE; - classEntry->addSubEntry(memEntry); - //EntryNav *memEntryNav = new EntryNav(classEntryNav,memEntry); - //memEntryNav->setEntry(memEntry); - //classEntryNav->addChild(memEntryNav); - } - if (info->baseClass1) - { - classEntry->extends->append(new BaseInfo(info->baseClass1,Public,info->virtualInheritance?Virtual:Normal)); - } - if (info->baseClass2) - { - classEntry->extends->append(new BaseInfo(info->baseClass2,Public,info->virtualInheritance?Virtual:Normal)); - } - if (info->iterators) - { - // add iterator class - addSTLIterator(classEntry,fullName+"::iterator"); - addSTLIterator(classEntry,fullName+"::const_iterator"); - addSTLIterator(classEntry,fullName+"::reverse_iterator"); - addSTLIterator(classEntry,fullName+"::const_reverse_iterator"); - } + addSTLClass(namespaceEntry,info); info++; } + + root->moveToSubEntryAndKeep(namespaceEntry); } //---------------------------------------------------------------------------- @@ -616,7 +604,7 @@ static void addRelatedPage(Entry *root) } } -static void buildGroupListFiltered(Entry *root,bool additional, bool includeExternal) +static void buildGroupListFiltered(const Entry *root,bool additional, bool includeExternal) { if (root->section==Entry::GROUPDOC_SEC && !root->name.isEmpty() && ((!includeExternal && root->tagInfo==0) || @@ -671,18 +659,10 @@ static void buildGroupListFiltered(Entry *root,bool additional, bool includeExte } } } - if (root->children()) - { - EntryListIterator eli(*root->children()); - Entry *e; - for (;(e=eli.current());++eli) - { - buildGroupListFiltered(e,additional,includeExternal); - } - } + for (const auto &e : root->children()) buildGroupListFiltered(e.get(),additional,includeExternal); } -static void buildGroupList(Entry *root) +static void buildGroupList(const Entry *root) { // --- first process only local groups // first process the @defgroups blocks @@ -697,7 +677,7 @@ static void buildGroupList(Entry *root) buildGroupListFiltered(root,TRUE,TRUE); } -static void findGroupScope(Entry *root) +static void findGroupScope(const Entry *root) { if (root->section==Entry::GROUPDOC_SEC && !root->name.isEmpty() && root->parent() && !root->parent()->name.isEmpty()) @@ -719,10 +699,10 @@ static void findGroupScope(Entry *root) } } } - RECURSE_ENTRYTREE(findGroupScope,root); + for (const auto &e : root->children()) findGroupScope(e.get()); } -static void organizeSubGroupsFiltered(Entry *root,bool additional) +static void organizeSubGroupsFiltered(const Entry *root,bool additional) { if (root->section==Entry::GROUPDOC_SEC && !root->name.isEmpty()) { @@ -737,18 +717,10 @@ static void organizeSubGroupsFiltered(Entry *root,bool additional) } } } - if (root->children()) - { - EntryListIterator eli(*root->children()); - Entry *e; - for (;(e=eli.current());++eli) - { - organizeSubGroupsFiltered(e,additional); - } - } + for (const auto &e : root->children()) organizeSubGroupsFiltered(e.get(),additional); } -static void organizeSubGroups(Entry *root) +static void organizeSubGroups(const Entry *root) { //printf("Defining groups\n"); // first process the @defgroups blocks @@ -760,7 +732,7 @@ static void organizeSubGroups(Entry *root) //---------------------------------------------------------------------- -static void buildFileList(Entry *root) +static void buildFileList(const Entry *root) { if (((root->section==Entry::FILEDOC_SEC) || ((root->section & Entry::FILE_MASK) && Config_getBool(EXTRACT_ALL))) && @@ -824,10 +796,10 @@ static void buildFileList(Entry *root) warn(fn,root->startLine,text); } } - RECURSE_ENTRYTREE(buildFileList,root); + for (const auto &e : root->children()) buildFileList(e.get()); } -static void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root) +static void addIncludeFile(ClassDef *cd,FileDef *ifd,const Entry *root) { if ( (!root->doc.stripWhiteSpace().isEmpty() || @@ -1220,7 +1192,7 @@ ClassDef::CompoundType convertToCompoundType(int section,uint64 specifier) } -static void addClassToContext(Entry *root) +static void addClassToContext(const Entry *root) { FileDef *fd = root->fileDef(); @@ -1386,7 +1358,7 @@ static void addClassToContext(Entry *root) //---------------------------------------------------------------------- // build a list of all classes mentioned in the documentation // and all classes that have a documentation block before their definition. -static void buildClassList(Entry *root) +static void buildClassList(const Entry *root) { if ( ((root->section & Entry::COMPOUND_MASK) || @@ -1395,10 +1367,10 @@ static void buildClassList(Entry *root) { addClassToContext(root); } - RECURSE_ENTRYTREE(buildClassList,root); + for (const auto &e : root->children()) buildClassList(e.get()); } -static void buildClassDocList(Entry *root) +static void buildClassDocList(const Entry *root) { if ( (root->section & Entry::COMPOUNDDOC_MASK) && !root->name.isEmpty() @@ -1406,7 +1378,7 @@ static void buildClassDocList(Entry *root) { addClassToContext(root); } - RECURSE_ENTRYTREE(buildClassDocList,root); + for (const auto &e : root->children()) buildClassDocList(e.get()); } static void resolveClassNestingRelations() @@ -1717,7 +1689,7 @@ static void findTagLessClasses() //---------------------------------------------------------------------- // build a list of all namespaces mentioned in the documentation // and all namespaces that have a documentation block before their definition. -static void buildNamespaceList(Entry *root) +static void buildNamespaceList(const Entry *root) { if ( (root->section==Entry::NAMESPACE_SEC || @@ -1847,7 +1819,7 @@ static void buildNamespaceList(Entry *root) } } } - RECURSE_ENTRYTREE(buildNamespaceList,root); + for (const auto &e : root->children()) buildNamespaceList(e.get()); } //---------------------------------------------------------------------- @@ -1871,7 +1843,7 @@ static const NamespaceDef *findUsedNamespace(const NamespaceSDict *unl, return usingNd; } -static void findUsingDirectives(Entry *root) +static void findUsingDirectives(const Entry *root) { if (root->section==Entry::USINGDIR_SEC) { @@ -2007,12 +1979,12 @@ static void findUsingDirectives(Entry *root) } } } - RECURSE_ENTRYTREE(findUsingDirectives,root); + for (const auto &e : root->children()) findUsingDirectives(e.get()); } //---------------------------------------------------------------------- -static void buildListOfUsingDecls(Entry *root) +static void buildListOfUsingDecls(const Entry *root) { if (root->section==Entry::USINGDECL_SEC && !(root->parent()->section&Entry::COMPOUND_MASK) // not a class/struct member @@ -2029,11 +2001,11 @@ static void buildListOfUsingDecls(Entry *root) } } } - RECURSE_ENTRYTREE(buildListOfUsingDecls,root); + for (const auto &e : root->children()) buildListOfUsingDecls(e.get()); } -static void findUsingDeclarations(Entry *root) +static void findUsingDeclarations(const Entry *root) { if (root->section==Entry::USINGDECL_SEC && !(root->parent()->section&Entry::COMPOUND_MASK) // not a class/struct member @@ -2113,12 +2085,12 @@ static void findUsingDeclarations(Entry *root) } } } - RECURSE_ENTRYTREE(findUsingDeclarations,root); + for (const auto &e : root->children()) findUsingDeclarations(e.get()); } //---------------------------------------------------------------------- -static void findUsingDeclImports(Entry *root) +static void findUsingDeclImports(const Entry *root) { if (root->section==Entry::USINGDECL_SEC && (root->parent()->section&Entry::COMPOUND_MASK) // in a class/struct member @@ -2211,7 +2183,7 @@ static void findUsingDeclImports(Entry *root) } } - RECURSE_ENTRYTREE(findUsingDeclImports,root); + for (const auto &e : root->children()) findUsingDeclImports(e.get()); } //---------------------------------------------------------------------- @@ -2250,10 +2222,12 @@ static void findIncludedUsingDirectives() //---------------------------------------------------------------------- static MemberDef *addVariableToClass( - Entry *root, + const Entry *root, ClassDef *cd, MemberType mtype, + const QCString &type, const QCString &name, + const QCString &args, bool fromAnnScope, MemberDef *fromAnnMemb, Protection prot, @@ -2270,38 +2244,38 @@ static MemberDef *addVariableToClass( Debug::print(Debug::Variables,0, " class variable:\n" " '%s' '%s'::'%s' '%s' prot=%d ann=%d init='%s'\n", - qPrint(root->type), + qPrint(type), qPrint(qualScope), qPrint(name), - qPrint(root->args), + qPrint(args), root->protection, fromAnnScope, qPrint(root->initializer) ); QCString def; - if (!root->type.isEmpty()) + if (!type.isEmpty()) { if (related || mtype==MemberType_Friend || Config_getBool(HIDE_SCOPE_NAMES)) { if (root->spec&Entry::Alias) // turn 'typedef B A' into 'using A = B' { - def="using "+name+" = "+root->type.mid(7); + def="using "+name+" = "+type.mid(7); } else { - def=root->type+" "+name+root->args; + def=type+" "+name+root->args; } } else { if (root->spec&Entry::Alias) // turn 'typedef B C::A' into 'using C::A = B' { - def="using "+qualScope+scopeSeparator+name+" = "+root->type.mid(7); + def="using "+qualScope+scopeSeparator+name+" = "+type.mid(7); } else { - def=root->type+" "+qualScope+scopeSeparator+name+root->args; + def=type+" "+qualScope+scopeSeparator+name+args; } } } @@ -2309,11 +2283,11 @@ static MemberDef *addVariableToClass( { if (Config_getBool(HIDE_SCOPE_NAMES)) { - def=name+root->args; + def=name+args; } else { - def=qualScope+scopeSeparator+name+root->args; + def=qualScope+scopeSeparator+name+args; } } def.stripPrefix("static "); @@ -2329,10 +2303,10 @@ static MemberDef *addVariableToClass( for (mni.toFirst();(md=mni.current());++mni) { //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n", - // md->getClassDef(),cd,root->type.data(),md->typeString()); + // md->getClassDef(),cd,type.data(),md->typeString()); if (!md->isAlias() && md->getClassDef()==cd && - removeRedundantWhiteSpace(root->type)==md->typeString()) + removeRedundantWhiteSpace(type)==md->typeString()) // member already in the scope { @@ -2344,7 +2318,7 @@ static MemberDef *addVariableToClass( md->setProtection(root->protection); cd->reclassifyMember(md,MemberType_Property); } - addMemberDocs(root,md,def,0,FALSE); + addMemberDocs(root,md,def,0,FALSE,root->spec); //printf(" Member already found!\n"); return md; } @@ -2360,7 +2334,7 @@ static MemberDef *addVariableToClass( // new member variable, typedef or enum value MemberDef *md=createMemberDef( fileName,root->startLine,root->startColumn, - root->type,name,root->args,root->exception, + type,name,args,root->exception, prot,Normal,root->stat,related, mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0, root->metaData); md->setTagInfo(root->tagInfo); @@ -2421,17 +2395,19 @@ static MemberDef *addVariableToClass( //TODO: insert FileDef instead of filename strings. cd->insertUsedFile(root->fileDef()); - root->changeSection(Entry::EMPTY_SEC); + root->markAsProcessed(); return md; } //---------------------------------------------------------------------- static MemberDef *addVariableToFile( - Entry *root, + const Entry *root, MemberType mtype, const QCString &scope, + const QCString &type, const QCString &name, + const QCString &args, bool fromAnnScope, /*int indentDepth,*/ MemberDef *fromAnnMemb) @@ -2440,10 +2416,10 @@ static MemberDef *addVariableToFile( " global variable:\n" " file='%s' type='%s' scope='%s' name='%s' args='%s' prot=`%d mtype=%d lang=%d\n", qPrint(root->fileName), - qPrint(root->type), + qPrint(type), qPrint(scope), qPrint(name), - qPrint(root->args), + qPrint(args), root->protection, mtype, root->lang @@ -2454,18 +2430,18 @@ static MemberDef *addVariableToFile( // see if we have a typedef that should hide a struct or union if (mtype==MemberType_Typedef && Config_getBool(TYPEDEF_HIDES_STRUCT)) { - QCString type = root->type; - type.stripPrefix("typedef "); - if (type.left(7)=="struct " || type.left(6)=="union ") + QCString ttype = type; + ttype.stripPrefix("typedef "); + if (ttype.left(7)=="struct " || ttype.left(6)=="union ") { - type.stripPrefix("struct "); - type.stripPrefix("union "); + ttype.stripPrefix("struct "); + ttype.stripPrefix("union "); static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*"); int l,s; - s = re.match(type,0,&l); + s = re.match(ttype,0,&l); if (s>=0) { - QCString typeValue = type.mid(s,l); + QCString typeValue = ttype.mid(s,l); ClassDef *cd = getClass(typeValue); if (cd) { @@ -2502,45 +2478,45 @@ static MemberDef *addVariableToFile( SrcLangExt lang = nd->getLanguage(); QCString sep=getLanguageSpecificSeparator(lang); - if (!root->type.isEmpty()) + if (!type.isEmpty()) { if (root->spec&Entry::Alias) // turn 'typedef B NS::A' into 'using NS::A = B' { - def="using "+nd->name()+sep+name+" = "+root->type; + def="using "+nd->name()+sep+name+" = "+type; } else // normal member { - def=root->type+" "+nd->name()+sep+name+root->args; + def=type+" "+nd->name()+sep+name+args; } } else { - def=nd->name()+sep+name+root->args; + def=nd->name()+sep+name+args; } } else { - if (!root->type.isEmpty() && !root->name.isEmpty()) + if (!type.isEmpty() && !root->name.isEmpty()) { if (name.at(0)=='@') // dummy variable representing anonymous union { - def=root->type; + def=type; } else { if (root->spec&Entry::Alias) // turn 'typedef B A' into 'using A = B' { - def="using "+root->name+" = "+root->type.mid(7); + def="using "+root->name+" = "+type.mid(7); } else // normal member { - def=root->type+" "+name+root->args; + def=type+" "+name+args; } } } else { - def=name+root->args; + def=name+args; } } def.stripPrefix("static "); @@ -2571,8 +2547,8 @@ static MemberDef *addVariableToFile( // variable already in the scope { bool isPHPArray = md->getLanguage()==SrcLangExt_PHP && - md->argsString()!=root->args && - root->args.find('[')!=-1; + md->argsString()!=args && + args.find('[')!=-1; bool staticsInDifferentFiles = root->stat && md->isStatic() && root->fileName!=md->getDefFileName(); @@ -2585,7 +2561,7 @@ static MemberDef *addVariableToFile( { Debug::print(Debug::Variables,0, " variable already found: scope=%s\n",qPrint(md->getOuterScope()->name())); - addMemberDocs(root,md,def,0,FALSE); + addMemberDocs(root,md,def,0,FALSE,root->spec); md->setRefItems(root->sli); // if md is a variable forward declaration and root is the definition that // turn md into the defintion @@ -2617,7 +2593,7 @@ static MemberDef *addVariableToFile( // new global variable, enum value or typedef MemberDef *md=createMemberDef( fileName,root->startLine,root->startColumn, - root->type,name,root->args,0, + type,name,args,0, root->protection, Normal,root->stat,Member, mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0, root->metaData); md->setTagInfo(root->tagInfo); @@ -2673,7 +2649,7 @@ static MemberDef *addVariableToFile( mn->append(md); Doxygen::functionNameSDict->append(name,mn); } - root->changeSection(Entry::EMPTY_SEC); + root->markAsProcessed(); return md; } @@ -2714,7 +2690,7 @@ static int findFunctionPtr(const QCString &type,int lang, int *pLength=0) /*! Returns TRUE iff \a type is a class within scope \a context. * Used to detect variable declarations that look like function prototypes. */ -static bool isVarWithConstructor(Entry *root) +static bool isVarWithConstructor(const Entry *root) { static QRegExp initChars("[0-9\"'&*!^]+"); static QRegExp idChars("[a-z_A-Z][a-z_A-Z0-9]*"); @@ -2833,7 +2809,7 @@ done: return result; } -static void addVariable(Entry *root,int isFuncPtr=-1) +static void addVariable(const Entry *root,int isFuncPtr=-1) { static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); @@ -2849,48 +2825,52 @@ static void addVariable(Entry *root,int isFuncPtr=-1) ); //printf("root->parent->name=%s\n",root->parent->name.data()); - if (root->type.isEmpty() && root->name.find("operator")==-1 && - (root->name.find('*')!=-1 || root->name.find('&')!=-1)) + QCString type = root->type; + QCString name = root->name; + QCString args = root->args; + if (type.isEmpty() && name.find("operator")==-1 && + (name.find('*')!=-1 || name.find('&')!=-1)) { // recover from parse error caused by redundant braces // like in "int *(var[10]);", which is parsed as // type="" name="int *" args="(var[10])" - root->type=root->name; + type=name; static const QRegExp reName("[a-z_A-Z][a-z_A-Z0-9]*"); int l=0; - int i=root->args.isEmpty() ? -1 : reName.match(root->args,0,&l); + int i=args.isEmpty() ? -1 : reName.match(args,0,&l); if (i!=-1) { - root->name=root->args.mid(i,l); - root->args=root->args.mid(i+l,root->args.find(')',i+l)-i-l); + name=args.mid(i,l); + args=args.mid(i+l,args.find(')',i+l)-i-l); } //printf("new: type='%s' name='%s' args='%s'\n", - // root->type.data(),root->name.data(),root->args.data()); + // type.data(),name.data(),args.data()); } else { int i=isFuncPtr; - if (i==-1 && (root->spec&Entry::Alias)==0) i=findFunctionPtr(root->type,root->lang); // for typedefs isFuncPtr is not yet set + if (i==-1 && (root->spec&Entry::Alias)==0) i=findFunctionPtr(type,root->lang); // for typedefs isFuncPtr is not yet set Debug::print(Debug::Variables,0," functionPtr? %s\n",i!=-1?"yes":"no"); if (i!=-1) // function pointer { - int ai = root->type.find('[',i); + int ai = type.find('[',i); if (ai>i) // function pointer array { - root->args.prepend(root->type.right(root->type.length()-ai)); - root->type=root->type.left(ai); + args.prepend(type.right(type.length()-ai)); + type=type.left(ai); } - else if (root->type.find(')',i)!=-1) // function ptr, not variable like "int (*bla)[10]" + else if (type.find(')',i)!=-1) // function ptr, not variable like "int (*bla)[10]" { - root->type=root->type.left(root->type.length()-1); - root->args.prepend(") "); - //printf("root->type=%s root->args=%s\n",root->type.data(),root->args.data()); + type=type.left(type.length()-1); + args.prepend(") "); + //printf("type=%s args=%s\n",type.data(),args.data()); } } } - QCString scope,name=removeRedundantWhiteSpace(root->name); + QCString scope; + name=removeRedundantWhiteSpace(name); // find the scope of this variable Entry *p = root->parent(); @@ -2906,7 +2886,7 @@ static void addVariable(Entry *root,int isFuncPtr=-1) } MemberType mtype; - QCString type=root->type.stripWhiteSpace(); + type=type.stripWhiteSpace(); ClassDef *cd=0; bool isRelated=FALSE; bool isMemberOf=FALSE; @@ -2915,10 +2895,10 @@ static void addVariable(Entry *root,int isFuncPtr=-1) classScope=stripTemplateSpecifiersFromScope(classScope,FALSE); QCString annScopePrefix=scope.left(scope.length()-classScope.length()); - if (root->name.findRev("::")!=-1) + if (name.findRev("::")!=-1) { - if (root->type=="friend class" || root->type=="friend struct" || - root->type=="friend union") + if (type=="friend class" || type=="friend struct" || + type=="friend union") { cd=getClass(scope); if (cd) @@ -2926,7 +2906,9 @@ static void addVariable(Entry *root,int isFuncPtr=-1) addVariableToClass(root, // entry cd, // class to add member to MemberType_Friend, // type of member - name, // name of the member + type, // type value as string + name, // name of the member + args, // arguments as string FALSE, // from Anonymous scope 0, // anonymous member Public, // protection @@ -3001,7 +2983,9 @@ static void addVariable(Entry *root,int isFuncPtr=-1) md=addVariableToClass(root, // entry pcd, // class to add member to mtype, // member type + type, // type value as string name, // member name + args, // arguments as string TRUE, // from anonymous scope 0, // from anonymous member root->protection, @@ -3013,7 +2997,7 @@ static void addVariable(Entry *root,int isFuncPtr=-1) { if (mtype==MemberType_Variable) { - md=addVariableToFile(root,mtype,pScope,name,TRUE,0); + md=addVariableToFile(root,mtype,pScope,type,name,args,TRUE,0); } //added=TRUE; } @@ -3026,7 +3010,9 @@ static void addVariable(Entry *root,int isFuncPtr=-1) addVariableToClass(root, // entry cd, // class to add member to mtype, // member type + type, // type value as string name, // name of the member + args, // arguments as string FALSE, // from anonymous scope md, // from anonymous member root->protection, @@ -3035,7 +3021,7 @@ static void addVariable(Entry *root,int isFuncPtr=-1) else if (!name.isEmpty()) // global variable { //printf("Inserting member in global scope %s!\n",scope.data()); - addVariableToFile(root,mtype,scope,name,FALSE,/*0,*/0); + addVariableToFile(root,mtype,scope,type,name,args,FALSE,/*0,*/0); } } @@ -3043,7 +3029,7 @@ static void addVariable(Entry *root,int isFuncPtr=-1) //---------------------------------------------------------------------- // Searches the Entry tree for typedef documentation sections. // If found they are stored in their class or in the global list. -static void buildTypedefList(Entry *root) +static void buildTypedefList(const Entry *root) { //printf("buildVarList(%s)\n",rootNav->name().data()); if (!root->name.isEmpty() && @@ -3053,24 +3039,15 @@ static void buildTypedefList(Entry *root) { addVariable(root); } - if (root->children()) - { - EntryListIterator eli(*root->children()); - Entry *e; - for (;(e=eli.current());++eli) - { - if (e->section!=Entry::ENUM_SEC) - { - buildTypedefList(e); - } - } - } + for (const auto &e : root->children()) + if (e->section!=Entry::ENUM_SEC) + buildTypedefList(e.get()); } //---------------------------------------------------------------------- // Searches the Entry tree for sequence documentation sections. // If found they are stored in the global list. -static void buildSequenceList(Entry *root) +static void buildSequenceList(const Entry *root) { if (!root->name.isEmpty() && root->section==Entry::VARIABLE_SEC && @@ -3079,24 +3056,15 @@ static void buildSequenceList(Entry *root) { addVariable(root); } - if (root->children()) - { - EntryListIterator eli(*root->children()); - Entry *e; - for (;(e=eli.current());++eli) - { - if (e->section!=Entry::ENUM_SEC) - { - buildSequenceList(e); - } - } - } + for (const auto &e : root->children()) + if (e->section!=Entry::ENUM_SEC) + buildSequenceList(e.get()); } //---------------------------------------------------------------------- // Searches the Entry tree for dictionary documentation sections. // If found they are stored in the global list. -static void buildDictionaryList(Entry *root) +static void buildDictionaryList(const Entry *root) { if (!root->name.isEmpty() && root->section==Entry::VARIABLE_SEC && @@ -3105,25 +3073,16 @@ static void buildDictionaryList(Entry *root) { addVariable(root); } - if (root->children()) - { - EntryListIterator eli(*root->children()); - Entry *e; - for (;(e=eli.current());++eli) - { - if (e->section!=Entry::ENUM_SEC) - { - buildDictionaryList(e); - } - } - } + for (const auto &e : root->children()) + if (e->section!=Entry::ENUM_SEC) + buildDictionaryList(e.get()); } //---------------------------------------------------------------------- // Searches the Entry tree for Variable documentation sections. // If found they are stored in their class or in the global list. -static void buildVarList(Entry *root) +static void buildVarList(const Entry *root) { //printf("buildVarList(%s) section=%08x\n",rootNav->name().data(),rootNav->section()); int isFuncPtr=-1; @@ -3143,18 +3102,9 @@ static void buildVarList(Entry *root) { addVariable(root,isFuncPtr); } - if (root->children()) - { - EntryListIterator eli(*root->children()); - Entry *e; - for (;(e=eli.current());++eli) - { - if (e->section!=Entry::ENUM_SEC) - { - buildVarList(e); - } - } - } + for (const auto &e : root->children()) + if (e->section!=Entry::ENUM_SEC) + buildVarList(e.get()); } //---------------------------------------------------------------------- @@ -3163,7 +3113,7 @@ static void buildVarList(Entry *root) // static void addInterfaceOrServiceToServiceOrSingleton( - Entry *const root, + const Entry *root, ClassDef *const cd, QCString const& rname) { @@ -3235,11 +3185,11 @@ static void addInterfaceOrServiceToServiceOrSingleton( cd->insertUsedFile(fd); addMemberToGroups(root,md); - root->changeSection(Entry::EMPTY_SEC); + root->markAsProcessed(); md->setRefItems(root->sli); } -static void buildInterfaceAndServiceList(Entry *root) +static void buildInterfaceAndServiceList(const Entry *root) { if (root->section==Entry::EXPORTED_INTERFACE_SEC || root->section==Entry::INCLUDED_SERVICE_SEC) @@ -3292,7 +3242,7 @@ static void buildInterfaceAndServiceList(Entry *root) { case SrcLangExt_Unknown: // fall through (root node always is Unknown) case SrcLangExt_IDL: - RECURSE_ENTRYTREE(buildInterfaceAndServiceList,root); + for (const auto &e : root->children()) buildInterfaceAndServiceList(e.get()); break; default: return; // nothing to do here @@ -3304,26 +3254,32 @@ static void buildInterfaceAndServiceList(Entry *root) // Searches the Entry tree for Function sections. // If found they are stored in their class or in the global list. -static void addMethodToClass(Entry *root,ClassDef *cd, - const QCString &rname,bool isFriend) +static void addMethodToClass(const Entry *root,ClassDef *cd, + const QCString &rtype,const QCString &rname,const QCString &rargs, + bool isFriend, + Protection protection,bool stat,Specifier virt,uint64 spec, + const QCString &relates + ) { FileDef *fd=root->fileDef(); int l; static QRegExp re("([a-z_A-Z0-9: ]*[ &*]+[ ]*"); - int ts=root->type.find('<'); - int te=root->type.findRev('>'); - int i=re.match(root->type,0,&l); + QCString type = rtype; + QCString args = rargs; + int ts=type.find('<'); + int te=type.findRev('>'); + int i=re.match(type,0,&l); if (i!=-1 && ts!=-1 && ts, see bug 677315 { i=-1; } if (cd->getLanguage()==SrcLangExt_Cpp && // only C has pointers - !root->type.isEmpty() && (root->spec&Entry::Alias)==0 && i!=-1) // function variable + !type.isEmpty() && (root->spec&Entry::Alias)==0 && i!=-1) // function variable { - root->args+=root->type.right(root->type.length()-i-l); - root->type=root->type.left(i+l); + args+=type.right(type.length()-i-l); + type=type.left(i+l); } QCString name=removeRedundantWhiteSpace(rname); @@ -3349,17 +3305,17 @@ static void addMethodToClass(Entry *root,ClassDef *cd, fileName = root->tagInfo->tagName; } - //printf("root->name='%s; root->args='%s' root->argList='%s'\n", - // root->name.data(),root->args.data(),argListToString(root->argList).data() + //printf("root->name='%s; args='%s' root->argList='%s'\n", + // root->name.data(),args.data(),argListToString(root->argList).data() // ); // adding class member MemberDef *md=createMemberDef( fileName,root->startLine,root->startColumn, - root->type,name,root->args,root->exception, - root->protection,root->virt, - root->stat && root->relatesType != MemberOf, - root->relates.isEmpty() ? Member : + type,name,args,root->exception, + protection,virt, + stat && root->relatesType != MemberOf, + relates.isEmpty() ? Member : root->relatesType == MemberOf ? Foreign : Related, mtype,root->tArgLists ? root->tArgLists->getLast() : 0,root->argList, root->metaData); md->setTagInfo(root->tagInfo); @@ -3369,7 +3325,7 @@ static void addMethodToClass(Entry *root,ClassDef *cd, md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); md->setBodySegment(root->bodyLine,root->endBodyLine); - md->setMemberSpecifiers(root->spec); + md->setMemberSpecifiers(spec); md->setMemberGroupId(root->mGrpId); md->setTypeConstraints(root->typeConstr); md->setLanguage(root->lang); @@ -3391,17 +3347,17 @@ static void addMethodToClass(Entry *root,ClassDef *cd, // for PHP we use Class::method and Namespace\method scopeSeparator="::"; } - if (!root->relates.isEmpty() || isFriend || Config_getBool(HIDE_SCOPE_NAMES)) + if (!relates.isEmpty() || isFriend || Config_getBool(HIDE_SCOPE_NAMES)) { - if (!root->type.isEmpty()) + if (!type.isEmpty()) { if (root->argList) { - def=root->type+" "+name; + def=type+" "+name; } else { - def=root->type+" "+name+root->args; + def=type+" "+name+args; } } else @@ -3412,21 +3368,21 @@ static void addMethodToClass(Entry *root,ClassDef *cd, } else { - def=name+root->args; + def=name+args; } } } else { - if (!root->type.isEmpty()) + if (!type.isEmpty()) { if (root->argList) { - def=root->type+" "+qualScope+scopeSeparator+name; + def=type+" "+qualScope+scopeSeparator+name; } else { - def=root->type+" "+qualScope+scopeSeparator+name+root->args; + def=type+" "+qualScope+scopeSeparator+name+args; } } else @@ -3437,7 +3393,7 @@ static void addMethodToClass(Entry *root,ClassDef *cd, } else { - def=qualScope+scopeSeparator+name+root->args; + def=qualScope+scopeSeparator+name+args; } } } @@ -3452,10 +3408,10 @@ static void addMethodToClass(Entry *root,ClassDef *cd, " Func Member:\n" " '%s' '%s'::'%s' '%s' proto=%d\n" " def='%s'\n", - qPrint(root->type), + qPrint(type), qPrint(qualScope), qPrint(rname), - qPrint(root->args), + qPrint(args), root->proto, qPrint(def) ); @@ -3480,12 +3436,12 @@ static void addMethodToClass(Entry *root,ClassDef *cd, cd->insertUsedFile(fd); addMemberToGroups(root,md); - root->changeSection(Entry::EMPTY_SEC); + root->markAsProcessed(); md->setRefItems(root->sli); } -static void buildFunctionList(Entry *root) +static void buildFunctionList(const Entry *root) { if (root->section==Entry::FUNCTION_SEC) { @@ -3576,7 +3532,8 @@ static void buildFunctionList(Entry *root) { Debug::print(Debug::Functions,0," --> member %s of class %s!\n", qPrint(rname),qPrint(cd->name())); - addMethodToClass(root,cd,rname,isFriend); + addMethodToClass(root,cd,root->type,rname,root->args,isFriend, + root->protection,root->stat,root->virt,root->spec,root->relates); } else if (!((root->parent()->section & Entry::COMPOUND_MASK) || root->parent()->section==Entry::OBJCIMPL_SEC @@ -3880,9 +3837,7 @@ static void buildFunctionList(Entry *root) if (root->relatesType == Simple) // if this is a relatesalso command, // allow find Member to pick it up { - root->changeSection(Entry::EMPTY_SEC); // Otherwise we have finished - // with this entry. - + root->markAsProcessed(); // Otherwise we have finished with this entry. } } else @@ -3911,7 +3866,7 @@ static void buildFunctionList(Entry *root) ); } } - RECURSE_ENTRYTREE(buildFunctionList,root); + for (const auto &e : root->children()) buildFunctionList(e.get()); } //---------------------------------------------------------------------- @@ -4259,7 +4214,7 @@ static ClassDef *findClassWithinClassContext(Definition *context,ClassDef *cd,co } -static void findUsedClassesForClass(Entry *root, +static void findUsedClassesForClass(const Entry *root, Definition *context, ClassDef *masterCd, ClassDef *instanceCd, @@ -4429,7 +4384,7 @@ static void findUsedClassesForClass(Entry *root, } static void findBaseClassesForClass( - Entry *root, + const Entry *root, Definition *context, ClassDef *masterCd, ClassDef *instanceCd, @@ -4491,7 +4446,7 @@ static void findBaseClassesForClass( //---------------------------------------------------------------------- -static bool findTemplateInstanceRelation(Entry *root, +static bool findTemplateInstanceRelation(const Entry *root, Definition *context, ClassDef *templateClass,const QCString &templSpec, QDict *templateNames, @@ -4531,9 +4486,10 @@ static bool findTemplateInstanceRelation(Entry *root, // search for new template instances caused by base classes of // instanceClass - Entry *templateRoot = g_classEntries.find(templateClass->name()); - if (templateRoot) + auto it = g_classEntries.find(templateClass->name().data()); + if (it!=g_classEntries.end()) { + const Entry *templateRoot = it->second; Debug::print(Debug::Classes,0," template root found %s templSpec=%s!\n", qPrint(templateRoot->name),qPrint(templSpec)); ArgumentList *templArgs = new ArgumentList; @@ -4653,7 +4609,7 @@ static int findEndOfTemplate(const QCString &s,int startPos) } static bool findClassRelation( - Entry *root, + const Entry *root, Definition *context, ClassDef *cd, BaseInfo *bi, @@ -5010,7 +4966,7 @@ static bool findClassRelation( //---------------------------------------------------------------------- // Computes the base and super classes for each class in the tree -static bool isClassSection(Entry *root) +static bool isClassSection(const Entry *root) { if ( !root->name.isEmpty() ) { @@ -5032,16 +4988,16 @@ static bool isClassSection(Entry *root) /*! Builds a dictionary of all entry nodes in the tree starting with \a root */ -static void findClassEntries(Entry *root) +static void findClassEntries(const Entry *root) { if (isClassSection(root)) { - g_classEntries.insert(root->name,root); + g_classEntries.insert({root->name.data(),root}); } - RECURSE_ENTRYTREE(findClassEntries,root); + for (const auto &e : root->children()) findClassEntries(e.get()); } -static QCString extractClassName(Entry *root) +static QCString extractClassName(const Entry *root) { // strip any anonymous scopes first QCString bName=stripAnonymousNamespaceScope(root->name); @@ -5066,10 +5022,9 @@ static void findInheritedTemplateInstances() { ClassSDict::Iterator cli(*Doxygen::classSDict); for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); - QDictIterator edi(g_classEntries); - Entry *root; - for (;(root=edi.current());++edi) + for (const auto &kv : g_classEntries) { + const Entry *root = kv.second; ClassDef *cd; QCString bName = extractClassName(root); Debug::print(Debug::Classes,0," Inheritance: Class %s : \n",qPrint(bName)); @@ -5085,10 +5040,9 @@ static void findUsedTemplateInstances() { ClassSDict::Iterator cli(*Doxygen::classSDict); for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); - QDictIterator edi(g_classEntries); - Entry *root; - for (;(root=edi.current());++edi) + for (const auto &kv : g_classEntries) { + const Entry *root = kv.second; ClassDef *cd; QCString bName = extractClassName(root); Debug::print(Debug::Classes,0," Usage: Class %s : \n",qPrint(bName)); @@ -5104,10 +5058,9 @@ static void computeClassRelations() { ClassSDict::Iterator cli(*Doxygen::classSDict); for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); - QDictIterator edi(g_classEntries); - Entry *root; - for (;(root=edi.current());++edi) + for (const auto &kv : g_classEntries) { + const Entry *root = kv.second; ClassDef *cd; QCString bName = extractClassName(root); @@ -5137,10 +5090,9 @@ static void computeClassRelations() static void computeTemplateClassRelations() { - QDictIterator edi(g_classEntries); - Entry *root; - for (;(root=edi.current());++edi) + for (const auto &kv : g_classEntries) { + const Entry *root = kv.second; QCString bName=stripAnonymousNamespaceScope(root->name); bName=stripTemplateSpecifiersFromScope(bName); ClassDef *cd=getClass(bName); @@ -5340,15 +5292,15 @@ static void generateXRefPages() // set the function declaration of the member to 'funcDecl'. If the boolean // over_load is set the standard overload text is added. -static void addMemberDocs(Entry *root, +static void addMemberDocs(const Entry *root, MemberDef *md, const char *funcDecl, ArgumentList *al, bool over_load, - NamespaceSDict * + uint64 spec ) { //printf("addMemberDocs: '%s'::'%s' '%s' funcDecl='%s' mSpec=%d\n", - // root->parent->name.data(),md->name().data(),md->argsString(),funcDecl,root->spec); + // root->parent->name.data(),md->name().data(),md->argsString(),funcDecl,spec); QCString fDecl=funcDecl; // strip extern specifier fDecl.stripPrefix("extern "); @@ -5452,7 +5404,7 @@ static void addMemberDocs(Entry *root, md->enableReferencedByRelation(md->hasReferencedByRelation() || root->referencedByRelation); md->enableReferencesRelation(md->hasReferencesRelation() || root->referencesRelation); - md->mergeMemberSpecifiers(root->spec); + md->mergeMemberSpecifiers(spec); md->addSectionsToDefinition(root->anchors); addMemberToGroups(root,md); if (cd) cd->insertUsedFile(rfd); @@ -5496,13 +5448,14 @@ static const ClassDef *findClassDefinition(FileDef *fd,NamespaceDef *nd, // with name 'name' and argument list 'args' (for overloading) and // function declaration 'decl' to the corresponding member definition. -static bool findGlobalMember(Entry *root, +static bool findGlobalMember(const Entry *root, const QCString &namespaceName, const char *type, const char *name, const char *tempArg, const char *, - const char *decl) + const char *decl, + uint64 spec) { Debug::print(Debug::FindMembers,0, "2. findGlobalMember(namespace=%s,type=%s,name=%s,tempArg=%s,decl=%s)\n", @@ -5612,7 +5565,7 @@ static bool findGlobalMember(Entry *root, if (matching) // add docs to the member { Debug::print(Debug::FindMembers,0,"5. Match found\n"); - addMemberDocs(root,md->resolveAlias(),decl,root->argList,FALSE); + addMemberDocs(root,md->resolveAlias(),decl,root->argList,FALSE,root->spec); found=TRUE; } } @@ -5822,7 +5775,10 @@ static void substituteTemplatesInArgList( * The boolean \a isFunc is a hint that indicates that this is a function * instead of a variable or typedef. */ -static void findMember(Entry *root, +static void findMember(const Entry *root, + const QCString &relates, + const QCString &type, + const QCString &args, QCString funcDecl, bool overloaded, bool isFunc @@ -5832,7 +5788,7 @@ static void findMember(Entry *root, "findMember(root=%p,funcDecl='%s',related='%s',overload=%d," "isFunc=%d mGrpId=%d tArgList=%p (#=%d) " "spec=%lld lang=%x\n", - root,qPrint(funcDecl),qPrint(root->relates),overloaded,isFunc,root->mGrpId, + root,qPrint(funcDecl),qPrint(relates),overloaded,isFunc,root->mGrpId, root->tArgLists,root->tArgLists ? root->tArgLists->count() : 0, root->spec,root->lang ); @@ -5850,6 +5806,7 @@ static void findMember(Entry *root, bool isMemberOf=FALSE; bool isFriend=FALSE; bool done; + uint64 spec = root->spec; do { done=TRUE; @@ -5860,17 +5817,17 @@ static void findMember(Entry *root, } if (funcDecl.stripPrefix("inline ")) { - root->spec|=Entry::Inline; + spec|=Entry::Inline; done=FALSE; } if (funcDecl.stripPrefix("explicit ")) { - root->spec|=Entry::Explicit; + spec|=Entry::Explicit; done=FALSE; } if (funcDecl.stripPrefix("mutable ")) { - root->spec|=Entry::Mutable; + spec|=Entry::Mutable; done=FALSE; } if (funcDecl.stripPrefix("virtual ")) @@ -5926,21 +5883,21 @@ static void findMember(Entry *root, // related field. //printf("scopeName='%s' className='%s' namespaceName='%s'\n", // scopeName.data(),className.data(),namespaceName.data()); - if (!root->relates.isEmpty()) + if (!relates.isEmpty()) { // related member, prefix user specified scope isRelated=TRUE; isMemberOf=(root->relatesType == MemberOf); - if (getClass(root->relates)==0 && !scopeName.isEmpty()) + if (getClass(relates)==0 && !scopeName.isEmpty()) { - scopeName= mergeScopes(scopeName,root->relates); + scopeName= mergeScopes(scopeName,relates); } else { - scopeName = root->relates; + scopeName = relates; } } - if (root->relates.isEmpty() && root->parent() && + if (relates.isEmpty() && root->parent() && ((root->parent()->section&Entry::SCOPE_MASK) || (root->parent()->section==Entry::OBJCIMPL_SEC) ) && @@ -6015,7 +5972,7 @@ static void findMember(Entry *root, { scopeName=namespaceName; } - else if (!root->relates.isEmpty() || // relates command with explicit scope + else if (!relates.isEmpty() || // relates command with explicit scope !getClass(className)) // class name only exists in a namespace { scopeName=namespaceName+"::"+className; @@ -6122,7 +6079,7 @@ static void findMember(Entry *root, " isFunc=%d\n\n", qPrint(namespaceName),qPrint(className), qPrint(funcType),qPrint(funcSpec),qPrint(funcName),qPrint(funcArgs),qPrint(funcTempList), - qPrint(funcDecl),qPrint(root->relates),qPrint(exceptions),isRelated,isMemberOf,isFriend, + qPrint(funcDecl),qPrint(relates),qPrint(exceptions),isRelated,isMemberOf,isFriend, isFunc ); @@ -6306,11 +6263,8 @@ static void findMember(Entry *root, // specialization. In this case we add it to the class // even though the member arguments do not match. - // TODO: copy other aspects? - root->protection=md->protection(); // copy protection level - root->stat=md->isStatic(); - root->virt=md->virtualness(); - addMethodToClass(root,cd,md->name(),isFriend); + addMethodToClass(root,cd,type,md->name(),args,isFriend, + md->protection(),md->isStatic(),md->virtualness(),spec,relates); return; } delete argList; @@ -6318,7 +6272,7 @@ static void findMember(Entry *root, } if (matching) { - addMemberDocs(root,md,funcDecl,0,overloaded,0/* TODO */); + addMemberDocs(root,md,funcDecl,0,overloaded,spec); count++; memFound=TRUE; } @@ -6354,10 +6308,8 @@ static void findMember(Entry *root, root->tArgLists->getLast()->count()<=templAl->count()) { Debug::print(Debug::FindMembers,0,"7. add template specialization\n"); - root->protection=md->protection(); - root->stat=md->isStatic(); - root->virt=md->virtualness(); - addMethodToClass(root,ccd,md->name(),isFriend); + addMethodToClass(root,ccd,type,md->name(),args,isFriend, + root->protection,root->stat,root->virt,spec,relates); return; } if (md->argsString()==argListToString(root->argList,TRUE,FALSE)) @@ -6387,7 +6339,7 @@ static void findMember(Entry *root, { // we didn't find an actual match on argument lists, but there is only 1 member with this // name in the same scope, so that has to be the one. - addMemberDocs(root,umd,funcDecl,0,overloaded,0); + addMemberDocs(root,umd,funcDecl,0,overloaded,spec); return; } else if (candidates>1 && ecd && emd) @@ -6395,7 +6347,7 @@ static void findMember(Entry *root, // we didn't find a unique match using type resolution, // but one of the matches has the exact same signature so // we take that one. - addMemberDocs(root,emd,funcDecl,0,overloaded,0); + addMemberDocs(root,emd,funcDecl,0,overloaded,spec); return; } } @@ -6505,7 +6457,7 @@ static void findMember(Entry *root, md->setBodySegment(root->bodyLine,root->endBodyLine); FileDef *fd=root->fileDef(); md->setBodyDef(fd); - md->setMemberSpecifiers(root->spec); + md->setMemberSpecifiers(spec); md->setMemberGroupId(root->mGrpId); mn->append(md); cd->insertMember(md); @@ -6575,7 +6527,7 @@ static void findMember(Entry *root, md->setBodySegment(root->bodyLine,root->endBodyLine); FileDef *fd=root->fileDef(); md->setBodyDef(fd); - md->setMemberSpecifiers(root->spec); + md->setMemberSpecifiers(spec); md->setMemberGroupId(root->mGrpId); mn->append(md); cd->insertMember(md); @@ -6585,7 +6537,7 @@ static void findMember(Entry *root, } else // unrelated function with the same name as a member { - if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl)) + if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec)) { QCString fullFuncDecl=funcDecl.copy(); if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE); @@ -6596,11 +6548,11 @@ static void findMember(Entry *root, } } } - else if (isRelated && !root->relates.isEmpty()) + else if (isRelated && !relates.isEmpty()) { Debug::print(Debug::FindMembers,0,"2. related function\n" " scopeName=%s className=%s\n",qPrint(scopeName),qPrint(className)); - if (className.isEmpty()) className=root->relates; + if (className.isEmpty()) className=relates; ClassDef *cd; //printf("scopeName='%s' className='%s'\n",scopeName.data(),className.data()); if ((cd=getClass(scopeName))) @@ -6649,7 +6601,7 @@ static void findMember(Entry *root, { //printf("addMemberDocs for related member %s\n",root->name.data()); //rmd->setMemberDefTemplateArguments(root->mtArgList); - addMemberDocs(root,rmd,funcDecl,0,overloaded); + addMemberDocs(root,rmd,funcDecl,0,overloaded,spec); } } @@ -6763,7 +6715,7 @@ static void findMember(Entry *root, // md->setMemberGroup(memberGroupDict[root->mGrpId]); //} md->setMemberClass(cd); - md->setMemberSpecifiers(root->spec); + md->setMemberSpecifiers(spec); md->setDefinition(funcDecl); md->enableCallGraph(root->callGraph); md->enableCallerGraph(root->callerGraph); @@ -6798,7 +6750,7 @@ static void findMember(Entry *root, } if (root->relatesType == Duplicate) { - if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl)) + if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec)) { QCString fullFuncDecl=funcDecl.copy(); if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE); @@ -6852,7 +6804,7 @@ localObjCMethod: md->setBodySegment(root->bodyLine,root->endBodyLine); FileDef *fd=root->fileDef(); md->setBodyDef(fd); - md->setMemberSpecifiers(root->spec); + md->setMemberSpecifiers(spec); md->setMemberGroupId(root->mGrpId); cd->insertMember(md); cd->insertUsedFile(fd); @@ -6875,7 +6827,7 @@ localObjCMethod: } else // unrelated not overloaded member found { - bool globMem = findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl); + bool globMem = findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec); if (className.isEmpty() && !globMem) { warn(root->fileName,root->startLine, @@ -6904,7 +6856,7 @@ localObjCMethod: // find the members corresponding to the different documentation blocks // that are extracted from the sources. -static void filterMemberDocumentation(Entry *root) +static void filterMemberDocumentation(const Entry *root,const QCString relates) { int i=-1,l; Debug::print(Debug::FindMembers,0, @@ -6914,26 +6866,20 @@ static void filterMemberDocumentation(Entry *root) //printf("root->parent()->name=%s\n",root->parent()->name.data()); bool isFunc=TRUE; - if (root->relatesType == Duplicate && !root->relates.isEmpty()) - { - QCString tmp = root->relates; - root->relates.resize(0); - filterMemberDocumentation(root); - root->relates = tmp; - } - + QCString type = root->type; + QCString args = root->args; if ( // detect func variable/typedef to func ptr - (i=findFunctionPtr(root->type,root->lang,&l))!=-1 + (i=findFunctionPtr(type,root->lang,&l))!=-1 ) { //printf("Fixing function pointer!\n"); // fix type and argument - root->args.prepend(root->type.right(root->type.length()-i-l)); - root->type=root->type.left(i+l); - //printf("Results type=%s,name=%s,args=%s\n",root->type.data(),root->name.data(),root->args.data()); + args.prepend(type.right(type.length()-i-l)); + type=type.left(i+l); + //printf("Results type=%s,name=%s,args=%s\n",type.data(),root->name.data(),args.data()); isFunc=FALSE; } - else if ((root->type.left(8)=="typedef " && root->args.find('(')!=-1)) + else if ((type.left(8)=="typedef " && args.find('(')!=-1)) // detect function types marked as functions { isFunc=FALSE; @@ -6943,80 +6889,117 @@ static void filterMemberDocumentation(Entry *root) if (root->section==Entry::MEMBERDOC_SEC) { //printf("Documentation for inline member '%s' found args='%s'\n", - // root->name.data(),root->args.data()); - //if (root->relates.length()) printf(" Relates %s\n",root->relates.data()); - if (root->type.isEmpty()) - { - findMember(root,root->name+root->args+root->exception,FALSE,isFunc); + // root->name.data(),args.data()); + //if (relates.length()) printf(" Relates %s\n",relates.data()); + if (type.isEmpty()) + { + findMember(root, + relates, + type, + args, + root->name + args + root->exception, + FALSE, + isFunc); } else { - findMember(root,root->type+" "+root->name+root->args+root->exception,FALSE,isFunc); + findMember(root, + relates, + type, + args, + type + " " + root->name + args + root->exception, + FALSE, + isFunc); } } else if (root->section==Entry::OVERLOADDOC_SEC) { //printf("Overloaded member %s found\n",root->name.data()); - findMember(root,root->name,TRUE,isFunc); + findMember(root, + relates, + type, + args, + root->name, + TRUE, + isFunc); } else if ((root->section==Entry::FUNCTION_SEC // function || (root->section==Entry::VARIABLE_SEC && // variable - !root->type.isEmpty() && // with a type - g_compoundKeywordDict.find(root->type)==0 // that is not a keyword + !type.isEmpty() && // with a type + g_compoundKeywordDict.find(type)==0 // that is not a keyword // (to skip forward declaration of class etc.) ) ) ) { //printf("Documentation for member '%s' found args='%s' excp='%s'\n", - // root->name.data(),root->args.data(),root->exception.data()); - //if (root->relates.length()) printf(" Relates %s\n",root->relates.data()); - //printf("Inside=%s\n Relates=%s\n",root->inside.data(),root->relates.data()); - if (root->type=="friend class" || root->type=="friend struct" || - root->type=="friend union") + // root->name.data(),args.data(),root->exception.data()); + //if (relates.length()) printf(" Relates %s\n",relates.data()); + //printf("Inside=%s\n Relates=%s\n",root->inside.data(),relates.data()); + if (type=="friend class" || type=="friend struct" || + type=="friend union") { findMember(root, - root->type+" "+ - root->name, + relates, + type, + args, + type+" "+root->name, FALSE,FALSE); } - else if (!root->type.isEmpty()) + else if (!type.isEmpty()) { findMember(root, - root->type+" "+ - root->inside+ - root->name+ - root->args+ - root->exception, + relates, + type, + args, + type+" "+ root->inside + root->name + args + root->exception, FALSE,isFunc); } else { findMember(root, - root->inside+ - root->name+ - root->args+ - root->exception, + relates, + type, + args, + root->inside + root->name + args + root->exception, FALSE,isFunc); } } - else if (root->section==Entry::DEFINE_SEC && !root->relates.isEmpty()) + else if (root->section==Entry::DEFINE_SEC && !relates.isEmpty()) { - findMember(root,root->name+root->args,FALSE,!root->args.isEmpty()); + findMember(root, + relates, + type, + args, + root->name + args, + FALSE, + !args.isEmpty()); } else if (root->section==Entry::VARIABLEDOC_SEC) { //printf("Documentation for variable %s found\n",root->name.data()); - //if (!root->relates.isEmpty()) printf(" Relates %s\n",root->relates.data()); - findMember(root,root->name,FALSE,FALSE); + //if (!relates.isEmpty()) printf(" Relates %s\n",relates.data()); + findMember(root, + relates, + type, + args, + root->name, + FALSE, + FALSE); } else if (root->section==Entry::EXPORTED_INTERFACE_SEC || root->section==Entry::INCLUDED_SERVICE_SEC) { - findMember(root,root->type + " " + root->name,FALSE,FALSE); + findMember(root, + relates, + type, + args, + type + " " + root->name, + FALSE, + FALSE); } else { @@ -7025,7 +7008,7 @@ static void filterMemberDocumentation(Entry *root) } } -static void findMemberDocumentation(Entry *root) +static void findMemberDocumentation(const Entry *root) { if (root->section==Entry::MEMBERDOC_SEC || root->section==Entry::OVERLOADDOC_SEC || @@ -7037,42 +7020,41 @@ static void findMemberDocumentation(Entry *root) root->section==Entry::EXPORTED_INTERFACE_SEC ) { - filterMemberDocumentation(root); + if (root->relatesType == Duplicate && !root->relates.isEmpty()) + { + filterMemberDocumentation(root,""); + } + filterMemberDocumentation(root,root->relates); } - if (root->children()) + for (const auto &e : root->children()) { - EntryListIterator eli(*root->children()); - Entry *e; - for (;(e=eli.current());++eli) + if (e->section!=Entry::ENUM_SEC) { - if (e->section!=Entry::ENUM_SEC) findMemberDocumentation(e); + findMemberDocumentation(e.get()); } } } //---------------------------------------------------------------------- -static void findObjCMethodDefinitions(Entry *root) +static void findObjCMethodDefinitions(const Entry *root) { - if (root->children()) + for (const auto &objCImpl : root->children()) { - EntryListIterator eli(*root->children()); - Entry *objCImpl; - for (;(objCImpl=eli.current());++eli) + if (objCImpl->section==Entry::OBJCIMPL_SEC) { - if (objCImpl->section==Entry::OBJCIMPL_SEC && objCImpl->children()) + for (const auto &objCMethod : objCImpl->children()) { - EntryListIterator seli(*objCImpl->children()); - Entry *objCMethod; - for (;(objCMethod=seli.current());++seli) + if (objCMethod->section==Entry::FUNCTION_SEC) { - if (objCMethod->section==Entry::FUNCTION_SEC) - { - //Printf(" Found ObjC method definition %s\n",objCMethod->name.data()); - findMember(objCMethod, objCMethod->type+" "+objCImpl->name+"::"+ - objCMethod->name+" "+objCMethod->args, FALSE,TRUE); - objCMethod->section=Entry::EMPTY_SEC; - } + //Printf(" Found ObjC method definition %s\n",objCMethod->name.data()); + findMember(objCMethod.get(), + objCMethod->relates, + objCMethod->type, + objCMethod->args, + objCMethod->type+" "+objCImpl->name+"::"+objCMethod->name+" "+objCMethod->args, + FALSE,TRUE); + objCMethod->section=Entry::EMPTY_SEC; } } } @@ -7082,7 +7064,7 @@ static void findObjCMethodDefinitions(Entry *root) //---------------------------------------------------------------------- // find and add the enumeration to their classes, namespaces or files -static void findEnums(Entry *root) +static void findEnums(const Entry *root) { if (root->section==Entry::ENUM_SEC) { @@ -7255,13 +7237,13 @@ static void findEnums(Entry *root) } else { - RECURSE_ENTRYTREE(findEnums,root); + for (const auto &e : root->children()) findEnums(e.get()); } } //---------------------------------------------------------------------- -static void addEnumValuesToEnums(Entry *root) +static void addEnumValuesToEnums(const Entry *root) { if (root->section==Entry::ENUM_SEC) // non anonymous enumeration @@ -7337,12 +7319,10 @@ static void addEnumValuesToEnums(Entry *root) MemberDef *md; for (mni.toFirst(); (md=mni.current()) ; ++mni) // for each enum in this list { - if (!md->isAlias() && md->isEnumerate() && root->children()) + if (!md->isAlias() && md->isEnumerate() && !root->children().empty()) { //printf(" enum with %d children\n",root->children()->count()); - EntryListIterator eli(*root->children()); // for each enum value - Entry *e; - for (;(e=eli.current());++eli) + for (const auto &e : root->children()) { SrcLangExt sle; if ( @@ -7474,7 +7454,7 @@ static void addEnumValuesToEnums(Entry *root) } else { - RECURSE_ENTRYTREE(addEnumValuesToEnums,root); + for (const auto &e : root->children()) addEnumValuesToEnums(e.get()); } } @@ -7482,7 +7462,7 @@ static void addEnumValuesToEnums(Entry *root) //---------------------------------------------------------------------- // find the documentation blocks for the enumerations -static void findEnumDocumentation(Entry *root) +static void findEnumDocumentation(const Entry *root) { if (root->section==Entry::ENUMDOC_SEC && !root->name.isEmpty() @@ -7615,7 +7595,7 @@ static void findEnumDocumentation(Entry *root) } } } - RECURSE_ENTRYTREE(findEnumDocumentation,root); + for (const auto &e : root->children()) findEnumDocumentation(e.get()); } // search for each enum (member or function) in mnl if it has documented @@ -8730,12 +8710,12 @@ static void findDefineDocumentation(Entry *root) } } } - RECURSE_ENTRYTREE(findDefineDocumentation,root); + for (const auto &e : root->children()) findDefineDocumentation(e.get()); } //---------------------------------------------------------------------------- -static void findDirDocumentation(Entry *root) +static void findDirDocumentation(const Entry *root) { if (root->section == Entry::DIRDOC_SEC) { @@ -8791,7 +8771,7 @@ static void findDirDocumentation(Entry *root) "directory found for command \\dir %s\n",normalizedName.data()); } } - RECURSE_ENTRYTREE(findDirDocumentation,root); + for (const auto &e : root->children()) findDirDocumentation(e.get()); } @@ -8821,7 +8801,7 @@ static void buildPageList(Entry *root) 0,0 ); } - RECURSE_ENTRYTREE(buildPageList,root); + for (const auto &e : root->children()) buildPageList(e.get()); } // search for the main page defined in this project @@ -8875,7 +8855,7 @@ static void findMainPage(Entry *root) Doxygen::mainPage->docFile().data(),Doxygen::mainPage->docLine()); } } - RECURSE_ENTRYTREE(findMainPage,root); + for (const auto &e : root->children()) findMainPage(e.get()); } // search for the main page imported via tag files and add only the section labels @@ -8888,7 +8868,7 @@ static void findMainPageTagFiles(Entry *root) Doxygen::mainPage->addSectionsToDefinition(root->anchors); } } - RECURSE_ENTRYTREE(findMainPageTagFiles,root); + for (const auto &e : root->children()) findMainPageTagFiles(e.get()); } static void computePageRelations(Entry *root) @@ -8925,7 +8905,7 @@ static void computePageRelations(Entry *root) } } } - RECURSE_ENTRYTREE(computePageRelations,root); + for (const auto &e : root->children()) computePageRelations(e.get()); } static void checkPageRelations() @@ -9071,7 +9051,7 @@ static void buildExampleList(Entry *root) //addExampleToGroups(root,pd); } } - RECURSE_ENTRYTREE(buildExampleList,root); + for (const auto &e : root->children()) buildExampleList(e.get()); } //---------------------------------------------------------------------------- @@ -9085,10 +9065,9 @@ void printNavTree(Entry *root,int indent) indentStr.isEmpty()?"":indentStr.data(), root->name.isEmpty()?"":root->name.data(), root->section); - if (root->children()) + for (const auto &e : root->children()) { - EntryListIterator eli(*root->children()); - for (;eli.current();++eli) printNavTree(eli.current(),indent+2); + printNavTree(e.get(),indent+2); } } @@ -9310,7 +9289,7 @@ static void compareDoxyfile() //---------------------------------------------------------------------------- -static void readTagFile(Entry *root,const char *tl) +static void readTagFile(const std::unique_ptr &root,const char *tl) { QCString tagLine = tl; QCString fileName; @@ -9479,7 +9458,7 @@ static ParserInterface *getParserForFile(const char *fn) } static void parseFile(ParserInterface *parser, - Entry *root,FileDef *fd,const char *fn, + const std::unique_ptr &root,FileDef *fd,const char *fn, bool sameTu,QStrList &filesInSameTu) { #if USE_LIBCLANG @@ -9532,15 +9511,15 @@ static void parseFile(ParserInterface *parser, fd->getAllIncludeFilesRecursively(filesInSameTu); } - Entry *fileRoot = new Entry; + std::unique_ptr fileRoot = std::make_unique(); // use language parse to parse the file parser->parseInput(fileName,convBuf.data(),fileRoot,sameTu,filesInSameTu); fileRoot->setFileDef(fd); - root->addSubEntry(fileRoot); + root->moveToSubEntryAndKeep(fileRoot); } //! parse the list of input files -static void parseFiles(Entry *root) +static void parseFiles(const std::unique_ptr &root) { #if USE_LIBCLANG static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); @@ -11346,7 +11325,7 @@ void parseInput() * Handle Tag Files * **************************************************************************/ - Entry *root=new Entry; + std::unique_ptr root = std::make_unique(); msg("Reading and parsing tag files\n"); QStrList &tagFileList = Config_getList(TAGFILES); @@ -11381,31 +11360,31 @@ void parseInput() **************************************************************************/ g_s.begin("Building group list...\n"); - buildGroupList(root); - organizeSubGroups(root); + buildGroupList(root.get()); + organizeSubGroups(root.get()); g_s.end(); g_s.begin("Building directory list...\n"); buildDirectories(); - findDirDocumentation(root); + findDirDocumentation(root.get()); g_s.end(); g_s.begin("Building namespace list...\n"); - buildNamespaceList(root); - findUsingDirectives(root); + buildNamespaceList(root.get()); + findUsingDirectives(root.get()); g_s.end(); g_s.begin("Building file list...\n"); - buildFileList(root); + buildFileList(root.get()); g_s.end(); //generateFileTree(); g_s.begin("Building class list...\n"); - buildClassList(root); + buildClassList(root.get()); g_s.end(); // build list of using declarations here (global list) - buildListOfUsingDecls(root); + buildListOfUsingDecls(root.get()); g_s.end(); g_s.begin("Computing nesting relations for classes...\n"); @@ -11422,14 +11401,14 @@ void parseInput() g_usingDeclarations.clear(); g_s.begin("Associating documentation with classes...\n"); - buildClassDocList(root); + buildClassDocList(root.get()); g_s.begin("Building example list...\n"); - buildExampleList(root); + buildExampleList(root.get()); g_s.end(); g_s.begin("Searching for enumerations...\n"); - findEnums(root); + findEnums(root.get()); g_s.end(); // Since buildVarList calls isVarWithConstructor @@ -11437,24 +11416,24 @@ void parseInput() // typedefs first so the relations between classes via typedefs // are properly resolved. See bug 536385 for an example. g_s.begin("Searching for documented typedefs...\n"); - buildTypedefList(root); + buildTypedefList(root.get()); g_s.end(); if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) { g_s.begin("Searching for documented sequences...\n"); - buildSequenceList(root); + buildSequenceList(root.get()); g_s.end(); g_s.begin("Searching for documented dictionaries...\n"); - buildDictionaryList(root); + buildDictionaryList(root.get()); g_s.end(); } g_s.begin("Searching for members imported via using declarations...\n"); // this should be after buildTypedefList in order to properly import // used typedefs - findUsingDeclarations(root); + findUsingDeclarations(root.get()); g_s.end(); g_s.begin("Searching for included using directives...\n"); @@ -11462,14 +11441,14 @@ void parseInput() g_s.end(); g_s.begin("Searching for documented variables...\n"); - buildVarList(root); + buildVarList(root.get()); g_s.end(); g_s.begin("Building interface member list...\n"); - buildInterfaceAndServiceList(root); // UNO IDL + buildInterfaceAndServiceList(root.get()); // UNO IDL g_s.begin("Building member list...\n"); // using class info only ! - buildFunctionList(root); + buildFunctionList(root.get()); g_s.end(); g_s.begin("Searching for friends...\n"); @@ -11477,11 +11456,11 @@ void parseInput() g_s.end(); g_s.begin("Searching for documented defines...\n"); - findDefineDocumentation(root); + findDefineDocumentation(root.get()); g_s.end(); g_s.begin("Computing class inheritance relations...\n"); - findClassEntries(root); + findClassEntries(root.get()); findInheritedTemplateInstances(); g_s.end(); @@ -11512,14 +11491,14 @@ void parseInput() g_s.end(); g_s.begin("Add enum values to enums...\n"); - addEnumValuesToEnums(root); - findEnumDocumentation(root); + addEnumValuesToEnums(root.get()); + findEnumDocumentation(root.get()); g_s.end(); g_s.begin("Searching for member function documentation...\n"); - findObjCMethodDefinitions(root); - findMemberDocumentation(root); // may introduce new members ! - findUsingDeclImports(root); // may introduce new members ! + findObjCMethodDefinitions(root.get()); + findMemberDocumentation(root.get()); // may introduce new members ! + findUsingDeclImports(root.get()); // may introduce new members ! transferRelatedFunctionDocumentation(); transferFunctionDocumentation(); @@ -11532,21 +11511,21 @@ void parseInput() g_s.end(); g_s.begin("Building page list...\n"); - buildPageList(root); + buildPageList(root.get()); g_s.end(); g_s.begin("Search for main page...\n"); - findMainPage(root); - findMainPageTagFiles(root); + findMainPage(root.get()); + findMainPageTagFiles(root.get()); g_s.end(); g_s.begin("Computing page relations...\n"); - computePageRelations(root); + computePageRelations(root.get()); checkPageRelations(); g_s.end(); g_s.begin("Determining the scope of groups...\n"); - findGroupScope(root); + findGroupScope(root.get()); g_s.end(); g_s.begin("Sorting lists...\n"); diff --git a/src/entry.cpp b/src/entry.cpp index e2a21c6..ec3c736 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -15,6 +15,7 @@ * */ +#include #include #include #include "entry.h" @@ -37,8 +38,6 @@ Entry::Entry() num++; m_parent=0; section = EMPTY_SEC; - m_sublist = new QList; - m_sublist->setAutoDelete(TRUE); extends = new QList; extends->setAutoDelete(TRUE); groups = new QList; @@ -137,17 +136,14 @@ Entry::Entry(const Entry &e) id = e.id; m_parent = e.m_parent; - m_sublist = new QList; - m_sublist->setAutoDelete(TRUE); - // deep copy of the child entry list - QListIterator eli(*e.m_sublist); - Entry *cur; - for (;(cur=eli.current());++eli) + // deep copy child entries + m_sublist.reserve(e.m_sublist.size()); + for (const auto &cur : e.m_sublist) { - m_sublist->append(new Entry(*cur)); + m_sublist.push_back(std::make_unique(*cur)); } - + // deep copy base class list QListIterator bli(*e.extends); BaseInfo *bi; @@ -192,9 +188,7 @@ Entry::~Entry() //printf("Entry::~Entry(%p) num=%d\n",this,num); //printf("Deleting entry %d name %s type %x children %d\n", // num,name.data(),section,sublist->count()); - - delete m_sublist; // each element is now own by a EntryNav so we do no longer own - // our children. + delete extends; delete groups; delete anchors; @@ -206,15 +200,44 @@ Entry::~Entry() num--; } -void Entry::addSubEntry(Entry *current) +void Entry::moveToSubEntryAndRefresh(Entry *¤t) +{ + current->m_parent=this; + m_sublist.emplace_back(current); + current = new Entry; +} + +void Entry::moveToSubEntryAndRefresh(std::unique_ptr ¤t) +{ + current->m_parent=this; + m_sublist.push_back(std::move(current)); + current = std::make_unique(); +} + +void Entry::moveToSubEntryAndKeep(Entry *current) +{ + current->m_parent=this; + m_sublist.emplace_back(current); +} + +void Entry::moveToSubEntryAndKeep(std::unique_ptr ¤t) { - //printf("Entry %d with name %s type 0x%x added to %s type 0x%x\n", - // current->num,current->name.data(),current->section, - // name.data(),section); - //printf("Entry::addSubEntry(%s:%p) to %s\n",current->name.data(), - // current,name.data()); current->m_parent=this; - m_sublist->append(current); + m_sublist.push_back(std::move(current)); +} + +void Entry::copyToSubEntry(Entry *current) +{ + Entry *copy = new Entry(*current); + copy->m_parent=this; + m_sublist.emplace_back(copy); +} + +void Entry::copyToSubEntry(const std::unique_ptr ¤t) +{ + std::unique_ptr copy = std::make_unique(*current); + copy->m_parent=this; + m_sublist.push_back(std::move(copy)); } void Entry::reset() @@ -271,7 +294,7 @@ void Entry::reset() groupDocType = GROUPDOC_NORMAL; id.resize(0); metaData.resize(0); - m_sublist->clear(); + m_sublist.clear(); extends->clear(); groups->clear(); anchors->clear(); @@ -293,14 +316,9 @@ int Entry::getSize() void Entry::setFileDef(FileDef *fd) { m_fileDef = fd; - if (m_sublist) + for (const auto &childNode : m_sublist) { - QListIterator eli(*m_sublist); - Entry *childNode; - for (eli.toFirst();(childNode=eli.current());++eli) - { childNode->setFileDef(fd); - } } } @@ -317,10 +335,14 @@ void Entry::addSpecialListItem(const char *listName,int itemId) sli->append(ili); } -Entry *Entry::removeSubEntry(Entry *e) +void Entry::removeSubEntry(Entry *e) { - int i = m_sublist->find(e); - return i!=-1 ? m_sublist->take(i) : 0; + auto it = std::find_if(m_sublist.begin(),m_sublist.end(), + [e](const std::unique_ptr&elem) { return elem.get()==e; }); + if (it!=m_sublist.end()) + { + m_sublist.erase(it); + } } //------------------------------------------------------------------ diff --git a/src/entry.h b/src/entry.h index 6dfa0c6..091e81b 100644 --- a/src/entry.h +++ b/src/entry.h @@ -23,6 +23,9 @@ #include #include +#include +#include + struct SectionInfo; class QFile; class FileDef; @@ -199,32 +202,42 @@ class Entry void addSpecialListItem(const char *listName,int index); - // while parsing a file these function can be used to navigate/build the tree - void setParent(Entry *parent) { m_parent = parent; } - /*! Returns the parent for this Entry or 0 if this entry has no parent. */ Entry *parent() const { return m_parent; } /*! Returns the list of children for this Entry * @see addSubEntry() and removeSubEntry() */ - const QList *children() const { return m_sublist; } + //const QList *children() const { return m_sublist; } + const std::vector< std::unique_ptr > &children() const { return m_sublist; } + + /*! @name add entry as a child and pass ownership. + * @note This makes the entry passed invalid! (TODO: tclscanner.l still has use after move!) + * @{ + */ + void moveToSubEntryAndKeep(Entry* e); + void moveToSubEntryAndKeep(std::unique_ptr &e); + /*! @} */ + + /*! @name add entry as a child, pass ownership and reinitialize entry */ + void moveToSubEntryAndRefresh(Entry* &e); + void moveToSubEntryAndRefresh(std::unique_ptr &e); - /*! Adds entry \a e as a child to this entry */ - void addSubEntry (Entry* e) ; + /*! make a copy of \a e and add it as a child to this entry */ + void copyToSubEntry (Entry* e); + void copyToSubEntry (const std::unique_ptr &e); /*! Removes entry \a e from the list of children. - * Returns a pointer to the entry or 0 if the entry was not a child. - * Note the entry will not be deleted. + * The entry will be deleted if found. */ - Entry *removeSubEntry(Entry *e); + void removeSubEntry(Entry *e); /*! Restore the state of this Entry to the default value it has * at construction time. */ void reset(); - void changeSection(int sec) { section = sec; } + void markAsProcessed() const { ((Entry*)(this))->section = Entry::EMPTY_SEC; } void setFileDef(FileDef *fd); FileDef *fileDef() const { return m_fileDef; } @@ -323,12 +336,9 @@ class Entry private: Entry *m_parent; //!< parent node in the tree - QList *m_sublist; //!< entries that are children of this one + std::vector< std::unique_ptr > m_sublist; Entry &operator=(const Entry &); FileDef *m_fileDef; }; -typedef QList EntryList; -typedef QListIterator EntryListIterator; - #endif diff --git a/src/fileparser.h b/src/fileparser.h index 4b311e6..7c3f40c 100644 --- a/src/fileparser.h +++ b/src/fileparser.h @@ -25,7 +25,7 @@ class FileParser : public ParserInterface virtual ~FileParser() {} void startTranslationUnit(const char *) {} void finishTranslationUnit() {} - void parseInput(const char *, const char *,Entry *, bool, QStrList &) {} + void parseInput(const char *, const char *,const std::unique_ptr &, bool, QStrList &) {} bool needsPreprocessing(const QCString &) { return FALSE; } void parseCode(CodeOutputInterface &codeOutIntf, const char *scopeName, diff --git a/src/fortranscanner.h b/src/fortranscanner.h index 15a9bf0..7490cde 100644 --- a/src/fortranscanner.h +++ b/src/fortranscanner.h @@ -33,7 +33,7 @@ class FortranLanguageScanner : public ParserInterface void finishTranslationUnit() {} void parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension); diff --git a/src/fortranscanner.l b/src/fortranscanner.l index d75134a..9ff89e7 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -165,11 +165,11 @@ static int yyColNr = 0 ; static Entry* current_root = 0 ; static Entry* global_root = 0 ; static Entry* file_root = 0 ; -static Entry* current = 0 ; static Entry* last_entry = 0 ; static Entry* last_enum = 0 ; +static std::unique_ptr current; static ScanVar v_type = V_IGNORE; // type of parsed variable -static QList moduleProcedures; // list of all interfaces which contain unresolved +static std::vector moduleProcedures; // list of all interfaces which contain unresolved // module procedures static QCString docBlock; static bool docBlockInBody = FALSE; @@ -202,7 +202,7 @@ static SymbolModifiers currentModifiers; //! Holds program scope->symbol name->symbol modifiers. static QMap > modifiers; -static Entry *global_scope = NULL; +static Entry *global_scope = 0; static int anonCount = 0 ; //----------------------------------------------------------------------------- @@ -211,7 +211,7 @@ static void startCommentBlock(bool); static void handleCommentBlock(const QCString &doc,bool brief); static void subrHandleCommentBlock(const QCString &doc,bool brief); static void subrHandleCommentBlockResult(const QCString &doc,bool brief); -static void addCurrentEntry(int case_insens); +static void addCurrentEntry(bool case_insens); static void addModule(const char *name, bool isModule=FALSE); static void addSubprogram(const char *text); static void addInterface(QCString name, InterfaceType type); @@ -221,7 +221,7 @@ static void scanner_abort(); static void startScope(Entry *scope); static bool endScope(Entry *scope, bool isGlobalRoot=FALSE); //static bool isTypeName(QCString name); -static void resolveModuleProcedures(QList &moduleProcedures, Entry *current_root); +static void resolveModuleProcedures(Entry *current_root); static int getAmpersandAtTheStart(const char *buf, int length); static int getAmpOrExclAtTheEnd(const char *buf, int length, char ch); static void truncatePrepass(int index); @@ -241,6 +241,7 @@ static const char *stateToString(int state); #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); #define YY_USER_ACTION yyColNr+=(int)yyleng; +#define INVALID_ENTRY ((Entry*)0x8) //----------------------------------------------------------------------------- %} @@ -444,8 +445,7 @@ SCOPENAME ({ID}{BS}"::"{BS})* current->name=yytext; current->fileName = yyFileName; current->section=Entry::USINGDIR_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); current->lang = SrcLangExt_Fortran; yy_pop_state(); } @@ -459,8 +459,7 @@ SCOPENAME ({ID}{BS}"::"{BS})* current->name= useModuleName+"::"+yytext; current->fileName = yyFileName; current->section=Entry::USINGDECL_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); current->lang = SrcLangExt_Fortran; } "\n" { @@ -516,8 +515,8 @@ SCOPENAME ({ID}{BS}"::"{BS})* current->section = Entry::FUNCTION_SEC ; current->name = yytext; - moduleProcedures.append(current); - addCurrentEntry(1); + moduleProcedures.push_back(current.get()); + addCurrentEntry(true); } "\n" { yyColNr -= 1; unput(*yytext); @@ -558,13 +557,13 @@ SCOPENAME ({ID}{BS}"::"{BS})* yy_pop_state(); } "end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!|;) { // end module - resolveModuleProcedures(moduleProcedures, current_root); + resolveModuleProcedures(current_root); if (!endScope(current_root)) yyterminate(); defaultProtection = Public; if (global_scope) { - if (global_scope != (Entry *) -1) + if (global_scope != INVALID_ENTRY) yy_push_state(Start); else yy_pop_state(); // cannot pop artrificial entry @@ -572,7 +571,7 @@ SCOPENAME ({ID}{BS}"::"{BS})* else { yy_push_state(Start); - global_scope = (Entry *)-1; // signal that the global_scope has already been used. + global_scope = INVALID_ENTRY; // signal that the global_scope has already been used. } } {ID} { @@ -647,7 +646,7 @@ private { current->name = current_root->name + "::" + current->name; } - addCurrentEntry(1); + addCurrentEntry(true); startScope(last_entry); BEGIN(TypedefBody); } @@ -679,7 +678,7 @@ private { current->fileName = yyFileName; current->bodyLine = yyLineNr; current->startLine = yyLineNr; - addCurrentEntry(1); + addCurrentEntry(true); } {BS}"=>"[^(\n|\!)]* { /* Specific bindings come after the ID. */ QCString args = yytext; @@ -866,17 +865,15 @@ private { current->startLine = yyLineNr; if (argType == "@") { - current_root->addSubEntry(current); - current = new Entry(*current); + current_root->copyToSubEntry(current); // add to the scope surrounding the enum (copy!) - current_root->parent()->addSubEntry(current); - last_enum = current; - current = new Entry ; + last_enum = current.get(); + current_root->parent()->moveToSubEntryAndRefresh(current); initEntry(); } else { - addCurrentEntry(1); + addCurrentEntry(true); } } else if (!argType.isEmpty()) @@ -889,7 +886,7 @@ private { if (!docBlock.isNull()) { subrHandleCommentBlock(docBlock,TRUE); - } + } } // save, it may be function return type if (parameter) @@ -1068,7 +1065,7 @@ private { current->name = current_root->name + "::" + current->name; } - addCurrentEntry(1); + addCurrentEntry(true); startScope(last_entry); BEGIN( Enum ) ; } @@ -1138,7 +1135,7 @@ private { ")" { current->args += ")"; current->args = removeRedundantWhiteSpace(current->args); - addCurrentEntry(1); + addCurrentEntry(true); startScope(last_entry); BEGIN(SubprogBody); } @@ -1164,7 +1161,7 @@ private { newLine(); //printf("3=========> without parameterlist \n"); //current->argList = ; - addCurrentEntry(1); + addCurrentEntry(true); startScope(last_entry); BEGIN(SubprogBody); } @@ -1217,11 +1214,20 @@ private { unput(*yytext); if (v_type == V_VARIABLE) { - Entry *tmp_entry = current; - current = last_entry; // temporarily switch to the previous entry - if (last_enum) current = last_enum; + std::unique_ptr tmp_entry; + current.swap(tmp_entry); + // temporarily switch to the previous entry + if (last_enum) + { + current.reset(last_enum); + } + else + { + current.reset(last_entry); + } handleCommentBlock(docBlock,TRUE); - current=tmp_entry; + // switch back + tmp_entry.swap(current); } else if (v_type == V_PARAMETER) { @@ -1773,34 +1779,30 @@ static void popBuffer() { } /** used to copy entry to an interface module procedure */ -static void copyEntry(Entry *dest, Entry *src) +static void copyEntry(Entry *dest, const std::unique_ptr &src) { - dest->type = src->type; - dest->fileName = src->fileName; - dest->startLine = src->startLine; - dest->bodyLine = src->bodyLine; + dest->type = src->type; + dest->fileName = src->fileName; + dest->startLine = src->startLine; + dest->bodyLine = src->bodyLine; dest->endBodyLine = src->endBodyLine; - dest->args = src->args; - dest->argList = new ArgumentList(*src->argList); - dest->doc = src->doc; - dest->brief = src->brief; + dest->args = src->args; + delete dest->argList; + dest->argList = new ArgumentList(*src->argList); + dest->doc = src->doc; + dest->brief = src->brief; } /** fill empty interface module procedures with info from corresponding module subprogs @TODO: handle procedures in used modules */ -void resolveModuleProcedures(QList &moduleProcedures, Entry *current_root) +void resolveModuleProcedures(Entry *current_root) { - if (moduleProcedures.isEmpty()) return; - - EntryListIterator eli1(moduleProcedures); - // for all module procedures - for (Entry *ce1; (ce1=eli1.current()); ++eli1) + for (const auto &ce1 : moduleProcedures) { // check all entries in this module - EntryListIterator eli2(*current_root->children()); - for (Entry *ce2; (ce2=eli2.current()); ++eli2) + for (const auto &ce2 : current_root->children()) { if (ce1->name == ce2->name) { @@ -2022,26 +2024,6 @@ static Argument *findArgument(Entry* subprog, QCString name, bool byTypeName = F return 0; } -/*! Find function with given name in \a entry. */ -#if 0 -static Entry *findFunction(Entry* entry, QCString name) -{ - QCString cname(name.lower()); - - EntryListIterator eli(*entry->children()); - Entry *ce; - for (;(ce=eli.current());++eli) - { - if (ce->section != Entry::FUNCTION_SEC) - continue; - - if (ce->name.lower() == cname) - return ce; - } - - return 0; -} -#endif /*! Apply modifiers stored in \a mdfs to the \a typeName string. */ static QCString applyModifiers(QCString typeName, SymbolModifiers& mdfs) @@ -2199,10 +2181,10 @@ static bool endScope(Entry *scope, bool isGlobalRoot) { if (global_scope == scope) { - global_scope = NULL; + global_scope = 0; return TRUE; } - if (global_scope == (Entry *) -1) + if (global_scope == INVALID_ENTRY) { return TRUE; } @@ -2250,11 +2232,9 @@ static bool endScope(Entry *scope, bool isGlobalRoot) // iterate functions of interface and // try to find types for dummy(ie. argument) procedures. //cout<<"Search in "<name<children()); - Entry *ce; int count = 0; int found = FALSE; - for (;(ce=eli.current());++eli) + for (const auto &ce : scope->children()) { count++; if (ce->section != Entry::FUNCTION_SEC) @@ -2273,7 +2253,7 @@ static bool endScope(Entry *scope, bool isGlobalRoot) { // clear all modifiers of the scope modifiers.remove(scope); - delete scope->parent()->removeSubEntry(scope); + scope->parent()->removeSubEntry(scope); scope = 0; return TRUE; } @@ -2282,16 +2262,14 @@ static bool endScope(Entry *scope, bool isGlobalRoot) if (scope->section!=Entry::FUNCTION_SEC) { // not function section // iterate variables: get and apply modifiers - EntryListIterator eli(*scope->children()); - Entry *ce; - for (;(ce=eli.current());++eli) + for (const auto &ce : scope->children()) { if (ce->section != Entry::VARIABLE_SEC && ce->section != Entry::FUNCTION_SEC) continue; //cout<name<<", "<name.lower())<name.lower())) - applyModifiers(ce, mdfsMap[ce->name.lower()]); + applyModifiers(ce.get(), mdfsMap[ce->name.lower()]); } } @@ -2345,19 +2323,18 @@ static void initEntry() current->virt = virt; current->stat = gstat; current->lang = SrcLangExt_Fortran; - Doxygen::docGroup.initGroupInfo(current); + Doxygen::docGroup.initGroupInfo(current.get()); } /** adds current entry to current_root and creates new current */ -static void addCurrentEntry(int case_insens) +static void addCurrentEntry(bool case_insens) { if (case_insens) current->name = current->name.lower(); //printf("===Adding entry %s to %s\n", current->name.data(), current_root->name.data()); - current_root->addSubEntry(current); - last_entry = current; - current = new Entry ; + last_entry = current.get(); + current_root->moveToSubEntryAndRefresh(current); initEntry(); } @@ -2375,7 +2352,7 @@ static void addModule(const char *name, bool isModule) if (name!=NULL) { current->name = name; - } + } else { QCString fname = yyFileName; @@ -2389,7 +2366,7 @@ static void addModule(const char *name, bool isModule) current->bodyLine = yyLineNr; // used for source reference current->startLine = yyLineNr; current->protection = Public ; - addCurrentEntry(1); + addCurrentEntry(true); startScope(last_entry); } @@ -2397,7 +2374,7 @@ static void addModule(const char *name, bool isModule) static void addSubprogram(const char *text) { DBG_CTX((stderr,"1=========> got subprog, type: %s\n",text)); - subrCurrent.prepend(current); + subrCurrent.prepend(current.get()); current->section = Entry::FUNCTION_SEC ; QCString subtype = text; subtype=subtype.lower().stripWhiteSpace(); functionLine = (subtype.find("function") != -1); @@ -2454,7 +2431,7 @@ static void addInterface(QCString name, InterfaceType type) current->fileName = yyFileName; current->bodyLine = yyLineNr; current->startLine = yyLineNr; - addCurrentEntry(1); + addCurrentEntry(true); } @@ -2513,7 +2490,7 @@ static void handleCommentBlock(const QCString &doc,bool brief) QCString processedDoc = preprocessCommentBlock(doc,yyFileName,lineNr); while (parseCommentBlock( g_thisParser, - docBlockInBody ? subrCurrent.getFirst() : current, + docBlockInBody ? subrCurrent.getFirst() : current.get(), processedDoc, // text yyFileName, // file lineNr, @@ -2526,11 +2503,11 @@ static void handleCommentBlock(const QCString &doc,bool brief) )) { DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry)); - if (needsEntry) addCurrentEntry(0); + if (needsEntry) addCurrentEntry(false); } DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry)); - if (needsEntry) addCurrentEntry(0); + if (needsEntry) addCurrentEntry(false); docBlockInBody = FALSE; } @@ -2541,8 +2518,9 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) QCString loc_doc; loc_doc = doc.stripWhiteSpace(); - Entry *tmp_entry = current; - current = subrCurrent.getFirst(); // temporarily switch to the entry of the subroutine / function + std::unique_ptr tmp_entry; + current.swap(tmp_entry); + current.reset(subrCurrent.getFirst()); // temporarily switch to the entry of the subroutine / function // Still in the specification section so no inbodyDocs yet, but parameter documentation current->inbodyDocs = ""; @@ -2566,14 +2544,11 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) loc_doc = loc_doc.right(loc_doc.length()-strlen(directionParam[SymbolModifiers::IN])); loc_doc.stripWhiteSpace(); // in case of empty documentation or (now) just name, consider it as no documemntation - if (loc_doc.isEmpty() || (loc_doc.lower() == argName.lower())) + if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower())) { - // reset current back to the part inside the routine - current=tmp_entry; - return; - } - handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::IN] + " " + + handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::IN] + " " + argName + " " + loc_doc,brief); + } } else { @@ -2594,7 +2569,7 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) loc_doc.stripWhiteSpace(); if (loc_doc.isEmpty() || (loc_doc.lower() == argName.lower())) { - current=tmp_entry; + tmp_entry.swap(current); return; } handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::OUT] + " " + @@ -2616,13 +2591,11 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) { loc_doc = loc_doc.right(loc_doc.length()-strlen(directionParam[SymbolModifiers::INOUT])); loc_doc.stripWhiteSpace(); - if (loc_doc.isEmpty() || (loc_doc.lower() == argName.lower())) + if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower())) { - current=tmp_entry; - return; + handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::INOUT] + " " + + argName + " " + loc_doc,brief); } - handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::INOUT] + " " + - argName + " " + loc_doc,brief); } else { @@ -2633,19 +2606,14 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) } } // analogous to the [in] case; here no direction specified - else + else if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower())) { - if (loc_doc.isEmpty() || (loc_doc.lower() == argName.lower())) - { - current=tmp_entry; - return; - } handleCommentBlock(QCString("\n\n@param ") + directionParam[dir1] + " " + argName + " " + loc_doc,brief); } // reset current back to the part inside the routine - current=tmp_entry; + tmp_entry.swap(current); } //---------------------------------------------------------------------------- /// Handle result description as defined after the declaration of the parameter @@ -2654,8 +2622,9 @@ static void subrHandleCommentBlockResult(const QCString &doc,bool brief) QCString loc_doc; loc_doc = doc.stripWhiteSpace(); - Entry *tmp_entry = current; - current = subrCurrent.getFirst(); // temporarily switch to the entry of the subroutine / function + std::unique_ptr tmp_entry; + current.swap(tmp_entry); + current.reset(subrCurrent.getFirst()); // temporarily switch to the entry of the subroutine / function // Still in the specification section so no inbodyDocs yet, but parameter documentation current->inbodyDocs = ""; @@ -2668,15 +2637,13 @@ static void subrHandleCommentBlockResult(const QCString &doc,bool brief) ) (void)loc_doc; // Do nothing work has been done by stripPrefix; (void)loc_doc: to overcome 'empty controlled statement' warning loc_doc.stripWhiteSpace(); - if (loc_doc.isEmpty() || (loc_doc.lower() == argName.lower())) + if (!loc_doc.isEmpty() && (loc_doc.lower() != argName.lower())) { - current=tmp_entry; - return; + handleCommentBlock(QCString("\n\n@returns ") + loc_doc,brief); } - handleCommentBlock(QCString("\n\n@returns ") + loc_doc,brief); // reset current back to the part inside the routine - current=tmp_entry; + tmp_entry.swap(current); } //---------------------------------------------------------------------------- @@ -2687,18 +2654,17 @@ static void debugCompounds(Entry *rt) // print Entry structure (for debugging) { level++; printf("%d) debugCompounds(%s) line %d\n",level, rt->name.data(), rt->bodyLine); - EntryListIterator eli(*rt->children()); - Entry *ce; - for (;(ce=eli.current());++eli) + for (const auto &ce : rt->children()) { - debugCompounds(ce); - } + debugCompounds(ce.get()); + } level--; } #endif -static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, FortranFormat format) +static void parseMain(const char *fileName,const char *fileBuf, + const std::unique_ptr &rt, FortranFormat format) { char *tmpBuf = NULL; initParser(); @@ -2713,8 +2679,8 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra mtype = Method; gstat = FALSE; virt = Normal; - current_root = rt; - global_root = rt; + current_root = rt.get(); + global_root = rt.get(); inputFile.setName(fileName); if (inputFile.open(IO_ReadOnly)) { @@ -2750,18 +2716,18 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra yyFileName = fileName; msg("Parsing file %s...\n",yyFileName.data()); - global_scope = rt; - startScope(rt); // implies current_root = rt + global_scope = rt.get(); + startScope(rt.get()); // implies current_root = rt initParser(); Doxygen::docGroup.enterFile(yyFileName,yyLineNr); - current = new Entry; + // add entry for the file + current = std::make_unique(); current->lang = SrcLangExt_Fortran; current->name = yyFileName; current->section = Entry::SOURCE_SEC; - current_root->addSubEntry(current); - file_root = current; - current = new Entry; + file_root = current.get(); + current_root->moveToSubEntryAndRefresh(current); current->lang = SrcLangExt_Fortran; fortranscannerYYrestart( fortranscannerYYin ); @@ -2772,12 +2738,12 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra fortranscannerYYlex(); Doxygen::docGroup.leaveFile(yyFileName,yyLineNr); - if (global_scope && global_scope != (Entry *) -1) endScope(current_root, TRUE); // TRUE - global root + if (global_scope && global_scope != INVALID_ENTRY) endScope(current_root, TRUE); // TRUE - global root //debugCompounds(rt); //debug rt->program.resize(0); - delete current; current=0; + //delete current; current=0; moduleProcedures.clear(); if (tmpBuf) { free((char*)tmpBuf); @@ -2796,7 +2762,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra void FortranLanguageScanner::parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { @@ -2856,13 +2822,11 @@ static void scanner_abort() fprintf(stderr,"Error in file %s line: %d, state: %d(%s)\n",yyFileName.data(),yyLineNr,YY_START,stateToString(YY_START)); fprintf(stderr,"********************************************************************\n"); - EntryListIterator eli(*global_root->children()); - Entry *ce; bool start=FALSE; - for (;(ce=eli.current());++eli) + for (const auto &ce : global_root->children()) { - if (ce == file_root) start=TRUE; + if (ce.get() == file_root) start=TRUE; if (start) ce->reset(); } diff --git a/src/groupdef.cpp b/src/groupdef.cpp index e1fab11..00e42d7 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -1460,7 +1460,7 @@ void GroupDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *current //---- helper functions ------------------------------------------------------ -void addClassToGroups(Entry *root,ClassDef *cd) +void addClassToGroups(const Entry *root,ClassDef *cd) { QListIterator gli(*root->groups); Grouping *g; @@ -1478,7 +1478,7 @@ void addClassToGroups(Entry *root,ClassDef *cd) } } -void addNamespaceToGroups(Entry *root,NamespaceDef *nd) +void addNamespaceToGroups(const Entry *root,NamespaceDef *nd) { //printf("root->groups->count()=%d\n",root->groups->count()); QListIterator gli(*root->groups); @@ -1495,7 +1495,7 @@ void addNamespaceToGroups(Entry *root,NamespaceDef *nd) } } -void addDirToGroups(Entry *root,DirDef *dd) +void addDirToGroups(const Entry *root,DirDef *dd) { //printf("*** root->groups->count()=%d\n",root->groups->count()); QListIterator gli(*root->groups); @@ -1513,7 +1513,7 @@ void addDirToGroups(Entry *root,DirDef *dd) } } -void addGroupToGroups(Entry *root,GroupDef *subGroup) +void addGroupToGroups(const Entry *root,GroupDef *subGroup) { //printf("addGroupToGroups for %s groups=%d\n",root->name.data(), // root->groups?root->groups->count():-1); @@ -1544,7 +1544,7 @@ void addGroupToGroups(Entry *root,GroupDef *subGroup) } /*! Add a member to the group with the highest priority */ -void addMemberToGroups(Entry *root,MemberDef *md) +void addMemberToGroups(const Entry *root,MemberDef *md) { //printf("addMemberToGroups: Root %p = %s, md %p=%s groups=%d\n", // root, root->name.data(), md, md->name().data(), root->groups->count() ); @@ -1650,7 +1650,7 @@ void addMemberToGroups(Entry *root,MemberDef *md) } -void addExampleToGroups(Entry *root,PageDef *eg) +void addExampleToGroups(const Entry *root,PageDef *eg) { QListIterator gli(*root->groups); Grouping *g; diff --git a/src/groupdef.h b/src/groupdef.h index 92d524f..8a84a98 100644 --- a/src/groupdef.h +++ b/src/groupdef.h @@ -18,6 +18,8 @@ #ifndef GROUPDEF_H #define GROUPDEF_H +#include + #include "sortdict.h" #include "definition.h" @@ -138,13 +140,13 @@ class GroupListIterator : public QListIterator virtual ~GroupListIterator() {} }; -void addClassToGroups(Entry *root,ClassDef *cd); -void addNamespaceToGroups(Entry *root,NamespaceDef *nd); -void addGroupToGroups(Entry *root,GroupDef *subGroup); -void addMemberToGroups(Entry *root,MemberDef *md); -void addPageToGroups(Entry *root,PageDef *pd); -void addExampleToGroups(Entry *root,PageDef *eg); -void addDirToGroups(Entry *root,DirDef *dd); +void addClassToGroups (const Entry *root,ClassDef *cd); +void addNamespaceToGroups(const Entry *root,NamespaceDef *nd); +void addGroupToGroups (const Entry *root,GroupDef *subGroup); +void addMemberToGroups (const Entry *root,MemberDef *md); +void addPageToGroups (const Entry *root,PageDef *pd); +void addExampleToGroups (const Entry *root,PageDef *eg); +void addDirToGroups (const Entry *root,DirDef *dd); #endif diff --git a/src/markdown.cpp b/src/markdown.cpp index ce28540..d1a6a63 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -2578,11 +2578,11 @@ QCString markdownFileNameToId(const QCString &fileName) void MarkdownFileParser::parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { - Entry *current = new Entry; + std::unique_ptr current = std::make_unique(); current->lang = SrcLangExt_Markdown; current->fileName = fileName; current->docFile = fileName; @@ -2630,7 +2630,7 @@ void MarkdownFileParser::parseInput(const char *fileName, QCString processedDocs = preprocessCommentBlock(docs,fileName,lineNr); while (parseCommentBlock( this, - current, + current.get(), processedDocs, fileName, lineNr, @@ -2644,8 +2644,7 @@ void MarkdownFileParser::parseInput(const char *fileName, if (needsEntry) { QCString docFile = current->docFile; - root->addSubEntry(current); - current = new Entry; + root->moveToSubEntryAndRefresh(current); current->lang = SrcLangExt_Markdown; current->docFile = docFile; current->docLine = lineNr; @@ -2653,7 +2652,7 @@ void MarkdownFileParser::parseInput(const char *fileName, } if (needsEntry) { - root->addSubEntry(current); + root->moveToSubEntryAndKeep(current); } // restore setting diff --git a/src/markdown.h b/src/markdown.h index 1a3895e..f101e5a 100644 --- a/src/markdown.h +++ b/src/markdown.h @@ -33,7 +33,7 @@ class MarkdownFileParser : public ParserInterface void finishTranslationUnit() {} void parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &) { return FALSE; } diff --git a/src/parserintf.h b/src/parserintf.h index f03aac7..a269bfb 100644 --- a/src/parserintf.h +++ b/src/parserintf.h @@ -21,6 +21,8 @@ #include #include +#include + #include "types.h" class Entry; @@ -67,7 +69,7 @@ class ParserInterface */ virtual void parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit) = 0; diff --git a/src/pyscanner.h b/src/pyscanner.h index 01235ee..13b10b9 100644 --- a/src/pyscanner.h +++ b/src/pyscanner.h @@ -39,7 +39,7 @@ class PythonLanguageScanner : public ParserInterface void finishTranslationUnit() {} void parseInput(const char * fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension); diff --git a/src/pyscanner.l b/src/pyscanner.l index 2320bca..c6120fb 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -73,7 +73,7 @@ static QFile inputFile; static Protection protection; static Entry* current_root = 0 ; -static Entry* current = 0 ; +static std::unique_ptr current; static Entry* previous = 0 ; static Entry* bodyEntry = 0 ; static int yyLineNr = 1 ; @@ -145,16 +145,14 @@ static void initEntry() current->virt = virt; current->stat = gstat; current->lang = SrcLangExt_Python; - current->setParent(current_root); - Doxygen::docGroup.initGroupInfo(current); + Doxygen::docGroup.initGroupInfo(current.get()); gstat = FALSE; } static void newEntry() { - previous = current; - current_root->addSubEntry(current); - current = new Entry ; + previous = current.get(); + current_root->moveToSubEntryAndRefresh(current); initEntry(); } @@ -240,8 +238,7 @@ static void addFrom(bool all) current->fileName = yyFileName; //printf("Adding using declaration: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data()); current->section=all ? Entry::USINGDIR_SEC : Entry::USINGDECL_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); } //----------------------------------------------------------------------------- @@ -261,43 +258,6 @@ static void incLineNr() yyLineNr++; } -#if 0 -// Appends the current-name to current-type; -// Destroys current-name. -// Destroys current->args and current->argList -static void addType( Entry* current ) -{ - uint tl=current->type.length(); - if ( tl>0 && !current->name.isEmpty() && current->type.at(tl-1)!='.') - { - current->type += ' ' ; - } - current->type += current->name ; - current->name.resize(0) ; - tl=current->type.length(); - if ( tl>0 && !current->args.isEmpty() && current->type.at(tl-1)!='.') - { - current->type += ' ' ; - } - current->type += current->args ; - current->args.resize(0) ; - current->argList->clear(); -} - -static QCString stripQuotes(const char *s) -{ - QCString name; - if (s==0 || *s==0) return name; - name=s; - if (name.at(0)=='"' && name.at(name.length()-1)=='"') - { - name=name.mid(1,name.length()-2); - } - return name; -} -#endif -//----------------------------------------------------------------- - //----------------------------------------------------------------- static void startCommentBlock(bool brief) { @@ -313,15 +273,6 @@ static void startCommentBlock(bool brief) } } -/* -static void appendDocBlock() { - previous = current; - current_root->addSubEntry(current); - current = new Entry; - initEntry(); -} -*/ - static void handleCommentBlock(const QCString &doc,bool brief) { //printf("handleCommentBlock(doc=[%s] brief=%d docBlockInBody=%d docBlockJavaStyle=%d\n", @@ -341,7 +292,7 @@ static void handleCommentBlock(const QCString &doc,bool brief) QCString processedDoc = preprocessCommentBlock(doc,yyFileName,lineNr); while (parseCommentBlock( g_thisParser, - (docBlockInBody && previous) ? previous : current, + (docBlockInBody && previous) ? previous : current.get(), processedDoc, // text yyFileName, // file lineNr, @@ -765,8 +716,7 @@ STARTDOCSYMS "##" current->fileName = yyFileName; //printf("Adding using declaration: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data()); current->section=Entry::USINGDECL_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(Search); } @@ -963,7 +913,7 @@ STARTDOCSYMS "##" } {B}":"{B} { // function without arguments g_specialBlock = TRUE; // expecting a docstring - bodyEntry = current; + bodyEntry = current.get(); BEGIN(FunctionBody); } @@ -1346,7 +1296,7 @@ STARTDOCSYMS "##" current->program+=yytext; //current->startLine = yyLineNr; g_curIndent=computeIndent(yytext); - bodyEntry = current; + bodyEntry = current.get(); DBG_CTX((stderr,"setting indent %d\n",g_curIndent)); //printf("current->program=[%s]\n",current->program.data()); //g_hideClassDocs = TRUE; @@ -1452,9 +1402,10 @@ STARTDOCSYMS "##" // do something based on the type of the IDENTIFIER if (current->type.isEmpty()) { - QListIterator eli(*(current_root->children())); - Entry *child; - for (eli.toFirst();(child=eli.current());++eli) + //QListIterator eli(*(current_root->children())); + //Entry *child; + //for (eli.toFirst();(child=eli.current());++eli) + for (const auto &child : current_root->children()) { if (child->name == QCString(yytext)) { @@ -1754,10 +1705,9 @@ STARTDOCSYMS "##" static void parseCompounds(Entry *rt) { //printf("parseCompounds(%s)\n",rt->name.data()); - EntryListIterator eli(*rt->children()); - Entry *ce; - for (;(ce=eli.current());++eli) + for (int i=0; ichildren().size(); ++i) { + Entry *ce = rt->children()[i].get(); if (!ce->program.isEmpty()) { //printf("-- %s ---------\n%s\n---------------\n", @@ -1768,7 +1718,7 @@ static void parseCompounds(Entry *rt) pyscannerYYrestart( pyscannerYYin ) ; if (ce->section&Entry::COMPOUND_MASK) { - current_root = ce ; + current_root = ce; BEGIN( Search ); } else if (ce->parent()) @@ -1780,18 +1730,17 @@ static void parseCompounds(Entry *rt) } yyFileName = ce->fileName; yyLineNr = ce->bodyLine ; - if (current) delete current; - current = new Entry; + current = std::make_unique(); initEntry(); - Doxygen::docGroup.enterCompound(yyFileName,yyLineNr,ce->name); - + QCString name = ce->name; + Doxygen::docGroup.enterCompound(yyFileName,yyLineNr,name); + pyscannerYYlex() ; g_lexInit=TRUE; - delete current; current=0; ce->program.resize(0); - Doxygen::docGroup.leaveCompound(yyFileName,yyLineNr,ce->name); + Doxygen::docGroup.leaveCompound(yyFileName,yyLineNr,name); } parseCompounds(ce); @@ -1801,7 +1750,7 @@ static void parseCompounds(Entry *rt) //---------------------------------------------------------------------------- -static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) +static void parseMain(const char *fileName,const char *fileBuf,const std::unique_ptr &rt) { initParser(); @@ -1812,7 +1761,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) mtype = Method; gstat = FALSE; virt = Normal; - current_root = rt; + current_root = rt.get(); g_specialBlock = FALSE; @@ -1836,7 +1785,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) g_moduleScope+=baseName; } - current = new Entry; + current = std::make_unique(); initEntry(); current->name = g_moduleScope; current->section = Entry::NAMESPACE_SEC; @@ -1845,11 +1794,11 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) current->startLine = yyLineNr; current->bodyLine = yyLineNr; - rt->addSubEntry(current); + current_root = current.get(); + + rt->moveToSubEntryAndRefresh(current); - current_root = current ; initParser(); - current = new Entry; Doxygen::docGroup.enterFile(yyFileName,yyLineNr); @@ -1863,7 +1812,6 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) Doxygen::docGroup.leaveFile(yyFileName,yyLineNr); current_root->program.resize(0); - delete current; current=0; parseCompounds(current_root); @@ -1936,7 +1884,7 @@ void pyscanFreeScanner() void PythonLanguageScanner::parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { diff --git a/src/scanner.h b/src/scanner.h index c0d3dff..7103cb0 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -34,7 +34,7 @@ class CLanguageScanner : public ParserInterface void finishTranslationUnit(); void parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension); diff --git a/src/scanner.l b/src/scanner.l index 07d5c71..fe20543 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -22,6 +22,11 @@ /* * includes */ + +#include +#include +#include + #include #include #include @@ -86,11 +91,11 @@ static int roundCount = 0 ; static int curlyCount = 0 ; static int squareCount = 0 ; static int padCount = 0 ; +static std::unique_ptr current; static Entry* current_root = 0 ; static Entry* global_root = 0 ; -static Entry* current = 0 ; static Entry* previous = 0 ; -static Entry* tempEntry = 0 ; +static std::unique_ptr tempEntry; static Entry* firstTypedefEntry = 0 ; static Entry* memspecEntry = 0 ; static int yyLineNr = 1 ; @@ -194,6 +199,8 @@ static int g_column; static int g_fencedSize=0; static bool g_nestedComment=0; +static std::vector< std::pair > > g_outerScopeEntries; + static const char *stateToString(int state); //----------------------------------------------------------------------------- @@ -205,6 +212,7 @@ static const char *stateToString(int state); static void initParser() { + g_outerScopeEntries.clear(); sectionLabel.resize(0); sectionTitle.resize(0); baseName.resize(0); @@ -228,7 +236,6 @@ static void initParser() sliceOpt=Config_getBool(OPTIMIZE_OUTPUT_SLICE); previous = 0; firstTypedefEntry = 0; - tempEntry = 0; memspecEntry =0; } @@ -249,7 +256,7 @@ static void initEntry() // //printf("Appending group %s\n",autoGroupStack.top()->groupname.data()); // current->groups->append(new Grouping(*autoGroupStack.top())); //} - Doxygen::docGroup.initGroupInfo(current); + Doxygen::docGroup.initGroupInfo(current.get()); isTypedef=FALSE; } @@ -329,7 +336,7 @@ static inline int computeIndent(const char *s,int startIndent) return col; } -static void addType( Entry* current ) +static void addType() { uint tl=current->type.length(); if( tl>0 && !current->name.isEmpty() && current->type.at(tl-1)!='.') @@ -1027,7 +1034,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } {ID} { - addType( current ); + addType(); current->name = yytext; } "[" { // C++/CLI indexed property @@ -1049,7 +1056,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) {B}* { } . { - addType( current ); + addType(); current->type += yytext; } "]" { @@ -1371,9 +1378,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) lineCount(); } ";" { - current_root->addSubEntry(current); - current_root = current ; - current = new Entry ; + Entry *tmp = current.get(); + current_root->moveToSubEntryAndRefresh(current); + current_root = tmp; initEntry(); BEGIN(FindMembers); } @@ -1509,7 +1516,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1528,7 +1535,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1547,7 +1554,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1560,7 +1567,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->spec = Entry::Service | // preserve UNO IDL [optional] or published (current->spec & (Entry::Optional|Entry::Published)); - addType( current ) ; + addType(); current->type += " service " ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1569,7 +1576,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else // TODO is addType right? just copy/pasted { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1581,7 +1588,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->section = Entry::CLASS_SEC; current->spec = Entry::Singleton | (current->spec & Entry::Published); // preserve - addType( current ) ; + addType(); current->type += " singleton " ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1590,7 +1597,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else // TODO is addType right? just copy/pasted { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1603,7 +1610,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->spec = Entry::Interface | // preserve UNO IDL [optional], published, Slice local (current->spec & (Entry::Optional|Entry::Published|Entry::Local)); - addType( current ) ; + addType(); current->type += " interface" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1613,7 +1620,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1624,7 +1631,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) language = current->lang = SrcLangExt_ObjC; insideObjC = TRUE; current->protection = protection = Public ; - addType( current ) ; + addType(); current->type += " implementation" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1642,7 +1649,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) insideObjC = TRUE; } current->protection = protection = Public ; - addType( current ) ; + addType(); current->type += " interface" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1658,7 +1665,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) language = current->lang = SrcLangExt_ObjC; insideObjC = TRUE; current->protection = protection = Public ; - addType( current ) ; + addType(); current->type += " protocol" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1673,7 +1680,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->spec = Entry::Exception | (current->spec & Entry::Published) | (current->spec & Entry::Local); - addType( current ) ; + addType(); current->type += " exception" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1690,7 +1697,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) bool isConst=decl.find("const")!=-1; bool isVolatile=decl.find("volatile")!=-1; current->section = Entry::CLASS_SEC; - addType( current ) ; + addType(); uint64 spec = current->spec; if (insidePHP && current->spec&Entry::Abstract) { @@ -1728,7 +1735,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Value; - addType( current ) ; + addType(); current->type += " value class" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1743,7 +1750,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Ref; - addType( current ) ; + addType(); current->type += " ref class" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1758,7 +1765,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Interface; - addType( current ) ; + addType(); current->type += " interface class" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1773,7 +1780,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { isTypedef=FALSE; current->section = Entry::CLASS_SEC; - addType( current ) ; + addType(); current->type += " coclass" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1784,7 +1791,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType(current); + addType(); current->name = yytext; current->name = current->name.stripWhiteSpace(); lineCount(); @@ -1805,7 +1812,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) (current->spec & Entry::Local); // bug 582676: can be a struct nested in an interface so keep insideObjC state //current->objc = insideObjC = FALSE; - addType( current ) ; + addType(); if (isConst) { current->type += " const"; @@ -1828,7 +1835,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Struct | Entry::Value; - addType( current ) ; + addType(); current->type += " value struct" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1843,7 +1850,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Struct | Entry::Ref; - addType( current ) ; + addType(); current->type += " ref struct" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1858,7 +1865,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Struct | Entry::Interface; - addType( current ) ; + addType(); current->type += " interface struct"; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1878,7 +1885,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->spec = Entry::Union; // bug 582676: can be a struct nested in an interface so keep insideObjC state //current->objc = insideObjC = FALSE; - addType( current ) ; + addType(); if (isConst) { current->type += " const"; @@ -1910,7 +1917,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->section = Entry::ENUM_SEC ; } - addType( current ) ; + addType(); current->type += " enum"; if (isStrongEnum) { @@ -2003,12 +2010,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->fileName = yyFileName; // add a using declaraton current->section=Entry::USINGDECL_SEC; - current_root->addSubEntry(current); - current = new Entry(*current); + current_root->copyToSubEntry(current); // also add it as a using directive current->section=Entry::USINGDIR_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); aliasName.resize(0); } @@ -2043,8 +2048,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name=removeRedundantWhiteSpace(substitute(scope.left(scope.length()-1),".","::")); current->fileName = yyFileName; current->section=Entry::USINGDIR_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(Using); } @@ -2062,9 +2066,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) //printf("import name = %s -> %s\n",yytext,current->name.data()); current->section=Entry::USINGDECL_SEC; } - current_root->addSubEntry(current); - previous = current; - current = new Entry ; + previous = current.get(); + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(Using); } @@ -2081,9 +2084,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->fileName = yyFileName; current->section=Entry::USINGDECL_SEC; current->startLine = yyLineNr; - current_root->addSubEntry(current); - previous = current; - current = new Entry ; + previous = current.get(); + current_root->moveToSubEntryAndRefresh(current); + initEntry(); if (insideCS) /* Hack: in C# a using declaration and directive have the same syntax, so we also add it as a using directive here @@ -2094,10 +2097,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->startLine = yyLineNr; current->startColumn = yyColNr; current->section=Entry::USINGDIR_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); + initEntry(); } - initEntry(); BEGIN(Using); } "=" { // C++11 style template alias? @@ -2156,22 +2158,21 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) {SCOPENAME} { current->name=removeRedundantWhiteSpace(yytext); current->fileName = yyFileName; current->section=Entry::USINGDIR_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(Using); } ";" { BEGIN(FindMembers); } {SCOPENAME}{BN}*"<>" { // guided template decl QCString n=yytext; - addType( current ); + addType(); current->name=n.left(n.length()-2); } {SCOPENAME}{BN}*/"<" { // Note: this could be a return type! roundCount=0; sharpCount=0; lineCount(); - addType( current ); + addType(); current->name=yytext; current->name=current->name.stripWhiteSpace(); //current->scopeSpec.resize(0); @@ -2437,7 +2438,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else if (insideCS && qstrcmp(yytext,"this")==0) { // C# indexer - addType( current ) ; + addType(); current->name="this"; BEGIN(CSIndexer); } @@ -2469,7 +2470,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { if (YY_START==FindMembers) { - addType( current ) ; + addType(); } bool javaLike = insideJava || insideCS || insideD || insidePHP || insideJS; if (javaLike && qstrcmp(yytext,"public")==0) @@ -2704,8 +2705,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->args = current->args.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); current->section = Entry::DEFINE_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(lastDefineContext); } @@ -2722,8 +2722,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->initializer = init; current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(FindMembers); } @@ -2758,7 +2757,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) [\^%] { // ^ and % are C++/CLI extensions if (insideCli) { - addType( current ); + addType(); current->name = yytext ; } else @@ -2768,7 +2767,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } [*&]+ { current->name += yytext ; - addType( current ); + addType(); } ";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { if (current->bodyLine==-1) @@ -2870,7 +2869,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { // link open command to the current entry - Doxygen::docGroup.open(current,yyFileName,yyLineNr); + Doxygen::docGroup.open(current.get(),yyFileName,yyLineNr); } //current = tmp; initEntry(); @@ -2914,7 +2913,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } "//"([!/]){B}*{CMD}"}".*|"/*"([!*]){B}*{CMD}"}"[^*]*"*/" { bool insideEnum = YY_START==FindFields || (YY_START==ReadInitializer && lastInitializerContext==FindFields); // see bug746226 - Doxygen::docGroup.close(current,yyFileName,yyLineNr,insideEnum); + Doxygen::docGroup.close(current.get(),yyFileName,yyLineNr,insideEnum); } "=" { // in PHP code this could also be due to "bodyLine = yyLineNr; @@ -2965,8 +2964,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->args = current->args.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(FindMembers); } @@ -3468,7 +3466,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { if (current->type.isEmpty()) // anonymous padding field, e.g. "int :7;" { - addType(current); + addType(); current->name.sprintf("__pad%d__",padCount++); } BEGIN(BitFields); @@ -3499,7 +3497,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->type.prepend("typedef "); } - bool needNewCurrent=FALSE; + bool stat = current->stat; if (!current->name.isEmpty() && current->section!=Entry::ENUM_SEC) { current->type=current->type.simplifyWhiteSpace(); @@ -3513,17 +3511,11 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->fileName = yyFileName; current->startLine = yyBegLineNr; current->startColumn = yyBegColNr; - current_root->addSubEntry( current ) ; - needNewCurrent=TRUE; + current_root->moveToSubEntryAndRefresh( current ) ; + initEntry(); } if ( *yytext == ',') { - bool stat = current->stat; - if (needNewCurrent) - { - current = new Entry(*current); - initEntry(); - } current->stat = stat; // the static attribute holds for all variables current->name.resize(0); current->args.resize(0); @@ -3539,11 +3531,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { mtype = Method; virt = Normal; - if (needNewCurrent) - { - current = new Entry ; - } - else if (current->groups) + if (current->groups) { current->groups->clear(); } @@ -3764,8 +3752,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->args += ")"; current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN( FindMembers ); } @@ -3794,7 +3781,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) BEGIN( SkipString ); } [^\n\[\]\"]+ -"<" { addType( current ) ; +"<" { addType(); current->type += yytext ; BEGIN( Sharp ) ; } @@ -3847,8 +3834,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->args = current->args.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); } @@ -3880,17 +3866,17 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; // add to the scope of the enum - current_root->addSubEntry(current); if (!insideCS && !insideJava && !(current_root->spec&Entry::Strong)) // for C# and Java 1.5+ enum values always have to be explicitly qualified, // same for C++11 style enums (enum class Name {}) { - current = new Entry(*current); // add to the scope surrounding the enum (copy!) - current_root->parent()->addSubEntry(current); + // we cannot during it directly as that would invalidate the iterator in parseCompounds. + //printf("*** adding outer scope entry for %s\n",current->name.data()); + g_outerScopeEntries.emplace_back(current_root->parent(), std::make_unique(*current)); } - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); } else // probably a redundant , @@ -3985,13 +3971,13 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { current->endBodyLine = yyLineNr; - Entry * original_root = current_root; // save root this namespace is in + Entry * original_root = current_root; // save root this namespace is in if (current->section == Entry::NAMESPACE_SEC && current->type == "namespace") { int split_point; while ((split_point = current->name.find("::")) != -1) { - Entry *new_current = new Entry(*current); + std::unique_ptr new_current = std::make_unique(*current); current->program = ""; new_current->doc = ""; new_current->docLine = 0; @@ -4003,9 +3989,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name = current->name.left(split_point); if (!current_root->name.isEmpty()) current->name.prepend(current_root->name+"::"); - current_root->addSubEntry(current); - current_root = current; - current = new_current; + Entry *tmp = current.get(); + current_root->moveToSubEntryAndKeep(current); + current_root = tmp; + current.swap(new_current); } } QCString &cn = current->name; @@ -4040,17 +4027,16 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - current_root->addSubEntry( current ) ; - memspecEntry = current; - current = new Entry(*current); - if (current->section==Entry::NAMESPACE_SEC || + memspecEntry = current.get(); + current_root->copyToSubEntry( current ) ; + if (current->section==Entry::NAMESPACE_SEC || (current->spec==Entry::Interface) || insideJava || insidePHP || insideCS || insideD || insideJS || insideSlice ) { // namespaces and interfaces and java classes ends with a closing bracket without semicolon - current->reset(); - current_root = original_root; // restore scope from before namespace descent + current->reset(); + current_root = original_root; // restore scope from before namespace descent initEntry(); memspecEntry = 0; BEGIN( FindMembers ) ; @@ -4105,12 +4091,11 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->args = current->args.simplifyWhiteSpace(); current->type = current->type.simplifyWhiteSpace(); //printf("Adding compound %s %s %s\n",current->type.data(),current->name.data(),current->args.data()); - current_root->addSubEntry( current ) ; if (!firstTypedefEntry) { - firstTypedefEntry = current; + firstTypedefEntry = current.get(); } - current = new Entry; + current_root->moveToSubEntryAndRefresh( current ) ; initEntry(); isTypedef=TRUE; // to undo reset by initEntry() BEGIN(MemberSpecSkip); @@ -4124,9 +4109,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // add compound definition to the tree current->args = current->args.simplifyWhiteSpace(); current->type = current->type.simplifyWhiteSpace(); - current_root->addSubEntry( current ) ; - memspecEntry = current; - current = new Entry(*current); + memspecEntry = current.get(); + current_root->moveToSubEntryAndRefresh( current ) ; initEntry(); unput(';'); BEGIN( MemberSpec ) ; @@ -4166,7 +4150,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } "(" { // function with struct return type - addType(current); + addType(); current->name = msName; current->spec = 0; unput('('); @@ -4179,7 +4163,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // anonymous compound. If so we insert a // special 'anonymous' variable. //Entry *p=current_root; - Entry *p=current; + const Entry *p=current.get(); while (p) { // only look for class scopes, not namespace scopes @@ -4197,7 +4181,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } //p=p->parent; - if (p==current) p=current_root; else p=p->parent(); + if (p==current.get()) p=current_root; else p=p->parent(); } } //printf("msName=%s current->name=%s\n",msName.data(),current->name.data()); @@ -4218,7 +4202,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else // case 2: create a typedef field { - Entry *varEntry=new Entry; + std::unique_ptr varEntry=std::make_unique(); varEntry->lang = language; varEntry->protection = current->protection ; varEntry->mtype = current->mtype; @@ -4273,7 +4257,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) //printf("Add: type='%s',name='%s',args='%s' brief=%s doc=%s\n", // varEntry->type.data(),varEntry->name.data(), // varEntry->args.data(),varEntry->brief.data(),varEntry->doc.data()); - current_root->addSubEntry(varEntry); + current_root->moveToSubEntryAndKeep(varEntry); } } if (*yytext==';') // end of a struct/class ... @@ -4327,8 +4311,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) lineCount() ; } "@end"/[^a-z_A-Z0-9] { // end of Objective C block - current_root->addSubEntry( current ) ; - current=new Entry; + current_root->moveToSubEntryAndRefresh( current ) ; initEntry(); language = current->lang = SrcLangExt_Cpp; // see bug746361 insideObjC=FALSE; @@ -4346,7 +4329,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->bodyLine = yyLineNr; lineCount(); - addType(current); + addType(); funcPtrType=yytext; roundCount=0; //current->type += yytext; @@ -4491,7 +4474,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } {BN}*{ID}{BN}*"*" { lineCount(); - addType(current); + addType(); funcPtrType="("; funcPtrType+=yytext; roundCount=0; @@ -5223,9 +5206,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { findAndRemoveWord(current->type,"function"); } - previous = current; - current_root->addSubEntry(current); - current = new Entry ; + previous = current.get(); + current_root->moveToSubEntryAndRefresh(current); initEntry(); // Objective C 2.0: Required/Optional section if (previous->spec & (Entry::Optional | Entry::Required)) @@ -5324,8 +5306,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->endBodyLine=yyLineNr; - tempEntry = current; // temporarily switch to the previous entry - current = previous; + current.swap(tempEntry); // remember current + current.reset(previous); // and temporarily switch to the previous entry previous = 0; docBlockContext = SkipCurlyEndDoc; @@ -5368,8 +5350,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) //addToBody("}"); if (tempEntry) // we can only switch back to current if no new item was created { - current = tempEntry; - tempEntry = 0; + tempEntry.swap(current); + tempEntry.reset(); } BEGIN( lastCurlyContext ); } @@ -5516,8 +5498,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) new BaseInfo(baseName,Public,Normal)); baseName.resize(0); } - current_root->addSubEntry( current ) ; - current = new Entry; + current_root->moveToSubEntryAndRefresh( current ) ; + initEntry(); } else { @@ -5615,8 +5597,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) prependScope(); } current->spec|=Entry::ForwardDecl; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); } else if (insideIDL && (((current_root->spec & (Entry::Interface | @@ -5637,8 +5618,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) : Entry::INCLUDED_SERVICE_SEC; // current->section = Entry::MEMBERDOC_SEC; current->spec &= ~(Entry::Interface|Entry::Service); // FIXME: horrible: Interface == Gettable, so need to clear it - actually we're mixing values from different enums in this case... granted only Optional and Interface are actually valid in this context but urgh... - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); } unput(';'); @@ -5722,7 +5702,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType(current); + addType(); current->name = yytext; current->name = current->name.stripWhiteSpace(); lineCount(); @@ -6546,8 +6526,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) ";" { current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(FindMembers); } @@ -6577,8 +6556,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) ";" { current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(FindMembers); } @@ -7009,11 +6987,15 @@ static void newEntry() // already added to current_root, so we should not add it again // (see bug723314) { - current_root->addSubEntry(current); + previous = current.get(); + current_root->moveToSubEntryAndRefresh(current); + } + else + { + previous = current.get(); + tempEntry.swap(current); + tempEntry.reset(); } - tempEntry = 0; - previous = current; - current = new Entry ; initEntry(); } @@ -7025,7 +7007,7 @@ static void handleCommentBlock(const QCString &doc,bool brief) int lineNr = brief ? current->briefLine : current->docLine; // line of block start // fill in inbodyFile && inbodyLine the first time, see bug 633891 - Entry *docEntry = docBlockInBody && previous ? previous : current; + Entry *docEntry = docBlockInBody && previous ? previous : current.get(); if (docBlockInBody && docEntry && docEntry->inbodyLine==-1) { docEntry->inbodyFile = yyFileName; @@ -7037,7 +7019,7 @@ static void handleCommentBlock(const QCString &doc,bool brief) QCString processedDoc = preprocessCommentBlock(stripIndentation(doc),yyFileName,lineNr); while (parseCommentBlock( g_thisParser, - docBlockInBody && previous ? previous : current, + docBlockInBody && previous ? previous : current.get(), processedDoc, // text yyFileName, // file lineNr, // line of block start @@ -7097,7 +7079,7 @@ static void handleParametersCommentBlocks(ArgumentList *al) //printf("handleParametersCommentBlock [%s]\n",doc.data()); while (parseCommentBlock( g_thisParser, - current, + current.get(), a->docs, // text yyFileName, // file current->docLine, // line of block start @@ -7131,12 +7113,10 @@ static void handleParametersCommentBlocks(ArgumentList *al) //---------------------------------------------------------------------------- -static void parseCompounds(Entry *rt) +static void parseCompounds(const std::unique_ptr &rt) { //printf("parseCompounds(%s)\n",rt->name.data()); - EntryListIterator eli(*rt->children()); - Entry *ce; - for (;(ce=eli.current());++eli) + for (const auto &ce : rt->children()) { if (!ce->program.isEmpty()) { @@ -7153,16 +7133,14 @@ static void parseCompounds(Entry *rt) BEGIN( FindFields ) ; else BEGIN( FindMembers ) ; - current_root = ce ; + current_root = ce.get() ; yyFileName = ce->fileName; //setContext(); yyLineNr = ce->startLine ; yyColNr = ce->startColumn ; insideObjC = ce->lang==SrcLangExt_ObjC; //printf("---> Inner block starts at line %d objC=%d\n",yyLineNr,insideObjC); - //current->reset(); - if (current) delete current; - current = new Entry; + current = std::make_unique(); gstat = FALSE; initEntry(); @@ -7229,15 +7207,15 @@ static void parseCompounds(Entry *rt) //memberGroupId = DOX_NOGROUP; //memberGroupRelates.resize(0); //memberGroupInside.resize(0); - Doxygen::docGroup.enterCompound(yyFileName,yyLineNr,ce->name); + QCString name = ce->name; + Doxygen::docGroup.enterCompound(yyFileName,yyLineNr,name); scannerYYlex() ; g_lexInit=TRUE; //forceEndGroup(); - Doxygen::docGroup.leaveCompound(yyFileName,yyLineNr,ce->name); + Doxygen::docGroup.leaveCompound(yyFileName,yyLineNr,name); - delete current; current=0; ce->program.resize(0); @@ -7254,7 +7232,7 @@ static void parseCompounds(Entry *rt) static void parseMain(const char *fileName, const char *fileBuf, - Entry *rt, + const std::unique_ptr &rt, bool sameTranslationUnit, QStrList & filesInSameTranslationUnit) { @@ -7270,8 +7248,8 @@ static void parseMain(const char *fileName, mtype = Method; gstat = FALSE; virt = Normal; - current_root = rt; - global_root = rt; + current_root = rt.get(); + global_root = rt.get(); inputFile.setName(fileName); if (inputFile.open(IO_ReadOnly)) { @@ -7293,18 +7271,17 @@ static void parseMain(const char *fileName, rt->lang = language; msg("Parsing file %s...\n",yyFileName.data()); - current_root = rt ; + current_root = rt.get() ; initParser(); Doxygen::docGroup.enterFile(yyFileName,yyLineNr); - current = new Entry; + current = std::make_unique(); //printf("current=%p current_root=%p\n",current,current_root); int sec=guessSection(yyFileName); if (sec) { current->name = yyFileName; current->section = sec; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); } current->reset(); initEntry(); @@ -7329,18 +7306,7 @@ static void parseMain(const char *fileName, //forceEndGroup(); Doxygen::docGroup.leaveFile(yyFileName,yyLineNr); - //if (depthIf>0) - //{ - // warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!"); - //} - rt->program.resize(0); - if (rt->children()->contains(current)==0) - // it could be that current is already added as a child to rt, so we - // only delete it if this is not the case. See bug 635317. - { - delete current; current=0; - } parseCompounds(rt); @@ -7348,6 +7314,14 @@ static void parseMain(const char *fileName, anonNSCount++; + // add additional entries that were created during processing + for (auto &kv: g_outerScopeEntries) + { + //printf(">>> adding '%s' to scope '%s'\n",kv.second->name.data(),kv.first->name.data()); + kv.first->moveToSubEntryAndKeep(kv.second); + } + g_outerScopeEntries.clear(); + } } @@ -7396,6 +7370,7 @@ static void parsePrototype(const QCString &text) inputString = orgInputString; inputPosition = orgInputPosition; + //printf("**** parsePrototype end\n"); } @@ -7438,7 +7413,7 @@ void CLanguageScanner::finishTranslationUnit() void CLanguageScanner::parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr &root, bool sameTranslationUnit, QStrList & filesInSameTranslationUnit) { diff --git a/src/sqlscanner.h b/src/sqlscanner.h index 3ca6fe3..b981b5b 100644 --- a/src/sqlscanner.h +++ b/src/sqlscanner.h @@ -28,7 +28,7 @@ public: virtual ~SQLScanner() {} void startTranslationUnit(const char *) {} void finishTranslationUnit() {} - void parseInput(const char *, const char *, Entry *, bool , QStrList &) {} + void parseInput(const char *, const char *, const std::unique_ptr &, bool , QStrList &) {} bool needsPreprocessing(const QCString &) { return FALSE; } void parseCode(CodeOutputInterface &codeOutIntf, diff --git a/src/tagreader.cpp b/src/tagreader.cpp index 56dbe7d..18f6161 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -21,6 +21,8 @@ #include #include #include +#include + #include #include @@ -912,12 +914,12 @@ class TagFileParser : public QXmlDefaultHandler } void dump(); - void buildLists(Entry *root); + void buildLists(const std::unique_ptr &root); void addIncludes(); private: - void buildMemberList(Entry *ce,QList &members); - void addDocAnchors(Entry *e,const TagAnchorInfoList &l); + void buildMemberList(const std::unique_ptr &ce,QList &members); + void addDocAnchors(const std::unique_ptr &e,const TagAnchorInfoList &l); QList m_tagFileClasses; QList m_tagFileFiles; QList m_tagFileNamespaces; @@ -1147,7 +1149,7 @@ void TagFileParser::dump() } } -void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l) +void TagFileParser::addDocAnchors(const std::unique_ptr &e,const TagAnchorInfoList &l) { QListIterator tli(l); TagAnchorInfo *ta; @@ -1169,13 +1171,13 @@ void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l) } } -void TagFileParser::buildMemberList(Entry *ce,QList &members) +void TagFileParser::buildMemberList(const std::unique_ptr &ce,QList &members) { QListIterator mii(members); TagMemberInfo *tmi; for (;(tmi=mii.current());++mii) { - Entry *me = new Entry; + std::unique_ptr me = std::make_unique(); me->type = tmi->type; me->name = tmi->name; me->args = tmi->arglist; @@ -1192,7 +1194,7 @@ void TagFileParser::buildMemberList(Entry *ce,QList &members) TagEnumValueInfo *evi; for (evii.toFirst();(evi=evii.current());++evii) { - Entry *ev = new Entry; + std::unique_ptr ev = std::make_unique(); ev->type = "@"; ev->name = evi->name; ev->id = evi->clangid; @@ -1202,7 +1204,7 @@ void TagFileParser::buildMemberList(Entry *ce,QList &members) ti->anchor = evi->anchor; ti->fileName = evi->file; ev->tagInfo = ti; - me->addSubEntry(ev); + me->moveToSubEntryAndKeep(ev); } } me->protection = tmi->prot; @@ -1287,7 +1289,7 @@ void TagFileParser::buildMemberList(Entry *ce,QList &members) me->section = Entry::FUNCTION_SEC; me->mtype = Slot; } - ce->addSubEntry(me); + ce->moveToSubEntryAndKeep(me); } } @@ -1308,14 +1310,14 @@ static QCString stripPath(const QCString &s) * This tree contains the information extracted from the input in a * "unrelated" form. */ -void TagFileParser::buildLists(Entry *root) +void TagFileParser::buildLists(const std::unique_ptr &root) { // build class list QListIterator cit(m_tagFileClasses); TagClassInfo *tci; for (cit.toFirst();(tci=cit.current());++cit) { - Entry *ce = new Entry; + std::unique_ptr ce = std::make_unique(); ce->section = Entry::CLASS_SEC; switch (tci->kind) { @@ -1374,7 +1376,7 @@ void TagFileParser::buildLists(Entry *root) } buildMemberList(ce,tci->members); - root->addSubEntry(ce); + root->moveToSubEntryAndKeep(ce); } // build file list @@ -1382,7 +1384,7 @@ void TagFileParser::buildLists(Entry *root) TagFileInfo *tfi; for (fit.toFirst();(tfi=fit.current());++fit) { - Entry *fe = new Entry; + std::unique_ptr fe = std::make_unique(); fe->section = guessSection(tfi->name); fe->name = tfi->name; addDocAnchors(fe,tfi->docAnchors); @@ -1390,7 +1392,7 @@ void TagFileParser::buildLists(Entry *root) ti->tagName = m_tagName; ti->fileName = tfi->filename; fe->tagInfo = ti; - + QCString fullName = m_tagName+":"+tfi->path+stripPath(tfi->name); fe->fileName = fullName; //printf("createFileDef() filename=%s\n",tfi->filename.data()); @@ -1411,7 +1413,7 @@ void TagFileParser::buildLists(Entry *root) Doxygen::inputNameDict->insert(tfi->name,mn); } buildMemberList(fe,tfi->members); - root->addSubEntry(fe); + root->moveToSubEntryAndKeep(fe); } // build namespace list @@ -1419,7 +1421,7 @@ void TagFileParser::buildLists(Entry *root) TagNamespaceInfo *tni; for (nit.toFirst();(tni=nit.current());++nit) { - Entry *ne = new Entry; + std::unique_ptr ne = std::make_unique(); ne->section = Entry::NAMESPACE_SEC; ne->name = tni->name; addDocAnchors(ne,tni->docAnchors); @@ -1430,7 +1432,7 @@ void TagFileParser::buildLists(Entry *root) ne->tagInfo = ti; buildMemberList(ne,tni->members); - root->addSubEntry(ne); + root->moveToSubEntryAndKeep(ne); } // build package list @@ -1438,7 +1440,7 @@ void TagFileParser::buildLists(Entry *root) TagPackageInfo *tpgi; for (pit.toFirst();(tpgi=pit.current());++pit) { - Entry *pe = new Entry; + std::unique_ptr pe = std::make_unique(); pe->section = Entry::PACKAGE_SEC; pe->name = tpgi->name; addDocAnchors(pe,tpgi->docAnchors); @@ -1448,7 +1450,7 @@ void TagFileParser::buildLists(Entry *root) pe->tagInfo = ti; buildMemberList(pe,tpgi->members); - root->addSubEntry(pe); + root->moveToSubEntryAndKeep(pe); } // build group list @@ -1456,7 +1458,7 @@ void TagFileParser::buildLists(Entry *root) TagGroupInfo *tgi; for (git.toFirst();(tgi=git.current());++git) { - Entry *ge = new Entry; + std::unique_ptr ge = std::make_unique(); ge->section = Entry::GROUPDOC_SEC; ge->name = tgi->name; ge->type = tgi->title; @@ -1467,7 +1469,7 @@ void TagFileParser::buildLists(Entry *root) ge->tagInfo = ti; buildMemberList(ge,tgi->members); - root->addSubEntry(ge); + root->moveToSubEntryAndKeep(ge); } // set subgroup relations bug_774118 @@ -1476,13 +1478,16 @@ void TagFileParser::buildLists(Entry *root) QCStringList::Iterator it; for ( it = tgi->subgroupList.begin(); it != tgi->subgroupList.end(); ++it ) { - QListIterator eli(*(root->children())); - Entry *childNode; - for (eli.toFirst();(childNode=eli.current());++eli) + //QListIterator eli(*(root->children())); + //Entry *childNode; + //for (eli.toFirst();(childNode=eli.current());++eli) + const auto &children = root->children(); + auto i = std::find_if(children.begin(),children.end(), + [&](const std::unique_ptr &e) { return e->name = *it; }); + if (i!=children.end()) { - if (childNode->name == (*it)) break; + (*i)->groups->append(new Grouping(tgi->name,Grouping::GROUPING_INGROUP)); } - childNode->groups->append(new Grouping(tgi->name,Grouping::GROUPING_INGROUP)); } } @@ -1491,7 +1496,7 @@ void TagFileParser::buildLists(Entry *root) TagPageInfo *tpi; for (pgit.toFirst();(tpi=pgit.current());++pgit) { - Entry *pe = new Entry; + std::unique_ptr pe = std::make_unique(); pe->section = tpi->filename=="index" ? Entry::MAINPAGEDOC_SEC : Entry::PAGEDOC_SEC; pe->name = tpi->name; pe->args = tpi->title; @@ -1500,7 +1505,7 @@ void TagFileParser::buildLists(Entry *root) ti->tagName = m_tagName; ti->fileName = tpi->filename; pe->tagInfo = ti; - root->addSubEntry(pe); + root->moveToSubEntryAndKeep(pe); } } @@ -1551,7 +1556,7 @@ void TagFileParser::addIncludes() } } -void parseTagFile(Entry *root,const char *fullName) +void parseTagFile(const std::unique_ptr &root,const char *fullName) { QFileInfo fi(fullName); if (!fi.exists()) return; diff --git a/src/tagreader.h b/src/tagreader.h index 6ea2d81..4c09a04 100644 --- a/src/tagreader.h +++ b/src/tagreader.h @@ -21,6 +21,8 @@ class Entry; -void parseTagFile(Entry *root,const char *fullPathName); +#include + +void parseTagFile(const std::unique_ptr &root,const char *fullPathName); #endif diff --git a/src/tclscanner.h b/src/tclscanner.h index 0e56bdd..482fb1f 100644 --- a/src/tclscanner.h +++ b/src/tclscanner.h @@ -33,7 +33,7 @@ class TclLanguageScanner : public ParserInterface void finishTranslationUnit() {} void parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension); diff --git a/src/tclscanner.l b/src/tclscanner.l index e763575..3b939ce 100644 --- a/src/tclscanner.l +++ b/src/tclscanner.l @@ -578,7 +578,7 @@ Entry* tcl_entry_namespace(const QCString ns) myEntry = tcl_entry_new(); myEntry->section = Entry::NAMESPACE_SEC; myEntry->name = ns; - tcl.entry_main->addSubEntry(myEntry); + tcl.entry_main->moveToSubEntryAndKeep(myEntry); tcl.ns.insert(ns,myEntry); } return myEntry; @@ -597,7 +597,7 @@ Entry* tcl_entry_class(const QCString cl) myEntry = tcl_entry_new(); myEntry->section = Entry::CLASS_SEC; myEntry->name = cl; - tcl.entry_main->addSubEntry(myEntry); + tcl.entry_main->moveToSubEntryAndKeep(myEntry); tcl.cl.insert(cl,myEntry); } return myEntry; @@ -1540,7 +1540,7 @@ tcl_inf("-> %s\n",(const char *)tcl.string_comment); processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine0); parseCommentBlock(tcl.this_parser, myEntry, processedDoc, tcl.file_name, myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); - tcl.entry_inside->addSubEntry(myEntry); + tcl.entry_inside->moveToSubEntryAndRefresh(myEntry); } else { // we can add to current entry in this case @@ -1562,7 +1562,7 @@ tcl_inf("-> %s\n",(const char *)tcl.string_comment); processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine0); parseCommentBlock(tcl.this_parser, myEntry, processedDoc, tcl.file_name, myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); - tcl.entry_inside->addSubEntry(myEntry); + tcl.entry_inside->moveToSubEntryAndKeep(myEntry); } else { // we can add to current entry @@ -1585,7 +1585,7 @@ tcl_inf("-> %s\n",(const char *)tcl.string_comment); { if (myNew) { - tcl.entry_inside->addSubEntry(tcl.entry_current); + tcl.entry_inside->moveToSubEntryAndKeep(tcl.entry_current); tcl.entry_current = tcl_entry_new(); } else @@ -1596,7 +1596,7 @@ tcl_inf("-> %s\n",(const char *)tcl.string_comment); } if (myNew) { - tcl.entry_inside->addSubEntry(tcl.entry_current); + tcl.entry_inside->moveToSubEntryAndKeep(tcl.entry_current); tcl.entry_current = tcl_entry_new(); } else @@ -2155,7 +2155,7 @@ D tcl.entry_current->endBodyLine = tcl.line_body1; tcl_protection(tcl.entry_current); tcl_command_ARGLIST(*tcl.list_commandwords.at(4)); - myEntryNs->addSubEntry(tcl.entry_current); + myEntryNs->moveToSubEntryAndKeep(tcl.entry_current); myEntry = tcl.entry_current; tcl.fn.insert(myName,myEntry); myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6), @@ -2197,7 +2197,7 @@ D tcl.entry_current->endBodyLine = tcl.line_body1; tcl_protection(tcl.entry_current); tcl_command_ARGLIST(*tcl.list_commandwords.at(4)); - myEntryCl->addSubEntry(tcl.entry_current); + myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); tcl.fn.insert(myName,tcl.entry_current); myEntry = tcl.entry_current; myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(6), @@ -2234,7 +2234,7 @@ D tcl.entry_current->endBodyLine = tcl.line_body1; tcl_protection(tcl.entry_current); tcl_command_ARGLIST(*tcl.list_commandwords.at(2)); - if (myEntryCl) myEntryCl->addSubEntry(tcl.entry_current); + if (myEntryCl) myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); myEntry = tcl.entry_current; tcl.fn.insert(myName,myEntry); myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4), @@ -2268,7 +2268,7 @@ D tcl.entry_current->bodyLine = tcl.line_body0; tcl.entry_current->endBodyLine = tcl.line_body1; tcl_protection(tcl.entry_current); - myEntryCl->addSubEntry(tcl.entry_current); + myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); myEntry = tcl.entry_current; tcl.fn.insert(myName,myEntry); myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(2), @@ -2300,7 +2300,7 @@ D tcl.entry_current->startLine = tcl.line_command; tcl.entry_current->bodyLine = tcl.line_body0; tcl.entry_current->endBodyLine = tcl.line_body1; - tcl.entry_main->addSubEntry(tcl.entry_current); + tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_current); tcl.ns.insert(myName,tcl.entry_current); //myEntryNs = tcl.entry_current; myStr = (*tcl.list_commandwords.at(6)); @@ -2338,7 +2338,7 @@ D tcl.entry_current->startLine = tcl.line_command; tcl.entry_current->bodyLine = tcl.line_body0; tcl.entry_current->endBodyLine = tcl.line_body1; - tcl.entry_main->addSubEntry(tcl.entry_current); + tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_current); tcl.cl.insert(myName,tcl.entry_current); myEntryCl = tcl.entry_current; myScan = tcl_scan_start(tcl.word_is,*tcl.list_commandwords.at(4), @@ -2370,7 +2370,7 @@ D tcl.entry_current->startLine = tcl.line_command; tcl.entry_current->bodyLine = tcl.line_body0; tcl.entry_current->endBodyLine = tcl.line_body1; - tcl.entry_main->addSubEntry(tcl.entry_current); + tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_current); //myEntryNs = tcl_entry_namespace(myName); tcl.cl.insert(myName,tcl.entry_current); myEntryCl = tcl.entry_current; @@ -2431,7 +2431,7 @@ D { tcl_command_ARGLIST(*tcl.list_commandwords.at(6)); } - if (myEntryCl) myEntryCl->addSubEntry(tcl.entry_current); + if (myEntryCl) myEntryCl->moveToSubEntryAndKeep(tcl.entry_current); tcl.fn.insert(myMethod,tcl.entry_current); myEntry = tcl.entry_current; myScan = tcl_scan_start('?',*tcl.list_commandwords.at(n-1), @@ -2493,7 +2493,7 @@ D tcl.entry_current->bodyLine = tcl.line_body0; tcl.entry_current->endBodyLine = tcl.line_body1; tcl_protection(tcl.entry_current); - myEntry->addSubEntry(tcl.entry_current); + myEntry->moveToSubEntryAndKeep(tcl.entry_current); tcl.entry_current = tcl_entry_new(); } @@ -2911,10 +2911,10 @@ static void tcl_parse(const QCString ns, const QCString cls) tcl.entry_file->name = tcl.file_name; tcl.entry_file->section = Entry::SOURCE_SEC; tcl.entry_file->protection = Public; - tcl.entry_main->addSubEntry(tcl.entry_file); + tcl.entry_main->moveToSubEntryAndKeep(tcl.entry_file); Entry *myEntry=tcl_entry_new(); myEntry->name=""; - tcl.entry_main->addSubEntry(myEntry); + tcl.entry_main->moveToSubEntryAndKeep(myEntry); tcl.ns.insert("::",myEntry); tcl.entry_current = tcl_entry_new(); @@ -2944,7 +2944,7 @@ static void tcl_parse(const QCString ns, const QCString cls) //! Parse text file and build up entry tree. void TclLanguageScanner::parseInput(const char *fileName, const char *input, - Entry *root, + const std::unique_ptr &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { @@ -2965,7 +2965,7 @@ tcl_inf("%s\n",fileName); tcl.code = NULL; tcl.file_name = fileName; tcl.this_parser = this; - tcl.entry_main = root; /* toplevel entry */ + tcl.entry_main = root.get(); /* toplevel entry */ tcl_parse("",""); Doxygen::docGroup.leaveFile(tcl.file_name,yylineno); root->program.resize(0); diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index 38a80ef..fca010e 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -71,7 +71,8 @@ static QDict g_vhdlKeyDict3(17,FALSE); static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief); static void writeUCFLink(const MemberDef* mdef,OutputList &ol); static void assignBinding(VhdlConfNode* conf); -static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst,Entry *cur,ClassDef* archBind=NULL); +static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst, + const std::unique_ptr &cur); //---------- create svg ------------------------------------------------------------- static void createSVG(); @@ -2577,7 +2578,7 @@ static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCStr qcs.stripPrefix("="); - Entry* current=new Entry; + std::unique_ptr current = std::make_unique(); current->spec=VhdlDocGen::UCF_CONST; current->section=Entry::VARIABLE_SEC; current->bodyLine=line; @@ -2604,7 +2605,7 @@ static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCStr brief.resize(0); } - root->addSubEntry(current); + root->moveToSubEntryAndKeep(current); } @@ -2761,9 +2762,6 @@ QCString VhdlDocGen::parseForBinding(QCString & entity,QCString & arch) void assignBinding(VhdlConfNode * conf) { - QList instList=getVhdlInstList(); - QListIterator eli(instList); - Entry *cur=0; ClassDef *archClass=0,*entClass=0; QCString archName; QCString arcBind,entBind; @@ -2826,7 +2824,7 @@ void assignBinding(VhdlConfNode * conf) all=allOt.lower()=="all" ; others= allOt.lower()=="others"; - for (;(cur=eli.current());++eli) + for (const auto &cur : getVhdlInstList()) { if (cur->exception.lower()==label || conf->isInlineConf) { @@ -2909,11 +2907,7 @@ void VhdlDocGen::computeVhdlComponentRelations() assignBinding(conf); } - QList qsl= getVhdlInstList(); - QListIterator eli(qsl); - Entry *cur; - - for (eli.toFirst();(cur=eli.current());++eli) + for (const auto &cur : getVhdlInstList()) { if (cur->stat ) // was bind { @@ -2949,7 +2943,7 @@ void VhdlDocGen::computeVhdlComponentRelations() } static void addInstance(ClassDef* classEntity, ClassDef* ar, - ClassDef *cd , Entry *cur,ClassDef* /*archBind*/) + ClassDef *cd , const std::unique_ptr &cur) { QCString bName,n1; @@ -3185,10 +3179,10 @@ void VhdlDocGen::createFlowChart(const MemberDef *mdef) VHDLLanguageScanner *pIntf =(VHDLLanguageScanner*) Doxygen::parserManager->getParser(".vhd"); VhdlDocGen::setFlowMember(mdef); - Entry root; + std::unique_ptr root = std::make_unique(); QStrList filesInSameTu; pIntf->startTranslationUnit(""); - pIntf->parseInput("",codeFragment.data(),&root,FALSE,filesInSameTu); + pIntf->parseInput("",codeFragment.data(),root,FALSE,filesInSameTu); pIntf->finishTranslationUnit(); } diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp index aeed048..9a817dc 100644 --- a/src/vhdljjparser.cpp +++ b/src/vhdljjparser.cpp @@ -48,16 +48,16 @@ static Entry* oldEntry; static bool varr=FALSE; static QCString varName; -static QList instFiles; -static QList libUse; -static QList lineEntry; +static std::vector< std::unique_ptr > instFiles; +static std::vector< std::unique_ptr > libUse; +static std::vector lineEntry; Entry* VhdlParser::currentCompound=0; Entry* VhdlParser::tempEntry=0; Entry* VhdlParser::lastEntity=0 ; Entry* VhdlParser::lastCompound=0 ; -Entry* VhdlParser::current=0; Entry* VhdlParser::current_root = 0; +std::unique_ptr VhdlParser::current=0; QCString VhdlParser::compSpec; QCString VhdlParser::currName; QCString VhdlParser::confName; @@ -84,13 +84,13 @@ static QCString strComment; static int iCodeLen; static const char *vhdlFileName = 0; -bool checkMultiComment(QCString& qcs,int line); -QList* getEntryAtLine(const Entry* ce,int line); +static bool checkMultiComment(QCString& qcs,int line); +static void insertEntryAtLine(const Entry* ce,int line); //------------------------------------- -QList& getVhdlConfiguration() { return configL; } -QList& getVhdlInstList() { return instFiles; } +const QList& getVhdlConfiguration() { return configL; } +const std::vector > &getVhdlInstList() { return instFiles; } Entry* getVhdlCompound() { @@ -105,8 +105,8 @@ bool isConstraintFile(const QCString &fileName,const QCString &ext) } -void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,Entry *root, - bool ,QStrList&) +void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf, + const std::unique_ptr &root, bool ,QStrList&) { g_thisParser=this; bool inLine=false; @@ -128,34 +128,32 @@ void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,En if (xilinx_ucf) { - VhdlDocGen::parseUCF(fileBuf,root,yyFileName,FALSE); + VhdlDocGen::parseUCF(fileBuf,root.get(),yyFileName,FALSE); return; } if (altera_qsf) { - VhdlDocGen::parseUCF(fileBuf,root,yyFileName,TRUE); + VhdlDocGen::parseUCF(fileBuf,root.get(),yyFileName,TRUE); return; } - libUse.setAutoDelete(true); yyLineNr=1; - VhdlParser::current_root=root; + VhdlParser::current_root=root.get(); VhdlParser::lastCompound=0; VhdlParser::lastEntity=0; VhdlParser::currentCompound=0; VhdlParser::lastEntity=0; oldEntry = 0; - VhdlParser::current=new Entry(); - VhdlParser::initEntry(VhdlParser::current); + VhdlParser::current=std::make_unique(); + VhdlParser::initEntry(VhdlParser::current.get()); Doxygen::docGroup.enterFile(fileName,yyLineNr); vhdlFileName = fileName; lineParse=new int[200]; // Dimitri: dangerous constant: should be bigger than largest token id in VhdlParserConstants.h VhdlParserIF::parseVhdlfile(fileBuf,inLine); - delete VhdlParser::current; - VhdlParser::current=0; + VhdlParser::current.reset(); if (!inLine) - VhdlParser::mapLibPackage(root); + VhdlParser::mapLibPackage(root.get()); delete[] lineParse; yyFileName.resize(0); @@ -198,34 +196,33 @@ void VhdlParser::initEntry(Entry *e) void VhdlParser::newEntry() { + previous = current.get(); if (current->spec==VhdlDocGen::ENTITY || current->spec==VhdlDocGen::PACKAGE || current->spec==VhdlDocGen::ARCHITECTURE || current->spec==VhdlDocGen::PACKAGE_BODY) { - current_root->addSubEntry(current); + current_root->moveToSubEntryAndRefresh(current); } else { if (lastCompound) { - lastCompound->addSubEntry(current); + lastCompound->moveToSubEntryAndRefresh(current); } else { if (lastEntity) { - lastEntity->addSubEntry(current); + lastEntity->moveToSubEntryAndRefresh(current); } else { - current_root->addSubEntry(current); + current_root->moveToSubEntryAndRefresh(current); } } } - previous = current; - current = new Entry ; - initEntry(current); + initEntry(current.get()); } void VhdlParser::handleFlowComment(const char* doc) @@ -259,7 +256,7 @@ void VhdlParser::handleCommentBlock(const char* doc1,bool brief) Protection protection=Public; - if (oldEntry==current) + if (oldEntry==current.get()) { //printf("\n find pending message < %s > at line: %d \n ",doc.data(),iDocLine); str_doc.doc=doc; @@ -269,7 +266,7 @@ void VhdlParser::handleCommentBlock(const char* doc1,bool brief) return; } - oldEntry=current; + oldEntry=current.get(); if (brief) { @@ -293,7 +290,7 @@ void VhdlParser::handleCommentBlock(const char* doc1,bool brief) QCString processedDoc = preprocessCommentBlock(doc,yyFileName,iDocLine); while (parseCommentBlock( g_thisParser, - current, + current.get(), processedDoc, // text yyFileName, // file iDocLine, // line of block start @@ -357,13 +354,11 @@ void VhdlParser::addCompInst(const char *n, const char* instName, const char* co current->args=lastCompound->name; if (true) // !findInstant(current->type)) { - initEntry(current); - instFiles.append(new Entry(*current)); + initEntry(current.get()); + instFiles.emplace_back(std::make_unique(*current)); } - Entry *temp=current; // hold current pointer (temp=oldEntry) - current=new Entry; // (oldEntry != current) - delete temp; + current=std::make_unique(); } else { @@ -401,7 +396,7 @@ void VhdlParser::addVhdlType(const char *n,int startLine,int section, if (!lastCompound && (section==Entry::VARIABLE_SEC) && (spec == VhdlDocGen::USE || spec == VhdlDocGen::LIBRARY) ) { - libUse.append(new Entry(*current)); + libUse.emplace_back(std::make_unique(*current)); current->reset(); } newEntry(); @@ -590,31 +585,30 @@ void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, */ void VhdlParser::mapLibPackage( Entry* root) { - QList epp=libUse; - EntryListIterator eli(epp); - Entry *rt; - for (;(rt=eli.current());++eli) + //QList epp=libUse; + //EntryListIterator eli(epp); + //Entry *rt; + //for (;(rt=eli.current());++eli) + for (const auto &rt : libUse) { if (addLibUseClause(rt->name)) { - Entry *current; - EntryListIterator eLib(*root->children()); bool bFound=FALSE; - for (eLib.toFirst();(current=eLib.current());++eLib) + for (const auto ¤t : root->children()) { - if (VhdlDocGen::isVhdlClass(current)) + if (VhdlDocGen::isVhdlClass(current.get())) { if (current->startLine > rt->startLine) { bFound=TRUE; - current->addSubEntry(new Entry(*rt)); + current->copyToSubEntry(rt); break; } } }//for if (!bFound) { - root->addSubEntry(new Entry(*rt)); + root->copyToSubEntry(rt); } } //if }// for @@ -718,37 +712,34 @@ void VhdlParser::oneLineComment(QCString qcs) bool checkMultiComment(QCString& qcs,int line) { - QList *pTemp=getEntryAtLine(VhdlParser::current_root,line); + insertEntryAtLine(VhdlParser::current_root,line); - if (pTemp->isEmpty()) return false; + if (lineEntry.empty()) return false; VhdlDocGen::prepareComment(qcs); - while (!pTemp->isEmpty()) + while (!lineEntry.empty()) { - Entry *e=(Entry*)pTemp->getFirst(); + Entry *e=lineEntry.back(); e->briefLine=line; e->brief+=qcs; - pTemp->removeFirst(); + lineEntry.pop_back(); } return true; } // returns the vhdl parsed types at line xxx -QList* getEntryAtLine(const Entry* ce,int line) +void insertEntryAtLine(const Entry* ce,int line) { - EntryListIterator eli(*ce->children()); - Entry *rt; - for (;(rt=eli.current());++eli) + for (const auto &rt : ce->children()) { if (rt->bodyLine==line) { - lineEntry.insert(0,rt); + lineEntry.push_back(rt.get()); } - getEntryAtLine(rt,line); + insertEntryAtLine(rt.get(),line); } - return &lineEntry; } const char *getVhdlFileName(void) diff --git a/src/vhdljjparser.h b/src/vhdljjparser.h index fffea47..a179630 100644 --- a/src/vhdljjparser.h +++ b/src/vhdljjparser.h @@ -1,6 +1,9 @@ #ifndef VHDLJJPARSER_H #define VHDLJJPARSER_H +#include +#include + #include "parserintf.h" #include #include @@ -45,7 +48,7 @@ class VHDLLanguageScanner : public ParserInterface void finishTranslationUnit() {} void parseInput(const char * fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); @@ -95,7 +98,7 @@ struct VhdlConfNode void vhdlscanFreeScanner(); -QList& getVhdlConfiguration(); -QList& getVhdlInstList(); +const QList& getVhdlConfiguration(); +const std::vector >&getVhdlInstList(); #endif diff --git a/src/xmlscanner.h b/src/xmlscanner.h index cb9792c..b54d416 100644 --- a/src/xmlscanner.h +++ b/src/xmlscanner.h @@ -28,7 +28,7 @@ public: virtual ~XMLScanner() {} void startTranslationUnit(const char *) {} void finishTranslationUnit() {} - void parseInput(const char *, const char *, Entry *, bool , QStrList &) {} + void parseInput(const char *, const char *, const std::unique_ptr &, bool , QStrList &) {} bool needsPreprocessing(const QCString &) { return FALSE; } void parseCode(CodeOutputInterface &codeOutIntf, diff --git a/vhdlparser/VhdlParser.cc b/vhdlparser/VhdlParser.cc index 4cf8ec0..aa0847a 100644 --- a/vhdlparser/VhdlParser.cc +++ b/vhdlparser/VhdlParser.cc @@ -462,7 +462,7 @@ void VhdlParser::architecture_body() {QCString s,s1;if (!hasError) { QCString t=s1+"::"+s; genLabels.resize(0); pushLabel(genLabels,s1); - lastCompound=current; + lastCompound=current.get(); addVhdlType(t,getLine(ARCHITECTURE_T),Entry::CLASS_SEC,VhdlDocGen::ARCHITECTURE,0,0,Private); } if (!hasError) { @@ -3336,7 +3336,7 @@ void VhdlParser::entity_declaration() {QCString s;if (!hasError) { } if (!hasError) { -lastEntity=current; +lastEntity=current.get(); lastCompound=0; addVhdlType(s.data(),getLine(ENTITY_T),Entry::CLASS_SEC,VhdlDocGen::ENTITY,0,0,Public); } @@ -4432,7 +4432,7 @@ QCString VhdlParser::full_type_declaration() {Entry *tmpEntry;QCString s,s1,s2;i } if (!hasError) { -tmpEntry=current; +tmpEntry=current.get(); addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::RECORD,0,0,Public); } if (!hasError) { @@ -6680,7 +6680,7 @@ void VhdlParser::package_body() {QCString s;if (!hasError) { } if (!hasError) { -lastCompound=current; +lastCompound=current.get(); s.prepend("_"); addVhdlType(s,getLine(),Entry::CLASS_SEC,VhdlDocGen::PACKAGE_BODY,0,0,Protected); } @@ -6875,15 +6875,15 @@ void VhdlParser::package_declaration() {QCString s;if (!hasError) { } if (!hasError) { -lastCompound=current; - Entry *clone=new Entry(*current); +lastCompound=current.get(); + std::unique_ptr clone=std::make_unique(*current); clone->section=Entry::NAMESPACE_SEC; clone->spec=VhdlDocGen::PACKAGE; clone->name=s; clone->startLine=getLine(PACKAGE_T); clone->bodyLine=getLine(PACKAGE_T); clone->protection=Package; - current_root->addSubEntry(clone); + current_root->moveToSubEntryAndKeep(clone); addVhdlType(s,getLine(PACKAGE_T),Entry::CLASS_SEC,VhdlDocGen::PACKAGE,0,0,Package); } if (!hasError) { @@ -7913,7 +7913,7 @@ if(s.isEmpty()) currName=s; current->name=currName; - tempEntry=current; + tempEntry=current.get(); current->endBodyLine=getLine(); currP=0; if(tok) @@ -9735,7 +9735,7 @@ void VhdlParser::subprogram_specification() {QCString s;Token *tok=0;Token *t; currP=VhdlDocGen::PROCEDURE; createFunction(s.data(),currP,0); - tempEntry=current; + tempEntry=current.get(); current->startLine=getLine(PROCEDURE_T); current->bodyLine=getLine(PROCEDURE_T); } @@ -9855,7 +9855,7 @@ currP=VhdlDocGen::FUNCTION; createFunction(tok->image.c_str(),currP,s.data()); else createFunction(0,currP,s.data()); - tempEntry=current; + tempEntry=current.get(); current->startLine=getLine(FUNCTION_T); current->bodyLine=getLine(FUNCTION_T); } @@ -9900,7 +9900,7 @@ param_sec=0; } if (!hasError) { -tempEntry=current; +tempEntry=current.get(); current->type=s; newEntry(); } diff --git a/vhdlparser/VhdlParser.h b/vhdlparser/VhdlParser.h index 3e32daa..3cd383a 100644 --- a/vhdlparser/VhdlParser.h +++ b/vhdlparser/VhdlParser.h @@ -8933,7 +8933,7 @@ static Entry* current_root; static Entry* tempEntry; static Entry* lastEntity ; static Entry* lastCompound ; -static Entry* current; +static std::unique_ptr current; static QCString compSpec; static QCString currName; static int levelCounter; diff --git a/vhdlparser/vhdlparser.jj b/vhdlparser/vhdlparser.jj index af1bd34..6eb95b4 100644 --- a/vhdlparser/vhdlparser.jj +++ b/vhdlparser/vhdlparser.jj @@ -31,7 +31,7 @@ static Entry* current_root; static Entry* tempEntry; static Entry* lastEntity ; static Entry* lastCompound ; -static Entry* current; +static std::unique_ptr current; static QCString compSpec; static QCString currName; static int levelCounter; @@ -409,7 +409,7 @@ void architecture_body() : {QCString s,s1;} QCString t=s1+"::"+s; genLabels.resize(0); pushLabel(genLabels,s1); - lastCompound=current; + lastCompound=current.get(); addVhdlType(t,getLine(ARCHITECTURE_T),Entry::CLASS_SEC,VhdlDocGen::ARCHITECTURE,0,0,Private); } try{ @@ -1012,7 +1012,7 @@ void entity_declaration() : {QCString s;} // try{ s=identifier() { - lastEntity=current; + lastEntity=current.get(); lastCompound=0; addVhdlType(s.data(),getLine(ENTITY_T),Entry::CLASS_SEC,VhdlDocGen::ENTITY,0,0,Public); } @@ -1209,7 +1209,7 @@ QCString full_type_declaration() : {Entry *tmpEntry;QCString s,s1,s2;} { s=identifier() { - tmpEntry=current; + tmpEntry=current.get(); addVhdlType(s.data(),getLine(),Entry::VARIABLE_SEC,VhdlDocGen::RECORD,0,0,Public); } try{ @@ -1693,7 +1693,7 @@ void package_body() : {QCString s;} { s=name() { - lastCompound=current; + lastCompound=current.get(); s.prepend("_"); addVhdlType(s,getLine(),Entry::CLASS_SEC,VhdlDocGen::PACKAGE_BODY,0,0,Protected); } @@ -1729,15 +1729,15 @@ void package_declaration(): {QCString s;} s=identifier() { - lastCompound=current; - Entry *clone=new Entry(*current); + lastCompound=current.get(); + std::unique_ptr clone=std::make_unique_ptr(*current); clone->section=Entry::NAMESPACE_SEC; clone->spec=VhdlDocGen::PACKAGE; clone->name=s; clone->startLine=getLine(PACKAGE_T); clone->bodyLine=getLine(PACKAGE_T); clone->protection=Package; - current_root->addSubEntry(clone); + current_root->moveToSubEntryAndKeep(clone); addVhdlType(s,getLine(PACKAGE_T),Entry::CLASS_SEC,VhdlDocGen::PACKAGE,0,0,Package); } package_declarative_part() @@ -2292,7 +2292,7 @@ void subprogram_specification() : {QCString s;Token *tok=0;Token *t;} { currP=VhdlDocGen::PROCEDURE; createFunction(s.data(),currP,0); - tempEntry=current; + tempEntry=current.get(); current->startLine=getLine(PROCEDURE_T); current->bodyLine=getLine(PROCEDURE_T); @@ -2309,14 +2309,14 @@ void subprogram_specification() : {QCString s;Token *tok=0;Token *t;} createFunction(tok->image.c_str(),currP,s.data()); else createFunction(0,currP,s.data()); - tempEntry=current; + tempEntry=current.get(); current->startLine=getLine(FUNCTION_T); current->bodyLine=getLine(FUNCTION_T); } [{ param_sec=PARAM_SEC; } formal_parameter_list() { param_sec=0; }] s=type_mark() { - tempEntry=current; + tempEntry=current.get(); current->type=s; newEntry(); } -- cgit v0.12 From 148162e48b8337fafffc61e5a1b5cdf86077d6ac Mon Sep 17 00:00:00 2001 From: albert-github Date: Tue, 8 Oct 2019 18:50:53 +0200 Subject: issue 7302: Parsing of template args in single-quotes is incorrect. In case we encounter an unescaped single or double quote during specialization we search for the closing quote. We are cionnsidering potential escape sequences in the strings as well. --- src/scanner.l | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/scanner.l b/src/scanner.l index fe20543..242a106 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -751,6 +751,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) %x GCopyCurly %x SkipUnionSwitch %x Specialization +%x SpecializationSingleQuote +%x SpecializationDoubleQuote %x FuncPtrInit %x FuncFunc %x FuncFuncEnd @@ -6145,6 +6147,19 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) "typename"{BN}+ { lineCount(); } "(" { *specName += *yytext; roundCount++; } ")" { *specName += *yytext; roundCount--; } + +"\\\\" { *specName += *yytext;} +"\\'" { *specName += *yytext;} +"\\\"" { *specName += *yytext;} +"'" { *specName += *yytext;BEGIN(SpecializationSingleQuote);} +"\"" { *specName += *yytext;BEGIN(SpecializationDoubleQuote);} +"\\\\" { *specName += *yytext;} +"\\'" { *specName += *yytext;} +"'" { *specName += *yytext; BEGIN(Specialization);} +"\\\"" { *specName += *yytext;} +"\"" { *specName += *yytext; BEGIN(Specialization);} +. { *specName += *yytext;} + . { *specName += *yytext; } -- cgit v0.12 From f23e59f2543f592bcbc2358c1d51825ab71f88bd Mon Sep 17 00:00:00 2001 From: albert-github Date: Wed, 9 Oct 2019 13:32:31 +0200 Subject: Problem with round brackets in PS output In case we use the doxygen inheritance diagrams in doxygen (i.e. `HAVE_DOT=NO`) for a construct like (based on #7302): ``` template struct one { }; /// The struct str_040 struct str_040 : one<'('> { }; ``` this will lead to a postscript error (epstopdf) as the `(` (and analogous the `)`) have to be escaped. --- src/diagram.cpp | 6 +++--- src/util.cpp | 20 ++++++++++++++++++++ src/util.h | 2 ++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/diagram.cpp b/src/diagram.cpp index 08b49ca..2dadc12 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -247,7 +247,7 @@ static void writeVectorBox(FTextStream &t,DiagramItem *di, float x,float y,bool children=FALSE) { if (di->virtualness()==Virtual) t << "dashed\n"; - t << " (" << di->label() << ") " << x << " " << y << " box\n"; + t << " (" << convertToPSString(di->label()) << ") " << x << " " << y << " box\n"; if (children) t << x << " " << y << " mark\n"; if (di->virtualness()==Virtual) t << "solid\n"; } @@ -1297,7 +1297,7 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path, for (;(di=rit.current());++rit) { done=di->isInList(); - t << "(" << di->label() << ") cw\n"; + t << "(" << convertToPSString(di->label()) << ") cw\n"; } } QListIterator sit(*super); @@ -1310,7 +1310,7 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path, for (;(di=rit.current());++rit) { done=di->isInList(); - t << "(" << di->label() << ") cw\n"; + t << "(" << convertToPSString(di->label()) << ") cw\n"; } } diff --git a/src/util.cpp b/src/util.cpp index 85536ca..e1e9fb5 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -6183,6 +6183,26 @@ QCString convertToJSString(const char *s, bool applyTextDir) return convertCharEntitiesToUTF8(growBuf.get()); } +QCString convertToPSString(const char *s) +{ + static GrowBuf growBuf; + growBuf.clear(); + if (s==0) return ""; + const char *p=s; + char c; + while ((c=*p++)) + { + switch (c) + { + case '(': growBuf.addStr("\\("); break; + case ')': growBuf.addStr("\\)"); break; + default: growBuf.addChar(c); break; + } + } + growBuf.addChar(0); + return growBuf.get(); +} + QCString convertToLaTeX(const QCString &s,bool insideTabbing,bool keepSpaces) { QGString result; diff --git a/src/util.h b/src/util.h index 4e6f622..cb2b957 100644 --- a/src/util.h +++ b/src/util.h @@ -291,6 +291,8 @@ QCString convertToDocBook(const char *s); QCString convertToJSString(const char *s, bool applyTextDir = true); +QCString convertToPSString(const char *s); + QCString getOverloadDocs(); void addMembersToMemberGroup(/* in,out */ MemberList *ml, -- cgit v0.12 From 44695af0c77cff4099bc8a53c5f3270cc6a6e33c Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 10 Oct 2019 15:47:58 +0200 Subject: Also span entire line in case of a memTemplItemRight Based on the CGAL issue https://github.com/CGAL/cgal/issues/2095 (and pull request https://github.com/CGAL/cgal/pull/4282) to see to it that all relevant table span the page. --- templates/html/doxygen.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/html/doxygen.css b/templates/html/doxygen.css index 09b7aad..ffba793 100644 --- a/templates/html/doxygen.css +++ b/templates/html/doxygen.css @@ -535,7 +535,7 @@ table.memberdecls { white-space: nowrap; } -.memItemRight { +.memItemRight, .memTemplItemRight { width: 100%; } -- cgit v0.12 From 78b5c447d516d64237f73e08a7ba2ad488201aa7 Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 10 Oct 2019 16:17:36 +0200 Subject: Properly close quotes in warning Found warning like: ``` Possible candidates: 'template < T > gmic::gmic(const T &pixel_type=(T) 0) 'template < T > gmic::gmic(const char *const commands_line, const char *const custom_commands=0, const bool include_stdlib=true, float *const p_progress=0, bool *const p_is_abort=0, const T &pixel_type=(T) 0) 'template < T > gmic::gmic(const char *const commands_line, cimg_library::CImgList< T > &images, cimg_library::CImgList< char > &images_names, const char *const custom_commands=0, const bool include_stdlib=true, float *const p_progress=0, bool *const p_is_abort=0) ``` Note the starting quote `'` but there is no closing quote (in case of a file and line the closing quote is present. --- src/doxygen.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 184220c..7b3c7d9 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -6405,6 +6405,8 @@ static void findMember(const Entry *root, warnMsg+="' at line "+QCString().setNum(md->getDefLine()) + " of file "+md->getDefFileName(); } + else + warnMsg += "'"; warnMsg+='\n'; } -- cgit v0.12 From 056a6ba3de9b9a558ffa9c908bed28ae3494e121 Mon Sep 17 00:00:00 2001 From: albert-github Date: Sat, 12 Oct 2019 18:47:29 +0200 Subject: Warning when using empty p HTML tag When we use the construct: ```

``` we get the warning: ``` warning: HTML tags may not use the 'empty tag' XHTML syntax. ``` tough the construct is handled properly, so we can omit the warning. --- src/docparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docparser.cpp b/src/docparser.cpp index da4cfb2..1b6dbca 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -5892,7 +5892,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta int retval=RetVal_OK; int tagId = Mappers::htmlTagMapper->map(tagName); if (g_token->emptyTag && !(tagId&XML_CmdMask) && - tagId!=HTML_UNKNOWN && tagId!=HTML_IMG && tagId!=HTML_BR) + tagId!=HTML_UNKNOWN && tagId!=HTML_IMG && tagId!=HTML_BR && tagId!=HTML_P) { warn_doc_error(g_fileName,doctokenizerYYlineno,"HTML tags may not use the 'empty tag' XHTML syntax."); } -- cgit v0.12 From 79f6a43c5fbd1f28f2fbdaa642cf42a0079b5be6 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Sun, 13 Oct 2019 23:53:12 +0200 Subject: Fix lifetime issue for Entry objects. --- src/entry.cpp | 35 ++++++++++++++++++++++++++--------- src/entry.h | 5 ++++- src/scanner.l | 4 ++-- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/entry.cpp b/src/entry.cpp index ec3c736..8ec7846 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -240,6 +240,32 @@ void Entry::copyToSubEntry(const std::unique_ptr ¤t) m_sublist.push_back(std::move(copy)); } +void Entry::moveFromSubEntry(const Entry *child,std::unique_ptr &moveTo) +{ + auto it = std::find_if(m_sublist.begin(),m_sublist.end(), + [child](const std::unique_ptr&elem) { return elem.get()==child; }); + if (it!=m_sublist.end()) + { + moveTo = std::move(*it); + m_sublist.erase(it); + } + else + { + moveTo.reset(); + } +} + +void Entry::removeSubEntry(const Entry *e) +{ + auto it = std::find_if(m_sublist.begin(),m_sublist.end(), + [e](const std::unique_ptr&elem) { return elem.get()==e; }); + if (it!=m_sublist.end()) + { + m_sublist.erase(it); + } +} + + void Entry::reset() { static bool entryCallGraph = Config_getBool(CALL_GRAPH); @@ -335,14 +361,5 @@ void Entry::addSpecialListItem(const char *listName,int itemId) sli->append(ili); } -void Entry::removeSubEntry(Entry *e) -{ - auto it = std::find_if(m_sublist.begin(),m_sublist.end(), - [e](const std::unique_ptr&elem) { return elem.get()==e; }); - if (it!=m_sublist.end()) - { - m_sublist.erase(it); - } -} //------------------------------------------------------------------ diff --git a/src/entry.h b/src/entry.h index 091e81b..c078936 100644 --- a/src/entry.h +++ b/src/entry.h @@ -223,6 +223,9 @@ class Entry void moveToSubEntryAndRefresh(Entry* &e); void moveToSubEntryAndRefresh(std::unique_ptr &e); + /*! take \a child of of to list of children and move it into \a moveTo */ + void moveFromSubEntry(const Entry *child,std::unique_ptr &moveTo); + /*! make a copy of \a e and add it as a child to this entry */ void copyToSubEntry (Entry* e); void copyToSubEntry (const std::unique_ptr &e); @@ -230,7 +233,7 @@ class Entry /*! Removes entry \a e from the list of children. * The entry will be deleted if found. */ - void removeSubEntry(Entry *e); + void removeSubEntry(const Entry *e); /*! Restore the state of this Entry to the default value it has * at construction time. diff --git a/src/scanner.l b/src/scanner.l index fe20543..4ed4a62 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -5305,9 +5305,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { current->endBodyLine=yyLineNr; - + // take previous out of current_root and move it into current current.swap(tempEntry); // remember current - current.reset(previous); // and temporarily switch to the previous entry + current_root->moveFromSubEntry(previous,current); previous = 0; docBlockContext = SkipCurlyEndDoc; -- cgit v0.12 From ef3063ef59cb1f41f02d7658490b0e554bb7a288 Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 14 Oct 2019 12:37:34 +0200 Subject: Warning when using empty HTML tag - the HR tag has in xhtml the form


. Supporting empty tag - better warning (with tag name, for empty tag. - `` does not exist, correcting warning (analogous to `
`) --- src/docparser.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/docparser.cpp b/src/docparser.cpp index 1b6dbca..5253b04 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -5892,9 +5892,10 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta int retval=RetVal_OK; int tagId = Mappers::htmlTagMapper->map(tagName); if (g_token->emptyTag && !(tagId&XML_CmdMask) && - tagId!=HTML_UNKNOWN && tagId!=HTML_IMG && tagId!=HTML_BR && tagId!=HTML_P) + tagId!=HTML_UNKNOWN && tagId!=HTML_IMG && tagId!=HTML_BR && tagId!=HTML_HR && tagId!=HTML_P) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"HTML tags may not use the 'empty tag' XHTML syntax."); + warn_doc_error(g_fileName,doctokenizerYYlineno,"HTML tag ('<%s/>') may not use the 'empty tag' XHTML syntax.", + tagName.data()); } switch (tagId) { @@ -6439,7 +6440,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag found"); break; case HTML_HR: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag found"); + warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal tag found\n"); break; case HTML_A: //warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag found"); -- cgit v0.12 From 1734f1a16f828013171bb67bb4dcb61be57fad04 Mon Sep 17 00:00:00 2001 From: albert-github Date: Wed, 16 Oct 2019 15:54:33 +0200 Subject: Support for Support besides `` also `` as `id=` is the HTML attribute to define an ad for an HTML element. --- doc/htmlcmds.doc | 2 ++ src/docparser.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/htmlcmds.doc b/doc/htmlcmds.doc index 12347ab..605bf5a 100644 --- a/doc/htmlcmds.doc +++ b/doc/htmlcmds.doc @@ -25,6 +25,8 @@ of a HTML tag are passed on to the HTML output only