diff options
Diffstat (limited to 'src/doxygen.cpp')
-rw-r--r-- | src/doxygen.cpp | 1222 |
1 files changed, 471 insertions, 751 deletions
diff --git a/src/doxygen.cpp b/src/doxygen.cpp index e1d7967..d760678 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -75,10 +75,12 @@ #include "searchindex.h" #include "parserintf.h" #include "htags.h" +#include "pycode.h" #include "pyscanner.h" +#include "fortrancode.h" #include "fortranscanner.h" -#include "xmlscanner.h" -#include "sqlscanner.h" +#include "xmlcode.h" +#include "sqlcode.h" #include "tclscanner.h" #include "code.h" #include "objcache.h" @@ -104,6 +106,7 @@ #include "fileparser.h" #include "emoji.h" #include "plantuml.h" +#include "stlsupport.h" // provided by the generated file resources.cpp extern void initResources(); @@ -171,6 +174,7 @@ bool Doxygen::generatingXmlOutput = FALSE; bool Doxygen::markdownSupport = TRUE; GenericsSDict *Doxygen::genericsDict; DocGroup Doxygen::docGroup; +Preprocessor *Doxygen::preprocessor = 0; // locally accessible globals static std::unordered_map< std::string, const Entry* > g_classEntries; @@ -294,7 +298,7 @@ void statistics() static void addMemberDocs(const Entry *root,MemberDef *md, const char *funcDecl, - ArgumentList *al,bool over_load,uint64 spec); + const ArgumentList *al,bool over_load,uint64 spec); static void findMember(const Entry *root, const QCString &relates, const QCString &type, @@ -315,239 +319,17 @@ static bool findClassRelation( const Entry *root, Definition *context, ClassDef *cd, - BaseInfo *bi, + const BaseInfo *bi, QDict<int> *templateNames, /*bool insertUndocumented*/ FindBaseClassRelation_Mode mode, bool isArtificial ); -/** A struct contained the data for an STL class */ -struct STLInfo -{ - const char *className; - const char *baseClass1; - const char *baseClass2; - const char *templType1; - const char *templName1; - const char *templType2; - const char *templName2; - bool virtualInheritance; - bool iterators; -}; - -static STLInfo g_stlinfo[] = -{ - // className baseClass1 baseClass2 templType1 templName1 templType2 templName2 virtInheritance // iterators - { "allocator", 0, 0, "T", "elements", 0, 0, FALSE, FALSE }, - { "array", 0, 0, "T", "elements", 0, 0, FALSE, FALSE }, // C++11 - { "auto_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // deprecated - { "smart_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11 - { "unique_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11 - { "shared_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++14 - { "weak_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11 - { "ios_base", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11 - { "error_code", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11 - { "error_category", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11 - { "system_error", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11 - { "error_condition", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11 - { "thread", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11 - { "basic_ios", "ios_base", 0, "Char", 0, 0, 0, FALSE, FALSE }, - { "basic_istream", "basic_ios<Char>", 0, "Char", 0, 0, 0, TRUE, FALSE }, - { "basic_ostream", "basic_ios<Char>", 0, "Char", 0, 0, 0, TRUE, FALSE }, - { "basic_iostream", "basic_istream<Char>", "basic_ostream<Char>", "Char", 0, 0, 0, FALSE, FALSE }, - { "basic_ifstream", "basic_istream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE }, - { "basic_ofstream", "basic_ostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE }, - { "basic_fstream", "basic_iostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE }, - { "basic_istringstream", "basic_istream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE }, - { "basic_ostringstream", "basic_ostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE }, - { "basic_stringstream", "basic_iostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE }, - { "ios", "basic_ios<char>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "wios", "basic_ios<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "istream", "basic_istream<char>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "wistream", "basic_istream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "ostream", "basic_ostream<char>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "wostream", "basic_ostream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "ifstream", "basic_ifstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "wifstream", "basic_ifstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "ofstream", "basic_ofstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "wofstream", "basic_ofstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "fstream", "basic_fstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "wfstream", "basic_fstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "istringstream", "basic_istringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "wistringstream", "basic_istringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "ostringstream", "basic_ostringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "wostringstream", "basic_ostringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "stringstream", "basic_stringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "wstringstream", "basic_stringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "basic_string", 0, 0, "Char", 0, 0, 0, FALSE, TRUE }, - { "string", "basic_string<char>", 0, 0, 0, 0, 0, FALSE, TRUE }, - { "wstring", "basic_string<wchar_t>", 0, 0, 0, 0, 0, FALSE, TRUE }, - { "complex", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, - { "bitset", 0, 0, "Bits", 0, 0, 0, FALSE, FALSE }, - { "deque", 0, 0, "T", "elements", 0, 0, FALSE, TRUE }, - { "list", 0, 0, "T", "elements", 0, 0, FALSE, TRUE }, - { "forward_list", 0, 0, "T", "elements", 0, 0, FALSE, TRUE }, // C++11 - { "map", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE }, - { "unordered_map", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE }, // C++11 - { "multimap", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE }, - { "unordered_multimap", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE }, // C++11 - { "set", 0, 0, "K", "keys", 0, 0, FALSE, TRUE }, - { "unordered_set", 0, 0, "K", "keys", 0, 0, FALSE, TRUE }, // C++11 - { "multiset", 0, 0, "K", "keys", 0, 0, FALSE, TRUE }, - { "unordered_multiset", 0, 0, "K", "keys", 0, 0, FALSE, TRUE }, // C++11 - { "vector", 0, 0, "T", "elements", 0, 0, FALSE, TRUE }, - { "queue", 0, 0, "T", "elements", 0, 0, FALSE, FALSE }, - { "priority_queue", 0, 0, "T", "elements", 0, 0, FALSE, FALSE }, - { "stack", 0, 0, "T", "elements", 0, 0, FALSE, FALSE }, - { "valarray", 0, 0, "T", "elements", 0, 0, FALSE, FALSE }, - { "exception", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, - { "bad_alloc", "exception", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "bad_cast", "exception", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "bad_typeid", "exception", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "logic_error", "exception", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "ios_base::failure", "exception", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "runtime_error", "exception", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "bad_exception", "exception", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "domain_error", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "invalid_argument", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "length_error", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "out_of_range", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "range_error", "runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "overflow_error", "runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE }, - { "underflow_error", "runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE }, - { 0, 0, 0, 0, 0, 0, 0, FALSE, FALSE } -}; - -static void addSTLMember(const std::unique_ptr<Entry> &root,const char *type,const char *name) -{ - std::unique_ptr<Entry> memEntry = std::make_unique<Entry>(); - memEntry->name = name; - memEntry->type = type; - memEntry->protection = Public; - memEntry->section = Entry::VARIABLE_SEC; - memEntry->brief = "STL member"; - memEntry->hidden = FALSE; - memEntry->artificial = TRUE; - root->moveToSubEntryAndKeep(memEntry); -} - -static void addSTLIterator(const std::unique_ptr<Entry> &classEntry,const char *name) -{ - std::unique_ptr<Entry> iteratorClassEntry = std::make_unique<Entry>(); - iteratorClassEntry->fileName = "[STL]"; - iteratorClassEntry->startLine = 1; - iteratorClassEntry->name = name; - iteratorClassEntry->section = Entry::CLASS_SEC; - iteratorClassEntry->brief = "STL iterator class"; - iteratorClassEntry->hidden = FALSE; - iteratorClassEntry->artificial= TRUE; - 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(const std::unique_ptr<Entry> &root) -{ - std::unique_ptr<Entry> namespaceEntry = std::make_unique<Entry>(); - namespaceEntry->fileName = "[STL]"; - namespaceEntry->startLine = 1; - namespaceEntry->name = "std"; - namespaceEntry->section = Entry::NAMESPACE_SEC; - namespaceEntry->brief = "STL namespace"; - namespaceEntry->hidden = FALSE; - namespaceEntry->artificial= TRUE; - - STLInfo *info = g_stlinfo; - while (info->className) - { - addSTLClass(namespaceEntry,info); - info++; - } - - root->moveToSubEntryAndKeep(namespaceEntry); -} - //---------------------------------------------------------------------------- static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n, - FileDef *fileScope,TagInfo *tagInfo); + FileDef *fileScope,const TagInfo *tagInfo); static void addPageToContext(PageDef *pd,Entry *root) { @@ -560,7 +342,7 @@ static void addPageToContext(PageDef *pd,Entry *root) } scope = stripAnonymousNamespaceScope(scope); scope+="::"+pd->name(); - Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo); + Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo()); if (d) { pd->setPageScope(d); @@ -571,11 +353,9 @@ static void addPageToContext(PageDef *pd,Entry *root) static void addRelatedPage(Entry *root) { GroupDef *gd=0; - QListIterator<Grouping> gli(*root->groups); - Grouping *g; - for (;(g=gli.current());++gli) + for (const Grouping &g : root->groups) { - if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) break; + if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname))) break; } //printf("---> addRelatedPage() %s gd=%p\n",root->name.data(),gd); QCString doc; @@ -588,10 +368,10 @@ static void addRelatedPage(Entry *root) doc=root->brief+"\n\n"+root->doc+root->inbodyDocs; } - PageDef *pd = addRelatedPage(root->name,root->args,doc,root->anchors, + PageDef *pd = addRelatedPage(root->name,root->args,doc, root->docFile,root->docLine, root->sli, - gd,root->tagInfo, + gd,root->tagInfo(), FALSE, root->lang ); @@ -607,8 +387,8 @@ static void addRelatedPage(Entry *root) static void buildGroupListFiltered(const Entry *root,bool additional, bool includeExternal) { if (root->section==Entry::GROUPDOC_SEC && !root->name.isEmpty() && - ((!includeExternal && root->tagInfo==0) || - ( includeExternal && root->tagInfo!=0)) + ((!includeExternal && root->tagInfo()==0) || + ( includeExternal && root->tagInfo()!=0)) ) { if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) || @@ -639,10 +419,10 @@ static void buildGroupListFiltered(const Entry *root,bool additional, bool inclu } else { - if (root->tagInfo) + if (root->tagInfo()) { - gd = createGroupDef(root->fileName,root->startLine,root->name,root->type,root->tagInfo->fileName); - gd->setReference(root->tagInfo->tagName); + gd = createGroupDef(root->fileName,root->startLine,root->name,root->type,root->tagInfo()->fileName); + gd->setReference(root->tagInfo()->tagName); } else { @@ -692,7 +472,7 @@ static void findGroupScope(const Entry *root) } scope = stripAnonymousNamespaceScope(scope); scope+="::"+gd->name(); - Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo); + Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo()); if (d) { gd->setGroupScope(d); @@ -736,7 +516,7 @@ static void buildFileList(const Entry *root) { if (((root->section==Entry::FILEDOC_SEC) || ((root->section & Entry::FILE_MASK) && Config_getBool(EXTRACT_ALL))) && - !root->name.isEmpty() && !root->tagInfo // skip any file coming from tag files + !root->name.isEmpty() && !root->tagInfo() // skip any file coming from tag files ) { bool ambig; @@ -762,12 +542,10 @@ static void buildFileList(const Entry *root) fd->setBriefDescription(root->brief,root->briefFile,root->briefLine); fd->addSectionsToDefinition(root->anchors); fd->setRefItems(root->sli); - QListIterator<Grouping> gli(*root->groups); - Grouping *g; - for (;(g=gli.current());++gli) + for (const Grouping &g : root->groups) { GroupDef *gd=0; - if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) + if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname))) { gd->addFile(fd); fd->makePartOfGroup(gd); @@ -958,7 +736,7 @@ static Definition *findScope(Entry *root,int level=0) * not found and set the parent/child scope relation if the scope is found. */ static Definition *buildScopeFromQualifiedName(const QCString name, - int level,SrcLangExt lang,TagInfo *tagInfo) + int level,SrcLangExt lang,const TagInfo *tagInfo) { //printf("buildScopeFromQualifiedName(%s) level=%d\n",name.data(),level); int i=0; @@ -1017,7 +795,7 @@ static Definition *buildScopeFromQualifiedName(const QCString name, } static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n, - FileDef *fileScope,TagInfo *tagInfo) + FileDef *fileScope,const TagInfo *tagInfo) { //printf("<findScopeFromQualifiedName(%s,%s)\n",startScope ? startScope->name().data() : 0, n.data()); Definition *resultScope=startScope; @@ -1105,17 +883,15 @@ static Definition *findScopeFromQualifiedName(Definition *startScope,const QCStr return resultScope; } -ArgumentList *getTemplateArgumentsFromName( +ArgumentList getTemplateArgumentsFromName( const QCString &name, - const QList<ArgumentList> *tArgLists) + const std::vector<ArgumentList> &tArgLists) { - if (tArgLists==0) return 0; - - QListIterator<ArgumentList> ali(*tArgLists); // for each scope fragment, check if it is a template and advance through // the list if so. int i,p=0; - while ((i=name.find("::",p))!=-1) + auto alIt = tArgLists.begin(); + while ((i=name.find("::",p))!=-1 && alIt!=tArgLists.end()) { NamespaceDef *nd = Doxygen::namespaceSDict->find(name.left(i)); if (nd==0) @@ -1123,15 +899,15 @@ ArgumentList *getTemplateArgumentsFromName( ClassDef *cd = getClass(name.left(i)); if (cd) { - if (cd->templateArguments()) + if (!cd->templateArguments().empty()) { - ++ali; + ++alIt; } } } p=i+2; } - return ali.current(); + return alIt!=tArgLists.end() ? *alIt : ArgumentList(); } static @@ -1240,13 +1016,12 @@ static void addClassToContext(const Entry *root) } //cd->setName(fullName); // change name to match docs - if (cd->templateArguments()==0 || (cd->isForwardDeclared() && (root->spec&Entry::ForwardDecl)==0)) + if (cd->templateArguments().empty() || (cd->isForwardDeclared() && (root->spec&Entry::ForwardDecl)==0)) { // this happens if a template class declared with @class is found // before the actual definition or if a forward declaration has different template // parameter names. - ArgumentList *tArgList = - getTemplateArgumentsFromName(cd->name(),root->tArgLists); + ArgumentList tArgList = getTemplateArgumentsFromName(cd->name(),root->tArgLists); cd->setTemplateArguments(tArgList); } @@ -1267,7 +1042,7 @@ static void addClassToContext(const Entry *root) QCString tagName; QCString refFileName; - TagInfo *tagInfo = root->tagInfo; + const TagInfo *tagInfo = root->tagInfo(); int i; if (tagInfo) { @@ -1280,13 +1055,12 @@ static void addClassToContext(const Entry *root) buildScopeFromQualifiedName(fullName,fullName.contains("::"),root->lang,tagInfo); } } - ArgumentList *tArgList = 0; + ArgumentList tArgList; if ((root->lang==SrcLangExt_CSharp || root->lang==SrcLangExt_Java) && (i=fullName.find('<'))!=-1) { // a Java/C# generic class looks like a C++ specialization, so we need to split the // name and template arguments here - tArgList = new ArgumentList; - stringToArgumentList(fullName.mid(i),tArgList); + stringToArgumentList(root->lang,fullName.mid(i),tArgList); fullName=fullName.left(i); } else @@ -1296,7 +1070,7 @@ static void addClassToContext(const Entry *root) cd=createClassDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn, fullName,sec,tagName,refFileName,TRUE,root->spec&Entry::Enum); Debug::print(Debug::Classes,0," New class '%s' (sec=0x%08x)! #tArgLists=%d tagInfo=%p\n", - qPrint(fullName),sec,root->tArgLists ? (int)root->tArgLists->count() : -1, tagInfo); + qPrint(fullName),sec,root->tArgLists.size(), tagInfo); cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition cd->setBriefDescription(root->brief,root->briefFile,root->briefLine); cd->setLanguage(root->lang); @@ -1328,7 +1102,7 @@ static void addClassToContext(const Entry *root) //printf("ClassDict.insert(%s)\n",fullName.data()); Doxygen::classSDict->append(fullName,cd); - if (cd->isGeneric()) // generics are also stored in a separate dictionary for fast lookup of instantions + if (cd->isGeneric()) // generics are also stored in a separate dictionary for fast lookup of instances { //printf("inserting generic '%s' cd=%p\n",fullName.data(),cd); Doxygen::genericsDict->insert(fullName,cd); @@ -1422,7 +1196,7 @@ static void resolveClassNestingRelations() d->addInnerCompound(aliasCd); QCString aliasFullName = d->qualifiedName()+"::"+aliasCd->localName(); Doxygen::classSDict->append(aliasFullName,aliasCd); - printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName)); + //printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName)); aliasCd->setVisited(TRUE); } } @@ -1456,7 +1230,7 @@ static void resolveClassNestingRelations() Definition *d = buildScopeFromQualifiedName(name,name.contains("::"),cd->getLanguage(),0); if (d!=cd && !cd->getDefFileName().isEmpty()) // avoid recursion in case of redundant scopes, i.e: namespace N { class N::C {}; } - // for this case doxygen assumes the exitance of a namespace N::N in which C is to be found! + // for this case doxygen assumes the existence of a namespace N::N in which C is to be found! // also avoid warning for stuff imported via a tagfile. { d->addInnerCompound(cd); @@ -1561,7 +1335,7 @@ static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QC md->typeString(),md->name(),md->argsString(),md->excpString(), md->protection(),md->virtualness(),md->isStatic(),Member, md->memberType(), - 0,0,""); + ArgumentList(),ArgumentList(),""); imd->setMemberClass(cd); imd->setDocumentation(md->documentation(),md->docFile(),md->docLine()); imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine()); @@ -1615,7 +1389,7 @@ static void processTagLessClasses(ClassDef *rootCd, if (type.find(icd->name())!=-1) // matching tag less struct/union { QCString name = md->name(); - if (name.at(0)=='@') name = "__unnamed__"; + if (md->isAnonymous()) name = "__unnamed__"; if (!prefix.isEmpty()) name.prepend(prefix+"."); //printf(" found %s for class %s\n",name.data(),cd->name().data()); ClassDef *ncd = createTagLessInstance(rootCd,icd,name); @@ -1723,7 +1497,7 @@ static void buildNamespaceList(const Entry *root) { nd->setLanguage(root->lang); } - if (root->tagInfo==0) // if we found the namespace in a tag file + if (root->tagInfo()==0) // if we found the namespace in a tag file // and also in a project file, then remove // the tag file reference { @@ -1743,7 +1517,7 @@ static void buildNamespaceList(const Entry *root) { QCString tagName; QCString tagFileName; - TagInfo *tagInfo = root->tagInfo; + const TagInfo *tagInfo = root->tagInfo(); if (tagInfo) { tagName = tagInfo->tagName; @@ -1954,12 +1728,13 @@ static void findUsingDirectives(const Entry *root) nd->setMetaData(root->metaData); nd->setInline((root->spec&Entry::Inline)!=0); - QListIterator<Grouping> gli(*root->groups); - Grouping *g; - for (;(g=gli.current());++gli) + //QListIterator<Grouping> gli(*root->groups); + //Grouping *g; + //for (;(g=gli.current());++gli) + for (const Grouping &g : root->groups) { GroupDef *gd=0; - if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) + if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname))) gd->addNamespace(nd); } @@ -2055,7 +1830,7 @@ static void findUsingDeclarations(const Entry *root) if (usingCd==0) // definition not in the input => add an artificial class { Debug::print(Debug::Classes,0," New using class '%s' (sec=0x%08x)! #tArgLists=%d\n", - qPrint(name),root->section,root->tArgLists ? (int)root->tArgLists->count() : -1); + qPrint(name),root->section,root->tArgLists.size()); usingCd = createClassDef( "<using>",1,1, name, @@ -2131,12 +1906,12 @@ static void findUsingDeclImports(const Entry *root) MemberDef *newMd = 0; { QCString fileName = root->fileName; - if (fileName.isEmpty() && root->tagInfo) + if (fileName.isEmpty() && root->tagInfo()) { - fileName = root->tagInfo->tagName; + fileName = root->tagInfo()->tagName; } - const ArgumentList *templAl = md->templateArguments(); - const ArgumentList *al = md->templateArguments(); + const ArgumentList &templAl = md->templateArguments(); + const ArgumentList &al = md->templateArguments(); newMd = createMemberDef( fileName,root->startLine,root->startColumn, md->typeString(),memName,md->argsString(), @@ -2326,9 +2101,9 @@ static MemberDef *addVariableToClass( } QCString fileName = root->fileName; - if (fileName.isEmpty() && root->tagInfo) + if (fileName.isEmpty() && root->tagInfo()) { - fileName = root->tagInfo->tagName; + fileName = root->tagInfo()->tagName; } // new member variable, typedef or enum value @@ -2336,8 +2111,9 @@ static MemberDef *addVariableToClass( fileName,root->startLine,root->startColumn, type,name,args,root->exception, prot,Normal,root->stat,related, - mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0, root->metaData); - md->setTagInfo(root->tagInfo); + mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), + ArgumentList(), root->metaData); + md->setTagInfo(root->tagInfo()); md->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope()) //md->setDefFile(root->fileName); //md->setDefLine(root->startLine); @@ -2470,7 +2246,7 @@ static MemberDef *addVariableToFile( QCString def; // determine the definition of the global variable - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@' && + if (nd && !nd->isAnonymous() && !Config_getBool(HIDE_SCOPE_NAMES) ) // variable is inside a namespace, so put the scope before the name @@ -2583,20 +2359,21 @@ static MemberDef *addVariableToFile( } QCString fileName = root->fileName; - if (fileName.isEmpty() && root->tagInfo) + if (fileName.isEmpty() && root->tagInfo()) { - fileName = root->tagInfo->tagName; + fileName = root->tagInfo()->tagName; } Debug::print(Debug::Variables,0, - " new variable, nd=%s tagInfo=%p!\n",nd?qPrint(nd->name()):"<global>",root->tagInfo); + " new variable, nd=%s tagInfo=%p!\n",nd?qPrint(nd->name()):"<global>",root->tagInfo()); // new global variable, enum value or typedef MemberDef *md=createMemberDef( fileName,root->startLine,root->startColumn, type,name,args,0, root->protection, Normal,root->stat,Member, - mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0, root->metaData); - md->setTagInfo(root->tagInfo); + mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), + ArgumentList(), root->metaData); + md->setTagInfo(root->tagInfo()); md->setMemberSpecifiers(root->spec); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setBriefDescription(root->brief,root->briefFile,root->briefLine); @@ -2624,7 +2401,7 @@ static MemberDef *addVariableToFile( addMemberToGroups(root,md); md->setRefItems(root->sli); - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') + if (nd && !nd->isAnonymous()) { md->setNamespace(nd); nd->insertMember(md); @@ -2739,19 +2516,16 @@ static bool isVarWithConstructor(const Entry *root) // we need to rely on heuristics :-( { //printf("typeIsClass\n"); - ArgumentList *al = root->argList; - if (al==0 || al->isEmpty()) + if (root->argList.empty()) { result=FALSE; // empty arg list -> function prototype. goto done; } - ArgumentListIterator ali(*al); - Argument *a; - for (ali.toFirst();(a=ali.current());++ali) + for (const Argument &a : root->argList) { - if (!a->name.isEmpty() || !a->defval.isEmpty()) + if (!a.name.isEmpty() || !a.defval.isEmpty()) { - if (a->name.find(initChars)==0) + if (a.name.find(initChars)==0) { result=TRUE; } @@ -2761,31 +2535,31 @@ static bool isVarWithConstructor(const Entry *root) } goto done; } - if (a->type.isEmpty() || getResolvedClass(ctx,fd,a->type)!=0) + if (a.type.isEmpty() || getResolvedClass(ctx,fd,a.type)!=0) { result=FALSE; // arg type is a known type goto done; } - if (checkIfTypedef(ctx,fd,a->type)) + if (checkIfTypedef(ctx,fd,a.type)) { //printf("%s:%d: false (arg is typedef)\n",__FILE__,__LINE__); result=FALSE; // argument is a typedef goto done; } - if (a->type.at(a->type.length()-1)=='*' || - a->type.at(a->type.length()-1)=='&') + if (a.type.at(a.type.length()-1)=='*' || + a.type.at(a.type.length()-1)=='&') // type ends with * or & => pointer or reference { result=FALSE; goto done; } - if (a->type.find(initChars)==0) + if (a.type.find(initChars)==0) { result=TRUE; // argument type starts with typical initializer char goto done; } - QCString resType=resolveTypeDef(ctx,a->type); - if (resType.isEmpty()) resType=a->type; + QCString resType=resolveTypeDef(ctx,a.type); + if (resType.isEmpty()) resType=a.type; int len; if (idChars.match(resType,0,&len)==0) // resType starts with identifier { @@ -3122,15 +2896,15 @@ static void addInterfaceOrServiceToServiceOrSingleton( ? MemberType_Interface : MemberType_Service; QCString fileName = root->fileName; - if (fileName.isEmpty() && root->tagInfo) + if (fileName.isEmpty() && root->tagInfo()) { - fileName = root->tagInfo->tagName; + fileName = root->tagInfo()->tagName; } MemberDef *const md = createMemberDef( fileName, root->startLine, root->startColumn, root->type, rname, "", "", root->protection, root->virt, root->stat, Member, - type, 0, root->argList, root->metaData); - md->setTagInfo(root->tagInfo); + type, ArgumentList(), root->argList, root->metaData); + md->setTagInfo(root->tagInfo()); md->setMemberClass(cd); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocsForDefinition(false); @@ -3206,7 +2980,7 @@ static void buildInterfaceAndServiceList(const Entry *root) qPrint(root->fileName), root->startLine, root->bodyLine, - root->tArgLists ? (int)root->tArgLists->count() : -1, + root->tArgLists.size(), root->mGrpId, root->spec, root->proto, @@ -3300,9 +3074,9 @@ static void addMethodToClass(const Entry *root,ClassDef *cd, } QCString fileName = root->fileName; - if (fileName.isEmpty() && root->tagInfo) + if (fileName.isEmpty() && root->tagInfo()) { - fileName = root->tagInfo->tagName; + fileName = root->tagInfo()->tagName; } //printf("root->name='%s; args='%s' root->argList='%s'\n", @@ -3317,8 +3091,9 @@ static void addMethodToClass(const Entry *root,ClassDef *cd, 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); + mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), + root->argList, root->metaData); + md->setTagInfo(root->tagInfo()); md->setMemberClass(cd); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocsForDefinition(!root->proto); @@ -3347,54 +3122,27 @@ static void addMethodToClass(const Entry *root,ClassDef *cd, // for PHP we use Class::method and Namespace\method scopeSeparator="::"; } +// QCString optArgs = root->argList.empty() ? args : QCString(); if (!relates.isEmpty() || isFriend || Config_getBool(HIDE_SCOPE_NAMES)) { if (!type.isEmpty()) { - if (root->argList) - { - def=type+" "+name; - } - else - { - def=type+" "+name+args; - } + def=type+" "+name; //+optArgs; } else { - if (root->argList) - { - def=name; - } - else - { - def=name+args; - } + def=name; //+optArgs; } } else { if (!type.isEmpty()) { - if (root->argList) - { - def=type+" "+qualScope+scopeSeparator+name; - } - else - { - def=type+" "+qualScope+scopeSeparator+name+args; - } + def=type+" "+qualScope+scopeSeparator+name; //+optArgs; } else { - if (root->argList) - { - def=qualScope+scopeSeparator+name; - } - else - { - def=qualScope+scopeSeparator+name+args; - } + def=qualScope+scopeSeparator+name; //+optArgs; } } if (def.left(7)=="friend ") def=def.right(def.length()-7); @@ -3457,7 +3205,7 @@ static void buildFunctionList(const Entry *root) qPrint(root->fileName), root->startLine, root->bodyLine, - root->tArgLists ? (int)root->tArgLists->count() : -1, + root->tArgLists.size(), root->mGrpId, root->spec, root->proto, @@ -3577,16 +3325,16 @@ static void buildFunctionList(const Entry *root) if (rnd) rnsName = rnd->name().copy(); //printf("matching arguments for %s%s %s%s\n", // md->name().data(),md->argsString(),rname.data(),argListToString(root->argList).data()); - ArgumentList *mdAl = md->argumentList(); - const ArgumentList *mdTempl = md->templateArguments(); + ArgumentList &mdAl = md->argumentList(); + const ArgumentList &mdTempl = md->templateArguments(); // in case of template functions, we need to check if the // functions have the same number of template parameters bool sameNumTemplateArgs = TRUE; bool matchingReturnTypes = TRUE; - if (mdTempl!=0 && root->tArgLists) + if (!mdTempl.empty() && !root->tArgLists.empty()) { - if (mdTempl->count()!=root->tArgLists->getLast()->count()) + if (mdTempl.size()!=root->tArgLists.back().size()) { sameNumTemplateArgs = FALSE; } @@ -3609,9 +3357,9 @@ static void buildFunctionList(const Entry *root) ) { GroupDef *gd=0; - if (root->groups->getFirst() && !root->groups->getFirst()->groupname.isEmpty()) + if (!root->groups.empty() && !root->groups.front().groupname.isEmpty()) { - gd = Doxygen::groupSDict->find(root->groups->getFirst()->groupname); + gd = Doxygen::groupSDict->find(root->groups.front().groupname); } //printf("match!\n"); //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,nsName.data(),rnsName.data()); @@ -3634,12 +3382,13 @@ static void buildFunctionList(const Entry *root) if (found) { // merge argument lists - mergeArguments(mdAl,root->argList,!root->doc.isEmpty()); + ArgumentList mergedArgList = root->argList; + mergeArguments(mdAl,mergedArgList,!root->doc.isEmpty()); // merge documentation if (md->documentation().isEmpty() && !root->doc.isEmpty()) { - ArgumentList *argList = new ArgumentList; - stringToArgumentList(root->args,argList); + ArgumentList argList; + stringToArgumentList(root->lang,root->args,argList); if (root->proto) { //printf("setDeclArgumentList to %p\n",argList); @@ -3674,16 +3423,15 @@ static void buildFunctionList(const Entry *root) md->enableReferencesRelation(md->hasReferencesRelation() || root->referencesRelation); // merge ingroup specifiers - if (md->getGroupDef()==0 && root->groups->getFirst()!=0) + if (md->getGroupDef()==0 && !root->groups.empty()) { addMemberToGroups(root,md); } - else if (md->getGroupDef()!=0 && root->groups->count()==0) + else if (md->getGroupDef()!=0 && root->groups.empty()) { //printf("existing member is grouped, new member not\n"); - root->groups->append(new Grouping(md->getGroupDef()->name(), md->getGroupPri())); } - else if (md->getGroupDef()!=0 && root->groups->getFirst()!=0) + else if (md->getGroupDef()!=0 && !root->groups.empty()) { //printf("both members are grouped\n"); } @@ -3712,15 +3460,16 @@ static void buildFunctionList(const Entry *root) // root->type.data(),rname.data(),root->args.data(),root->bodyLine); // new global function - ArgumentList *tArgList = root->tArgLists ? root->tArgLists->getLast() : 0; QCString name=removeRedundantWhiteSpace(rname); md=createMemberDef( root->fileName,root->startLine,root->startColumn, root->type,name,root->args,root->exception, root->protection,root->virt,root->stat,Member, - MemberType_Function,tArgList,root->argList,root->metaData); + MemberType_Function, + !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), + root->argList,root->metaData); - md->setTagInfo(root->tagInfo); + md->setTagInfo(root->tagInfo()); md->setLanguage(root->lang); md->setId(root->id); //md->setDefFile(root->fileName); @@ -3762,27 +3511,14 @@ static void buildFunctionList(const Entry *root) } QCString def; + //QCString optArgs = root->argList.empty() ? QCString() : root->args; if (!root->type.isEmpty()) { - if (root->argList) - { - def=root->type+" "+scope+name; - } - else - { - def=root->type+" "+scope+name+root->args; - } + def=root->type+" "+scope+name; //+optArgs; } else { - if (root->argList) - { - def=scope+name.copy(); - } - else - { - def=scope+name+root->args; - } + def=scope+name; //+optArgs; } Debug::print(Debug::Functions,0, " Global Function:\n" @@ -3906,8 +3642,8 @@ static void findFriends() ) // if the member is related and the arguments match then the // function is actually a friend. { - ArgumentList *mmdAl = mmd->argumentList(); - ArgumentList *fmdAl = fmd->argumentList(); + ArgumentList &mmdAl = mmd->argumentList(); + ArgumentList &fmdAl = fmd->argumentList(); mergeArguments(mmdAl,fmdAl); if (!fmd->documentation().isEmpty()) { @@ -3988,7 +3724,7 @@ static void transferFunctionDocumentation() MemberNameIterator mni2(*mn); for (;(mdef=mni2.current());++mni2) { - if (!mdec->isAlias() && !mdef->isAlias()) + if (mdec!=mdef && !mdec->isAlias() && !mdef->isAlias()) { combineDeclarationAndDefinition(mdec,mdef); } @@ -4023,8 +3759,8 @@ static void transferFunctionReferences() } if (mdef && mdec) { - ArgumentList *mdefAl = mdef->argumentList(); - ArgumentList *mdecAl = mdec->argumentList(); + ArgumentList &mdefAl = mdef->argumentList(); + ArgumentList &mdecAl = mdec->argumentList(); if ( matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdefAl, mdec->getOuterScope(),mdec->getFileDef(),mdecAl, @@ -4144,31 +3880,26 @@ static void transferRelatedFunctionDocumentation() * Example: A template class A with template arguments <R,S,T> * that inherits from B<T,T,S> will have T and S in the dictionary. */ -static QDict<int> *getTemplateArgumentsInName(ArgumentList *templateArguments,const QCString &name) +static QDict<int> *getTemplateArgumentsInName(const ArgumentList &templateArguments,const QCString &name) { QDict<int> *templateNames = new QDict<int>(17); templateNames->setAutoDelete(TRUE); static QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*"); - if (templateArguments) + int count=0; + for (const Argument &arg : templateArguments) { - ArgumentListIterator ali(*templateArguments); - Argument *arg; - int count=0; - for (ali.toFirst();(arg=ali.current());++ali,count++) + int i,p=0,l; + while ((i=re.match(name,p,&l))!=-1) { - int i,p=0,l; - while ((i=re.match(name,p,&l))!=-1) + QCString n = name.mid(i,l); + if (n==arg.name) { - QCString n = name.mid(i,l); - if (n==arg->name) + if (templateNames->find(n)==0) { - if (templateNames->find(n)==0) - { - templateNames->insert(n,new int(count)); - } + templateNames->insert(n,new int(count)); } - p=i+l; } + p=i+l; } } return templateNames; @@ -4219,12 +3950,12 @@ static void findUsedClassesForClass(const Entry *root, ClassDef *masterCd, ClassDef *instanceCd, bool isArtificial, - ArgumentList *actualArgs=0, + const ArgumentList &actualArgs=ArgumentList(), QDict<int> *templateNames=0 ) { masterCd->setVisited(TRUE); - ArgumentList *formalArgs = masterCd->templateArguments(); + const ArgumentList &formalArgs = masterCd->templateArguments(); if (masterCd->memberNameInfoSDict()) { MemberNameInfoSDict::Iterator mnili(*masterCd->memberNameInfoSDict()); @@ -4250,10 +3981,7 @@ static void findUsedClassesForClass(const Entry *root, QCString templSpec; bool found=FALSE; // the type can contain template variables, replace them if present - if (actualArgs) - { - type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs); - } + type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs); //printf(" template substitution gives=%s\n",type.data()); while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec,root->lang)!=-1) @@ -4293,37 +4021,32 @@ static void findUsedClassesForClass(const Entry *root, BaseInfo bi(usedName,Public,Normal); findClassRelation(root,context,instanceCd,&bi,templateNames,TemplateInstances,isArtificial); - if (masterCd->templateArguments()) + int count=0; + for (const Argument &arg : masterCd->templateArguments()) { - ArgumentListIterator ali(*masterCd->templateArguments()); - Argument *arg; - int count=0; - for (ali.toFirst();(arg=ali.current());++ali,++count) + if (arg.name==usedName) // type is a template argument { - if (arg->name==usedName) // type is a template argument - { - found=TRUE; - Debug::print(Debug::Classes,0," New used class '%s'\n", qPrint(usedName)); + found=TRUE; + Debug::print(Debug::Classes,0," New used class '%s'\n", qPrint(usedName)); - ClassDef *usedCd = Doxygen::hiddenClasses->find(usedName); - if (usedCd==0) - { - usedCd = createClassDef( - masterCd->getDefFileName(),masterCd->getDefLine(), - masterCd->getDefColumn(), - usedName, - ClassDef::Class); - //printf("making %s a template argument!!!\n",usedCd->name().data()); - usedCd->makeTemplateArgument(); - usedCd->setUsedOnly(TRUE); - usedCd->setLanguage(masterCd->getLanguage()); - Doxygen::hiddenClasses->append(usedName,usedCd); - } - if (isArtificial) usedCd->setArtificial(TRUE); - Debug::print(Debug::Classes,0," Adding used class '%s' (1)\n", qPrint(usedCd->name())); - instanceCd->addUsedClass(usedCd,md->name(),md->protection()); - usedCd->addUsedByClass(instanceCd,md->name(),md->protection()); + ClassDef *usedCd = Doxygen::hiddenClasses->find(usedName); + if (usedCd==0) + { + usedCd = createClassDef( + masterCd->getDefFileName(),masterCd->getDefLine(), + masterCd->getDefColumn(), + usedName, + ClassDef::Class); + //printf("making %s a template argument!!!\n",usedCd->name().data()); + usedCd->makeTemplateArgument(); + usedCd->setUsedOnly(TRUE); + usedCd->setLanguage(masterCd->getLanguage()); + Doxygen::hiddenClasses->append(usedName,usedCd); } + if (isArtificial) usedCd->setArtificial(TRUE); + Debug::print(Debug::Classes,0," Adding used class '%s' (1)\n", qPrint(usedCd->name())); + instanceCd->addUsedClass(usedCd,md->name(),md->protection()); + usedCd->addUsedByClass(instanceCd,md->name(),md->protection()); } } @@ -4390,31 +4113,26 @@ static void findBaseClassesForClass( ClassDef *instanceCd, FindBaseClassRelation_Mode mode, bool isArtificial, - ArgumentList *actualArgs=0, + const ArgumentList &actualArgs=ArgumentList(), QDict<int> *templateNames=0 ) { //if (masterCd->visited) return; masterCd->setVisited(TRUE); // The base class could ofcouse also be a non-nested class - ArgumentList *formalArgs = masterCd->templateArguments(); - QListIterator<BaseInfo> bii(*root->extends); - BaseInfo *bi=0; - for (bii.toFirst();(bi=bii.current());++bii) + const ArgumentList &formalArgs = masterCd->templateArguments(); + for (const BaseInfo &bi : root->extends) { //printf("masterCd=%s bi->name='%s' #actualArgs=%d\n", // masterCd->localName().data(),bi->name.data(),actualArgs?(int)actualArgs->count():-1); bool delTempNames=FALSE; if (templateNames==0) { - templateNames = getTemplateArgumentsInName(formalArgs,bi->name); + templateNames = getTemplateArgumentsInName(formalArgs,bi.name); delTempNames=TRUE; } - BaseInfo tbi(bi->name,bi->prot,bi->virt); - if (actualArgs) // substitute the formal template arguments of the base class - { - tbi.name = substituteTemplateArgumentsInString(bi->name,formalArgs,actualArgs); - } + BaseInfo tbi = bi; + tbi.name = substituteTemplateArgumentsInString(bi.name,formalArgs,actualArgs); //printf("bi->name=%s tbi.name=%s\n",bi->name.data(),tbi.name.data()); if (mode==DocumentedOnly) @@ -4492,14 +4210,13 @@ static bool findTemplateInstanceRelation(const Entry *root, 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; - stringToArgumentList(templSpec,templArgs); + ArgumentList templArgs; + stringToArgumentList(root->lang,templSpec,templArgs); findBaseClassesForClass(templateRoot,context,templateClass,instanceClass, TemplateInstances,isArtificial,templArgs,templateNames); findUsedClassesForClass(templateRoot,context,templateClass,instanceClass, isArtificial,templArgs,templateNames); - delete templArgs; } else { @@ -4612,7 +4329,7 @@ static bool findClassRelation( const Entry *root, Definition *context, ClassDef *cd, - BaseInfo *bi, + const BaseInfo *bi, QDict<int> *templateNames, FindBaseClassRelation_Mode mode, bool isArtificial @@ -4715,7 +4432,7 @@ static bool findClassRelation( // base class has template specifiers { // TODO: here we should try to find the correct template specialization - // but for now, we only look for the unspecializated base class. + // but for now, we only look for the unspecialized base class. int e=findEndOfTemplate(baseClassName,i+1); //printf("baseClass==0 i=%d e=%d\n",i,e); if (e!=-1) // end of template was found at e @@ -4840,13 +4557,13 @@ static bool findClassRelation( usedName=biName; //printf("***** usedName=%s templSpec=%s\n",usedName.data(),templSpec.data()); } - static bool sipSupport = Config_getBool(SIP_SUPPORT); - if (sipSupport) bi->prot=Public; + Protection prot = bi->prot; + if (Config_getBool(SIP_SUPPORT)) prot=Public; if (!cd->isSubClass(baseClass)) // check for recursion, see bug690787 { - cd->insertBaseClass(baseClass,usedName,bi->prot,bi->virt,templSpec); + cd->insertBaseClass(baseClass,usedName,prot,bi->virt,templSpec); // add this class as super class to the base class - baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec); + baseClass->insertSubClass(cd,prot,bi->virt,templSpec); } else { @@ -4895,7 +4612,7 @@ static bool findClassRelation( int si = baseClassName.findRev("::"); if (si!=-1) // class is nested { - Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),0,root->tagInfo); + Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),0,root->tagInfo()); if (sd==0 || sd==Doxygen::globalScope) // outer scope not found { baseClass->setArtificial(TRUE); // see bug678139 @@ -4978,8 +4695,8 @@ static bool isClassSection(const Entry *root) else if (root->section & Entry::COMPOUNDDOC_MASK) // is it a documentation block with inheritance info. { - bool extends = root->extends->count()>0; - if (extends) return TRUE; + bool hasExtends = !root->extends.empty(); + if (hasExtends) return TRUE; } } return FALSE; @@ -5107,20 +4824,17 @@ static void computeTemplateClassRelations() { Debug::print(Debug::Classes,0," Template instance %s : \n",qPrint(tcd->name())); QCString templSpec = tdi.currentKey(); - ArgumentList *templArgs = new ArgumentList; - stringToArgumentList(templSpec,templArgs); - QList<BaseInfo> *baseList=root->extends; - QListIterator<BaseInfo> it(*baseList); - BaseInfo *bi; - for (;(bi=it.current());++it) // for each base class of the template + ArgumentList templArgs; + stringToArgumentList(tcd->getLanguage(),templSpec,templArgs); + for (const BaseInfo &bi : root->extends) { // check if the base class is a template argument - BaseInfo tbi(bi->name,bi->prot,bi->virt); - ArgumentList *tl = cd->templateArguments(); - if (tl) + BaseInfo tbi = bi; + const ArgumentList &tl = cd->templateArguments(); + if (!tl.empty()) { QDict<int> *baseClassNames = tcd->getTemplateBaseClassNames(); - QDict<int> *templateNames = getTemplateArgumentsInName(tl,bi->name); + QDict<int> *templateNames = getTemplateArgumentsInName(tl,bi.name); // for each template name that we inherit from we need to // substitute the formal with the actual arguments QDict<int> *actualTemplateNames = new QDict<int>(17); @@ -5129,23 +4843,25 @@ static void computeTemplateClassRelations() for (qdi.toFirst();qdi.current();++qdi) { int templIndex = *qdi.current(); - Argument *actArg = 0; - if (templIndex<(int)templArgs->count()) + Argument actArg; + bool hasActArg=FALSE; + if (templIndex<(int)templArgs.size()) { - actArg=templArgs->at(templIndex); + actArg=templArgs.at(templIndex); + hasActArg=TRUE; } - if (actArg!=0 && + if (hasActArg && baseClassNames!=0 && - baseClassNames->find(actArg->type)!=0 && - actualTemplateNames->find(actArg->type)==0 + baseClassNames->find(actArg.type)!=0 && + actualTemplateNames->find(actArg.type)==0 ) { - actualTemplateNames->insert(actArg->type,new int(templIndex)); + actualTemplateNames->insert(actArg.type,new int(templIndex)); } } delete templateNames; - tbi.name = substituteTemplateArgumentsInString(bi->name,tl,templArgs); + tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs); // find a documented base class in the correct scope if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE)) { @@ -5155,7 +4871,6 @@ static void computeTemplateClassRelations() delete actualTemplateNames; } } - delete templArgs; } // class has no base classes } } @@ -5250,7 +4965,7 @@ static void addListReferences() name = pd->getGroupDef()->getOutputFileBase(); } { - QList<ListItemInfo> *xrefItems = pd->xrefListItems(); + const std::vector<ListItemInfo> &xrefItems = pd->xrefListItems(); addRefItem(xrefItems, name, theTranslator->trPage(TRUE,TRUE), @@ -5267,7 +4982,7 @@ static void addListReferences() //{ // name = dd->getGroupDef()->getOutputFileBase(); //} - QList<ListItemInfo> *xrefItems = dd->xrefListItems(); + const std::vector<ListItemInfo> &xrefItems = dd->xrefListItems(); addRefItem(xrefItems, name, theTranslator->trDir(TRUE,TRUE), @@ -5294,13 +5009,13 @@ static void generateXRefPages() static void addMemberDocs(const Entry *root, MemberDef *md, const char *funcDecl, - ArgumentList *al, + const ArgumentList *al, bool over_load, uint64 spec ) { - //printf("addMemberDocs: '%s'::'%s' '%s' funcDecl='%s' mSpec=%d\n", - // root->parent->name.data(),md->name().data(),md->argsString(),funcDecl,spec); + //printf("addMemberDocs: '%s'::'%s' '%s' funcDecl='%s' mSpec=%lld\n", + // root->parent()->name.data(),md->name().data(),md->argsString(),funcDecl,spec); QCString fDecl=funcDecl; // strip extern specifier fDecl.stripPrefix("extern "); @@ -5324,11 +5039,12 @@ static void addMemberDocs(const Entry *root, // TODO determine scope based on root not md Definition *rscope = md->getOuterScope(); - ArgumentList *mdAl = md->argumentList(); + ArgumentList &mdAl = md->argumentList(); if (al) { + ArgumentList mergedAl = *al; //printf("merging arguments (1) docs=%d\n",root->doc.isEmpty()); - mergeArguments(mdAl,al,!root->doc.isEmpty()); + mergeArguments(mdAl,mergedAl,!root->doc.isEmpty()); } else { @@ -5340,7 +5056,8 @@ static void addMemberDocs(const Entry *root, ) { //printf("merging arguments (2)\n"); - mergeArguments(mdAl,root->argList,!root->doc.isEmpty()); + ArgumentList mergedArgList = root->argList; + mergeArguments(mdAl,mergedArgList,!root->doc.isEmpty()); } } if (over_load) // the \overload keyword was used @@ -5511,9 +5228,9 @@ static bool findGlobalMember(const Entry *root, NamespaceDef *rnd = 0; if (!namespaceName.isEmpty()) rnd = Doxygen::namespaceSDict->find(namespaceName); - const ArgumentList *mdAl = const_cast<const MemberDef *>(md)->argumentList(); + const ArgumentList &mdAl = const_cast<const MemberDef *>(md)->argumentList(); bool matching= - (mdAl==0 && root->argList->count()==0) || + (mdAl.empty() && root->argList.empty()) || md->isVariable() || md->isTypedef() || /* in case of function pointers */ matchArguments2(md->getOuterScope(),const_cast<const MemberDef *>(md)->getFileDef(),mdAl, rnd ? rnd : Doxygen::globalScope,fd,root->argList, @@ -5522,15 +5239,12 @@ static bool findGlobalMember(const Entry *root, // for template members we need to check if the number of // template arguments is the same, otherwise we are dealing with // different functions. - if (matching && root->tArgLists) + if (matching && !root->tArgLists.empty()) { - const ArgumentList *mdTempl = md->templateArguments(); - if (mdTempl) + const ArgumentList &mdTempl = md->templateArguments(); + if (root->tArgLists.back().size()!=mdTempl.size()) { - if (root->tArgLists->getLast()->count()!=mdTempl->count()) - { - matching=FALSE; - } + matching=FALSE; } } @@ -5550,11 +5264,11 @@ static bool findGlobalMember(const Entry *root, } // for template member we also need to check the return type - if (md->templateArguments()!=0 && root->tArgLists!=0) + if (!md->templateArguments().empty() && !root->tArgLists.empty()) { //printf("Comparing return types '%s'<->'%s'\n", // md->typeString(),type); - if (md->templateArguments()->count()!=root->tArgLists->getLast()->count() || + if (md->templateArguments().size()!=root->tArgLists.back().size() || qstrcmp(md->typeString(),type)!=0) { //printf(" ---> no matching\n"); @@ -5565,7 +5279,7 @@ static bool findGlobalMember(const 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,root->spec); + addMemberDocs(root,md->resolveAlias(),decl,&root->argList,FALSE,root->spec); found=TRUE; } } @@ -5573,7 +5287,7 @@ static bool findGlobalMember(const Entry *root, if (!found && root->relatesType != Duplicate && root->section==Entry::FUNCTION_SEC) // no match { QCString fullFuncDecl=decl; - if (root->argList) fullFuncDecl+=argListToString(root->argList,TRUE); + if (!root->argList.empty()) fullFuncDecl+=argListToString(root->argList,TRUE); QCString warnMsg = QCString("no matching file member found for \n")+substitute(fullFuncDecl,"%","%%"); if (mn->count()>0) @@ -5609,17 +5323,17 @@ static bool findGlobalMember(const Entry *root, } static bool isSpecialization( - const QList<ArgumentList> &srcTempArgLists, - const QList<ArgumentList> &dstTempArgLists + const std::vector<ArgumentList> &srcTempArgLists, + const std::vector<ArgumentList> &dstTempArgLists ) { - QListIterator<ArgumentList> srclali(srcTempArgLists); - QListIterator<ArgumentList> dstlali(dstTempArgLists); - for (;srclali.current();++srclali,++dstlali) + auto srcIt = srcTempArgLists.begin(); + auto dstIt = dstTempArgLists.begin(); + while (srcIt!=srcTempArgLists.end() && dstIt!=dstTempArgLists.end()) { - ArgumentList *sal = srclali.current(); - ArgumentList *dal = dstlali.current(); - if (!(sal && dal && sal->count()==dal->count())) return TRUE; + if ((*srcIt).size()!=(*dstIt).size()) return TRUE; + ++srcIt; + ++dstIt; } return FALSE; } @@ -5629,15 +5343,15 @@ static bool scopeIsTemplate(const Definition *d) bool result=FALSE; if (d && d->definitionType()==Definition::TypeClass) { - result = (dynamic_cast<const ClassDef*>(d))->templateArguments() || scopeIsTemplate(d->getOuterScope()); + result = !(dynamic_cast<const ClassDef*>(d))->templateArguments().empty() || + scopeIsTemplate(d->getOuterScope()); } return result; } static QCString substituteTemplatesInString( - const QList<ArgumentList> &srcTempArgLists, - const QList<ArgumentList> &dstTempArgLists, - ArgumentList *funcTempArgList, // can be used to match template specializations + const std::vector<ArgumentList> &srcTempArgLists, + const std::vector<ArgumentList> &dstTempArgLists, const QCString &src ) { @@ -5651,61 +5365,59 @@ static QCString substituteTemplatesInString( dst+=src.mid(p,i-p); QCString name=src.mid(i,l); - QListIterator<ArgumentList> srclali(srcTempArgLists); - QListIterator<ArgumentList> dstlali(dstTempArgLists); - for (;srclali.current() && !found;++srclali,++dstlali) + auto srcIt = srcTempArgLists.begin(); + auto dstIt = dstTempArgLists.begin(); + while (srcIt!=srcTempArgLists.end() && !found) { - ArgumentListIterator tsali(*srclali.current()); - ArgumentListIterator tdali(*dstlali.current()); - ArgumentListIterator *fali=0; - Argument *tsa =0,*tda=0, *fa=0; - if (funcTempArgList) + const ArgumentList *tdAli = 0; + std::vector<Argument>::const_iterator tdaIt; + if (dstIt!=dstTempArgLists.end()) { - fali = new ArgumentListIterator(*funcTempArgList); - fa = fali->current(); + tdAli = &(*dstIt); + tdaIt = tdAli->begin(); + ++dstIt; } - for (tsali.toFirst();(tsa=tsali.current()) && !found;++tsali) + const ArgumentList &tsaLi = *srcIt; + for (auto tsaIt = tsaLi.begin(); tsaIt!=tsaLi.end() && !found; ++tsaIt) { - tda = tdali.current(); + Argument tsa = *tsaIt; + const Argument *tda = 0; + if (tdAli && tdaIt!=tdAli->end()) + { + tda = &(*tdaIt); + ++tdaIt; + } //if (tda) printf("tsa=%s|%s tda=%s|%s\n", - // tsa->type.data(),tsa->name.data(), + // tsa.type.data(),tsa.name.data(), // tda->type.data(),tda->name.data()); - if (name==tsa->name) + if (name==tsa.name) { if (tda && tda->name.isEmpty()) { + QCString tdaName = tda->name; + QCString tdaType = tda->type; int vc=0; - if (tda->type.left(6)=="class ") vc=6; - else if (tda->type.left(9)=="typename ") vc=9; + if (tdaType.left(6)=="class ") vc=6; + else if (tdaType.left(9)=="typename ") vc=9; if (vc>0) // convert type=="class T" to type=="class" name=="T" { - tda->name = tda->type.mid(vc); - tda->type = tda->type.left(vc-1); + tdaName = tdaType.mid(vc); + } + if (!tdaName.isEmpty()) + { + name=tdaName; // substitute + found=TRUE; } - } - if (tda && !tda->name.isEmpty()) - { - name=tda->name; // substitute - found=TRUE; - } - else if (fa) - { - name=fa->type; - found=TRUE; } } - if (tda) - ++tdali; - else if (fali) - { ++(*fali); fa=fali->current(); } } - delete fali; //printf(" srcList='%s' dstList='%s faList='%s'\n", // argListToString(srclali.current()).data(), // argListToString(dstlali.current()).data(), // funcTempArgList ? argListToString(funcTempArgList).data() : "<none>"); + ++srcIt; } dst+=name; p=i+l; @@ -5717,48 +5429,39 @@ static QCString substituteTemplatesInString( } static void substituteTemplatesInArgList( - const QList<ArgumentList> &srcTempArgLists, - const QList<ArgumentList> &dstTempArgLists, - ArgumentList *src, - ArgumentList *dst, - ArgumentList *funcTempArgs = 0 + const std::vector<ArgumentList> &srcTempArgLists, + const std::vector<ArgumentList> &dstTempArgLists, + const ArgumentList &src, + ArgumentList &dst ) { - ArgumentListIterator sali(*src); - ArgumentListIterator dali(*dst); - Argument *sa=0; - Argument *da=dali.current(); - - for (sali.toFirst();(sa=sali.current());++sali) // for each member argument + auto dstIt = dst.begin(); + for (const Argument &sa : src) { - QCString dstType = substituteTemplatesInString( - srcTempArgLists,dstTempArgLists,funcTempArgs, - sa->type); - QCString dstArray = substituteTemplatesInString( - srcTempArgLists,dstTempArgLists,funcTempArgs, - sa->array); - if (da==0) + QCString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type); + QCString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array); + if (dstIt == dst.end()) { - da=new Argument(*sa); - dst->append(da); - da->type=dstType; - da->array=dstArray; - da=0; + Argument da = sa; + da.type = dstType; + da.array = dstArray; + dst.push_back(da); + dstIt = dst.end(); } else { - da->type=dstType; - da->type=dstArray; - ++dali; - da=dali.current(); + Argument da = *dstIt; + da.type = dstType; + da.array = dstArray; + ++dstIt; } } - dst->constSpecifier = src->constSpecifier; - dst->volatileSpecifier = src->volatileSpecifier; - dst->pureSpecifier = src->pureSpecifier; - dst->trailingReturnType = substituteTemplatesInString( + dst.constSpecifier = src.constSpecifier; + dst.volatileSpecifier = src.volatileSpecifier; + dst.pureSpecifier = src.pureSpecifier; + dst.trailingReturnType = substituteTemplatesInString( srcTempArgLists,dstTempArgLists, - funcTempArgs,src->trailingReturnType); + src.trailingReturnType); //printf("substituteTemplatesInArgList: replacing %s with %s\n", // argListToString(src).data(),argListToString(dst).data() // ); @@ -5786,10 +5489,10 @@ static void findMember(const Entry *root, { Debug::print(Debug::FindMembers,0, "findMember(root=%p,funcDecl='%s',related='%s',overload=%d," - "isFunc=%d mGrpId=%d tArgList=%p (#=%d) " + "isFunc=%d mGrpId=%d #tArgList=%d " "spec=%lld lang=%x\n", root,qPrint(funcDecl),qPrint(relates),overloaded,isFunc,root->mGrpId, - root->tArgLists,root->tArgLists ? root->tArgLists->count() : 0, + root->tArgLists.size(), root->spec,root->lang ); @@ -5946,9 +5649,8 @@ static void findMember(const Entry *root, // empty while funcSpec is not empty we assume this is a // specialization of a method. If not, we clear the funcSpec and treat // this as a normal method of a template class. - if (!(root->tArgLists && - root->tArgLists->count()>0 && - root->tArgLists->getFirst()->count()==0 + if (!(root->tArgLists.size()>0 && + root->tArgLists.front().size()==0 ) ) { @@ -5995,7 +5697,7 @@ static void findMember(const Entry *root, if (funcSpec.isEmpty()) { int argListIndex=0; - tempScopeName=cd->qualifiedNameWithTemplateParameters(root->tArgLists,&argListIndex); + tempScopeName=cd->qualifiedNameWithTemplateParameters(&root->tArgLists,&argListIndex); } else { @@ -6145,39 +5847,33 @@ static void findMember(const Entry *root, "4. class definition %s found\n",cd->name().data()); // get the template parameter lists found at the member declaration - QList<ArgumentList> declTemplArgs; - cd->getTemplateParameterLists(declTemplArgs); - const ArgumentList *templAl = md->templateArguments(); - if (templAl) + std::vector<ArgumentList> declTemplArgs = cd->getTemplateParameterLists(); + const ArgumentList &templAl = md->templateArguments(); + if (!templAl.empty()) { - declTemplArgs.append(templAl); + declTemplArgs.push_back(templAl); } // get the template parameter lists found at the member definition - QList<ArgumentList> *defTemplArgs = root->tArgLists; + const std::vector<ArgumentList> &defTemplArgs = root->tArgLists; //printf("defTemplArgs=%p\n",defTemplArgs); // do we replace the decl argument lists with the def argument lists? bool substDone=FALSE; - ArgumentList *argList=0; + ArgumentList argList; /* substitute the occurrences of class template names in the * argument list before matching */ - ArgumentList *mdAl = md->argumentList(); - if (declTemplArgs.count()>0 && defTemplArgs && - declTemplArgs.count()==defTemplArgs->count() && - mdAl - ) + const ArgumentList &mdAl = md->argumentList(); + if (declTemplArgs.size()>0 && declTemplArgs.size()==defTemplArgs.size()) { /* the function definition has template arguments * and the class definition also has template arguments, so * we must substitute the template names of the class by that * of the function definition before matching. */ - argList = new ArgumentList; - substituteTemplatesInArgList(declTemplArgs,*defTemplArgs, - mdAl,argList); + substituteTemplatesInArgList(declTemplArgs,defTemplArgs,mdAl,argList); substDone=TRUE; } @@ -6194,7 +5890,7 @@ static void findMember(const Entry *root, bool matching= md->isVariable() || md->isTypedef() || // needed for function pointers - (mdAl==0 && root->argList->count()==0) || + (mdAl.empty() && root->argList.empty()) || matchArguments2( md->getClassDef(),md->getFileDef(),argList, cd,fd,root->argList, @@ -6206,7 +5902,7 @@ static void findMember(const Entry *root, } // for template member we also need to check the return type - if (md->templateArguments()!=0 && root->tArgLists!=0) + if (!md->templateArguments().empty() && !root->tArgLists.empty()) { QCString memType = md->typeString(); memType.stripPrefix("static "); // see bug700696 @@ -6217,8 +5913,8 @@ static void findMember(const Entry *root, Debug::print(Debug::FindMembers,0, "5b. Comparing return types '%s'<->'%s' #args %d<->%d\n", qPrint(md->typeString()),qPrint(funcType), - md->templateArguments()->count(),root->tArgLists->getLast()->count()); - if (md->templateArguments()->count()!=root->tArgLists->getLast()->count() || + md->templateArguments().size(),root->tArgLists.back().size()); + if (md->templateArguments().size()!=root->tArgLists.back().size() || qstrcmp(memType,funcType)) { //printf(" ---> no matching\n"); @@ -6227,9 +5923,9 @@ static void findMember(const Entry *root, } bool rootIsUserDoc = (root->section&Entry::MEMBERDOC_SEC)!=0; bool classIsTemplate = scopeIsTemplate(md->getClassDef()); - bool mdIsTemplate = md->templateArguments()!=0; + bool mdIsTemplate = md->templateArguments().hasParameters(); bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate; - bool rootIsTemplate = root->tArgLists!=0; + bool rootIsTemplate = !root->tArgLists.empty(); //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate); if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457 (mdIsTemplate || rootIsTemplate) && // either md or root is a template @@ -6245,19 +5941,19 @@ static void findMember(const Entry *root, Debug::print(Debug::FindMembers,0, - "6. match results of matchArguments2 = %d\n",matching); + "6. match results of matchArguments2 = %d substDone=%d\n",matching,substDone); if (substDone) // found a new argument list { if (matching) // replace member's argument list { md->setDefinitionTemplateParameterLists(root->tArgLists); - md->setArgumentList(argList); // new owner of the list => no delete + md->setArgumentList(argList); } else // no match { if (!funcTempList.isEmpty() && - isSpecialization(declTemplArgs,*defTemplArgs)) + isSpecialization(declTemplArgs,defTemplArgs)) { // check if we are dealing with a partial template // specialization. In this case we add it to the class @@ -6267,7 +5963,6 @@ static void findMember(const Entry *root, md->protection(),md->isStatic(),md->virtualness(),spec,relates); return; } - delete argList; } } if (matching) @@ -6303,9 +5998,9 @@ static void findMember(const Entry *root, //printf("ccd->name()==%s className=%s\n",ccd->name().data(),className.data()); if (ccd!=0 && rightScopeMatch(ccd->name(),className)) { - const ArgumentList *templAl = md->templateArguments(); - if (root->tArgLists && templAl!=0 && - root->tArgLists->getLast()->count()<=templAl->count()) + const ArgumentList &templAl = md->templateArguments(); + if (!root->tArgLists.empty() && !templAl.empty() && + root->tArgLists.back().size()<=templAl.size()) { Debug::print(Debug::FindMembers,0,"7. add template specialization\n"); addMethodToClass(root,ccd,type,md->name(),args,isFriend, @@ -6356,17 +6051,13 @@ static void findMember(const Entry *root, if (noMatchCount>1) warnMsg+="uniquely "; warnMsg+="matching class member found for \n"; - if (root->tArgLists) + for (const ArgumentList &al : root->tArgLists) { - QListIterator<ArgumentList> alli(*root->tArgLists); - ArgumentList *al; - for (;(al=alli.current());++alli) - { - warnMsg+=" template "; - warnMsg+=tempArgListToString(al,root->lang); - warnMsg+='\n'; - } + warnMsg+=" template "; + warnMsg+=tempArgListToString(al,root->lang); + warnMsg+='\n'; } + QCString fullFuncDecl=funcDecl.copy(); if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE); @@ -6382,14 +6073,15 @@ static void findMember(const Entry *root, const ClassDef *cd=md->getClassDef(); if (cd!=0 && rightScopeMatch(cd->name(),className)) { - const ArgumentList *templAl = md->templateArguments(); - if (templAl!=0) + const ArgumentList &templAl = md->templateArguments(); + warnMsg+=" '"; + if (templAl.hasParameters()) { - warnMsg+=" 'template "; + warnMsg+="template "; warnMsg+=tempArgListToString(templAl,root->lang); warnMsg+='\n'; + warnMsg+=" "; } - warnMsg+=" "; if (md->typeString()) { warnMsg+=md->typeString(); @@ -6430,7 +6122,7 @@ static void findMember(const Entry *root, } } MemberType mtype=MemberType_Function; - ArgumentList *tArgList = new ArgumentList; + ArgumentList tArgList; // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); md=createMemberDef( root->fileName,root->startLine,root->startColumn, @@ -6439,7 +6131,7 @@ static void findMember(const Entry *root, root->virt,root->stat,Member, mtype,tArgList,root->argList,root->metaData); //printf("new specialized member %s args='%s'\n",md->name().data(),funcArgs.data()); - md->setTagInfo(root->tagInfo); + md->setTagInfo(root->tagInfo()); md->setLanguage(root->lang); md->setId(root->id); md->setMemberClass(cd); @@ -6464,7 +6156,6 @@ static void findMember(const Entry *root, mn->append(md); cd->insertMember(md); md->setRefItems(root->sli); - delete tArgList; } else { @@ -6499,7 +6190,7 @@ static void findMember(const Entry *root, else mtype=MemberType_Function; // new overloaded member function - ArgumentList *tArgList = + ArgumentList tArgList = getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); //printf("new related member %s args='%s'\n",md->name().data(),funcArgs.data()); MemberDef *md=createMemberDef( @@ -6507,7 +6198,7 @@ static void findMember(const Entry *root, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,Related, mtype,tArgList,root->argList,root->metaData); - md->setTagInfo(root->tagInfo); + md->setTagInfo(root->tagInfo()); md->setLanguage(root->lang); md->setId(root->id); md->setTypeConstraints(root->typeConstr); @@ -6590,7 +6281,7 @@ static void findMember(const Entry *root, MemberDef *rmd; while ((rmd=mni.current()) && newMember) // see if we got another member with matching arguments { - ArgumentList *rmdAl = rmd->argumentList(); + const ArgumentList &rmdAl = rmd->argumentList(); newMember= className!=rmd->getOuterScope()->name() || @@ -6634,7 +6325,7 @@ static void findMember(const Entry *root, // first note that we pass: // (root->tArgLists ? root->tArgLists->last() : 0) - // for the template arguments fo the new "member." + // for the template arguments for the new "member." // this accurately reflects the template arguments of // the related function, which don't have to do with // those of the related class. @@ -6645,8 +6336,9 @@ static void findMember(const Entry *root, root->stat && !isMemberOf, isMemberOf ? Foreign : Related, mtype, - (root->tArgLists ? root->tArgLists->getLast() : 0), - funcArgs.isEmpty() ? 0 : root->argList,root->metaData); + (!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList()), + funcArgs.isEmpty() ? ArgumentList() : root->argList, + root->metaData); if (isDefine && mdDefine) { @@ -6666,7 +6358,7 @@ static void findMember(const Entry *root, // md->setDefinitionTemplateParameterLists(root->tArgLists); - md->setTagInfo(root->tagInfo); + md->setTagInfo(root->tagInfo()); @@ -6685,7 +6377,7 @@ static void findMember(const Entry *root, const MemberDef *rmd; while ((rmd=rmni.current()) && !found) // see if we got another member with matching arguments { - const ArgumentList *rmdAl = rmd->argumentList(); + const ArgumentList &rmdAl = rmd->argumentList(); // check for matching argument lists if ( matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmdAl, @@ -6786,8 +6478,8 @@ localObjCMethod: root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,Member, - MemberType_Function,0,root->argList,root->metaData); - md->setTagInfo(root->tagInfo); + MemberType_Function,ArgumentList(),root->argList,root->metaData); + md->setTagInfo(root->tagInfo()); md->setLanguage(root->lang); md->setId(root->id); md->makeImplementationDetail(); @@ -7120,7 +6812,7 @@ static void findEnums(const Entry *root) mnsd=Doxygen::memberNameSDict; isGlobal=FALSE; } - else if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') // found enum inside namespace + else if (nd) // found enum inside namespace { mnsd=Doxygen::functionNameSDict; isGlobal=TRUE; @@ -7141,8 +6833,8 @@ static void findEnums(const Entry *root) root->protection,Normal,FALSE, isMemberOf ? Foreign : isRelated ? Related : Member, MemberType_Enumeration, - 0,0,root->metaData); - md->setTagInfo(root->tagInfo); + ArgumentList(),ArgumentList(),root->metaData); + md->setTagInfo(root->tagInfo()); md->setLanguage(root->lang); md->setId(root->id); if (!isGlobal) md->setMemberClass(cd); else md->setFileDef(fd); @@ -7169,7 +6861,7 @@ static void findEnums(const Entry *root) baseType.prepend(" : "); } - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') + if (nd) { if (isRelated || Config_getBool(HIDE_SCOPE_NAMES)) { @@ -7188,7 +6880,7 @@ static void findEnums(const Entry *root) // even if we have already added the enum to a namespace, we still // also want to add it to other appropriate places such as file // or class. - if (isGlobal) + if (isGlobal && (nd==0 || !nd->isAnonymous())) { if (!defSet) md->setDefinition(name+baseType); if (fd==0 && root->parent()) @@ -7297,7 +6989,7 @@ static void addEnumValuesToEnums(const Entry *root) mnsd=Doxygen::memberNameSDict; isGlobal=FALSE; } - else if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') // found enum inside namespace + else if (nd && !nd->isAnonymous()) // found enum inside namespace { //printf("Enum in namespace '%s'::'%s'\n",nd->name().data(),name.data()); mnsd=Doxygen::functionNameSDict; @@ -7340,7 +7032,7 @@ static void addEnumValuesToEnums(const Entry *root) //printf("md->qualifiedName()=%s e->name=%s tagInfo=%p name=%s\n", // md->qualifiedName().data(),e->name.data(),e->tagInfo,e->name.data()); QCString qualifiedName = substitute(root->name,"::","."); - if (!scope.isEmpty() && root->tagInfo) + if (!scope.isEmpty() && root->tagInfo()) { qualifiedName=substitute(scope,"::",".")+"."+qualifiedName; } @@ -7349,20 +7041,20 @@ static void addEnumValuesToEnums(const Entry *root) ) { QCString fileName = e->fileName; - if (fileName.isEmpty() && e->tagInfo) + if (fileName.isEmpty() && e->tagInfo()) { - fileName = e->tagInfo->tagName; + fileName = e->tagInfo()->tagName; } MemberDef *fmd=createMemberDef( fileName,e->startLine,e->startColumn, e->type,e->name,e->args,0, e->protection, Normal,e->stat,Member, - MemberType_EnumValue,0,0,e->metaData); + MemberType_EnumValue,ArgumentList(),ArgumentList(),e->metaData); if (md->getClassDef()) fmd->setMemberClass(md->getClassDef()); else if (md->getNamespaceDef()) fmd->setNamespace(md->getNamespaceDef()); else if (md->getFileDef()) fmd->setFileDef(md->getFileDef()); fmd->setOuterScope(md->getOuterScope()); - fmd->setTagInfo(e->tagInfo); + fmd->setTagInfo(e->tagInfo()); fmd->setLanguage(e->lang); fmd->setId(e->id); fmd->setDocumentation(e->doc,e->docFile,e->docLine); @@ -7405,7 +7097,7 @@ static void addEnumValuesToEnums(const Entry *root) { //printf("found enum value with same name %s in scope %s\n", // fmd->name().data(),fmd->getOuterScope()->name().data()); - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') + if (nd && !nd->isAnonymous()) { const NamespaceDef *fnd=fmd->getNamespaceDef(); if (fnd==nd) // enum value is inside a namespace @@ -7544,7 +7236,7 @@ static void findEnumDocumentation(const Entry *root) md->setRefItems(root->sli); const GroupDef *gd=md->getGroupDef(); - if (gd==0 &&root->groups->getFirst()!=0) // member not grouped but out-of-line documentation is + if (gd==0 && !root->groups.empty()) // member not grouped but out-of-line documentation is { addMemberToGroups(root,md); } @@ -7578,7 +7270,7 @@ static void findEnumDocumentation(const Entry *root) md->setMemberGroupId(root->mGrpId); const GroupDef *gd=md->getGroupDef(); - if (gd==0 && root->groups->getFirst()!=0) // member not grouped but out-of-line documentation is + if (gd==0 && !root->groups.empty()) // member not grouped but out-of-line documentation is { addMemberToGroups(root,md); } @@ -7755,8 +7447,8 @@ static void computeMemberRelations() mcd->isBaseClass(bmcd,TRUE)) { //printf(" derived scope\n"); - ArgumentList *bmdAl = bmd->argumentList(); - ArgumentList *mdAl = md->argumentList(); + const ArgumentList &bmdAl = bmd->argumentList(); + const ArgumentList &mdAl = md->argumentList(); //printf(" Base argList='%s'\n Super argList='%s'\n", // argListToString(bmdAl.pointer()).data(), // argListToString(mdAl.pointer()).data() @@ -8587,12 +8279,13 @@ static void findDefineDocumentation(Entry *root) //printf("found define '%s' '%s' brief='%s' doc='%s'\n", // root->name.data(),root->args.data(),root->brief.data(),root->doc.data()); - if (root->tagInfo && !root->name.isEmpty()) // define read from a tag file + if (root->tagInfo() && !root->name.isEmpty()) // define read from a tag file { - MemberDef *md=createMemberDef(root->tagInfo->tagName,1,1, + MemberDef *md=createMemberDef(root->tagInfo()->tagName,1,1, "#define",root->name,root->args,0, - Public,Normal,FALSE,Member,MemberType_Define,0,0,""); - md->setTagInfo(root->tagInfo); + Public,Normal,FALSE,Member,MemberType_Define, + ArgumentList(),ArgumentList(),""); + md->setTagInfo(root->tagInfo()); md->setLanguage(root->lang); //printf("Searching for '%s' fd=%p\n",filePathName.data(),fd); md->setFileDef(root->parent()->fileDef()); @@ -8811,7 +8504,7 @@ static void findMainPage(Entry *root) { if (root->section == Entry::MAINPAGEDOC_SEC) { - if (Doxygen::mainPage==0 && root->tagInfo==0) + if (Doxygen::mainPage==0 && root->tagInfo()==0) { //printf("Found main page! \n======\n%s\n=======\n",root->doc.data()); QCString title=root->args.stripWhiteSpace(); @@ -8850,7 +8543,7 @@ static void findMainPage(Entry *root) Doxygen::mainPage->addSectionsToDefinition(root->anchors); } } - else if (root->tagInfo==0) + else if (root->tagInfo()==0) { warn(root->fileName,root->startLine, "found more than one \\mainpage comment block! (first occurrence: %s, line %d), Skipping current block!", @@ -8865,7 +8558,7 @@ static void findMainPageTagFiles(Entry *root) { if (root->section == Entry::MAINPAGEDOC_SEC) { - if (Doxygen::mainPage && root->tagInfo) + if (Doxygen::mainPage && root->tagInfo()) { Doxygen::mainPage->addSectionsToDefinition(root->anchors); } @@ -8886,17 +8579,14 @@ static void computePageRelations(Entry *root) Doxygen::mainPage; if (pd) { - QListIterator<BaseInfo> bii(*root->extends); - BaseInfo *bi; - for (bii.toFirst();(bi=bii.current());++bii) + for (const BaseInfo &bi : root->extends) { - PageDef *subPd = Doxygen::pageSDict->find(bi->name); + PageDef *subPd = Doxygen::pageSDict->find(bi.name); if (pd==subPd) { - err("page defined at line %d of file %s with label %s is a direct " + term("page defined at line %d of file %s with label %s is a direct " "subpage of itself! Please remove this cyclic dependency.\n", pd->docLine(),pd->docFile().data(),pd->name().data()); - exit(1); } else if (subPd) { @@ -8921,10 +8611,9 @@ static void checkPageRelations() { if (ppd==pd) { - err("page defined at line %d of file %s with label %s is a subpage " + term("page defined at line %d of file %s with label %s is a subpage " "of itself! Please remove this cyclic dependency.\n", pd->docLine(),pd->docFile().data(),pd->name().data()); - exit(1); } ppd=ppd->getOuterScope(); } @@ -9085,7 +8774,8 @@ static void generateExampleDocs() for (pdi.toFirst();(pd=pdi.current());++pdi) { msg("Generating docs for example %s...\n",pd->name().data()); - resetCCodeParserState(); + CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(".c"); // TODO: do this on code type + intf.resetCodeParserState(); QCString n=pd->getOutputFileBase(); startFile(*g_outputList,n,n,pd->name()); startTitle(*g_outputList,n); @@ -9256,8 +8946,7 @@ static void generateConfigFile(const char *configFile,bool shortList, } else { - err("Cannot open file %s for writing\n",configFile); - exit(1); + term("Cannot open file %s for writing\n",configFile); } } static void compareDoxyfile() @@ -9274,8 +8963,7 @@ static void compareDoxyfile() } else { - err("Cannot open file %s for writing\n",configFile); - exit(1); + term("Cannot open file %s for writing\n",configFile); } } //---------------------------------------------------------------------------- @@ -9291,7 +8979,7 @@ static void compareDoxyfile() //---------------------------------------------------------------------------- -static void readTagFile(const std::unique_ptr<Entry> &root,const char *tl) +static void readTagFile(const std::shared_ptr<Entry> &root,const char *tl) { QCString tagLine = tl; QCString fileName; @@ -9301,6 +8989,7 @@ static void readTagFile(const std::unique_ptr<Entry> &root,const char *tl) { fileName = tagLine.left(eqPos).stripWhiteSpace(); destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace(); + if (fileName.isEmpty() || destName.isEmpty()) return; QFileInfo fi(fileName); Doxygen::tagDestinationDict.insert(fi.absFilePath().utf8(),new QCString(destName)); //printf("insert tagDestination %s->%s\n",fi.fileName().data(),destName.data()); @@ -9441,7 +9130,7 @@ static void copyExtraFiles(QStrList files,const QCString &filesOption,const QCSt //---------------------------------------------------------------------------- -static ParserInterface *getParserForFile(const char *fn) +static OutlineParserInterface &getParserForFile(const char *fn) { QCString fileName=fn; QCString extension; @@ -9456,11 +9145,11 @@ static ParserInterface *getParserForFile(const char *fn) extension = ".no_extension"; } - return Doxygen::parserManager->getParser(extension); + return Doxygen::parserManager->getOutlineParser(extension); } -static void parseFile(ParserInterface *parser, - const std::unique_ptr<Entry> &root,FileDef *fd,const char *fn, +static void parseFile(OutlineParserInterface &parser, + const std::shared_ptr<Entry> &root,FileDef *fd,const char *fn, bool sameTu,QStrList &filesInSameTu) { #if USE_LIBCLANG @@ -9484,12 +9173,12 @@ static void parseFile(ParserInterface *parser, BufStr preBuf(fi.size()+4096); if (Config_getBool(ENABLE_PREPROCESSING) && - parser->needsPreprocessing(extension)) + parser.needsPreprocessing(extension)) { BufStr inBuf(fi.size()+4096); msg("Preprocessing %s...\n",fn); readInputFile(fileName,inBuf); - preprocessFile(fileName,inBuf,preBuf); + Doxygen::preprocessor->processFile(fileName,inBuf,preBuf); } else // no preprocessing { @@ -9513,15 +9202,15 @@ static void parseFile(ParserInterface *parser, fd->getAllIncludeFilesRecursively(filesInSameTu); } - std::unique_ptr<Entry> fileRoot = std::make_unique<Entry>(); + std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>(); // use language parse to parse the file - parser->parseInput(fileName,convBuf.data(),fileRoot,sameTu,filesInSameTu); + parser.parseInput(fileName,convBuf.data(),fileRoot,sameTu,filesInSameTu); fileRoot->setFileDef(fd); root->moveToSubEntryAndKeep(fileRoot); } //! parse the list of input files -static void parseFiles(const std::unique_ptr<Entry> &root) +static void parseFiles(const std::shared_ptr<Entry> &root) { #if USE_LIBCLANG static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); @@ -9547,8 +9236,8 @@ static void parseFiles(const std::unique_ptr<Entry> &root) if (fd->isSource() && !fd->isReference()) // this is a source file { QStrList filesInSameTu; - ParserInterface * parser = getParserForFile(s->data()); - parser->startTranslationUnit(s->data()); + OutlineParserInterface &parser = getParserForFile(s->data()); + parser.startTranslationUnit(s->data()); parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); //printf(" got %d extra files in tu\n",filesInSameTu.count()); @@ -9570,7 +9259,7 @@ static void parseFiles(const std::unique_ptr<Entry> &root) } incFile = filesInSameTu.next(); } - parser->finishTranslationUnit(); + parser.finishTranslationUnit(); g_processedFiles.insert(*s,(void*)0x8); } } @@ -9583,15 +9272,15 @@ static void parseFiles(const std::unique_ptr<Entry> &root) QStrList filesInSameTu; FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig); ASSERT(fd!=0); - ParserInterface * parser = getParserForFile(s->data()); - parser->startTranslationUnit(s->data()); + OutlineParserInterface &parser = getParserForFile(s->data()); + parser.startTranslationUnit(s->data()); parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); - parser->finishTranslationUnit(); + parser.finishTranslationUnit(); g_processedFiles.insert(*s,(void*)0x8); } } } - else // normal pocessing + else // normal processing #endif { StringListIterator it(g_inputFiles); @@ -9602,8 +9291,8 @@ static void parseFiles(const std::unique_ptr<Entry> &root) QStrList filesInSameTu; FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig); ASSERT(fd!=0); - ParserInterface * parser = getParserForFile(s->data()); - parser->startTranslationUnit(s->data()); + OutlineParserInterface &parser = getParserForFile(s->data()); + parser.startTranslationUnit(s->data()); parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); } } @@ -9682,7 +9371,7 @@ static QDict<void> g_pathsVisited(1009); //---------------------------------------------------------------------------- // Read all files matching at least one pattern in 'patList' in the // directory represented by 'fi'. -// The directory is read iff the recusiveFlag is set. +// The directory is read iff the recursiveFlag is set. // The contents of all files is append to the input string int readDir(QFileInfo *fi, @@ -9913,17 +9602,15 @@ void readFormulaRepository(QCString dir, bool cmp) { if ((f=Doxygen::formulaDict->find(formText))==0) { - err("discrepancy between formula repositories! Remove " + term("discrepancy between formula repositories! Remove " "formula.repository and from_* files from output directories."); - exit(1); } QCString formLabel; formLabel.sprintf("\\form#%d",f->getId()); if (formLabel != formName) { - err("discrepancy between formula repositories! Remove " + term("discrepancy between formula repositories! Remove " "formula.repository and from_* files from output directories."); - exit(1); } new_repository++; } @@ -9940,9 +9627,8 @@ void readFormulaRepository(QCString dir, bool cmp) } if (cmp && (current_repository != new_repository)) { - err("size discrepancy between formula repositories! Remove " + term("size discrepancy between formula repositories! Remove " "formula.repository and from_* files from output directories."); - exit(1); } } @@ -10116,29 +9802,31 @@ static void usage(const char *name,const char *versionString) msg("You can use doxygen in a number of ways:\n\n"); msg("1) Use doxygen to generate a template configuration file:\n"); msg(" %s [-s] -g [configName]\n\n",name); - msg(" If - is used for configName doxygen will write to standard output.\n\n"); msg("2) Use doxygen to update an old configuration file:\n"); msg(" %s [-s] -u [configName]\n\n",name); msg("3) Use doxygen to generate documentation using an existing "); msg("configuration file:\n"); msg(" %s [configName]\n\n",name); - msg(" If - is used for configName doxygen will read from standard input.\n\n"); msg("4) Use doxygen to generate a template file controlling the layout of the\n"); msg(" generated documentation:\n"); - msg(" %s -l [layoutFileName.xml]\n\n",name); + msg(" %s -l [layoutFileName]\n\n",name); + msg(" In case layoutFileName is omitted layoutFileName.xml will be used as filename.\n"); + msg(" If - is used for layoutFileName doxygen will write to standard output.\n\n"); msg("5) Use doxygen to generate a template style sheet file for RTF, HTML or Latex.\n"); msg(" RTF: %s -w rtf styleSheetFile\n",name); msg(" HTML: %s -w html headerFile footerFile styleSheetFile [configFile]\n",name); msg(" LaTeX: %s -w latex headerFile footerFile styleSheetFile [configFile]\n\n",name); msg("6) Use doxygen to generate a rtf extensions file\n"); msg(" RTF: %s -e rtf extensionsFile\n\n",name); + msg(" If - is used for extensionsFile doxygen will write to standard output.\n\n"); msg("7) Use doxygen to compare the used configuration file with the template configuration file\n"); msg(" %s -x [configFile]\n\n",name); msg("8) Use doxygen to show a list of built-in emojis.\n"); msg(" %s -f emoji outputFileName\n\n",name); msg(" If - is used for outputFileName doxygen will write to standard output.\n\n"); msg("If -s is specified the comments of the configuration items in the config file will be omitted.\n"); - msg("If configName is omitted 'Doxyfile' will be used as a default.\n\n"); + msg("If configName is omitted 'Doxyfile' will be used as a default.\n"); + msg("If - is used for configFile doxygen will write / read the configuration to /from standard output / input.\n\n"); msg("-v print version string\n"); } @@ -10158,32 +9846,55 @@ static const char *getArg(int argc,char **argv,int &optind) //---------------------------------------------------------------------------- +/** @brief /dev/null outline parser */ +class NullOutlineParser : public OutlineParserInterface +{ + public: + void startTranslationUnit(const char *) {} + void finishTranslationUnit() {} + void parseInput(const char *, const char *,const std::shared_ptr<Entry> &, bool, QStrList &) {} + bool needsPreprocessing(const QCString &) const { return FALSE; } + void parsePrototype(const char *) {} +}; + + + void initDoxygen() { initResources(); - const char *lang = portable_getenv("LC_ALL"); - if (lang) portable_setenv("LANG",lang); + const char *lang = Portable::getenv("LC_ALL"); + if (lang) Portable::setenv("LANG",lang); setlocale(LC_ALL,""); setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8 setlocale(LC_NUMERIC,"C"); - portable_correct_path(); + Portable::correct_path(); Doxygen::runningTime.start(); - initPreprocessor(); - - Doxygen::parserManager = new ParserManager; - Doxygen::parserManager->registerDefaultParser( new FileParser); - Doxygen::parserManager->registerParser("c", new CLanguageScanner); - Doxygen::parserManager->registerParser("python", new PythonLanguageScanner); - Doxygen::parserManager->registerParser("fortran", new FortranLanguageScanner); - Doxygen::parserManager->registerParser("fortranfree", new FortranLanguageScannerFree); - Doxygen::parserManager->registerParser("fortranfixed", new FortranLanguageScannerFixed); - Doxygen::parserManager->registerParser("vhdl", new VHDLLanguageScanner); - Doxygen::parserManager->registerParser("xml", new XMLScanner); - Doxygen::parserManager->registerParser("sql", new SQLScanner); - Doxygen::parserManager->registerParser("tcl", new TclLanguageScanner); - Doxygen::parserManager->registerParser("md", new MarkdownFileParser); + Doxygen::preprocessor = new Preprocessor(); + + Doxygen::parserManager = new ParserManager( std::make_unique<NullOutlineParser>(), + std::make_unique<FileCodeParser>()); + Doxygen::parserManager->registerParser("c", std::make_unique<COutlineParser>(), + std::make_unique<CCodeParser>()); + Doxygen::parserManager->registerParser("python", std::make_unique<PythonOutlineParser>(), + std::make_unique<PythonCodeParser>()); + Doxygen::parserManager->registerParser("fortran", std::make_unique<FortranOutlineParser>(), + std::make_unique<FortranCodeParser>()); + Doxygen::parserManager->registerParser("fortranfree", std::make_unique<FortranOutlineParserFree>(), + std::make_unique<FortranCodeParserFree>()); + Doxygen::parserManager->registerParser("fortranfixed", std::make_unique<FortranOutlineParserFixed>(), + std::make_unique<FortranCodeParserFixed>()); + Doxygen::parserManager->registerParser("vhdl", std::make_unique<VHDLOutlineParser>(), + std::make_unique<VHDLCodeParser>()); + Doxygen::parserManager->registerParser("xml", std::make_unique<NullOutlineParser>(), + std::make_unique<XMLCodeParser>()); + Doxygen::parserManager->registerParser("sql", std::make_unique<NullOutlineParser>(), + std::make_unique<SQLCodeParser>()); + Doxygen::parserManager->registerParser("tcl", std::make_unique<TclOutlineParser>(), + std::make_unique<TclCodeParser>()); + Doxygen::parserManager->registerParser("md", std::make_unique<MarkdownOutlineParser>(), + std::make_unique<FileCodeParser>()); // register any additional parsers here... @@ -10274,11 +9985,10 @@ void cleanUpDoxygen() delete Doxygen::globalScope; delete Doxygen::xrefLists; delete Doxygen::parserManager; - cleanUpPreprocessor(); + delete Doxygen::preprocessor; delete theTranslator; delete g_outputList; Mappers::freeMappers(); - codeFreeScanner(); if (Doxygen::symbolMap) { @@ -10365,9 +10075,14 @@ void readConfiguration(int argc, char **argv) genConfig=TRUE; break; case 'l': - layoutName=getArg(argc,argv,optind); - if (!layoutName) - { layoutName="DoxygenLayout.xml"; } + if (optind+1>=argc) + { + layoutName="DoxygenLayout.xml"; + } + else + { + layoutName=argv[optind+1]; + } writeDefaultLayoutFile(layoutName); cleanUpDoxygen(); exit(0); @@ -10749,7 +10464,7 @@ void adjustConfiguration() while (s) { QFileInfo fi(s); - addSearchDir(fi.absFilePath().utf8()); + Doxygen::preprocessor->addSearchDir(fi.absFilePath().utf8()); s=includePath.next(); } @@ -10775,11 +10490,22 @@ void adjustConfiguration() while (mapping) { QCString mapStr = mapping; - int i; - if ((i=mapStr.find('='))!=-1) + int i=mapStr.find('='); + if (i==-1) + { + mapping = extMaps.next(); + continue; + } + else { - QCString ext=mapStr.left(i).stripWhiteSpace().lower(); - QCString language=mapStr.mid(i+1).stripWhiteSpace().lower(); + QCString ext = mapStr.left(i).stripWhiteSpace().lower(); + QCString language = mapStr.mid(i+1).stripWhiteSpace().lower(); + if (ext.isEmpty() || language.isEmpty()) + { + mapping = extMaps.next(); + continue; + } + if (!updateLanguageMapping(ext,language)) { err("Failed to map file extension '%s' to unsupported language '%s'.\n" @@ -10795,7 +10521,6 @@ void adjustConfiguration() mapping = extMaps.next(); } - // add predefined macro name to a dictionary QStrList &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED); s=expandAsDefinedList.first(); @@ -11189,7 +10914,7 @@ void parseInput() signal(SIGINT, stopDoxygen); #endif - uint pid = portable_pid(); + uint pid = Portable::pid(); Doxygen::objDBFileName.sprintf("doxygen_objdb_%d.tmp",pid); Doxygen::objDBFileName.prepend(outputDirectory+"/"); Doxygen::entryDBFileName.sprintf("doxygen_entrydb_%d.tmp",pid); @@ -11249,18 +10974,18 @@ void parseInput() QCString curFontPath = Config_getString(DOT_FONTPATH); if (curFontPath.isEmpty()) { - portable_getenv("DOTFONTPATH"); + Portable::getenv("DOTFONTPATH"); QCString newFontPath = "."; if (!curFontPath.isEmpty()) { - newFontPath+=portable_pathListSeparator(); + newFontPath+=Portable::pathListSeparator(); newFontPath+=curFontPath; } - portable_setenv("DOTFONTPATH",newFontPath); + Portable::setenv("DOTFONTPATH",newFontPath); } else { - portable_setenv("DOTFONTPATH",curFontPath); + Portable::setenv("DOTFONTPATH",curFontPath); } } @@ -11327,7 +11052,7 @@ void parseInput() * Handle Tag Files * **************************************************************************/ - std::unique_ptr<Entry> root = std::make_unique<Entry>(); + std::shared_ptr<Entry> root = std::make_shared<Entry>(); msg("Reading and parsing tag files\n"); QStrList &tagFileList = Config_getList(TAGFILES); @@ -11342,10 +11067,7 @@ void parseInput() * Parse source files * **************************************************************************/ - if (Config_getBool(BUILTIN_STL_SUPPORT)) - { - addSTLClasses(root); - } + addSTLSupport(root); g_s.begin("Parsing files\n"); parseFiles(root); @@ -11353,8 +11075,6 @@ void parseInput() // we are done with input scanning now, so free up the buffers used by flex // (can be around 4MB) - preFreeScanner(); - scanFreeScanner(); pyscanFreeScanner(); /************************************************************************** @@ -11736,7 +11456,7 @@ void generateOutput() g_s.begin("Generating search indices...\n"); if (searchEngine && !serverBasedSearch && (generateHtml || g_useOutputTemplate)) { - createJavascriptSearchIndex(); + createJavaScriptSearchIndex(); } // generate search indices (need to do this before writing other HTML @@ -11748,14 +11468,13 @@ void generateOutput() QDir searchDir(searchDirName); if (!searchDir.exists() && !searchDir.mkdir(searchDirName)) { - err("Could not create search results directory '%s' $PWD='%s'\n", + term("Could not create search results directory '%s' $PWD='%s'\n", searchDirName.data(),QDir::currentDirPath().data()); - exit(1); } HtmlGenerator::writeSearchData(searchDirName); if (!serverBasedSearch) // client side search index { - writeJavascriptSearchIndex(); + writeJavaScriptSearchIndex(); } } g_s.end(); @@ -11887,7 +11606,7 @@ void generateOutput() { searchDataFile="searchdata.xml"; } - if (!portable_isAbsolutePath(searchDataFile)) + if (!Portable::isAbsolutePath(searchDataFile)) { searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/"); } @@ -11949,12 +11668,13 @@ void generateOutput() g_s.begin("Running html help compiler...\n"); QString oldDir = QDir::currentDirPath(); QDir::setCurrent(Config_getString(HTML_OUTPUT)); - portable_sysTimerStart(); - if (portable_system(Config_getString(HHC_LOCATION), "index.hhp", Debug::isFlagSet(Debug::ExtCmd))!=1) + Portable::setShortDir(); + Portable::sysTimerStart(); + if (Portable::system(Config_getString(HHC_LOCATION), "index.hhp", Debug::isFlagSet(Debug::ExtCmd))!=1) { err("failed to run html help compiler on index.hhp\n"); } - portable_sysTimerStop(); + Portable::sysTimerStop(); QDir::setCurrent(oldDir); g_s.end(); } @@ -11969,12 +11689,12 @@ void generateOutput() QCString const args = QCString().sprintf("%s -o \"%s\"", qhpFileName.data(), qchFileName.data()); QString const oldDir = QDir::currentDirPath(); QDir::setCurrent(Config_getString(HTML_OUTPUT)); - portable_sysTimerStart(); - if (portable_system(Config_getString(QHG_LOCATION), args.data(), FALSE)) + Portable::sysTimerStart(); + if (Portable::system(Config_getString(QHG_LOCATION), args.data(), FALSE)) { err("failed to run qhelpgenerator on index.qhp\n"); } - portable_sysTimerStop(); + Portable::sysTimerStop(); QDir::setCurrent(oldDir); g_s.end(); } @@ -11995,7 +11715,7 @@ void generateOutput() { msg("Total elapsed time: %.3f seconds\n(of which %.3f seconds waiting for external tools to finish)\n", ((double)Doxygen::runningTime.elapsed())/1000.0, - portable_getSysElapsedTime() + Portable::getSysElapsedTime() ); g_s.print(); } @@ -12011,7 +11731,7 @@ void generateOutput() cleanUpDoxygen(); - finializeSearchIndexer(); + finalizeSearchIndexer(); // Doxygen::symbolStorage->close(); QDir thisDir; thisDir.remove(Doxygen::objDBFileName); |