diff options
Diffstat (limited to 'src')
37 files changed, 1089 insertions, 1122 deletions
diff --git a/src/commentscan.l b/src/commentscan.l index f7a4e7d..edd4910 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<GuardedSection> 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<ListItemInfo> slii(*docEntry->sli); + QListIterator<ListItemInfo> 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/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/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<DiagramRow> 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/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/docparser.cpp b/src/docparser.cpp index da4cfb2..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_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 </img> found"); break; case HTML_HR: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </hr> found"); + warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal </hr> tag found\n"); break; case HTML_A: //warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </a> found"); 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..7b3c7d9 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -33,6 +33,9 @@ #include <qptrdict.h> #include <qtextstream.h> +#include <unordered_map> +#include <memory> + #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 <signal.h> #define HAS_SIGNALS @@ -177,7 +173,7 @@ GenericsSDict *Doxygen::genericsDict; DocGroup Doxygen::docGroup; // locally accessible globals -static QDict<Entry> g_classEntries(1009); +static std::unordered_map< std::string, const Entry* > g_classEntries; static StringList g_inputFiles; static QDict<void> 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<Entry> &root,const char *type,const char *name) { - Entry *memEntry = new Entry; + std::unique_ptr<Entry> memEntry = std::make_unique<Entry>(); 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<Entry> &classEntry,const char *name) { - Entry *iteratorClassEntry = new Entry; + std::unique_ptr<Entry> iteratorClassEntry = std::make_unique<Entry>(); 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<Entry> &root,const STLInfo *info) +{ + //printf("Adding STL class %s\n",info->className); + QCString fullName = info->className; + fullName.prepend("std::"); + + // add fake Entry for the class + std::unique_ptr<Entry> classEntry = std::make_unique<Entry>(); + 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<ArgumentList>; + 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<Entry> memEntry = std::make_unique<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->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<Entry> &root) { - Entry *namespaceEntry = new Entry; + std::unique_ptr<Entry> namespaceEntry = std::make_unique<Entry>(); 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<ArgumentList>; - 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,10 +2561,10 @@ 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 + // turn md into the definition if (!root->explicitExternal && md->isExternal()) { md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn()); @@ -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<te && ts<i && i<te) // avoid changing A<int(int*)>, 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<int> *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<Entry> 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<Entry> 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<Entry> 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<Entry> 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; } } @@ -6453,6 +6405,8 @@ static void findMember(Entry *root, warnMsg+="' at line "+QCString().setNum(md->getDefLine()) + " of file "+md->getDefFileName(); } + else + warnMsg += "'"; warnMsg+='\n'; } @@ -6505,7 +6459,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 +6529,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 +6539,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 +6550,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 +6603,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 +6717,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 +6752,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 +6806,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 +6829,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 +6858,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 +6868,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 +6891,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 +7010,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 +7022,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 +7066,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 +7239,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 +7321,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 +7456,7 @@ static void addEnumValuesToEnums(Entry *root) } else { - RECURSE_ENTRYTREE(addEnumValuesToEnums,root); + for (const auto &e : root->children()) addEnumValuesToEnums(e.get()); } } @@ -7482,7 +7464,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 +7597,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 +8712,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 +8773,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 +8803,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 +8857,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 +8870,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 +8907,7 @@ static void computePageRelations(Entry *root) } } } - RECURSE_ENTRYTREE(computePageRelations,root); + for (const auto &e : root->children()) computePageRelations(e.get()); } static void checkPageRelations() @@ -9071,7 +9053,7 @@ static void buildExampleList(Entry *root) //addExampleToGroups(root,pd); } } - RECURSE_ENTRYTREE(buildExampleList,root); + for (const auto &e : root->children()) buildExampleList(e.get()); } //---------------------------------------------------------------------------- @@ -9085,10 +9067,9 @@ void printNavTree(Entry *root,int indent) indentStr.isEmpty()?"":indentStr.data(), root->name.isEmpty()?"<empty>":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 +9291,7 @@ static void compareDoxyfile() //---------------------------------------------------------------------------- -static void readTagFile(Entry *root,const char *tl) +static void readTagFile(const std::unique_ptr<Entry> &root,const char *tl) { QCString tagLine = tl; QCString fileName; @@ -9479,7 +9460,7 @@ static ParserInterface *getParserForFile(const char *fn) } static void parseFile(ParserInterface *parser, - Entry *root,FileDef *fd,const char *fn, + const std::unique_ptr<Entry> &root,FileDef *fd,const char *fn, bool sameTu,QStrList &filesInSameTu) { #if USE_LIBCLANG @@ -9532,15 +9513,15 @@ static void parseFile(ParserInterface *parser, fd->getAllIncludeFilesRecursively(filesInSameTu); } - Entry *fileRoot = new Entry; + std::unique_ptr<Entry> fileRoot = std::make_unique<Entry>(); // 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<Entry> &root) { #if USE_LIBCLANG static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); @@ -11346,7 +11327,7 @@ void parseInput() * Handle Tag Files * **************************************************************************/ - Entry *root=new Entry; + std::unique_ptr<Entry> root = std::make_unique<Entry>(); msg("Reading and parsing tag files\n"); QStrList &tagFileList = Config_getList(TAGFILES); @@ -11381,31 +11362,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 +11403,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 +11418,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 +11443,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 +11458,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 +11493,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 +11513,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..8ec7846 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -15,6 +15,7 @@ * */ +#include <algorithm> #include <stdlib.h> #include <qfile.h> #include "entry.h" @@ -37,8 +38,6 @@ Entry::Entry() num++; m_parent=0; section = EMPTY_SEC; - m_sublist = new QList<Entry>; - m_sublist->setAutoDelete(TRUE); extends = new QList<BaseInfo>; extends->setAutoDelete(TRUE); groups = new QList<Grouping>; @@ -137,17 +136,14 @@ Entry::Entry(const Entry &e) id = e.id; m_parent = e.m_parent; - m_sublist = new QList<Entry>; - m_sublist->setAutoDelete(TRUE); - // deep copy of the child entry list - QListIterator<Entry> 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<Entry>(*cur)); } - + // deep copy base class list QListIterator<BaseInfo> 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,17 +200,72 @@ 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<Entry> ¤t) +{ + current->m_parent=this; + m_sublist.push_back(std::move(current)); + current = std::make_unique<Entry>(); +} + +void Entry::moveToSubEntryAndKeep(Entry *current) +{ + current->m_parent=this; + m_sublist.emplace_back(current); +} + +void Entry::moveToSubEntryAndKeep(std::unique_ptr<Entry> ¤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<Entry> ¤t) +{ + std::unique_ptr<Entry> copy = std::make_unique<Entry>(*current); + copy->m_parent=this; + m_sublist.push_back(std::move(copy)); +} + +void Entry::moveFromSubEntry(const Entry *child,std::unique_ptr<Entry> &moveTo) +{ + auto it = std::find_if(m_sublist.begin(),m_sublist.end(), + [child](const std::unique_ptr<Entry>&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<Entry>&elem) { return elem.get()==e; }); + if (it!=m_sublist.end()) + { + m_sublist.erase(it); + } +} + + void Entry::reset() { static bool entryCallGraph = Config_getBool(CALL_GRAPH); @@ -271,7 +320,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 +342,9 @@ int Entry::getSize() void Entry::setFileDef(FileDef *fd) { m_fileDef = fd; - if (m_sublist) + for (const auto &childNode : m_sublist) { - QListIterator<Entry> eli(*m_sublist); - Entry *childNode; - for (eli.toFirst();(childNode=eli.current());++eli) - { childNode->setFileDef(fd); - } } } @@ -317,10 +361,5 @@ void Entry::addSpecialListItem(const char *listName,int itemId) sli->append(ili); } -Entry *Entry::removeSubEntry(Entry *e) -{ - int i = m_sublist->find(e); - return i!=-1 ? m_sublist->take(i) : 0; -} //------------------------------------------------------------------ diff --git a/src/entry.h b/src/entry.h index 6dfa0c6..c078936 100644 --- a/src/entry.h +++ b/src/entry.h @@ -23,6 +23,9 @@ #include <qlist.h> #include <qgstring.h> +#include <vector> +#include <memory> + struct SectionInfo; class QFile; class FileDef; @@ -199,32 +202,45 @@ 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<Entry> *children() const { return m_sublist; } + //const QList<Entry> *children() const { return m_sublist; } + const std::vector< std::unique_ptr<Entry> > &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<Entry> &e); + /*! @} */ - /*! Adds entry \a e as a child to this entry */ - void addSubEntry (Entry* e) ; + /*! @name add entry as a child, pass ownership and reinitialize entry */ + void moveToSubEntryAndRefresh(Entry* &e); + void moveToSubEntryAndRefresh(std::unique_ptr<Entry> &e); + + /*! take \a child of of to list of children and move it into \a moveTo */ + void moveFromSubEntry(const Entry *child,std::unique_ptr<Entry> &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<Entry> &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(const 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 +339,9 @@ class Entry private: Entry *m_parent; //!< parent node in the tree - QList<Entry> *m_sublist; //!< entries that are children of this one + std::vector< std::unique_ptr<Entry> > m_sublist; Entry &operator=(const Entry &); FileDef *m_fileDef; }; -typedef QList<Entry> EntryList; -typedef QListIterator<Entry> 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<Entry> &, bool, QStrList &) {} bool needsPreprocessing(const QCString &) { return FALSE; } void parseCode(CodeOutputInterface &codeOutIntf, const char *scopeName, 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.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<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension); diff --git a/src/fortranscanner.l b/src/fortranscanner.l index d75134a..d7eefd6 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<Entry> current; static ScanVar v_type = V_IGNORE; // type of parsed variable -static QList<Entry> moduleProcedures; // list of all interfaces which contain unresolved +static std::vector<Entry*> 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<Entry*,QMap<QCString,SymbolModifiers> > 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<Entry> &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; } <Use,UseOnly>"\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); } <ModuleProcedure>"\n" { yyColNr -= 1; unput(*yytext); @@ -558,13 +557,13 @@ SCOPENAME ({ID}{BS}"::"{BS})* yy_pop_state(); } <Start,ModuleBody,ModuleBodyContains>"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. } } <Module>{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 { <Parameterlist>")" { 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<Entry> 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<Entry> &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<Entry> &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) { @@ -1840,7 +1842,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); @@ -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 "<<scope->name<<endl; - EntryListIterator eli(*scope->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<<ce->name<<", "<<mdfsMap.contains(ce->name.lower())<<mdfsMap.count()<<endl; if (mdfsMap.contains(ce->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<Entry> 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<Entry> 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<Entry> &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<Entry>(); 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<Entry> &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<Grouping> 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<Grouping> 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<Grouping> 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<Grouping> 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 <memory> + #include "sortdict.h" #include "definition.h" @@ -138,13 +140,13 @@ class GroupListIterator : public QListIterator<GroupDef> 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<Entry> &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { - Entry *current = new Entry; + std::unique_ptr<Entry> current = std::make_unique<Entry>(); 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<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &) { return FALSE; } 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/parserintf.h b/src/parserintf.h index f03aac7..a269bfb 100644 --- a/src/parserintf.h +++ b/src/parserintf.h @@ -21,6 +21,8 @@ #include <qdict.h> #include <qstrlist.h> +#include <memory> + #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<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit) = 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.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<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension); diff --git a/src/pyscanner.l b/src/pyscanner.l index 2320bca..ee72c7c 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<Entry> 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<Entry> eli(*(current_root->children())); - Entry *child; - for (eli.toFirst();(child=eli.current());++eli) + //QListIterator<Entry> 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)) { @@ -1619,7 +1570,7 @@ STARTDOCSYMS "##" incLineNr(); docBlock += yytext; } - \\. { // espaced char + \\. { // escaped char docBlock += yytext; } . { @@ -1654,7 +1605,7 @@ STARTDOCSYMS "##" addToString(yytext); incLineNr(); } - \\. { // espaced char + \\. { // escaped char addToString(yytext); } "\"\"\"" { // triple double quotes @@ -1677,7 +1628,7 @@ STARTDOCSYMS "##" addToString(yytext); incLineNr(); } - \\. { // espaced char + \\. { // escaped char addToString(yytext); } "'''" { // triple single quotes @@ -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; i<rt->children().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<Entry>(); 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<Entry> &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<Entry>(); 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<Entry> &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<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension); diff --git a/src/scanner.l b/src/scanner.l index 07d5c71..50ebe5e 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -22,6 +22,11 @@ /* * includes */ + +#include <algorithm> +#include <vector> +#include <utility> + #include <stdio.h> #include <stdlib.h> #include <assert.h> @@ -86,11 +91,11 @@ static int roundCount = 0 ; static int curlyCount = 0 ; static int squareCount = 0 ; static int padCount = 0 ; +static std::unique_ptr<Entry> 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<Entry> 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<Entry*,std::unique_ptr<Entry> > > 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)!='.') @@ -744,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 @@ -1027,7 +1036,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } <CliPropertyType>{ID} { - addType( current ); + addType(); current->name = yytext; } <CliPropertyType>"[" { // C++/CLI indexed property @@ -1049,7 +1058,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <CliPropertyType>{B}* { } <CliPropertyType>. { - addType( current ); + addType(); current->type += yytext; } <CliPropertyIndex>"]" { @@ -1371,9 +1380,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) lineCount(); } <PackageName>";" { - 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 +1518,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1528,7 +1537,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1547,7 +1556,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1560,7 +1569,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 +1578,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 +1590,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 +1599,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 +1612,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 +1622,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1624,7 +1633,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 +1651,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 +1667,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 +1682,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 +1699,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 +1737,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 +1752,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 +1767,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 +1782,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 +1793,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType(current); + addType(); current->name = yytext; current->name = current->name.stripWhiteSpace(); lineCount(); @@ -1805,7 +1814,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 +1837,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 +1852,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 +1867,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 +1887,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 +1919,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->section = Entry::ENUM_SEC ; } - addType( current ) ; + addType(); current->type += " enum"; if (isStrongEnum) { @@ -2001,14 +2010,12 @@ 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); + 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 +2050,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 +2068,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 +2086,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 +2099,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); } <Using>"=" { // C++11 style template alias? @@ -2156,22 +2160,21 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <UsingDirective>{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); } <Using>";" { BEGIN(FindMembers); } <FindMembers>{SCOPENAME}{BN}*"<>" { // guided template decl QCString n=yytext; - addType( current ); + addType(); current->name=n.left(n.length()-2); } <FindMembers>{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 +2440,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 +2472,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 +2707,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 +2724,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 +2759,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <FindMembers>[\^%] { // ^ and % are C++/CLI extensions if (insideCli) { - addType( current ); + addType(); current->name = yytext ; } else @@ -2768,9 +2769,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <FindMembers>[*&]+ { current->name += yytext ; - addType( current ); + addType(); } -<FindMembers,MemberSpec,Function,NextSemi,EnumBaseType,BitFields,ReadInitializer,OldStyleArgs>";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { +<FindMembers,MemberSpec,Function,NextSemi,EnumBaseType,BitFields,ReadInitializer,OldStyleArgs,DefinePHPEnd>";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { if (current->bodyLine==-1) { current->bodyLine=yyLineNr; @@ -2870,7 +2871,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 +2915,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <FindMembers,FindFields,ReadInitializer>"//"([!/]){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); } <FindMembers>"=" { // in PHP code this could also be due to "<?=" current->bodyLine = yyLineNr; @@ -2965,8 +2966,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 +3468,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 +3499,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 +3513,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 +3533,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 +3754,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 +3783,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) BEGIN( SkipString ); } <SkipSquare>[^\n\[\]\"]+ -<FindMembers>"<" { addType( current ) ; +<FindMembers>"<" { addType(); current->type += yytext ; BEGIN( Sharp ) ; } @@ -3847,8 +3836,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 +3868,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<Entry>(*current)); } - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); } else // probably a redundant , @@ -3985,13 +3973,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<Entry> new_current = std::make_unique<Entry>(*current); current->program = ""; new_current->doc = ""; new_current->docLine = 0; @@ -4003,9 +3991,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 +4029,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 +4093,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 +4111,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 +4152,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } <MemberSpec>"(" { // function with struct return type - addType(current); + addType(); current->name = msName; current->spec = 0; unput('('); @@ -4179,7 +4165,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 +4183,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 +4204,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else // case 2: create a typedef field { - Entry *varEntry=new Entry; + std::unique_ptr<Entry> varEntry=std::make_unique<Entry>(); varEntry->lang = language; varEntry->protection = current->protection ; varEntry->mtype = current->mtype; @@ -4273,7 +4259,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 +4313,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) lineCount() ; } <ReadBodyIntf>"@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 +4331,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->bodyLine = yyLineNr; lineCount(); - addType(current); + addType(); funcPtrType=yytext; roundCount=0; //current->type += yytext; @@ -4491,7 +4476,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <GetCallType>{BN}*{ID}{BN}*"*" { lineCount(); - addType(current); + addType(); funcPtrType="("; funcPtrType+=yytext; roundCount=0; @@ -5223,9 +5208,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)) @@ -5323,9 +5307,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { current->endBodyLine=yyLineNr; - - tempEntry = current; // temporarily switch to the previous entry - current = previous; + // take previous out of current_root and move it into current + current.swap(tempEntry); // remember current + current_root->moveFromSubEntry(previous,current); previous = 0; docBlockContext = SkipCurlyEndDoc; @@ -5368,8 +5352,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 +5500,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 +5599,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 +5620,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 +5704,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType(current); + addType(); current->name = yytext; current->name = current->name.stripWhiteSpace(); lineCount(); @@ -6165,6 +6147,19 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <Specialization>"typename"{BN}+ { lineCount(); } <Specialization>"(" { *specName += *yytext; roundCount++; } <Specialization>")" { *specName += *yytext; roundCount--; } + +<Specialization>"\\\\" { *specName += *yytext;} +<Specialization>"\\'" { *specName += *yytext;} +<Specialization>"\\\"" { *specName += *yytext;} +<Specialization>"'" { *specName += *yytext;BEGIN(SpecializationSingleQuote);} +<Specialization>"\"" { *specName += *yytext;BEGIN(SpecializationDoubleQuote);} +<SpecializationSingleQuote,SpecializationDoubleQuote>"\\\\" { *specName += *yytext;} +<SpecializationSingleQuote>"\\'" { *specName += *yytext;} +<SpecializationSingleQuote>"'" { *specName += *yytext; BEGIN(Specialization);} +<SpecializationDoubleQuote>"\\\"" { *specName += *yytext;} +<SpecializationDoubleQuote>"\"" { *specName += *yytext; BEGIN(Specialization);} +<SpecializationSingleQuote,SpecializationDoubleQuote>. { *specName += *yytext;} + <Specialization>. { *specName += *yytext; } @@ -6546,8 +6541,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <SliceSequenceName>";" { current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(FindMembers); } @@ -6577,8 +6571,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <SliceDictionaryName>";" { current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(FindMembers); } @@ -7009,11 +7002,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 +7022,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 +7034,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 +7094,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 +7128,10 @@ static void handleParametersCommentBlocks(ArgumentList *al) //---------------------------------------------------------------------------- -static void parseCompounds(Entry *rt) +static void parseCompounds(const std::unique_ptr<Entry> &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 +7148,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<Entry>(); gstat = FALSE; initEntry(); @@ -7229,15 +7222,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 +7247,7 @@ static void parseCompounds(Entry *rt) static void parseMain(const char *fileName, const char *fileBuf, - Entry *rt, + const std::unique_ptr<Entry> &rt, bool sameTranslationUnit, QStrList & filesInSameTranslationUnit) { @@ -7270,8 +7263,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 +7286,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<Entry>(); //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 +7321,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 +7329,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 +7385,7 @@ static void parsePrototype(const QCString &text) inputString = orgInputString; inputPosition = orgInputPosition; + //printf("**** parsePrototype end\n"); } @@ -7438,7 +7428,7 @@ void CLanguageScanner::finishTranslationUnit() void CLanguageScanner::parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr<Entry> &root, bool sameTranslationUnit, QStrList & filesInSameTranslationUnit) { 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/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<Entry> &, 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 <assert.h> #include <stdio.h> #include <stdarg.h> +#include <algorithm> + #include <qxml.h> #include <qstack.h> @@ -912,12 +914,12 @@ class TagFileParser : public QXmlDefaultHandler } void dump(); - void buildLists(Entry *root); + void buildLists(const std::unique_ptr<Entry> &root); void addIncludes(); private: - void buildMemberList(Entry *ce,QList<TagMemberInfo> &members); - void addDocAnchors(Entry *e,const TagAnchorInfoList &l); + void buildMemberList(const std::unique_ptr<Entry> &ce,QList<TagMemberInfo> &members); + void addDocAnchors(const std::unique_ptr<Entry> &e,const TagAnchorInfoList &l); QList<TagClassInfo> m_tagFileClasses; QList<TagFileInfo> m_tagFileFiles; QList<TagNamespaceInfo> m_tagFileNamespaces; @@ -1147,7 +1149,7 @@ void TagFileParser::dump() } } -void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l) +void TagFileParser::addDocAnchors(const std::unique_ptr<Entry> &e,const TagAnchorInfoList &l) { QListIterator<TagAnchorInfo> tli(l); TagAnchorInfo *ta; @@ -1169,13 +1171,13 @@ void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l) } } -void TagFileParser::buildMemberList(Entry *ce,QList<TagMemberInfo> &members) +void TagFileParser::buildMemberList(const std::unique_ptr<Entry> &ce,QList<TagMemberInfo> &members) { QListIterator<TagMemberInfo> mii(members); TagMemberInfo *tmi; for (;(tmi=mii.current());++mii) { - Entry *me = new Entry; + std::unique_ptr<Entry> me = std::make_unique<Entry>(); me->type = tmi->type; me->name = tmi->name; me->args = tmi->arglist; @@ -1192,7 +1194,7 @@ void TagFileParser::buildMemberList(Entry *ce,QList<TagMemberInfo> &members) TagEnumValueInfo *evi; for (evii.toFirst();(evi=evii.current());++evii) { - Entry *ev = new Entry; + std::unique_ptr<Entry> ev = std::make_unique<Entry>(); ev->type = "@"; ev->name = evi->name; ev->id = evi->clangid; @@ -1202,7 +1204,7 @@ void TagFileParser::buildMemberList(Entry *ce,QList<TagMemberInfo> &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<TagMemberInfo> &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<Entry> &root) { // build class list QListIterator<TagClassInfo> cit(m_tagFileClasses); TagClassInfo *tci; for (cit.toFirst();(tci=cit.current());++cit) { - Entry *ce = new Entry; + std::unique_ptr<Entry> ce = std::make_unique<Entry>(); 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<Entry> fe = std::make_unique<Entry>(); 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<Entry> ne = std::make_unique<Entry>(); 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<Entry> pe = std::make_unique<Entry>(); 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<Entry> ge = std::make_unique<Entry>(); 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<Entry> eli(*(root->children())); - Entry *childNode; - for (eli.toFirst();(childNode=eli.current());++eli) + //QListIterator<Entry> 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<Entry> &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<Entry> pe = std::make_unique<Entry>(); 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<Entry> &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 <memory> + +void parseTagFile(const std::unique_ptr<Entry> &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<Entry> &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<Entry> &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/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; @@ -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, 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<QCString> 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<Entry> &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<Entry> current = std::make_unique<Entry>(); 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<Entry> instList=getVhdlInstList(); - QListIterator<Entry> 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<Entry> qsl= getVhdlInstList(); - QListIterator<Entry> 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<Entry> &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<Entry> root = std::make_unique<Entry>(); 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..ae10f4d 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<Entry> instFiles; -static QList<Entry> libUse; -static QList<Entry> lineEntry; +static std::vector< std::unique_ptr<Entry> > instFiles; +static std::vector< std::unique_ptr<Entry> > libUse; +static std::vector<Entry*> 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<Entry> 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<Entry>* getEntryAtLine(const Entry* ce,int line); +static bool checkMultiComment(QCString& qcs,int line); +static void insertEntryAtLine(const Entry* ce,int line); //------------------------------------- -QList<VhdlConfNode>& getVhdlConfiguration() { return configL; } -QList<Entry>& getVhdlInstList() { return instFiles; } +const QList<VhdlConfNode>& getVhdlConfiguration() { return configL; } +const std::vector<std::unique_ptr<Entry> > &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<Entry> &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<Entry>(); + 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 @@ -343,7 +340,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) { @@ -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<Entry>(*current)); } - Entry *temp=current; // hold current pointer (temp=oldEntry) - current=new Entry; // (oldEntry != current) - delete temp; + current=std::make_unique<Entry>(); } 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<Entry>(*current)); current->reset(); } newEntry(); @@ -584,37 +579,36 @@ void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, * ..... * library * package - * enity zzz + * entity zzz * ..... * and so on.. */ void VhdlParser::mapLibPackage( Entry* root) { - QList<Entry> epp=libUse; - EntryListIterator eli(epp); - Entry *rt; - for (;(rt=eli.current());++eli) + //QList<Entry> 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<Entry> *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<Entry>* 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 <vector> +#include <memory> + #include "parserintf.h" #include <stdio.h> #include <stdlib.h> @@ -45,7 +48,7 @@ class VHDLLanguageScanner : public ParserInterface void finishTranslationUnit() {} void parseInput(const char * fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); @@ -95,7 +98,7 @@ struct VhdlConfNode void vhdlscanFreeScanner(); -QList<VhdlConfNode>& getVhdlConfiguration(); -QList<Entry>& getVhdlInstList(); +const QList<VhdlConfNode>& getVhdlConfiguration(); +const std::vector<std::unique_ptr<Entry> >&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<Entry> &, bool , QStrList &) {} bool needsPreprocessing(const QCString &) { return FALSE; } void parseCode(CodeOutputInterface &codeOutIntf, |