diff options
Diffstat (limited to 'src/definition.cpp')
-rw-r--r-- | src/definition.cpp | 1032 |
1 files changed, 499 insertions, 533 deletions
diff --git a/src/definition.cpp b/src/definition.cpp index 7540eff..2a03ef9 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -16,6 +16,10 @@ */ #include <algorithm> +#include <iterator> +#include <unordered_map> +#include <string> + #include <ctype.h> #include <qregexp.h> #include "md5.h" @@ -44,6 +48,8 @@ #include "dirdef.h" #include "pagedef.h" #include "bufstr.h" +#include "reflist.h" + //----------------------------------------------------------------------------------------- @@ -55,12 +61,14 @@ class DefinitionImpl::IMPL void init(const char *df, const char *n); void setDefFileName(const QCString &df); - SectionDict *sectionDict = 0; // dictionary of all sections, not accessible + Definition *def = 0; - MemberSDict *sourceRefByDict = 0; - MemberSDict *sourceRefsDict = 0; - std::vector<ListItemInfo> xrefListItems; - GroupList *partOfGroups = 0; + SectionRefs sectionRefs; + + std::unordered_map<std::string,const MemberDef *> sourceRefByDict; + std::unordered_map<std::string,const MemberDef *> sourceRefsDict; + RefItemVector xrefListItems; + GroupList partOfGroups; DocInfo *details = 0; // not exported DocInfo *inbodyDocs = 0; // not exported @@ -93,16 +101,12 @@ class DefinitionImpl::IMPL QCString symbolName; int defLine; int defColumn; - Cookie *cookie; + Definition::Cookie *cookie; }; DefinitionImpl::IMPL::~IMPL() { - delete sectionDict; - delete sourceRefByDict; - delete sourceRefsDict; - delete partOfGroups; delete brief; delete details; delete body; @@ -122,8 +126,8 @@ void DefinitionImpl::IMPL::setDefFileName(const QCString &df) void DefinitionImpl::IMPL::init(const char *df, const char *n) { setDefFileName(df); - QCString name = n; - if (name!="<globalScope>") + QCString lname = n; + if (lname!="<globalScope>") { //extractNamespaceName(m_name,m_localName,ns); localName=stripScope(n); @@ -138,11 +142,9 @@ void DefinitionImpl::IMPL::init(const char *df, const char *n) details = 0; body = 0; inbodyDocs = 0; - sourceRefByDict = 0; - sourceRefsDict = 0; - sectionDict = 0, + sourceRefByDict.clear(); + sourceRefsDict.clear(); outerScope = Doxygen::globalScope; - partOfGroups = 0; hidden = FALSE; isArtificial = FALSE; lang = SrcLangExt_Unknown; @@ -160,31 +162,31 @@ void DefinitionImpl::setDefFile(const QCString &df,int defLine,int defCol) static bool matchExcludedSymbols(const char *name) { - static QStrList &exclSyms = Config_getList(EXCLUDE_SYMBOLS); - if (exclSyms.count()==0) return FALSE; // nothing specified - const char *pat = exclSyms.first(); + const StringVector &exclSyms = Config_getList(EXCLUDE_SYMBOLS); + if (exclSyms.empty()) return FALSE; // nothing specified QCString symName = name; - while (pat) + for (const auto &pat : exclSyms) { - QCString pattern = pat; + QCString pattern = pat.c_str(); bool forceStart=FALSE; bool forceEnd=FALSE; - if (pattern.at(0)=='^') + if (pattern.at(0)=='^') pattern=pattern.mid(1),forceStart=TRUE; - if (pattern.at(pattern.length()-1)=='$') + if (pattern.at(pattern.length()-1)=='$') pattern=pattern.left(pattern.length()-1),forceEnd=TRUE; if (pattern.find('*')!=-1) // wildcard mode { QRegExp re(substitute(pattern,"*",".*"),TRUE); - int i,pl; - i = re.match(symName,0,&pl); - //printf(" %d = re.match(%s) pattern=%s\n",i,symName.data(),pattern.data()); + int pl; + int i = re.match(symName,0,&pl); + //printf(" %d = re.match(%s) pattern=%s pl=%d len=%d\n",i,symName.data(),pattern.data(),pl,symName.length()); if (i!=-1) // wildcard match { - int sl=symName.length(); + uint ui=(uint)i; + uint sl=symName.length(); // check if it is a whole word match - if ((i==0 || pattern.at(0)=='*' || (!isId(symName.at(i-1)) && !forceStart)) && - (i+pl==sl || pattern.at(i+pl)=='*' || (!isId(symName.at(i+pl)) && !forceEnd)) + if ((ui==0 || pattern.at(0)=='*' || (!isId(symName.at(ui-1)) && !forceStart)) && + (ui+pl==sl || pattern.at(pattern.length()-1)=='*' || (!isId(symName.at(ui+pl)) && !forceEnd)) ) { //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i); @@ -197,19 +199,19 @@ static bool matchExcludedSymbols(const char *name) int i = symName.find(pattern); if (i!=-1) // we have a match! { - int pl=pattern.length(); - int sl=symName.length(); + uint ui=(uint)i; + uint pl=pattern.length(); + uint sl=symName.length(); // check if it is a whole word match - if ((i==0 || (!isId(symName.at(i-1)) && !forceStart)) && - (i+pl==sl || (!isId(symName.at(i+pl)) && !forceEnd)) + if ((ui==0 || (!isId(symName.at(ui-1)) && !forceStart)) && + (ui+pl==sl || (!isId(symName.at(ui+pl)) && !forceEnd)) ) { //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i); - return TRUE; + return TRUE; } } } - pat = exclSyms.next(); } //printf("--> name=%s: no match\n",name); return FALSE; @@ -221,91 +223,35 @@ static void addToMap(const char *name,Definition *d) QCString symbolName = name; int index=computeQualifiedIndex(symbolName); if (!vhdlOpt && index!=-1) symbolName=symbolName.mid(index+2); - if (!symbolName.isEmpty()) + if (!symbolName.isEmpty()) { - //printf("******* adding symbol '%s' (%p)\n",symbolName.data(),d); - DefinitionIntf *di=Doxygen::symbolMap->find(symbolName); - //printf(" addToMap(%p): looking for symbol %s: %p\n",d,symbolName.data(),di); - if (di==0) // new Symbol - { - //printf(" new symbol!\n"); - Doxygen::symbolMap->insert(symbolName,d); - } - else // existing symbol - { - //printf(" existing symbol: "); - if (di->definitionType()==DefinitionIntf::TypeSymbolList) // already multiple symbols - { - //printf("adding to exiting list\n"); - DefinitionList *dl = (DefinitionList*)di; - dl->append(d); - } - else // going from one to two symbols - { - Doxygen::symbolMap->take(symbolName); - DefinitionList *dl = new DefinitionList; - //printf("replacing symbol by list %p with elements %p and %p\n",dl,di,d); - dl->append((Definition*)di); - dl->append(d); - Doxygen::symbolMap->insert(symbolName,dl); - } - } - - // auto resize if needed - static int sizeIndex=9; - if (Doxygen::symbolMap->size()>SDict_primes[sizeIndex]) - { - Doxygen::symbolMap->resize(SDict_primes[++sizeIndex]); - } + Doxygen::symbolMap.add(symbolName,d); d->_setSymbolName(symbolName); } } -static void removeFromMap(Definition *d) +static void removeFromMap(const char *name,Definition *d) { - QCString symbolName = d->_symbolName(); - if (!symbolName.isEmpty()) - { - //printf("******* removing symbol '%s' (%p)\n",symbolName.data(),d); - DefinitionIntf *di=Doxygen::symbolMap->find(symbolName); - if (di) - { - if (di!=d) // symbolName not unique - { - //printf(" removing from list: %p!\n",di); - DefinitionList *dl = (DefinitionList*)di; - bool b = dl->removeRef(d); - ASSERT(b==TRUE); - if (dl->isEmpty()) - { - Doxygen::symbolMap->take(symbolName); - delete dl; - } - } - else // symbolName unique - { - //printf(" removing symbol %p\n",di); - Doxygen::symbolMap->take(symbolName); - } - } - } + Doxygen::symbolMap.remove(name,d); } -DefinitionImpl::DefinitionImpl(const char *df,int dl,int dc, +DefinitionImpl::DefinitionImpl(Definition *def, + const char *df,int dl,int dc, const char *name,const char *b, const char *d,bool isSymbol) { m_impl = new DefinitionImpl::IMPL; setName(name); + m_impl->def = def; m_impl->defLine = dl; m_impl->defColumn = dc; m_impl->init(df,name); m_impl->isSymbol = isSymbol; - if (isSymbol) addToMap(name,this); + if (isSymbol) addToMap(name,def); _setBriefDescription(b,df,dl); _setDocumentation(d,df,dl,TRUE,FALSE); - if (matchExcludedSymbols(name)) + if (matchExcludedSymbols(name)) { m_impl->hidden = TRUE; } @@ -315,53 +261,10 @@ DefinitionImpl::DefinitionImpl(const DefinitionImpl &d) { m_impl = new DefinitionImpl::IMPL; *m_impl = *d.m_impl; - m_impl->sectionDict = 0; - m_impl->sourceRefByDict = 0; - m_impl->sourceRefsDict = 0; - m_impl->partOfGroups = 0; m_impl->brief = 0; m_impl->details = 0; m_impl->body = 0; m_impl->inbodyDocs = 0; - if (d.m_impl->sectionDict) - { - m_impl->sectionDict = new SectionDict(17); - SDict<SectionInfo>::Iterator it(*d.m_impl->sectionDict); - SectionInfo *si; - for (it.toFirst();(si=it.current());++it) - { - m_impl->sectionDict->append(si->label,si); - } - } - if (d.m_impl->sourceRefByDict) - { - m_impl->sourceRefByDict = new MemberSDict; - MemberSDict::IteratorDict it(*d.m_impl->sourceRefByDict); - MemberDef *md; - for (it.toFirst();(md=it.current());++it) - { - m_impl->sourceRefByDict->append(it.currentKey(),md); - } - } - if (d.m_impl->sourceRefsDict) - { - m_impl->sourceRefsDict = new MemberSDict; - MemberSDict::IteratorDict it(*d.m_impl->sourceRefsDict); - MemberDef *md; - for (it.toFirst();(md=it.current());++it) - { - m_impl->sourceRefsDict->append(it.currentKey(),md); - } - } - if (d.m_impl->partOfGroups) - { - GroupListIterator it(*d.m_impl->partOfGroups); - GroupDef *gd; - for (it.toFirst();(gd=it.current());++it) - { - makePartOfGroup(gd); - } - } if (d.m_impl->brief) { m_impl->brief = new BriefInfo(*d.m_impl->brief); @@ -379,20 +282,17 @@ DefinitionImpl::DefinitionImpl(const DefinitionImpl &d) m_impl->inbodyDocs = new DocInfo(*d.m_impl->inbodyDocs); } - if (m_impl->isSymbol) addToMap(m_impl->name,this); + if (m_impl->isSymbol) addToMap(m_impl->name,m_impl->def); } DefinitionImpl::~DefinitionImpl() { if (m_impl->isSymbol) { - removeFromMap(this); - } - if (m_impl) - { - delete m_impl; - m_impl=0; + removeFromMap(m_impl->symbolName,m_impl->def); } + delete m_impl; + m_impl=0; } void DefinitionImpl::setName(const char *name) @@ -408,10 +308,10 @@ void DefinitionImpl::setId(const char *id) { if (id==0) return; m_impl->id = id; - if (Doxygen::clangUsrMap) + if (Doxygen::clangUsrMap) { //printf("DefinitionImpl::setId '%s'->'%s'\n",id,m_impl->name.data()); - Doxygen::clangUsrMap->insert(id,this); + Doxygen::clangUsrMap->insert(std::make_pair(id,m_impl->def)); } } @@ -426,22 +326,18 @@ void DefinitionImpl::addSectionsToDefinition(const std::vector<const SectionInfo for (const SectionInfo *si : anchorList) { //printf("Add section '%s' to definition '%s'\n", - // si->label.data(),name().data()); - SectionInfo *gsi=Doxygen::sectionDict->find(si->label); + // si->label().data(),name().data()); + SectionManager &sm = SectionManager::instance(); + SectionInfo *gsi=sm.find(si->label()); //printf("===== label=%s gsi=%p\n",si->label.data(),gsi); if (gsi==0) { - gsi = new SectionInfo(*si); - Doxygen::sectionDict->append(si->label,gsi); - } - if (m_impl->sectionDict==0) - { - m_impl->sectionDict = new SectionDict(17); + gsi = sm.add(*si); } - if (m_impl->sectionDict->find(gsi->label)==0) + if (m_impl->sectionRefs.find(gsi->label())==0) { - m_impl->sectionDict->append(gsi->label,gsi); - gsi->definition = this; + m_impl->sectionRefs.add(gsi); + gsi->setDefinition(m_impl->def); } } } @@ -449,16 +345,11 @@ void DefinitionImpl::addSectionsToDefinition(const std::vector<const SectionInfo bool DefinitionImpl::hasSections() const { //printf("DefinitionImpl::hasSections(%s) #sections=%d\n",name().data(), - // m_impl->sectionDict ? m_impl->sectionDict->count() : 0); - if (m_impl->sectionDict==0) return FALSE; - SDict<SectionInfo>::Iterator li(*m_impl->sectionDict); - SectionInfo *si; - for (li.toFirst();(si=li.current());++li) + // m_impl->sectionRefs.size()); + if (m_impl->sectionRefs.empty()) return FALSE; + for (const SectionInfo *si : m_impl->sectionRefs) { - if (si->type==SectionInfo::Section || - si->type==SectionInfo::Subsection || - si->type==SectionInfo::Subsubsection || - si->type==SectionInfo::Paragraph) + if (isSection(si->type())) { return TRUE; } @@ -468,20 +359,17 @@ bool DefinitionImpl::hasSections() const void DefinitionImpl::addSectionsToIndex() { - if (m_impl->sectionDict==0) return; + if (m_impl->sectionRefs.empty()) return; //printf("DefinitionImpl::addSectionsToIndex()\n"); - SDict<SectionInfo>::Iterator li(*m_impl->sectionDict); - SectionInfo *si; int level=1; - for (li.toFirst();(si=li.current());++li) + for (auto it = m_impl->sectionRefs.begin(); it!=m_impl->sectionRefs.end(); ++it) { - if (si->type==SectionInfo::Section || - si->type==SectionInfo::Subsection || - si->type==SectionInfo::Subsubsection || - si->type==SectionInfo::Paragraph) + const SectionInfo *si = *it; + SectionType type = si->type(); + if (isSection(type)) { //printf(" level=%d title=%s\n",level,si->title.data()); - int nextLevel = (int)si->type; + int nextLevel = (int)type; int i; if (nextLevel>level) { @@ -497,16 +385,16 @@ void DefinitionImpl::addSectionsToIndex() Doxygen::indexList->decContentsDepth(); } } - QCString title = si->title; - if (title.isEmpty()) title = si->label; + QCString title = si->title(); + if (title.isEmpty()) title = si->label(); // determine if there is a next level inside this item - ++li; - bool isDir = ((li.current()) ? (int)(li.current()->type > nextLevel):FALSE); - --li; + auto it_next = std::next(it); + bool isDir = (it_next!=m_impl->sectionRefs.end()) ? + ((int)((*it_next)->type()) > nextLevel) : FALSE; Doxygen::indexList->addContentsItem(isDir,title, getReference(), - getOutputFileBase(), - si->label, + m_impl->def->getOutputFileBase(), + si->label(), FALSE, TRUE); level = nextLevel; @@ -521,23 +409,21 @@ void DefinitionImpl::addSectionsToIndex() void DefinitionImpl::writeDocAnchorsToTagFile(FTextStream &tagFile) const { - if (m_impl->sectionDict) + if (!m_impl->sectionRefs.empty()) { - //printf("%s: writeDocAnchorsToTagFile(%d)\n",name().data(),m_impl->sectionDict->count()); - SDict<SectionInfo>::Iterator sdi(*m_impl->sectionDict); - SectionInfo *si; - for (;(si=sdi.current());++sdi) + //printf("%s: writeDocAnchorsToTagFile(%d)\n",name().data(),m_impl->sectionRef.size()); + for (const SectionInfo *si : m_impl->sectionRefs) { - if (!si->generated && si->ref.isEmpty() && !si->label.startsWith("autotoc_md")) + if (!si->generated() && si->ref().isEmpty() && !si->label().startsWith("autotoc_md")) { //printf("write an entry!\n"); - if (definitionType()==TypeMember) tagFile << " "; - tagFile << " <docanchor file=\"" << addHtmlExtensionIfMissing(si->fileName) << "\""; - if (!si->title.isEmpty()) + if (m_impl->def->definitionType()==Definition::TypeMember) tagFile << " "; + tagFile << " <docanchor file=\"" << addHtmlExtensionIfMissing(si->fileName()) << "\""; + if (!si->title().isEmpty()) { - tagFile << " title=\"" << convertToXML(si->title) << "\""; + tagFile << " title=\"" << convertToXML(si->title()) << "\""; } - tagFile << ">" << si->label << "</docanchor>" << endl; + tagFile << ">" << si->label() << "</docanchor>" << endl; } } } @@ -619,14 +505,14 @@ void DefinitionImpl::setDocumentation(const char *d,const char *docFile,int docL #define uni_isupper(c) (QChar(c).category()==QChar::Letter_Uppercase) -// do a UTF-8 aware search for the last real character and return TRUE +// do a UTF-8 aware search for the last real character and return TRUE // if that is a multibyte one. static bool lastCharIsMultibyte(const QCString &s) { - int l = s.length(); + uint l = s.length(); int p = 0; int pp = -1; - while ((p=nextUtf8CharPosition(s,l,p))<l) pp=p; + while ((p=nextUtf8CharPosition(s,l,(uint)p))<(int)l) pp=p; if (pp==-1 || ((uchar)s[pp])<0x80) return FALSE; return TRUE; } @@ -634,21 +520,23 @@ static bool lastCharIsMultibyte(const QCString &s) void DefinitionImpl::_setBriefDescription(const char *b,const char *briefFile,int briefLine) { static QCString outputLanguage = Config_getEnum(OUTPUT_LANGUAGE); - static bool needsDot = outputLanguage!="Japanese" && + static bool needsDot = outputLanguage!="Japanese" && outputLanguage!="Chinese" && outputLanguage!="Korean"; QCString brief = b; brief = brief.stripWhiteSpace(); + brief = stripLeadingAndTrailingEmptyLines(brief,briefLine); + brief = brief.stripWhiteSpace(); if (brief.isEmpty()) return; - int bl = brief.length(); + uint bl = brief.length(); if (bl>0 && needsDot) // add punctuation if needed { int c = brief.at(bl-1); switch(c) { case '.': case '!': case '?': case '>': case ':': case ')': break; - default: - if (uni_isupper(brief.at(0)) && !lastCharIsMultibyte(brief)) brief+='.'; + default: + if (uni_isupper(brief.at(0)) && !lastCharIsMultibyte(brief)) brief+='.'; break; } } @@ -686,8 +574,8 @@ void DefinitionImpl::_setBriefDescription(const char *b,const char *briefFile,in } } -void DefinitionImpl::setBriefDescription(const char *b,const char *briefFile,int briefLine) -{ +void DefinitionImpl::setBriefDescription(const char *b,const char *briefFile,int briefLine) +{ if (b==0) return; _setBriefDescription(b,briefFile,briefLine); } @@ -721,14 +609,14 @@ void DefinitionImpl::setInbodyDocumentation(const char *d,const char *inbodyFile struct FilterCacheItem { portable_off_t filePos; - uint fileSize; + size_t fileSize; }; /*! Cache for storing the result of filtering a file */ class FilterCache { public: - FilterCache() : m_endPos(0) { m_cache.setAutoDelete(TRUE); } + FilterCache() : m_endPos(0) { } bool getFileContents(const QCString &fileName,BufStr &str) { static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); @@ -737,30 +625,31 @@ class FilterCache FILE *f=0; const int blockSize = 4096; char buf[blockSize]; - FilterCacheItem *item=0; - if (usePipe && (item = m_cache.find(fileName))) // cache hit: reuse stored result + auto it = m_cache.find(fileName.str()); + if (usePipe && it!=m_cache.end()) // cache hit: reuse stored result { + auto item = it->second; //printf("getFileContents(%s): cache hit\n",qPrint(fileName)); // file already processed, get the results after filtering from the tmp file Debug::print(Debug::FilterOutput,0,"Reusing filter result for %s from %s at offset=%d size=%d\n", - qPrint(fileName),qPrint(Doxygen::filterDBFileName),(int)item->filePos,(int)item->fileSize); + qPrint(fileName),qPrint(Doxygen::filterDBFileName),(int)item.filePos,(int)item.fileSize); f = Portable::fopen(Doxygen::filterDBFileName,"rb"); if (f) { bool success=TRUE; - str.resize(item->fileSize+1); - if (Portable::fseek(f,item->filePos,SEEK_SET)==-1) + str.resize(static_cast<uint>(item.fileSize+1)); + if (Portable::fseek(f,item.filePos,SEEK_SET)==-1) { - err("Failed to seek to position %d in filter database file %s\n",(int)item->filePos,qPrint(Doxygen::filterDBFileName)); + err("Failed to seek to position %d in filter database file %s\n",(int)item.filePos,qPrint(Doxygen::filterDBFileName)); success=FALSE; } if (success) { - int numBytes = fread(str.data(),1,item->fileSize,f); - if (numBytes!=item->fileSize) + size_t numBytes = fread(str.data(),1,item.fileSize,f); + if (numBytes!=item.fileSize) { err("Failed to read %d bytes from position %d in filter database file %s: got %d bytes\n", - (int)item->fileSize,(int)item->filePos,qPrint(Doxygen::filterDBFileName),numBytes); + (int)item.fileSize,(int)item.filePos,qPrint(Doxygen::filterDBFileName),(int)numBytes); success=FALSE; } } @@ -782,43 +671,41 @@ class FilterCache Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd)); f = Portable::popen(cmd,"r"); FILE *bf = Portable::fopen(Doxygen::filterDBFileName,"a+b"); - FilterCacheItem *item = new FilterCacheItem; - item->filePos = m_endPos; + FilterCacheItem item; + item.filePos = m_endPos; if (bf==0) { // handle error err("Error opening filter database file %s\n",qPrint(Doxygen::filterDBFileName)); str.addChar('\0'); - delete item; Portable::pclose(f); return FALSE; } // append the filtered output to the database file - int size=0; + size_t size=0; while (!feof(f)) { - int bytesRead = fread(buf,1,blockSize,f); - int bytesWritten = fwrite(buf,1,bytesRead,bf); + size_t bytesRead = fread(buf,1,blockSize,f); + size_t bytesWritten = fwrite(buf,1,bytesRead,bf); if (bytesRead!=bytesWritten) { // handle error err("Failed to write to filter database %s. Wrote %d out of %d bytes\n", - qPrint(Doxygen::filterDBFileName),bytesWritten,bytesRead); + qPrint(Doxygen::filterDBFileName),(int)bytesWritten,(int)bytesRead); str.addChar('\0'); - delete item; Portable::pclose(f); fclose(bf); return FALSE; } size+=bytesWritten; - str.addArray(buf,bytesWritten); + str.addArray(buf,static_cast<uint>(bytesWritten)); } str.addChar('\0'); - item->fileSize = size; + item.fileSize = size; // add location entry to the dictionary - m_cache.append(fileName,item); + m_cache.insert(std::make_pair(fileName.str(),item)); Debug::print(Debug::FilterOutput,0,"Storing new filter result for %s in %s at offset=%d size=%d\n", - qPrint(fileName),qPrint(Doxygen::filterDBFileName),(int)item->filePos,(int)item->fileSize); + qPrint(fileName),qPrint(Doxygen::filterDBFileName),(int)item.filePos,(int)item.fileSize); // update end of file position m_endPos += size; Portable::pclose(f); @@ -831,8 +718,8 @@ class FilterCache f = Portable::fopen(fileName,"r"); while (!feof(f)) { - int bytesRead = fread(buf,1,blockSize,f); - str.addArray(buf,bytesRead); + size_t bytesRead = fread(buf,1,blockSize,f); + str.addArray(buf,static_cast<uint>(bytesRead)); } str.addChar('\0'); fclose(f); @@ -840,7 +727,7 @@ class FilterCache return TRUE; } private: - SDict<FilterCacheItem> m_cache; + std::unordered_map<std::string,FilterCacheItem> m_cache; portable_off_t m_endPos; }; @@ -849,7 +736,7 @@ static FilterCache g_filterCache; //----------------------------------------- -/*! Reads a fragment of code from file \a fileName starting at +/*! Reads a fragment of code from file \a fileName starting at * line \a startLine and ending at line \a endLine (inclusive). The fragment is * stored in \a result. If FALSE is returned the code fragment could not be * found. @@ -874,14 +761,13 @@ bool readCodeFragment(const char *fileName, g_filterCache.getFileContents(fileName,str); bool found = lang==SrcLangExt_VHDL || - lang==SrcLangExt_Tcl || lang==SrcLangExt_Python || lang==SrcLangExt_Fortran; - // for VHDL, TCL, Python, and Fortran no bracket search is possible + // for VHDL, Python, and Fortran no bracket search is possible char *p=str.data(); if (p) { - int c=0; + char c=0; int col=0; int lineNr=1; // skip until the startLine has reached @@ -984,7 +870,7 @@ bool readCodeFragment(const char *fileName, int braceIndex = result.findRev('}'); if (braceIndex > newLineIndex) { - result.truncate(braceIndex+1); + result.truncate((uint)braceIndex+1); } endLine=lineNr-1; } @@ -1002,11 +888,11 @@ bool readCodeFragment(const char *fileName, } QCString DefinitionImpl::getSourceFileBase() const -{ - ASSERT(definitionType()!=Definition::TypeFile); // file overloads this method +{ + ASSERT(m_impl->def->definitionType()!=Definition::TypeFile); // file overloads this method QCString fn; static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); - if (sourceBrowser && + if (sourceBrowser && m_impl->body && m_impl->body->startLine!=-1 && m_impl->body->fileDef) { fn = m_impl->body->fileDef->getSourceFileBase(); @@ -1023,11 +909,11 @@ QCString DefinitionImpl::getSourceAnchor() const { if (Htags::useHtags) { - qsnprintf(anchorStr,maxAnchorStrLen,"L%d",m_impl->body->startLine); + qsnprintf(anchorStr,maxAnchorStrLen,"L%d",m_impl->body->defLine); } else { - qsnprintf(anchorStr,maxAnchorStrLen,"l%05d",m_impl->body->startLine); + qsnprintf(anchorStr,maxAnchorStrLen,"l%05d",m_impl->body->defLine); } } return anchorStr; @@ -1050,15 +936,15 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const if (lineMarkerPos!=-1 && fileMarkerPos!=-1) // should always pass this. { QCString lineStr; - lineStr.sprintf("%d",m_impl->body->startLine); + lineStr.sprintf("%d",m_impl->body->defLine); QCString anchorStr = getSourceAnchor(); ol.startParagraph("definition"); if (lineMarkerPos<fileMarkerPos) // line marker before file marker { // write text left from linePos marker - ol.parseText(refText.left(lineMarkerPos)); + ol.parseText(refText.left(lineMarkerPos)); ol.pushGeneratorState(); - ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Man); if (!latexSourceCode) { ol.disable(OutputGenerator::Latex); @@ -1075,7 +961,7 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const ol.writeObjectLink(0,fn,anchorStr,lineStr); ol.enableAll(); ol.disable(OutputGenerator::Html); - if (latexSourceCode) + if (latexSourceCode) { ol.disable(OutputGenerator::Latex); } @@ -1090,13 +976,13 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const // write normal text (Man, Latex optionally, RTF optionally) ol.docify(lineStr); ol.popGeneratorState(); - + // write text between markers ol.parseText(refText.mid(lineMarkerPos+2, fileMarkerPos-lineMarkerPos-2)); ol.pushGeneratorState(); - ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Man); if (!latexSourceCode) { ol.disable(OutputGenerator::Latex); @@ -1113,7 +999,7 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const ol.writeObjectLink(0,fn,0,m_impl->body->fileDef->name()); ol.enableAll(); ol.disable(OutputGenerator::Html); - if (latexSourceCode) + if (latexSourceCode) { ol.disable(OutputGenerator::Latex); } @@ -1128,17 +1014,16 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const // write normal text (Man, Latex optionally, RTF optionally) ol.docify(m_impl->body->fileDef->name()); ol.popGeneratorState(); - + // write text right from file marker - ol.parseText(refText.right( - refText.length()-fileMarkerPos-2)); + ol.parseText(refText.right(refText.length()-(uint)fileMarkerPos-2)); } else // file marker before line marker { // write text left from file marker - ol.parseText(refText.left(fileMarkerPos)); + ol.parseText(refText.left(fileMarkerPos)); ol.pushGeneratorState(); - ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Man); if (!latexSourceCode) { ol.disable(OutputGenerator::Latex); @@ -1155,7 +1040,7 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const ol.writeObjectLink(0,fn,0,m_impl->body->fileDef->name()); ol.enableAll(); ol.disable(OutputGenerator::Html); - if (latexSourceCode) + if (latexSourceCode) { ol.disable(OutputGenerator::Latex); } @@ -1170,14 +1055,14 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const // write normal text (RTF/Latex/Man only) ol.docify(m_impl->body->fileDef->name()); ol.popGeneratorState(); - + // write text between markers ol.parseText(refText.mid(fileMarkerPos+2, - lineMarkerPos-fileMarkerPos-2)); + lineMarkerPos-fileMarkerPos-2)); ol.pushGeneratorState(); - ol.disable(OutputGenerator::Man); - ol.disableAllBut(OutputGenerator::Html); + ol.disable(OutputGenerator::Man); + ol.disableAllBut(OutputGenerator::Html); if (latexSourceCode) { ol.enable(OutputGenerator::Latex); @@ -1194,7 +1079,7 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const ol.writeObjectLink(0,fn,anchorStr,lineStr); ol.enableAll(); ol.disable(OutputGenerator::Html); - if (latexSourceCode) + if (latexSourceCode) { ol.disable(OutputGenerator::Latex); } @@ -1211,8 +1096,7 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const ol.popGeneratorState(); // write text right from linePos marker - ol.parseText(refText.right( - refText.length()-lineMarkerPos-2)); + ol.parseText(refText.right(refText.length()-(uint)lineMarkerPos-2)); } ol.endParagraph(); } @@ -1224,18 +1108,19 @@ void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const ol.popGeneratorState(); } -void DefinitionImpl::setBodySegment(int bls,int ble) +void DefinitionImpl::setBodySegment(int defLine, int bls,int ble) { //printf("setBodySegment(%d,%d) for %s\n",bls,ble,name().data()); if (m_impl->body==0) m_impl->body = new BodyInfo; - m_impl->body->startLine=bls; - m_impl->body->endLine=ble; + m_impl->body->defLine = defLine; + m_impl->body->startLine = bls; + m_impl->body->endLine = ble; } -void DefinitionImpl::setBodyDef(FileDef *fd) +void DefinitionImpl::setBodyDef(FileDef *fd) { if (m_impl->body==0) m_impl->body = new BodyInfo; - m_impl->body->fileDef=fd; + m_impl->body->fileDef=fd; } bool DefinitionImpl::hasSources() const @@ -1262,63 +1147,84 @@ void DefinitionImpl::writeInlineCode(OutputList &ol,const char *scopeName) const { //printf("Adding code fragment '%s' ext='%s'\n", // codeFragment.data(),m_impl->defFileExt.data()); - CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(m_impl->defFileExt); - intf.resetCodeParserState(); + auto intf = Doxygen::parserManager->getCodeParser(m_impl->defFileExt); + intf->resetCodeParserState(); //printf("Read:\n'%s'\n\n",codeFragment.data()); const MemberDef *thisMd = 0; - if (definitionType()==TypeMember) thisMd = dynamic_cast <const MemberDef*>(this); - - ol.startCodeFragment(); - intf.parseCode(ol, // codeOutIntf - scopeName, // scope - codeFragment, // input - m_impl->lang, // lang - FALSE, // isExample - 0, // exampleName - m_impl->body->fileDef, // fileDef - actualStart, // startLine - actualEnd, // endLine - TRUE, // inlineFragment - thisMd, // memberDef - TRUE // show line numbers - ); - ol.endCodeFragment(); + if (m_impl->def->definitionType()==Definition::TypeMember) + { + thisMd = toMemberDef(m_impl->def); + } + + ol.startCodeFragment("DoxyCode"); + intf->parseCode(ol, // codeOutIntf + scopeName, // scope + codeFragment, // input + m_impl->lang, // lang + FALSE, // isExample + 0, // exampleName + m_impl->body->fileDef, // fileDef + actualStart, // startLine + actualEnd, // endLine + TRUE, // inlineFragment + thisMd, // memberDef + TRUE // show line numbers + ); + ol.endCodeFragment("DoxyCode"); } } ol.popGeneratorState(); } -/*! Write a reference to the source code fragments in which this +static inline std::vector<const MemberDef*> refMapToVector(const std::unordered_map<std::string,const MemberDef *> &map) +{ + // convert map to a vector of values + std::vector<const MemberDef *> result; + std::transform(map.begin(),map.end(), // iterate over map + std::back_inserter(result), // add results to vector + [](const auto &item) + { return item.second; } // extract value to add from map Key,Value pair + ); + // and sort it + std::sort(result.begin(),result.end(), + [](const auto &m1,const auto &m2) { return genericCompareMembers(m1,m2)<0; }); + return result; +} + +/*! Write a reference to the source code fragments in which this * definition is used. */ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, - const QCString &text,MemberSDict *members,bool /*funcOnly*/) const + const QCString &text,const std::unordered_map<std::string,const MemberDef *> &membersMap, + bool /*funcOnly*/) const { - static bool latexSourceCode = Config_getBool(LATEX_SOURCE_CODE); + static bool latexSourceCode = Config_getBool(LATEX_SOURCE_CODE); static bool docbookSourceCode = Config_getBool(DOCBOOK_PROGRAMLISTING); static bool rtfSourceCode = Config_getBool(RTF_SOURCE_CODE); static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); static bool refLinkSource = Config_getBool(REFERENCES_LINK_SOURCE); ol.pushGeneratorState(); - if (members) + if (!membersMap.empty()) { - members->sort(); + auto members = refMapToVector(membersMap); ol.startParagraph("reference"); ol.parseText(text); ol.docify(" "); - QCString ldefLine=theTranslator->trWriteList(members->count()); + QCString ldefLine=theTranslator->trWriteList((int)members.size()); QRegExp marker("@[0-9]+"); - int index=0,newIndex,matchLen; + uint index=0; + int matchLen; + int newIndex; // now replace all markers in inheritLine with links to the classes while ((newIndex=marker.match(ldefLine,index,&matchLen))!=-1) { bool ok; - ol.parseText(ldefLine.mid(index,newIndex-index)); + ol.parseText(ldefLine.mid(index,(uint)newIndex-index)); uint entryIndex = ldefLine.mid(newIndex+1,matchLen-1).toUInt(&ok); - MemberDef *md=members->at(entryIndex); + const MemberDef *md=members.at(entryIndex); if (ok && md) { QCString scope=md->getScopeString(); @@ -1329,27 +1235,27 @@ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, name.prepend(scope+getLanguageSpecificSeparator(m_impl->lang)); } if (!md->isObjCMethod() && - (md->isFunction() || md->isSlot() || + (md->isFunction() || md->isSlot() || md->isPrototype() || md->isSignal() ) - ) + ) { name+="()"; } //DefinitionImpl *d = md->getOutputFileBase(); //if (d==Doxygen::globalScope) d=md->getBodyDef(); if (sourceBrowser && - !(md->isLinkable() && !refLinkSource) && - md->getStartBodyLine()!=-1 && + !(md->isLinkable() && !refLinkSource) && + md->getStartBodyLine()!=-1 && md->getBodyDef() ) { - //printf("md->getBodyDef()=%p global=%p\n",md->getBodyDef(),Doxygen::globalScope); + //printf("md->getBodyDef()=%p global=%p\n",md->getBodyDef(),Doxygen::globalScope); // for HTML write a real link ol.pushGeneratorState(); //ol.disableAllBut(OutputGenerator::Html); - ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Man); if (!latexSourceCode) { ol.disable(OutputGenerator::Latex); @@ -1391,8 +1297,8 @@ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, { // for HTML write a real link ol.pushGeneratorState(); - //ol.disableAllBut(OutputGenerator::Html); - ol.disable(OutputGenerator::Man); + //ol.disableAllBut(OutputGenerator::Html); + ol.disable(OutputGenerator::Man); if (!latexSourceCode) { ol.disable(OutputGenerator::Latex); @@ -1434,8 +1340,8 @@ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, ol.docify(name); } } - index=newIndex+matchLen; - } + index=(uint)newIndex+matchLen; + } ol.parseText(ldefLine.right(ldefLine.length()-index)); ol.writeString("."); ol.endParagraph(); @@ -1454,15 +1360,15 @@ void DefinitionImpl::writeSourceRefs(OutputList &ol,const char *scopeName) const } bool DefinitionImpl::hasDocumentation() const -{ - static bool extractAll = Config_getBool(EXTRACT_ALL); +{ + static bool extractAll = Config_getBool(EXTRACT_ALL); //static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); - bool hasDocs = + bool hasDocs = (m_impl->details && !m_impl->details->doc.isEmpty()) || // has detailed docs (m_impl->brief && !m_impl->brief->doc.isEmpty()) || // has brief description (m_impl->inbodyDocs && !m_impl->inbodyDocs->doc.isEmpty()) || // has inbody docs extractAll //|| // extract everything - // (sourceBrowser && m_impl->body && + // (sourceBrowser && m_impl->body && // m_impl->body->startLine!=-1 && m_impl->body->fileDef) ; // link to definition return hasDocs; @@ -1470,7 +1376,7 @@ bool DefinitionImpl::hasDocumentation() const bool DefinitionImpl::hasUserDocumentation() const { - bool hasDocs = + bool hasDocs = (m_impl->details && !m_impl->details->doc.isEmpty()) || (m_impl->brief && !m_impl->brief->doc.isEmpty()) || (m_impl->inbodyDocs && !m_impl->inbodyDocs->doc.isEmpty()); @@ -1490,14 +1396,7 @@ void DefinitionImpl::addSourceReferencedBy(const MemberDef *md) name.prepend(scope+"::"); } - if (m_impl->sourceRefByDict==0) - { - m_impl->sourceRefByDict = new MemberSDict; - } - if (m_impl->sourceRefByDict->find(name)==0) - { - m_impl->sourceRefByDict->append(name,md); - } + m_impl->sourceRefByDict.insert({name.str(),md}); } } @@ -1513,18 +1412,11 @@ void DefinitionImpl::addSourceReferences(const MemberDef *md) name.prepend(scope+"::"); } - if (m_impl->sourceRefsDict==0) - { - m_impl->sourceRefsDict = new MemberSDict; - } - if (m_impl->sourceRefsDict->find(name)==0) - { - m_impl->sourceRefsDict->append(name,md); - } + m_impl->sourceRefsDict.insert({name.str(),md}); } } -Definition *DefinitionImpl::findInnerCompound(const char *) const +const Definition *DefinitionImpl::findInnerCompound(const char *) const { return 0; } @@ -1538,24 +1430,24 @@ QCString DefinitionImpl::qualifiedName() const { //static int count=0; //count++; - if (!m_impl->qualifiedName.isEmpty()) + if (!m_impl->qualifiedName.isEmpty()) { //count--; return m_impl->qualifiedName; } - + //printf("start %s::qualifiedName() localName=%s\n",name().data(),m_impl->localName.data()); - if (m_impl->outerScope==0) + if (m_impl->outerScope==0) { - if (m_impl->localName=="<globalScope>") + if (m_impl->localName=="<globalScope>") { //count--; return ""; } - else + else { //count--; - return m_impl->localName; + return m_impl->localName; } } @@ -1598,13 +1490,12 @@ QCString DefinitionImpl::localName() const return m_impl->localName; } -void DefinitionImpl::makePartOfGroup(GroupDef *gd) +void DefinitionImpl::makePartOfGroup(const GroupDef *gd) { - if (m_impl->partOfGroups==0) m_impl->partOfGroups = new GroupList; - m_impl->partOfGroups->append(gd); + m_impl->partOfGroups.push_back(gd); } -void DefinitionImpl::setRefItems(const std::vector<ListItemInfo> &sli) +void DefinitionImpl::setRefItems(const RefItemVector &sli) { m_impl->xrefListItems.insert(m_impl->xrefListItems.end(), sli.cbegin(), sli.cend()); } @@ -1620,31 +1511,34 @@ void DefinitionImpl::mergeRefItems(Definition *d) // sort results on itemId std::sort(m_impl->xrefListItems.begin(),m_impl->xrefListItems.end(), - [](const ListItemInfo &left,const ListItemInfo &right) - { return left.itemId<right.itemId || - (left.itemId==right.itemId && qstrcmp(left.type,right.type)<0); + [](RefItem *left,RefItem *right) + { return left->id() <right->id() || + (left->id()==right->id() && + qstrcmp(left->list()->listName(),right->list()->listName())<0); }); // filter out duplicates auto last = std::unique(m_impl->xrefListItems.begin(),m_impl->xrefListItems.end(), - [](const ListItemInfo &left,const ListItemInfo &right) - { return left.itemId==right.itemId && left.type==right.type; }); + [](const RefItem *left,const RefItem *right) + { return left->id()==right->id() && + left->list()->listName()==right->list()->listName(); + }); m_impl->xrefListItems.erase(last, m_impl->xrefListItems.end()); } int DefinitionImpl::_getXRefListId(const char *listName) const { - for (const ListItemInfo &lii : m_impl->xrefListItems) + for (const RefItem *item : m_impl->xrefListItems) { - if (lii.type==listName) + if (item->list()->listName()==listName) { - return lii.itemId; + return item->id(); } } return -1; } -const std::vector<ListItemInfo> &DefinitionImpl::xrefListItems() const +const RefItemVector &DefinitionImpl::xrefListItems() const { return m_impl->xrefListItems; } @@ -1656,16 +1550,18 @@ QCString DefinitionImpl::pathFragment() const { result = m_impl->outerScope->pathFragment(); } - if (isLinkable()) + if (m_impl->def->isLinkable()) { if (!result.isEmpty()) result+="/"; - if (definitionType()==Definition::TypeGroup && (dynamic_cast <const GroupDef*>(this))->groupTitle()) + if (m_impl->def->definitionType()==Definition::TypeGroup && + (toGroupDef(m_impl->def))->groupTitle()) { - result+=(dynamic_cast <const GroupDef*>(this))->groupTitle(); + result+=(toGroupDef(m_impl->def))->groupTitle(); } - else if (definitionType()==Definition::TypePage && (dynamic_cast <const PageDef*>(this))->hasTitle()) + else if (m_impl->def->definitionType()==Definition::TypePage && + (toPageDef(m_impl->def))->hasTitle()) { - result+=(dynamic_cast <const PageDef*>(this))->title(); + result+=(toPageDef(m_impl->def))->title(); } else { @@ -1682,7 +1578,7 @@ QCString DefinitionImpl::pathFragment() const //---------------------------------------------------------------------------------------- // TODO: move to htmlgen -/*! Returns the string used in the footer for $navpath when +/*! Returns the string used in the footer for $navpath when * GENERATE_TREEVIEW is enabled */ QCString DefinitionImpl::navigationPathAsString() const @@ -1694,37 +1590,37 @@ QCString DefinitionImpl::navigationPathAsString() const { result+=outerScope->navigationPathAsString(); } - else if (definitionType()==Definition::TypeFile && (dynamic_cast<const FileDef*>(this))->getDirDef()) + else if (m_impl->def->definitionType()==Definition::TypeFile && (toFileDef(m_impl->def))->getDirDef()) { - result+=(dynamic_cast<const FileDef*>(this))->getDirDef()->navigationPathAsString(); + result+=(toFileDef(m_impl->def))->getDirDef()->navigationPathAsString(); } result+="<li class=\"navelem\">"; - if (isLinkable()) + if (m_impl->def->isLinkable()) { - if (definitionType()==Definition::TypeGroup && (dynamic_cast<const GroupDef*>(this))->groupTitle()) + if (m_impl->def->definitionType()==Definition::TypeGroup && (toGroupDef(m_impl->def))->groupTitle()) { - result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+ - convertToHtml((dynamic_cast<const GroupDef*>(this))->groupTitle())+"</a>"; + result+="<a class=\"el\" href=\"$relpath^"+m_impl->def->getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+ + convertToHtml((toGroupDef(m_impl->def))->groupTitle())+"</a>"; } - else if (definitionType()==Definition::TypePage && (dynamic_cast<const PageDef*>(this))->hasTitle()) + else if (m_impl->def->definitionType()==Definition::TypePage && (toPageDef(m_impl->def))->hasTitle()) { - result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+ - convertToHtml((dynamic_cast<const PageDef*>(this))->title())+"</a>"; + result+="<a class=\"el\" href=\"$relpath^"+m_impl->def->getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+ + convertToHtml((toPageDef(m_impl->def))->title())+"</a>"; } - else if (definitionType()==Definition::TypeClass) + else if (m_impl->def->definitionType()==Definition::TypeClass) { QCString name = locName; if (name.right(2)=="-p" /*|| name.right(2)=="-g"*/) { name = name.left(name.length()-2); } - result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension; - if (!anchor().isEmpty()) result+="#"+anchor(); + result+="<a class=\"el\" href=\"$relpath^"+m_impl->def->getOutputFileBase()+Doxygen::htmlFileExtension; + if (!m_impl->def->anchor().isEmpty()) result+="#"+m_impl->def->anchor(); result+="\">"+convertToHtml(name)+"</a>"; } else { - result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+ + result+="<a class=\"el\" href=\"$relpath^"+m_impl->def->getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+ convertToHtml(locName)+"</a>"; } } @@ -1756,8 +1652,7 @@ void DefinitionImpl::writeNavigationPath(OutputList &ol) const // TODO: move to htmlgen void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const { - SectionDict *sectionDict = m_impl->sectionDict; - if (sectionDict==0) return; + if (m_impl->sectionRefs.empty()) return; if (localToc.isHtmlEnabled()) { int maxLevel = localToc.htmlLevel(); @@ -1768,21 +1663,17 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const ol.writeString(theTranslator->trRTFTableOfContents()); ol.writeString("</h3>\n"); ol.writeString("<ul>"); - SDict<SectionInfo>::Iterator li(*sectionDict); - SectionInfo *si; int level=1,l; char cs[2]; cs[1]='\0'; - bool inLi[5]={ FALSE, FALSE, FALSE, FALSE, FALSE }; - for (li.toFirst();(si=li.current());++li) + BoolVector inLi(maxLevel+1,false); + for (const SectionInfo *si : m_impl->sectionRefs) { - if (si->type==SectionInfo::Section || - si->type==SectionInfo::Subsection || - si->type==SectionInfo::Subsubsection || - si->type==SectionInfo::Paragraph) + SectionType type = si->type(); + if (isSection(type)) { //printf(" level=%d title=%s\n",level,si->title.data()); - int nextLevel = (int)si->type; + int nextLevel = (int)type; if (nextLevel>level) { for (l=level;l<nextLevel;l++) @@ -1795,28 +1686,39 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const for (l=level;l>nextLevel;l--) { if (l <= maxLevel && inLi[l]) ol.writeString("</li>\n"); - inLi[l]=FALSE; + inLi[l]=false; if (l <= maxLevel) ol.writeString("</ul>\n"); } } - cs[0]='0'+nextLevel; - if (nextLevel <= maxLevel && inLi[nextLevel]) ol.writeString("</li>\n"); - QCString titleDoc = convertToHtml(si->title); - if (nextLevel <= maxLevel) ol.writeString("<li class=\"level"+QCString(cs)+"\"><a href=\"#"+si->label+"\">"+(si->title.isEmpty()?si->label:titleDoc)+"</a>"); - inLi[nextLevel]=TRUE; + cs[0]=(char)('0'+nextLevel); + if (nextLevel <= maxLevel && inLi[nextLevel]) + { + ol.writeString("</li>\n"); + } + QCString titleDoc = convertToHtml(si->title()); + if (nextLevel <= maxLevel) + { + ol.writeString("<li class=\"level"+QCString(cs)+"\">" + "<a href=\"#"+si->label()+"\">"+ + (si->title().isEmpty()?si->label():titleDoc)+"</a>"); + } + inLi[nextLevel]=true; level = nextLevel; } } if (level > maxLevel) level = maxLevel; while (level>1 && level <= maxLevel) { - if (inLi[level]) ol.writeString("</li>\n"); + if (inLi[level]) + { + ol.writeString("</li>\n"); + } inLi[level]=FALSE; ol.writeString("</ul>\n"); level--; } if (level <= maxLevel && inLi[level]) ol.writeString("</li>\n"); - inLi[level]=FALSE; + inLi[level]=false; ol.writeString("</ul>\n"); ol.writeString("</div>\n"); ol.popGeneratorState(); @@ -1828,21 +1730,16 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const ol.disableAllBut(OutputGenerator::Docbook); ol.writeString(" <toc>\n"); ol.writeString(" <title>" + theTranslator->trRTFTableOfContents() + "</title>\n"); - SectionDict *sectionDict = getSectionDict(); - SDict<SectionInfo>::Iterator li(*sectionDict); - SectionInfo *si; int level=1,l; - bool inLi[5]={ FALSE, FALSE, FALSE, FALSE, FALSE }; int maxLevel = localToc.docbookLevel(); - for (li.toFirst();(si=li.current());++li) + BoolVector inLi(maxLevel+1,false); + for (const SectionInfo *si : m_impl->sectionRefs) { - if (si->type==SectionInfo::Section || - si->type==SectionInfo::Subsection || - si->type==SectionInfo::Subsubsection || - si->type==SectionInfo::Paragraph) + SectionType type = si->type(); + if (isSection(type)) { //printf(" level=%d title=%s\n",level,si->title.data()); - int nextLevel = (int)si->type; + int nextLevel = (int)type; if (nextLevel>level) { for (l=level;l<nextLevel;l++) @@ -1860,8 +1757,10 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const } if (nextLevel <= maxLevel) { - QCString titleDoc = convertToDocBook(si->title); - ol.writeString(" <tocentry>" + (si->title.isEmpty()?si->label:titleDoc) + "</tocentry>\n"); + QCString titleDoc = convertToDocBook(si->title()); + ol.writeString(" <tocentry>" + + (si->title().isEmpty()?si->label():titleDoc) + + "</tocentry>\n"); } inLi[nextLevel]=TRUE; level = nextLevel; @@ -1894,31 +1793,31 @@ void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const //---------------------------------------------------------------------------------------- -SectionDict * DefinitionImpl::getSectionDict() const +const SectionRefs &DefinitionImpl::getSectionRefs() const { - return m_impl->sectionDict; + return m_impl->sectionRefs; } -QCString DefinitionImpl::symbolName() const -{ - return m_impl->symbolName; +QCString DefinitionImpl::symbolName() const +{ + return m_impl->symbolName; } //---------------------- -QCString DefinitionImpl::documentation() const -{ - return m_impl->details ? m_impl->details->doc : QCString(""); +QCString DefinitionImpl::documentation() const +{ + return m_impl->details ? m_impl->details->doc : QCString(""); } -int DefinitionImpl::docLine() const -{ - return m_impl->details ? m_impl->details->line : 1; +int DefinitionImpl::docLine() const +{ + return m_impl->details ? m_impl->details->line : 1; } -QCString DefinitionImpl::docFile() const -{ - return m_impl->details ? m_impl->details->file : QCString("<"+m_impl->name+">"); +QCString DefinitionImpl::docFile() const +{ + return m_impl->details ? m_impl->details->file : QCString("<"+m_impl->name+">"); } //---------------------------------------------------------------------------- @@ -1926,7 +1825,7 @@ QCString DefinitionImpl::docFile() const static bool stripWord(QCString &s,QCString w) { bool success=FALSE; - if (s.left(w.length())==w) + if (s.left(w.length())==w) { success=TRUE; s=s.right(s.length()-w.length()); @@ -1944,25 +1843,23 @@ QCString abbreviate(const char *s,const char *name) QCString result=s; result=result.stripWhiteSpace(); // strip trailing . - if (!result.isEmpty() && result.at(result.length()-1)=='.') + if (!result.isEmpty() && result.at(result.length()-1)=='.') result=result.left(result.length()-1); // strip any predefined prefix - QStrList &briefDescAbbrev = Config_getList(ABBREVIATE_BRIEF); - const char *p = briefDescAbbrev.first(); - while (p) + const StringVector &briefDescAbbrev = Config_getList(ABBREVIATE_BRIEF); + for (const auto &p : briefDescAbbrev) { - QCString s = p; - s.replace(QRegExp("\\$name"), scopelessName); // replace $name with entity name - s += " "; - stripWord(result,s); - p = briefDescAbbrev.next(); + QCString str = p.c_str(); + str.replace(QRegExp("\\$name"), scopelessName); // replace $name with entity name + str += " "; + stripWord(result,str); } // capitalize first word if (!result.isEmpty()) { - int c=result[0]; + char c=result[0]; if (c>='a' && c<='z') c+='A'-'a'; result[0]=c; } @@ -1972,77 +1869,68 @@ QCString abbreviate(const char *s,const char *name) //---------------------- -QCString DefinitionImpl::briefDescription(bool abbr) const -{ +QCString DefinitionImpl::briefDescription(bool abbr) const +{ //printf("%s::briefDescription(%d)='%s'\n",name().data(),abbr,m_impl->brief?m_impl->brief->doc.data():"<none>"); - return m_impl->brief ? - (abbr ? abbreviate(m_impl->brief->doc,displayName()) : m_impl->brief->doc) : - QCString(""); + return m_impl->brief ? + (abbr ? abbreviate(m_impl->brief->doc,m_impl->def->displayName()) : m_impl->brief->doc) : + QCString(""); } -QCString DefinitionImpl::briefDescriptionAsTooltip() const +void DefinitionImpl::computeTooltip() { - if (m_impl->brief) + if (m_impl->brief && m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty()) { - if (m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty()) - { - static bool reentering=FALSE; - if (!reentering) - { - const MemberDef *md = definitionType()==TypeMember ? dynamic_cast<const MemberDef*>(this) : 0; - const Definition *scope = definitionType()==TypeMember ? getOuterScope() : this; - reentering=TRUE; // prevent requests for tooltips while parsing a tooltip - m_impl->brief->tooltip = parseCommentAsText( - scope,md, - m_impl->brief->doc, - m_impl->brief->file, - m_impl->brief->line); - reentering=FALSE; - } - } - return m_impl->brief->tooltip; + const MemberDef *md = m_impl->def->definitionType()==Definition::TypeMember ? toMemberDef(m_impl->def) : 0; + const Definition *scope = m_impl->def->definitionType()==Definition::TypeMember ? m_impl->def->getOuterScope() : m_impl->def; + m_impl->brief->tooltip = parseCommentAsText(scope,md, + m_impl->brief->doc, m_impl->brief->file, m_impl->brief->line); } - return QCString(""); } -int DefinitionImpl::briefLine() const -{ - return m_impl->brief ? m_impl->brief->line : 1; +QCString DefinitionImpl::briefDescriptionAsTooltip() const +{ + return m_impl->brief ? m_impl->brief->tooltip : QCString(); } -QCString DefinitionImpl::briefFile() const -{ - return m_impl->brief ? m_impl->brief->file : QCString("<"+m_impl->name+">"); +int DefinitionImpl::briefLine() const +{ + return m_impl->brief ? m_impl->brief->line : 1; +} + +QCString DefinitionImpl::briefFile() const +{ + return m_impl->brief ? m_impl->brief->file : QCString("<"+m_impl->name+">"); } //---------------------- QCString DefinitionImpl::inbodyDocumentation() const { - return m_impl->inbodyDocs ? m_impl->inbodyDocs->doc : QCString(""); + return m_impl->inbodyDocs ? m_impl->inbodyDocs->doc : QCString(""); } -int DefinitionImpl::inbodyLine() const -{ - return m_impl->inbodyDocs ? m_impl->inbodyDocs->line : 1; +int DefinitionImpl::inbodyLine() const +{ + return m_impl->inbodyDocs ? m_impl->inbodyDocs->line : 1; } -QCString DefinitionImpl::inbodyFile() const -{ - return m_impl->inbodyDocs ? m_impl->inbodyDocs->file : QCString("<"+m_impl->name+">"); +QCString DefinitionImpl::inbodyFile() const +{ + return m_impl->inbodyDocs ? m_impl->inbodyDocs->file : QCString("<"+m_impl->name+">"); } //---------------------- -QCString DefinitionImpl::getDefFileName() const -{ - return m_impl->defFileName; +QCString DefinitionImpl::getDefFileName() const +{ + return m_impl->defFileName; } -QCString DefinitionImpl::getDefFileExtension() const -{ - return m_impl->defFileExt; +QCString DefinitionImpl::getDefFileExtension() const +{ + return m_impl->defFileExt; } bool DefinitionImpl::isHidden() const @@ -2050,14 +1938,14 @@ bool DefinitionImpl::isHidden() const return m_impl->hidden; } -bool DefinitionImpl::isVisibleInProject() const -{ - return isLinkableInProject() && !m_impl->hidden; +bool DefinitionImpl::isVisibleInProject() const +{ + return m_impl->def->isLinkableInProject() && !m_impl->hidden; } bool DefinitionImpl::isVisible() const -{ - return isLinkable() && !m_impl->hidden; +{ + return m_impl->def->isLinkable() && !m_impl->hidden; } bool DefinitionImpl::isArtificial() const @@ -2065,69 +1953,101 @@ bool DefinitionImpl::isArtificial() const return m_impl->isArtificial; } -QCString DefinitionImpl::getReference() const -{ - return m_impl->ref; +QCString DefinitionImpl::getReference() const +{ + return m_impl->ref; } -bool DefinitionImpl::isReference() const -{ - return !m_impl->ref.isEmpty(); +bool DefinitionImpl::isReference() const +{ + return !m_impl->ref.isEmpty(); +} + +int DefinitionImpl::getStartDefLine() const +{ + return m_impl->body ? m_impl->body->defLine : -1; } -int DefinitionImpl::getStartBodyLine() const -{ - return m_impl->body ? m_impl->body->startLine : -1; +int DefinitionImpl::getStartBodyLine() const +{ + return m_impl->body ? m_impl->body->startLine : -1; } -int DefinitionImpl::getEndBodyLine() const -{ - return m_impl->body ? m_impl->body->endLine : -1; +int DefinitionImpl::getEndBodyLine() const +{ + return m_impl->body ? m_impl->body->endLine : -1; } FileDef *DefinitionImpl::getBodyDef() const -{ - return m_impl->body ? m_impl->body->fileDef : 0; +{ + return m_impl->body ? m_impl->body->fileDef : 0; } -GroupList *DefinitionImpl::partOfGroups() const -{ - return m_impl->partOfGroups; +const GroupList &DefinitionImpl::partOfGroups() const +{ + return m_impl->partOfGroups; } bool DefinitionImpl::isLinkableViaGroup() const { - GroupList *gl = partOfGroups(); - if (gl) + for (const auto &gd : partOfGroups()) { - GroupListIterator gli(*gl); - GroupDef *gd; - for (gli.toFirst();(gd=gli.current());++gli) - { - if (gd->isLinkable()) return TRUE; - } + if (gd->isLinkable()) return true; } - return FALSE; + return false; } -Definition *DefinitionImpl::getOuterScope() const -{ - return m_impl->outerScope; +Definition *DefinitionImpl::getOuterScope() const +{ + return m_impl->outerScope; +} + +std::vector<const MemberDef*> DefinitionImpl::getReferencesMembers() const +{ + return refMapToVector(m_impl->sourceRefsDict); } -MemberSDict *DefinitionImpl::getReferencesMembers() const -{ - return m_impl->sourceRefsDict; +std::vector<const MemberDef*> DefinitionImpl::getReferencedByMembers() const +{ + return refMapToVector(m_impl->sourceRefByDict); +} + +void DefinitionImpl::mergeReferences(const Definition *other) +{ + const DefinitionImpl *defImpl = other->toDefinitionImpl_(); + if (defImpl) + { + for (const auto &kv : defImpl->m_impl->sourceRefsDict) + { + auto it = m_impl->sourceRefsDict.find(kv.first); + if (it != m_impl->sourceRefsDict.end()) + { + m_impl->sourceRefsDict.insert(kv); + } + } + } } -MemberSDict *DefinitionImpl::getReferencedByMembers() const -{ - return m_impl->sourceRefByDict; +void DefinitionImpl::mergeReferencedBy(const Definition *other) +{ + const DefinitionImpl *defImpl = other->toDefinitionImpl_(); + if (defImpl) + { + for (const auto &kv : defImpl->m_impl->sourceRefByDict) + { + auto it = m_impl->sourceRefByDict.find(kv.first); + if (it != m_impl->sourceRefByDict.end()) + { + m_impl->sourceRefByDict.insert({kv.first,kv.second}); + } + } + } } -void DefinitionImpl::setReference(const char *r) -{ - m_impl->ref=r; + +void DefinitionImpl::setReference(const char *r) +{ + m_impl->ref=r; } SrcLangExt DefinitionImpl::getLanguage() const @@ -2135,9 +2055,9 @@ SrcLangExt DefinitionImpl::getLanguage() const return m_impl->lang; } -void DefinitionImpl::setHidden(bool b) -{ - m_impl->hidden = m_impl->hidden || b; +void DefinitionImpl::setHidden(bool b) +{ + m_impl->hidden = m_impl->hidden || b; } void DefinitionImpl::setArtificial(bool b) @@ -2145,20 +2065,20 @@ void DefinitionImpl::setArtificial(bool b) m_impl->isArtificial = b; } -void DefinitionImpl::setLocalName(const QCString name) -{ - m_impl->localName=name; +void DefinitionImpl::setLocalName(const QCString name) +{ + m_impl->localName=name; } -void DefinitionImpl::setLanguage(SrcLangExt lang) -{ - m_impl->lang=lang; +void DefinitionImpl::setLanguage(SrcLangExt lang) +{ + m_impl->lang=lang; } -void DefinitionImpl::_setSymbolName(const QCString &name) -{ - m_impl->symbolName=name; +void DefinitionImpl::_setSymbolName(const QCString &name) +{ + m_impl->symbolName=name; } QCString DefinitionImpl::_symbolName() const @@ -2181,7 +2101,7 @@ QCString DefinitionImpl::externalReference(const QCString &relPath) const if (dest) { QCString result = *dest; - int l = result.length(); + uint l = result.length(); if (!relPath.isEmpty() && l>0 && result.at(0)=='.') { // relative path -> prepend relPath. result.prepend(relPath); @@ -2214,7 +2134,7 @@ int DefinitionImpl::getDefColumn() const return m_impl->defColumn; } -void DefinitionImpl::setCookie(Cookie *cookie) const +void DefinitionImpl::setCookie(Definition::Cookie *cookie) const { delete m_impl->cookie; m_impl->cookie = cookie; @@ -2235,16 +2155,62 @@ void DefinitionImpl::writeSummaryLinks(OutputList &) const //--------------------------------------------------------------------------------- -DefinitionAliasImpl::DefinitionAliasImpl(const Definition *scope,const Definition *alias) - : m_scope(scope), m_def(alias), m_cookie(0) +DefinitionAliasImpl::DefinitionAliasImpl(Definition *def,const Definition *scope, const Definition *alias) + : m_def(def), m_scope(scope), m_symbolName(alias->_symbolName()) +{ +} + +DefinitionAliasImpl::~DefinitionAliasImpl() +{ +} + +void DefinitionAliasImpl::init() { //printf("%s::addToMap(%s)\n",qPrint(name()),qPrint(alias->name())); - addToMap(alias->name(),this); + addToMap(m_symbolName,m_def); +} + +void DefinitionAliasImpl::deinit() +{ + removeFromMap(m_symbolName,m_def); +} + +QCString DefinitionAliasImpl::qualifiedName() const +{ + //printf("start %s::qualifiedName() localName=%s\n",name().data(),m_impl->localName.data()); + if (m_scope==0) + { + return m_def->localName(); + } + else + { + return m_scope->qualifiedName()+ + getLanguageSpecificSeparator(m_scope->getLanguage())+ + m_def->localName(); + } +} + +QCString DefinitionAliasImpl::name() const +{ + return qualifiedName(); +} + +//--------------------------------------------------------------------------------- + +Definition *toDefinition(DefinitionMutable *dm) +{ + if (dm==0) return 0; + return dm->toDefinition_(); +} + +DefinitionMutable *toDefinitionMutable(Definition *d) +{ + if (d==0) return 0; + return d->toDefinitionMutable_(); } -DefinitionAliasImpl::~DefinitionAliasImpl() +DefinitionMutable *toDefinitionMutable(const Definition *d) { - //printf("~DefinitionAliasImpl()\n"); - removeFromMap(this); + return toDefinitionMutable(const_cast<Definition*>(d)); } |