diff options
Diffstat (limited to 'src')
86 files changed, 2731 insertions, 2714 deletions
diff --git a/src/cite.cpp b/src/cite.cpp index 03bdb02..e02641a 100644 --- a/src/cite.cpp +++ b/src/cite.cpp @@ -368,7 +368,7 @@ void CitationManager::generatePage() //printf("doc=[%s]\n",doc.data()); // 7. add it as a page - addRelatedPage(fileName(),theTranslator->trCiteReferences(),doc,fileName(),1); + addRelatedPage(fileName(),theTranslator->trCiteReferences(),doc,fileName(),1,1); // 8. for latex we just copy the bib files to the output and let // latex do this work. diff --git a/src/clangparser.cpp b/src/clangparser.cpp index 1ac9138..d17ed91 100644 --- a/src/clangparser.cpp +++ b/src/clangparser.cpp @@ -129,10 +129,11 @@ class ClangTUParser::Private std::vector<CXUnsavedFile> ufs; std::vector<CXCursor> cursors; std::unordered_map<std::string,uint> fileMapping; - CXTranslationUnit tu; + CXTranslationUnit tu = 0; CXToken *tokens = 0; uint numTokens = 0; StringVector filesInSameTU; + TooltipManager tooltipManager; // state while parsing sources MemberDef *currentMemberDef=0; @@ -572,7 +573,7 @@ void ClangTUParser::writeMultiLineCodeLink(CodeOutputInterface &ol, const char *text) { static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); - TooltipManager::instance()->addTooltip(d); + p->tooltipManager.addTooltip(d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); @@ -858,7 +859,7 @@ class ClangParser::Private QCString clangCompileDatabase = Config_getString(CLANG_DATABASE_PATH); // load a clang compilation database (https://clang.llvm.org/docs/JSONCompilationDatabase.html) db = clang::tooling::CompilationDatabase::loadFromDirectory(clangCompileDatabase.data(), error); - if (clangCompileDatabase!="0" && db==nullptr) + if (!clangCompileDatabase.isEmpty() && clangCompileDatabase!="0" && db==nullptr) { // user specified a path, but DB file was not found err("%s using clang compilation database path of: \"%s\"\n", error.c_str(), @@ -884,6 +885,7 @@ ClangParser::~ClangParser() std::unique_ptr<ClangTUParser> ClangParser::createTUParser(const FileDef *fd) const { + //printf("ClangParser::createTUParser()\n"); return std::make_unique<ClangTUParser>(*this,fd); } diff --git a/src/clangparser.h b/src/clangparser.h index 8ee1bdb..f948c33 100644 --- a/src/clangparser.h +++ b/src/clangparser.h @@ -30,7 +30,7 @@ class ClangTUParser void parse(); /** Switches to another file within the translation unit started with start(). - * @param[in] fileName The name of the file to switch to. + * @param[in] fd The file definition with the name of the file to switch to. */ void switchToFile(FileDef *fd); diff --git a/src/classdef.cpp b/src/classdef.cpp index 5e2b2fa..91730a0 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -81,8 +81,10 @@ class ClassDefImpl : public DefinitionImpl, public ClassDef virtual QCString displayName(bool includeScope=TRUE) const; virtual CompoundType compoundType() const; virtual QCString compoundTypeString() const; - virtual BaseClassList *baseClasses() const; - virtual BaseClassList *subClasses() const; + virtual BaseClassList baseClasses() const; + virtual void updateBaseClasses(const BaseClassList &bcd); + virtual BaseClassList subClasses() const; + virtual void updateSubClasses(const BaseClassList &bcd); virtual const MemberNameInfoLinkedMap &memberNameInfoLinkedMap() const; virtual Protection protection() const; virtual bool isLinkableInProject() const; @@ -318,9 +320,9 @@ class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef { return getCdAlias()->compoundType(); } virtual QCString compoundTypeString() const { return getCdAlias()->compoundTypeString(); } - virtual BaseClassList *baseClasses() const + virtual BaseClassList baseClasses() const { return getCdAlias()->baseClasses(); } - virtual BaseClassList *subClasses() const + virtual BaseClassList subClasses() const { return getCdAlias()->subClasses(); } virtual const MemberNameInfoLinkedMap &memberNameInfoLinkedMap() const { return getCdAlias()->memberNameInfoLinkedMap(); } @@ -510,6 +512,8 @@ class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef virtual void addGroupedInheritedMembers(OutputList &,MemberListType, const ClassDef *,const QCString &) const {} virtual void writeTagFile(FTextStream &) {} + virtual void updateBaseClasses(const BaseClassList &) {} + virtual void updateSubClasses(const BaseClassList &) {} virtual void setVisited(bool visited) const { m_visited = visited; } virtual bool isVisited() const { return m_visited; } @@ -567,11 +571,11 @@ class ClassDefImpl::IMPL /*! List of base class (or super-classes) from which this class derives * directly. */ - BaseClassList *inherits = 0; + BaseClassList inherits; /*! List of sub-classes that directly derive from this class */ - BaseClassList *inheritedBy = 0; + BaseClassList inheritedBy; /*! Namespace this class is part of * (this is the inner most namespace in case of nested namespaces) @@ -703,8 +707,6 @@ void ClassDefImpl::IMPL::init(const char *defFileName, const char *name, fileName=ctStr+name; } exampleSDict = 0; - inherits = 0; - inheritedBy = 0; incInfo=0; prot=Public; nspace=0; @@ -756,8 +758,6 @@ ClassDefImpl::IMPL::IMPL() : vhdlSummaryTitles(17) ClassDefImpl::IMPL::~IMPL() { - delete inherits; - delete inheritedBy; delete exampleSDict; delete usesImplClassDict; delete usedByImplClassDict; @@ -855,13 +855,7 @@ void ClassDefImpl::insertBaseClass(ClassDef *cd,const char *n,Protection p, Specifier s,const char *t) { //printf("*** insert base class %s into %s\n",cd->name().data(),name().data()); - //inherits->inSort(new BaseClassDef(cd,p,s,t)); - if (m_impl->inherits==0) - { - m_impl->inherits = new BaseClassList; - m_impl->inherits->setAutoDelete(TRUE); - } - m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t)); + m_impl->inherits.push_back(BaseClassDef(cd,n,p,s,t)); m_impl->isSimple = FALSE; } @@ -872,12 +866,7 @@ void ClassDefImpl::insertSubClass(ClassDef *cd,Protection p, //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data()); static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); if (!extractPrivate && cd->protection()==Private) return; - if (m_impl->inheritedBy==0) - { - m_impl->inheritedBy = new BaseClassList; - m_impl->inheritedBy->setAutoDelete(TRUE); - } - m_impl->inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t)); + m_impl->inheritedBy.push_back(BaseClassDef(cd,0,p,s,t)); m_impl->isSimple = FALSE; } @@ -1287,22 +1276,22 @@ void ClassDefImpl::insertUsedFile(FileDef *fd) } } -static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd) +static void writeInheritanceSpecifier(OutputList &ol,const BaseClassDef &bcd) { - if (bcd->prot!=Public || bcd->virt!=Normal) + if (bcd.prot!=Public || bcd.virt!=Normal) { ol.startTypewriter(); ol.docify(" ["); - QStrList sl; - if (bcd->prot==Protected) sl.append("protected"); - else if (bcd->prot==Private) sl.append("private"); - if (bcd->virt==Virtual) sl.append("virtual"); - const char *s=sl.first(); - while (s) + StringVector sl; + if (bcd.prot==Protected) sl.push_back("protected"); + else if (bcd.prot==Private) sl.push_back("private"); + if (bcd.virt==Virtual) sl.push_back("virtual"); + bool first=true; + for (const auto &s : sl) { - ol.docify(s); - s=sl.next(); - if (s) ol.docify(", "); + if (!first) ol.docify(", "); + ol.docify(s.c_str()); + first=false; } ol.docify("]"); ol.endTypewriter(); @@ -1660,24 +1649,15 @@ void ClassDefImpl::showUsedFiles(OutputList &ol) const int ClassDefImpl::countInheritanceNodes() const { int count=0; - BaseClassDef *ibcd; - if (m_impl->inheritedBy) + for (const auto &ibcd : m_impl->inheritedBy) { - BaseClassListIterator it(*m_impl->inheritedBy); - for (;(ibcd=it.current());++it) - { - ClassDef *icd=ibcd->classDef; - if ( icd->isVisibleInHierarchy()) count++; - } + const ClassDef *icd=ibcd.classDef; + if ( icd->isVisibleInHierarchy()) count++; } - if (m_impl->inherits) + for (const auto &ibcd : m_impl->inherits) { - BaseClassListIterator it(*m_impl->inherits); - for (;(ibcd=it.current());++it) - { - ClassDef *icd=ibcd->classDef; - if ( icd->isVisibleInHierarchy()) count++; - } + const ClassDef *icd=ibcd.classDef; + if ( icd->isVisibleInHierarchy()) count++; } return count; } @@ -1727,12 +1707,12 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const ol.disableAllBut(OutputGenerator::Man); } - if (m_impl->inherits && m_impl->inherits->count()>0) + if (!m_impl->inherits.empty()) { ol.startParagraph(); //parseText(ol,theTranslator->trInherits()+" "); - QCString inheritLine = theTranslator->trInheritsList((int)m_impl->inherits->count()); + QCString inheritLine = theTranslator->trInheritsList((int)m_impl->inherits.size()); QRegExp marker("@[0-9]+"); int index=0,newIndex,matchLen; // now replace all markers in inheritLine with links to the classes @@ -1741,15 +1721,15 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const ol.parseText(inheritLine.mid(index,newIndex-index)); bool ok; uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok); - BaseClassDef *bcd=m_impl->inherits->at(entryIndex); - if (ok && bcd) + BaseClassDef &bcd=m_impl->inherits.at(entryIndex); + if (ok) { - ClassDef *cd=bcd->classDef; + ClassDef *cd=bcd.classDef; // use the class name but with the template arguments as given // in the inheritance relation QCString displayName = insertTemplateSpecifierInScope( - cd->displayName(),bcd->templSpecifiers); + cd->displayName(),bcd.templSpecifiers); if (cd->isLinkable()) { @@ -1774,10 +1754,10 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const } // write subclasses - if (m_impl->inheritedBy && m_impl->inheritedBy->count()>0) + if (!m_impl->inheritedBy.empty()) { ol.startParagraph(); - QCString inheritLine = theTranslator->trInheritedByList((int)m_impl->inheritedBy->count()); + QCString inheritLine = theTranslator->trInheritedByList((int)m_impl->inheritedBy.size()); QRegExp marker("@[0-9]+"); int index=0,newIndex,matchLen; // now replace all markers in inheritLine with links to the classes @@ -1786,10 +1766,10 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const ol.parseText(inheritLine.mid(index,newIndex-index)); bool ok; uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok); - BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex); - if (ok && bcd) + BaseClassDef &bcd=m_impl->inheritedBy.at(entryIndex); + if (ok) { - ClassDef *cd=bcd->classDef; + ClassDef *cd=bcd.classDef; if (cd->isLinkable()) { ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),cd->displayName()); @@ -1935,35 +1915,30 @@ void ClassDefImpl::writeIncludeFilesForSlice(OutputList &ol) const ol.docify("class "); } ol.docify(stripScope(name())); - if (m_impl->inherits) + if (!m_impl->inherits.empty()) { if (m_impl->spec & (Entry::Interface|Entry::Exception)) { ol.docify(" extends "); - BaseClassListIterator it(*m_impl->inherits); - BaseClassDef *ibcd; - for (;(ibcd=it.current());++it) + bool first=true; + for (const auto &ibcd : m_impl->inherits) { - ClassDef *icd = ibcd->classDef; + if (!first) ol.docify(", "); + ClassDef *icd = ibcd.classDef; ol.docify(icd->name()); - if (!it.atLast()) - { - ol.docify(", "); - } + first=false; } } else { // Must be a class. - bool implements = FALSE; - BaseClassListIterator it(*m_impl->inherits); - BaseClassDef *ibcd; - for (;(ibcd=it.current());++it) + bool implements = false; + for (const auto &ibcd : m_impl->inherits) { - ClassDef *icd = ibcd->classDef; + ClassDef *icd = ibcd.classDef; if (icd->isInterface()) { - implements = TRUE; + implements = true; } else { @@ -1974,20 +1949,14 @@ void ClassDefImpl::writeIncludeFilesForSlice(OutputList &ol) const if (implements) { ol.docify(" implements "); - bool first = TRUE; - for (ibcd=it.toFirst();(ibcd=it.current());++it) + bool first = true; + for (const auto &ibcd : m_impl->inherits) { - ClassDef *icd = ibcd->classDef; + ClassDef *icd = ibcd.classDef; if (icd->isInterface()) { - if (!first) - { - ol.docify(", "); - } - else - { - first = FALSE; - } + if (!first) ol.docify(", "); + first = false; ol.docify(icd->name()); } } @@ -2223,32 +2192,27 @@ void ClassDefImpl::writeTagFile(FTextStream &tagFile) { tagFile << " <templarg>" << convertToXML(a.name) << "</templarg>" << endl; } - if (m_impl->inherits) + for (const auto &ibcd : m_impl->inherits) { - BaseClassListIterator it(*m_impl->inherits); - BaseClassDef *ibcd; - for (it.toFirst();(ibcd=it.current());++it) + ClassDef *cd=ibcd.classDef; + if (cd && cd->isLinkable()) { - ClassDef *cd=ibcd->classDef; - if (cd && cd->isLinkable()) + if (!Config_getString(GENERATE_TAGFILE).isEmpty()) { - if (!Config_getString(GENERATE_TAGFILE).isEmpty()) + tagFile << " <base"; + if (ibcd.prot==Protected) { - tagFile << " <base"; - if (ibcd->prot==Protected) - { - tagFile << " protection=\"protected\""; - } - else if (ibcd->prot==Private) - { - tagFile << " protection=\"private\""; - } - if (ibcd->virt==Virtual) - { - tagFile << " virtualness=\"virtual\""; - } - tagFile << ">" << convertToXML(cd->name()) << "</base>" << endl; + tagFile << " protection=\"protected\""; + } + else if (ibcd.prot==Private) + { + tagFile << " protection=\"private\""; } + if (ibcd.virt==Virtual) + { + tagFile << " virtualness=\"virtual\""; + } + tagFile << ">" << convertToXML(cd->name()) << "</base>" << endl; } } } @@ -3338,29 +3302,29 @@ bool ClassDefImpl::hasNonReferenceSuperClass() const { return TRUE; // we're done if this class is not a reference } - if (m_impl->inheritedBy) + for (const auto &ibcd : m_impl->inheritedBy) { - BaseClassListIterator bcli(*m_impl->inheritedBy); - for ( ; bcli.current() && !found ; ++bcli ) // for each super class + ClassDef *bcd=ibcd.classDef; + // recurse into the super class branch + found = found || bcd->hasNonReferenceSuperClass(); + if (!found) { - ClassDef *bcd=bcli.current()->classDef; - // recurse into the super class branch - found = found || bcd->hasNonReferenceSuperClass(); - if (!found) + // look for template instances that might have non-reference super classes + QDict<ClassDef> *cil = bcd->getTemplateInstances(); + if (cil) { - // look for template instances that might have non-reference super classes - QDict<ClassDef> *cil = bcd->getTemplateInstances(); - if (cil) + QDictIterator<ClassDef> tidi(*cil); + for ( ; tidi.current() && !found ; ++tidi) // for each template instance { - QDictIterator<ClassDef> tidi(*cil); - for ( ; tidi.current() && !found ; ++tidi) // for each template instance - { - // recurse into the template instance branch - found = found || tidi.current()->hasNonReferenceSuperClass(); - } + // recurse into the template instance branch + found = found || tidi.current()->hasNonReferenceSuperClass(); } } } + else + { + break; + } } return found; } @@ -3456,16 +3420,14 @@ bool ClassDefImpl::isLinkable() const /*! the class is visible in a class diagram, or class hierarchy */ bool ClassDefImpl::isVisibleInHierarchy() const { - static bool allExternals = Config_getBool(ALLEXTERNALS); - static bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES); - static bool extractStatic = Config_getBool(EXTRACT_STATIC); + bool allExternals = Config_getBool(ALLEXTERNALS); + bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES); + bool extractStatic = Config_getBool(EXTRACT_STATIC); return // show all classes or a subclass is visible - (allExternals || hasNonReferenceSuperClass()) && + ((allExternals && !isArtificial()) || hasNonReferenceSuperClass()) && // and not an anonymous compound !isAnonymous() && - // not an artificially introduced class - /*!isArtificial() &&*/ // 1.8.2: allowed these to appear // and not privately inherited protectionLevelVisible(m_impl->prot) && // documented or shown anyway or documentation is external @@ -3497,21 +3459,12 @@ bool ClassDefImpl::isBaseClass(const ClassDef *bcd, bool followInstances,int lev err("Possible recursive class relation while inside %s and looking for base class %s\n",qPrint(name()),qPrint(bcd->name())); return FALSE; } - if (baseClasses()) + for (const auto &bclass : baseClasses()) { - // Beware: trying to optimise the iterator away using ->first() & ->next() - // causes bug 625531 - BaseClassListIterator bcli(*baseClasses()); - for ( ; bcli.current() && !found ; ++bcli) - { - const ClassDef *ccd=bcli.current()->classDef; - if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster(); - //printf("isBaseClass() baseclass %s\n",ccd->name().data()); - if (ccd==bcd) - found=TRUE; - else - found=ccd->isBaseClass(bcd,followInstances,level+1); - } + const ClassDef *ccd = bclass.classDef; + if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster(); + found = (ccd==bcd) || ccd->isBaseClass(bcd,followInstances,level+1); + if (found) break; } return found; } @@ -3526,17 +3479,11 @@ bool ClassDefImpl::isSubClass(ClassDef *cd,int level) const err("Possible recursive class relation while inside %s and looking for derived class %s\n",qPrint(name()),qPrint(cd->name())); return FALSE; } - if (subClasses()) + for (const auto &iscd : subClasses()) { - BaseClassListIterator bcli(*subClasses()); - for ( ; bcli.current() && !found ; ++bcli) - { - ClassDef *ccd=bcli.current()->classDef; - if (ccd==cd) - found=TRUE; - else - found=ccd->isSubClass(cd,level+1); - } + ClassDef *ccd=iscd.classDef; + found = (ccd==cd) || ccd->isSubClass(cd,level+1); + if (found) break; } return found; } @@ -3569,212 +3516,206 @@ void ClassDefImpl::mergeMembers() //printf(" mergeMembers for %s\n",name().data()); static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); - if (baseClasses()) + for (const auto &bcd : baseClasses()) { - //printf(" => has base classes!\n"); - BaseClassListIterator bcli(*baseClasses()); - BaseClassDef *bcd; - for ( ; (bcd=bcli.current()) ; ++bcli ) - { - ClassDef *bClass=bcd->classDef; + ClassDef *bClass=bcd.classDef; - // merge the members in the base class of this inheritance branch first - bClass->mergeMembers(); + // merge the members in the base class of this inheritance branch first + bClass->mergeMembers(); - const MemberNameInfoLinkedMap &srcMnd = bClass->memberNameInfoLinkedMap(); - MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap; + const MemberNameInfoLinkedMap &srcMnd = bClass->memberNameInfoLinkedMap(); + MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap; - for (auto &srcMni : srcMnd) + for (auto &srcMni : srcMnd) + { + //printf(" Base member name %s\n",srcMni->memberName()); + MemberNameInfo *dstMni; + if ((dstMni=dstMnd.find(srcMni->memberName()))) + // a member with that name is already in the class. + // the member may hide or reimplement the one in the sub class + // or there may be another path to the base class that is already + // visited via another branch in the class hierarchy. { - //printf(" Base member name %s\n",srcMni->memberName()); - MemberNameInfo *dstMni; - if ((dstMni=dstMnd.find(srcMni->memberName()))) - // a member with that name is already in the class. - // the member may hide or reimplement the one in the sub class - // or there may be another path to the base class that is already - // visited via another branch in the class hierarchy. + for (auto &srcMi : *srcMni) { - for (auto &srcMi : *srcMni) + MemberDef *srcMd = srcMi->memberDef(); + bool found=FALSE; + bool ambiguous=FALSE; + bool hidden=FALSE; + const ClassDef *srcCd = srcMd->getClassDef(); + for (auto &dstMi : *dstMni) { - MemberDef *srcMd = srcMi->memberDef(); - bool found=FALSE; - bool ambiguous=FALSE; - bool hidden=FALSE; - const ClassDef *srcCd = srcMd->getClassDef(); - for (auto &dstMi : *dstMni) + MemberDef *dstMd = dstMi->memberDef(); + if (srcMd!=dstMd) // different members { - MemberDef *dstMd = dstMi->memberDef(); - if (srcMd!=dstMd) // different members + const ClassDef *dstCd = dstMd->getClassDef(); + //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data()); + if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE)) + // member is in the same or a base class { - const ClassDef *dstCd = dstMd->getClassDef(); - //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data()); - if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE)) - // member is in the same or a base class - { - ArgumentList &srcAl = srcMd->argumentList(); - ArgumentList &dstAl = dstMd->argumentList(); - found=matchArguments2( - srcMd->getOuterScope(),srcMd->getFileDef(),&srcAl, - dstMd->getOuterScope(),dstMd->getFileDef(),&dstAl, - TRUE - ); - //printf(" Yes, matching (%s<->%s): %d\n", - // argListToString(srcMd->argumentList()).data(), - // argListToString(dstMd->argumentList()).data(), - // found); - hidden = hidden || !found; - } - else // member is in a non base class => multiple inheritance - // using the same base class. - { - //printf("$$ Existing member %s %s add scope %s\n", - // dstMi->ambiguityResolutionScope.data(), - // dstMd->name().data(), - // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data()); - - QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen); - if (scope!=dstMi->ambiguityResolutionScope().left(scope.length())) - { - dstMi->setAmbiguityResolutionScope(scope+dstMi->ambiguityResolutionScope()); - } - ambiguous=TRUE; - } + ArgumentList &srcAl = srcMd->argumentList(); + ArgumentList &dstAl = dstMd->argumentList(); + found=matchArguments2( + srcMd->getOuterScope(),srcMd->getFileDef(),&srcAl, + dstMd->getOuterScope(),dstMd->getFileDef(),&dstAl, + TRUE + ); + //printf(" Yes, matching (%s<->%s): %d\n", + // argListToString(srcMd->argumentList()).data(), + // argListToString(dstMd->argumentList()).data(), + // found); + hidden = hidden || !found; } - else // same members + else // member is in a non base class => multiple inheritance + // using the same base class. { - // do not add if base class is virtual or - // if scope paths are equal or - // if base class is an interface (and thus implicitly virtual). - //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt); - if ((srcMi->virt()!=Normal && dstMi->virt()!=Normal) || - bClass->name()+sep+srcMi->scopePath() == dstMi->scopePath() || - dstMd->getClassDef()->compoundType()==Interface - ) - { - found=TRUE; - } - else // member can be reached via multiple paths in the - // inheritance tree + //printf("$$ Existing member %s %s add scope %s\n", + // dstMi->ambiguityResolutionScope.data(), + // dstMd->name().data(), + // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data()); + + QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen); + if (scope!=dstMi->ambiguityResolutionScope().left(scope.length())) { - //printf("$$ Existing member %s %s add scope %s\n", - // dstMi->ambiguityResolutionScope.data(), - // dstMd->name().data(), - // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data()); - - QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen); - if (scope!=dstMi->ambiguityResolutionScope().left(scope.length())) - { - dstMi->setAmbiguityResolutionScope(dstMi->ambiguityResolutionScope()+scope); - } - ambiguous=TRUE; + dstMi->setAmbiguityResolutionScope(scope+dstMi->ambiguityResolutionScope()); } + ambiguous=TRUE; } - if (found) break; } - //printf("member %s::%s hidden %d ambiguous %d srcMi->ambigClass=%p\n", - // srcCd->name().data(),srcMd->name().data(),hidden,ambiguous,srcMi->ambigClass); - - // TODO: fix the case where a member is hidden by inheritance - // of a member with the same name but with another prototype, - // while there is more than one path to the member in the - // base class due to multiple inheritance. In this case - // it seems that the member is not reachable by prefixing a - // scope name either (according to my compiler). Currently, - // this case is shown anyway. - if (!found && srcMd->protection()!=Private && !srcMd->isFriend()) + else // same members { - Protection prot=srcMd->protection(); - if (bcd->prot==Protected && prot==Public) prot=bcd->prot; - else if (bcd->prot==Private) prot=bcd->prot; - - if (inlineInheritedMembers) + // do not add if base class is virtual or + // if scope paths are equal or + // if base class is an interface (and thus implicitly virtual). + //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt); + if ((srcMi->virt()!=Normal && dstMi->virt()!=Normal) || + bClass->name()+sep+srcMi->scopePath() == dstMi->scopePath() || + dstMd->getClassDef()->compoundType()==Interface + ) { - if (!isStandardFunc(srcMd)) - { - //printf(" insertMember '%s'\n",srcMd->name().data()); - internalInsertMember(srcMd,prot,FALSE); - } + found=TRUE; } - - Specifier virt=srcMi->virt(); - if (virt==Normal && bcd->virt!=Normal) virt=bcd->virt; - - std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(srcMd,prot,virt,TRUE); - newMi->setScopePath(bClass->name()+sep+srcMi->scopePath()); - if (ambiguous) + else // member can be reached via multiple paths in the + // inheritance tree { - //printf("$$ New member %s %s add scope %s::\n", - // srcMi->ambiguityResolutionScope.data(), - // srcMd->name().data(), - // bClass->name().data()); + //printf("$$ Existing member %s %s add scope %s\n", + // dstMi->ambiguityResolutionScope.data(), + // dstMd->name().data(), + // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data()); - QCString scope=bClass->name()+sep; - if (scope!=srcMi->ambiguityResolutionScope().left(scope.length())) + QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen); + if (scope!=dstMi->ambiguityResolutionScope().left(scope.length())) { - newMi->setAmbiguityResolutionScope(scope+srcMi->ambiguityResolutionScope()); + dstMi->setAmbiguityResolutionScope(dstMi->ambiguityResolutionScope()+scope); } + ambiguous=TRUE; } - if (hidden) + } + if (found) break; + } + //printf("member %s::%s hidden %d ambiguous %d srcMi->ambigClass=%p\n", + // srcCd->name().data(),srcMd->name().data(),hidden,ambiguous,srcMi->ambigClass); + + // TODO: fix the case where a member is hidden by inheritance + // of a member with the same name but with another prototype, + // while there is more than one path to the member in the + // base class due to multiple inheritance. In this case + // it seems that the member is not reachable by prefixing a + // scope name either (according to my compiler). Currently, + // this case is shown anyway. + if (!found && srcMd->protection()!=Private && !srcMd->isFriend()) + { + Protection prot=srcMd->protection(); + if (bcd.prot==Protected && prot==Public) prot=bcd.prot; + else if (bcd.prot==Private) prot=bcd.prot; + + if (inlineInheritedMembers) + { + if (!isStandardFunc(srcMd)) { - if (srcMi->ambigClass()==0) - { - newMi->setAmbigClass(bClass); - newMi->setAmbiguityResolutionScope(bClass->name()+sep); - } - else - { - newMi->setAmbigClass(srcMi->ambigClass()); - newMi->setAmbiguityResolutionScope(srcMi->ambigClass()->name()+sep); - } + //printf(" insertMember '%s'\n",srcMd->name().data()); + internalInsertMember(srcMd,prot,FALSE); } - dstMni->push_back(std::move(newMi)); } - } - } - else // base class has a member that is not in the sub class => copy - { - // create a deep copy of the list (only the MemberInfo's will be - // copied, not the actual MemberDef's) - MemberNameInfo *newMni = dstMnd.add(srcMni->memberName()); - // copy the member(s) from the base to the sub class - for (auto &mi : *srcMni) - { - if (!mi->memberDef()->isFriend()) // don't inherit friends + Specifier virt=srcMi->virt(); + if (virt==Normal && bcd.virt!=Normal) virt=bcd.virt; + + std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(srcMd,prot,virt,TRUE); + newMi->setScopePath(bClass->name()+sep+srcMi->scopePath()); + if (ambiguous) { - Protection prot = mi->prot(); - if (bcd->prot==Protected) + //printf("$$ New member %s %s add scope %s::\n", + // srcMi->ambiguityResolutionScope.data(), + // srcMd->name().data(), + // bClass->name().data()); + + QCString scope=bClass->name()+sep; + if (scope!=srcMi->ambiguityResolutionScope().left(scope.length())) { - if (prot==Public) prot=Protected; + newMi->setAmbiguityResolutionScope(scope+srcMi->ambiguityResolutionScope()); } - else if (bcd->prot==Private) + } + if (hidden) + { + if (srcMi->ambigClass()==0) { - prot=Private; + newMi->setAmbigClass(bClass); + newMi->setAmbiguityResolutionScope(bClass->name()+sep); } - //printf("%s::%s: prot=%d bcd->prot=%d result=%d\n", - // name().data(),mi->memberDef->name().data(),mi->prot, - // bcd->prot,prot); - - if (prot!=Private || extractPrivate) + else { - Specifier virt=mi->virt(); - if (virt==Normal && bcd->virt!=Normal) virt=bcd->virt; + newMi->setAmbigClass(srcMi->ambigClass()); + newMi->setAmbiguityResolutionScope(srcMi->ambigClass()->name()+sep); + } + } + dstMni->push_back(std::move(newMi)); + } + } + } + else // base class has a member that is not in the sub class => copy + { + // create a deep copy of the list (only the MemberInfo's will be + // copied, not the actual MemberDef's) + MemberNameInfo *newMni = dstMnd.add(srcMni->memberName()); + + // copy the member(s) from the base to the sub class + for (auto &mi : *srcMni) + { + if (!mi->memberDef()->isFriend()) // don't inherit friends + { + Protection prot = mi->prot(); + if (bcd.prot==Protected) + { + if (prot==Public) prot=Protected; + } + else if (bcd.prot==Private) + { + prot=Private; + } + //printf("%s::%s: prot=%d bcd.prot=%d result=%d\n", + // name().data(),mi->memberDef->name().data(),mi->prot, + // bcd.prot,prot); + + if (prot!=Private || extractPrivate) + { + Specifier virt=mi->virt(); + if (virt==Normal && bcd.virt!=Normal) virt=bcd.virt; - if (inlineInheritedMembers) + if (inlineInheritedMembers) + { + if (!isStandardFunc(mi->memberDef())) { - if (!isStandardFunc(mi->memberDef())) - { - //printf(" insertMember '%s'\n",mi->memberDef->name().data()); - internalInsertMember(mi->memberDef(),prot,FALSE); - } + //printf(" insertMember '%s'\n",mi->memberDef->name().data()); + internalInsertMember(mi->memberDef(),prot,FALSE); } - //printf("Adding!\n"); - std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(mi->memberDef(),prot,virt,TRUE); - newMi->setScopePath(bClass->name()+sep+mi->scopePath()); - newMi->setAmbigClass(mi->ambigClass()); - newMi->setAmbiguityResolutionScope(mi->ambiguityResolutionScope()); - newMni->push_back(std::move(newMi)); } + //printf("Adding!\n"); + std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(mi->memberDef(),prot,virt,TRUE); + newMi->setScopePath(bClass->name()+sep+mi->scopePath()); + newMi->setAmbigClass(mi->ambigClass()); + newMi->setAmbiguityResolutionScope(mi->ambiguityResolutionScope()); + newMni->push_back(std::move(newMi)); } } } @@ -3803,28 +3744,20 @@ void ClassDefImpl::mergeCategory(ClassDef *category) category->setArtificial(TRUE); // copy base classes/protocols from extension - if (category->baseClasses()) + for (const auto &bcd : category->baseClasses()) { - BaseClassListIterator bcli(*category->baseClasses()); - BaseClassDef *bcd; - for ( ; (bcd=bcli.current()) ; ++bcli ) + insertBaseClass(bcd.classDef,bcd.usedName,bcd.prot,bcd.virt,bcd.templSpecifiers); + // correct bcd.classDef so that they do no longer derive from + // category, but from this class! + BaseClassList scl = bcd.classDef->subClasses(); + for (auto &scd : scl) { - insertBaseClass(bcd->classDef,bcd->usedName,bcd->prot,bcd->virt,bcd->templSpecifiers); - // correct bcd->classDef so that they do no longer derive from - // category, but from this class! - if (bcd->classDef->subClasses()) + if (scd.classDef==category) { - BaseClassListIterator scli(*bcd->classDef->subClasses()); - BaseClassDef *scd; - for ( ; (scd=scli.current()) ; ++scli ) - { - if (scd->classDef==category) - { - scd->classDef=this; - } - } + scd.classDef=this; } } + bcd.classDef->updateSubClasses(scl); } } // make methods private for categories defined in the .m file @@ -4537,26 +4470,21 @@ int ClassDefImpl::countInheritedDecMembers(MemberListType lt, // name().data(),lt,process,count,invert); if ((process^invert) || showAlways) { - if (m_impl->inherits) + for (const auto &ibcd : m_impl->inherits) { - BaseClassListIterator it(*m_impl->inherits); - BaseClassDef *ibcd; - for (it.toFirst();(ibcd=it.current());++it) + ClassDef *icd=ibcd.classDef; + int lt1,lt2; + if (icd->isLinkable()) { - ClassDef *icd=ibcd->classDef; - int lt1,lt2; - if (icd->isLinkable()) + convertProtectionLevel(lt,ibcd.prot,<1,<2); + //printf("%s: convert %d->(%d,%d) prot=%d\n", + // icd->name().data(),lt,lt1,lt2,ibcd->prot); + if (visitedClasses->find(icd)==0) { - convertProtectionLevel(lt,ibcd->prot,<1,<2); - //printf("%s: convert %d->(%d,%d) prot=%d\n", - // icd->name().data(),lt,lt1,lt2,ibcd->prot); - if (visitedClasses->find(icd)==0) + visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance + if (lt1!=-1) { - visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance - if (lt1!=-1) - { - inhCount+=icd->countMemberDeclarations((MemberListType)lt1,inheritedFrom,lt2,FALSE,TRUE,visitedClasses); - } + inhCount+=icd->countMemberDeclarations((MemberListType)lt1,inheritedFrom,lt2,FALSE,TRUE,visitedClasses); } } } @@ -4678,36 +4606,31 @@ void ClassDefImpl::writeInheritedMemberDeclarations(OutputList &ol, // name().data(),lt,process,invert,showAlways); if ((process^invert) || showAlways) { - if (m_impl->inherits) + for (const auto &ibcd : m_impl->inherits) { - BaseClassListIterator it(*m_impl->inherits); - BaseClassDef *ibcd; - for (it.toFirst();(ibcd=it.current());++it) + ClassDef *icd=ibcd.classDef; + if (icd->isLinkable()) { - ClassDef *icd=ibcd->classDef; - if (icd->isLinkable()) + int lt1,lt3; + convertProtectionLevel(lt,ibcd.prot,<1,<3); + if (lt2==-1 && lt3!=-1) { - int lt1,lt3; - convertProtectionLevel(lt,ibcd->prot,<1,<3); - if (lt2==-1 && lt3!=-1) - { - lt2=lt3; - } - //printf("%s:convert %d->(%d,%d) prot=%d\n",icd->name().data(),lt,lt1,lt2,ibcd->prot); - if (visitedClasses->find(icd)==0) - { - visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance - if (lt1!=-1) - { - icd->writeMemberDeclarations(ol,(MemberListType)lt1, - title,QCString(),FALSE,inheritedFrom,lt2,FALSE,TRUE,visitedClasses); - } - } - else + lt2=lt3; + } + //printf("%s:convert %d->(%d,%d) prot=%d\n",icd->name().data(),lt,lt1,lt2,ibcd->prot); + if (visitedClasses->find(icd)==0) + { + visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance + if (lt1!=-1) { - //printf("%s: class already visited!\n",icd->name().data()); + icd->writeMemberDeclarations(ol,(MemberListType)lt1, + title,QCString(),FALSE,inheritedFrom,lt2,FALSE,TRUE,visitedClasses); } } + else + { + //printf("%s: class already visited!\n",icd->name().data()); + } } } } @@ -4822,16 +4745,26 @@ ClassDefImpl::CompoundType ClassDefImpl::compoundType() const return m_impl->compType; } -BaseClassList *ClassDefImpl::baseClasses() const +BaseClassList ClassDefImpl::baseClasses() const { return m_impl->inherits; } -BaseClassList *ClassDefImpl::subClasses() const +void ClassDefImpl::updateBaseClasses(const BaseClassList &bcd) +{ + m_impl->inherits = bcd; +} + +BaseClassList ClassDefImpl::subClasses() const { return m_impl->inheritedBy; } +void ClassDefImpl::updateSubClasses(const BaseClassList &bcd) +{ + m_impl->inheritedBy = bcd; +} + const MemberNameInfoLinkedMap &ClassDefImpl::memberNameInfoLinkedMap() const { return m_impl->allMemberNameInfoLinkedMap; diff --git a/src/classdef.h b/src/classdef.h index d413794..faaf0f6 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -37,7 +37,6 @@ class ClassSDict; class OutputList; class FileDef; class FileList; -class BaseClassList; class NamespaceDef; class MemberDef; class ExampleSDict; @@ -52,6 +51,38 @@ class StringDict; struct IncludeInfo; class ClassDefImpl; class FTextStream; +class ClassDef; + +/** Class that contains information about an inheritance relation. + */ +struct BaseClassDef +{ + BaseClassDef(ClassDef *cd,const char *n,Protection p, Specifier v,const char *t) : + classDef(cd), usedName(n), prot(p), virt(v), templSpecifiers(t) {} + + /** Class definition that this relation inherits from. */ + ClassDef *classDef; + + /** name used in the inheritance list + * (may be a typedef name instead of the class name) + */ + QCString usedName; + + /** Protection level of the inheritance relation: + * Public, Protected, or Private + */ + Protection prot; + + /** Virtualness of the inheritance relation: + * Normal, or Virtual + */ + Specifier virt; + + /** Template arguments used for the base class */ + QCString templSpecifiers; +}; + +using BaseClassList = std::vector<BaseClassDef>; /** A abstract class representing of a compound symbol. * @@ -126,11 +157,17 @@ class ClassDef : virtual public Definition /** Returns the list of base classes from which this class directly * inherits. */ - virtual BaseClassList *baseClasses() const = 0; + virtual BaseClassList baseClasses() const = 0; + + /** Update the list of base classes to the one passed */ + virtual void updateBaseClasses(const BaseClassList &bcd) = 0; /** Returns the list of sub classes that directly derive from this class */ - virtual BaseClassList *subClasses() const = 0; + virtual BaseClassList subClasses() const = 0; + + /** Update the list of sub classes to the one passed */ + virtual void updateSubClasses(const BaseClassList &bcd) = 0; /** Returns a dictionary of all members. This includes any inherited * members. Members are sorted alphabetically. @@ -480,65 +517,6 @@ class UsesClassDictIterator : public QDictIterator<UsesClassDef> //------------------------------------------------------------------------ -/** Class that contains information about an inheritance relation. - */ -struct BaseClassDef -{ - BaseClassDef(ClassDef *cd,const char *n,Protection p, Specifier v,const char *t) : - classDef(cd), usedName(n), prot(p), virt(v), templSpecifiers(t) {} - - /** Class definition that this relation inherits from. */ - ClassDef *classDef; - - /** name used in the inheritance list - * (may be a typedef name instead of the class name) - */ - QCString usedName; - - /** Protection level of the inheritance relation: - * Public, Protected, or Private - */ - Protection prot; - - /** Virtualness of the inheritance relation: - * Normal, or Virtual - */ - Specifier virt; - - /** Template arguments used for the base class */ - QCString templSpecifiers; -}; - -/** List of base classes. - * - * The classes are alphabetically sorted on name if inSort() is used. - */ -class BaseClassList : public QList<BaseClassDef> -{ - public: - ~BaseClassList() {} - int compareValues(const BaseClassDef *item1,const BaseClassDef *item2) const - { - const ClassDef *c1=item1->classDef; - const ClassDef *c2=item2->classDef; - if (c1==0 || c2==0) - return FALSE; - else - return qstricmp(c1->name(),c2->name()); - } -}; - -/** Iterator for a list of base classes. - */ -class BaseClassListIterator : public QListIterator<BaseClassDef> -{ - public: - BaseClassListIterator(const BaseClassList &bcl) : - QListIterator<BaseClassDef>(bcl) {} -}; - -//------------------------------------------------------------------------ - /** Class that contains information about a type constraint relations. */ @@ -26,12 +26,14 @@ * includes */ +#include <utility> #include <memory> #include <algorithm> #include <unordered_map> #include <stack> #include <vector> #include <string> +#include <mutex> #include <stdio.h> #include <assert.h> @@ -55,6 +57,7 @@ #include "filename.h" #include "namespacedef.h" #include "tooltip.h" +#include "scopedtypevariant.h" // Toggle for some debugging info //#define DBG_CTX(x) fprintf x @@ -68,10 +71,6 @@ #define USE_STATE2STRING 0 -/* ----------------------------------------------------------------- - * statics - */ - // context for an Objective-C method call struct ObjCCallCtx { @@ -87,116 +86,11 @@ struct ObjCCallCtx int braceCount; }; -/*! Represents a stack of variable to class mappings as found in the - * code. Each scope is enclosed in pushScope() and popScope() calls. - * Variables are added by calling addVariables() and one can search - * for variable using findVariable(). - */ -class VariableContext -{ - public: - static const ClassDef *dummyContext; - - using Scope = std::unordered_map<std::string,const ClassDef*>; - - void pushScope() - { - m_scopes.push_back(Scope()); - DBG_CTX((stderr,"** Push var context %zu\n",m_scopes.size())); - } - - void popScope() - { - if (!m_scopes.empty()) - { - DBG_CTX((stderr,"** Pop var context %zu\n",m_scopes.size())); - m_scopes.pop_back(); - } - else - { - DBG_CTX((stderr,"** ILLEGAL: Pop var context\n")); - } - } - - void clear() - { - m_scopes.clear(); - m_globalScope.clear(); - } - - void addVariable(yyscan_t yyscanner,const QCString &type,const QCString &name); - const ClassDef *findVariable(const QCString &name); - - private: - Scope m_globalScope; - std::vector<Scope> m_scopes; -}; - -//------------------------------------------------------------------- - -class CallContext -{ - public: - struct Ctx - { - Ctx(QCString name_, QCString type_) : name(name_), type(type_) {} - QCString name; - QCString type; - const Definition *d = 0; - }; - - CallContext() - { - clear(); - } - - void setScope(const Definition *d) - { - Ctx &ctx = m_defList.back(); - DBG_CTX((stderr,"** Set call context %s (%p)\n",d==0 ? "<null>" : d->name().data(),d)); - ctx.d=d; - } - void pushScope(QCString name_, QCString type_) - { - m_defList.push_back(Ctx(name_,type_)); - DBG_CTX((stderr,"** Push call context %zu\n",m_defList.size())); - } - void popScope(QCString &name_, QCString &type_) - { - if (m_defList.size()>1) - { - DBG_CTX((stderr,"** Pop call context %zu\n",m_defList.size())); - const Ctx &ctx = m_defList.back(); - name_ = ctx.name; - type_ = ctx.type; - m_defList.pop_back(); - } - else - { - DBG_CTX((stderr,"** ILLEGAL: Pop call context\n")); - } - } - void clear() - { - DBG_CTX((stderr,"** Clear call context\n")); - m_defList.clear(); - m_defList.push_back(Ctx("","")); - } - const Definition *getScope() const - { - return m_defList.back().d; - } - - private: - std::vector<Ctx> m_defList; -}; - - struct codeYY_state { CodeOutputInterface * code = 0; - std::unordered_map< std::string, std::unique_ptr<ClassDef> > codeClassMap; + std::unordered_map< std::string, ScopedTypeVariant > codeClassMap; QCString curClassName; QStrList curClassBases; @@ -260,7 +154,7 @@ struct codeYY_state std::stack<int> classScopeLengthStack; - int prefixed_with_this_keyword = FALSE; + int isPrefixedWithThis = FALSE; const Definition *searchCtx = 0; bool collectXRefs = FALSE; @@ -281,6 +175,7 @@ struct codeYY_state QCString forceTagReference; VariableContext theVarContext; CallContext theCallContext; + TooltipManager tooltipManager; }; static bool isCastKeyword(const QCString &s); @@ -312,7 +207,7 @@ static void addParmType(yyscan_t yyscanner); static void addUsingDirective(yyscan_t yyscanner,const char *name); static void setParameterList(yyscan_t yyscanner,const MemberDef *md); static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,const Definition *d); -static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name); +static const MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name); static void updateCallContextForSmartPointer(yyscan_t yyscanner); static bool getLinkInScope(yyscan_t yyscanner,const QCString &c, // scope const QCString &m, // member @@ -342,7 +237,12 @@ static QCString escapeWord(yyscan_t yyscanner,const char *s); static QCString escapeComment(yyscan_t yyscanner,const char *s); static bool skipLanguageSpecificKeyword(yyscan_t yyscanner,const QCString &kw); static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); +static void addVariable(yyscan_t yyscanner,QCString type,QCString name); +//------------------------------------------------------------------- + +static std::mutex g_searchIndexMutex; +static std::mutex g_docCrossReferenceMutex; /* ----------------------------------------------------------------- */ @@ -551,7 +451,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} <ObjCParams>{ID} { yyextra->code->codify(yytext); yyextra->parmName=yytext; - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + addVariable(yyscanner,yyextra->parmType,yyextra->parmName); yyextra->parmType.resize(0);yyextra->parmName.resize(0); } <ObjCMethod,ObjCParams,ObjCParamType>{ID} { @@ -827,7 +727,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} yyextra->name = yytext; if (yyextra->insideBody) { - yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); + addVariable(yyscanner,yyextra->type,yyextra->name); } generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); } @@ -860,8 +760,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} if (getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,yyextra->curClassName)==0) { DBG_CTX((stderr,"Adding new class %s\n",yyextra->curClassName.data())); - std::unique_ptr<ClassDef> ncd { createClassDef("<code>",1,1, - yyextra->curClassName,ClassDef::Class,0,0,FALSE) }; + ScopedTypeVariant var(yyextra->curClassName); // insert base classes. char *s=yyextra->curClassBases.first(); while (s) @@ -870,16 +769,16 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} auto it = yyextra->codeClassMap.find(s); if (it!=yyextra->codeClassMap.end()) { - bcd=it->second.get(); + bcd = dynamic_cast<const ClassDef*>(it->second.globalDef()); } if (bcd==0) bcd=getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,s); - if (bcd && bcd!=ncd.get()) + if (bcd && bcd->name()!=yyextra->curClassName) { - ncd->insertBaseClass(const_cast<ClassDef*>(bcd),s,Public,Normal); + var.localDef()->insertBaseClass(bcd->name()); } s=yyextra->curClassBases.next(); } - yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(ncd))); + yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(var))); } //printf("yyextra->codeClassList.count()=%d\n",yyextra->codeClassList.count()); } @@ -1005,7 +904,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} <UsingName>\n { codifyLines(yyscanner,yytext); BEGIN(Body); } <UsingName>. { codifyLines(yyscanner,yytext); BEGIN(Body); } <Body,FuncCall>"$"?"this"("->"|".") { yyextra->code->codify(yytext); // this-> for C++, this. for C# - yyextra->prefixed_with_this_keyword = TRUE; + yyextra->isPrefixedWithThis = TRUE; } <Body>{KEYWORD}/([^a-z_A-Z0-9]) { if (yyextra->lang==SrcLangExt_Java && qstrcmp("internal",yytext) ==0) REJECT; @@ -1039,7 +938,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} endFontClass(yyscanner); // insert the variable in the parent scope, see bug 546158 yyextra->theVarContext.popScope(); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + addVariable(yyscanner,yyextra->parmType,yyextra->parmName); yyextra->theVarContext.pushScope(); yyextra->name.resize(0);yyextra->type.resize(0); } @@ -1359,9 +1258,9 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} BEGIN( MemberCall ); } <MemberCall>{SCOPETNAME}/{BN}*"(" { - if (yyextra->theCallContext.getScope()) + if (yyextra->theCallContext.getScope().globalDef()) { - if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext)) + if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope().globalDef(),yytext)) { yyextra->code->codify(yytext); addToSearchIndex(yyscanner,yytext); @@ -1385,10 +1284,10 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} } } <MemberCall>{SCOPENAME}/{B}* { - if (yyextra->theCallContext.getScope()) + if (yyextra->theCallContext.getScope().globalDef()) { - DBG_CTX((stderr,"yyextra->theCallContext.getClass()=%p\n",yyextra->theCallContext.getScope())); - if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext)) + DBG_CTX((stderr,"yyextra->theCallContext.getClass()=%p\n",yyextra->theCallContext.getScope().globalDef())); + if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope().globalDef(),yytext)) { yyextra->code->codify(yytext); addToSearchIndex(yyscanner,yytext); @@ -1435,7 +1334,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} { //printf("AddVariable: '%s' '%s' context=%d\n", // yyextra->type.data(),yyextra->name.data(),yyextra->theVarContext.count()); - yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); + addVariable(yyscanner,yyextra->type,yyextra->name); } yyextra->name.resize(0); } @@ -1665,7 +1564,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} } <MemberCall2,FuncCall>, { yyextra->code->codify(yytext); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + addVariable(yyscanner,yyextra->parmType,yyextra->parmName); yyextra->parmType.resize(0);yyextra->parmName.resize(0); } <MemberCall2,FuncCall>"{" { @@ -1727,13 +1626,13 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} yyextra->parmType=yyextra->parmName; yyextra->parmName.resize(0); } - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + addVariable(yyscanner,yyextra->parmType,yyextra->parmName); } else { yyextra->parmType = yyextra->parmName; yyextra->parmName.resize(0); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + addVariable(yyscanner,yyextra->parmType,yyextra->parmName); } yyextra->theCallContext.popScope(yyextra->name, yyextra->type); yyextra->inForEachExpression = FALSE; @@ -1762,10 +1661,10 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} if (!yyextra->type.isEmpty()) { DBG_CTX((stderr,"add variable yyextra->type=%s yyextra->name=%s)\n",yyextra->type.data(),yyextra->name.data())); - yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); + addVariable(yyscanner,yyextra->type,yyextra->name); } yyextra->parmType.resize(0);yyextra->parmName.resize(0); - yyextra->theCallContext.setScope(0); + yyextra->theCallContext.setScope(ScopedTypeVariant()); if (*yytext==';' || yyextra->insideBody) { if (!yyextra->insideBody) @@ -1791,7 +1690,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} { yyextra->theVarContext.pushScope(); } - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + addVariable(yyscanner,yyextra->parmType,yyextra->parmName); //yyextra->theCallContext.popScope(yyextra->name, yyextra->type); yyextra->parmType.resize(0);yyextra->parmName.resize(0); int index = yyextra->name.findRev("::"); @@ -1865,7 +1764,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} } <OldStyleArgs>[,;] { yyextra->code->codify(yytext); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + addVariable(yyscanner,yyextra->parmType,yyextra->parmName); if (*yytext==';') yyextra->parmType.resize(0); yyextra->parmName.resize(0); } @@ -1912,6 +1811,14 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} yyextra->type.resize(0); yyextra->name.resize(0); BEGIN( Body ); } +<SkipInits>{ID}{B}*"{" { + QCString text = yytext; + int bracketPos = text.find('{'); + int spacePos = text.find(' '); + int len = spacePos==-1 ? bracketPos : spacePos; + generateClassOrGlobalLink(yyscanner,*yyextra->code,text.left(len)); + yyextra->code->codify(yytext+len); + } <SkipInits>{ID} { generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); } @@ -2290,7 +2197,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} /*@ ---------------------------------------------------------------------------- */ -void VariableContext::addVariable(yyscan_t yyscanner,const QCString &type,const QCString &name) +static void addVariable(yyscan_t yyscanner,QCString type,QCString name) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //printf("VariableContext::addVariable(%s,%s)\n",type.data(),name.data()); @@ -2307,102 +2214,44 @@ void VariableContext::addVariable(yyscan_t yyscanner,const QCString &type,const if (ltype.isEmpty() || lname.isEmpty()) return; DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' currentDefinition=%s\n", ltype.data(),lname.data(),yyextra->currentDefinition?yyextra->currentDefinition->name().data():"<none>")); - Scope *scope = m_scopes.empty() ? &m_globalScope : &m_scopes.back(); - const ClassDef *varType = 0; auto it = yyextra->codeClassMap.find(ltype.str()); if (it!=yyextra->codeClassMap.end()) // look for class definitions inside the code block { - varType = it->second.get(); - } - if (varType==0) // look for global class definitions - { - varType = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,ltype); - } - int i=0; - if (varType) - { DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",ltype.data(),lname.data())); - scope->emplace(std::make_pair(lname.str(),varType)); // add it to a list + yyextra->theVarContext.addVariable(lname,std::move(it->second)); // add it to a list } - else if ((i=ltype.find('<'))!=-1) + else { - // probably a template class - QCString typeName(ltype.left(i)); - const ClassDef* newDef = 0; - QCString templateArgs(ltype.right(ltype.length() - i)); - it = yyextra->codeClassMap.find(typeName.str()); - if (!typeName.isEmpty()) + const ClassDef *varDef = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,ltype); + int i=0; + if (varDef) { - if (it!=yyextra->codeClassMap.end()) // look for class definitions inside the code block - { - varType = it->second.get(); - } - else // otherwise look for global class definitions - { - varType = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,typeName,0,0,TRUE,TRUE); - } + DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",ltype.data(),lname.data())); + yyextra->theVarContext.addVariable(lname,ScopedTypeVariant(varDef)); // add it to a list } - if (varType && !varType->templateArguments().empty()) // and it must be a template + else if ((i=ltype.find('<'))!=-1) { - newDef = varType->getVariableInstance( templateArgs ); - } - if (newDef) - { - DBG_CTX((stderr,"** addVariable type='%s' templ='%s' name='%s'\n",typeName.data(),templateArgs.data(),lname.data())); - scope->emplace(std::make_pair(lname.str(), newDef)); - } - else - { - // Doesn't seem to be a template. Try just the base name. + // probably a template class + QCString typeName(ltype.left(i)); addVariable(yyscanner,typeName,name); } - } - else - { - if (!m_scopes.empty()) // for local variables add a dummy entry so the name - // is hidden to avoid false links to global variables with the same name - // TODO: make this work for namespaces as well! - { - DBG_CTX((stderr,"** addVariable: dummy context for '%s'\n",lname.data())); - scope->emplace(std::make_pair(lname.str(),dummyContext)); - } else { - DBG_CTX((stderr,"** addVariable: not adding variable!\n")); - } - } -} - -const ClassDef *VariableContext::findVariable(const QCString &name) -{ - if (name.isEmpty()) return 0; - const ClassDef *result = 0; - - // search from inner to outer scope - auto it = std::rbegin(m_scopes); - while (it != std::rend(m_scopes)) - { - auto it2 = it->find(name.str()); - if (it2 != std::end(*it)) - { - result = it2->second; - DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result)); - return result; + if (!yyextra->theVarContext.atGlobalScope()) // for local variables add a dummy entry so the name + // is hidden to avoid false links to global variables with the same name + // TODO: make this work for namespaces as well! + { + DBG_CTX((stderr,"** addVariable: dummy context for '%s'\n",lname.data())); + yyextra->theVarContext.addVariable(lname,ScopedTypeVariant()); + } + else + { + DBG_CTX((stderr,"** addVariable: not adding variable!\n")); + } } - ++it; } - // nothing found -> also try the global scope - auto it2 = m_globalScope.find(name.str()); - if (it2 != m_globalScope.end()) - { - result = it2->second; - } - DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result)); - return result; } -const ClassDef *VariableContext::dummyContext = (ClassDef*)0x8; - //------------------------------------------------------------------- /*! add class/namespace name s to the scope */ @@ -2445,6 +2294,7 @@ static void setCurrentDoc(yyscan_t yyscanner,const QCString &anchor) struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (Doxygen::searchIndex) { + std::lock_guard<std::mutex> lock(g_searchIndexMutex); if (yyextra->searchCtx) { yyextra->code->setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),FALSE); @@ -2461,6 +2311,7 @@ static void addToSearchIndex(yyscan_t yyscanner,const char *text) struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (Doxygen::searchIndex) { + std::lock_guard<std::mutex> lock(g_searchIndexMutex); yyextra->code->addWord(text,FALSE); } } @@ -2620,8 +2471,8 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, const char *text) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); - TooltipManager::instance()->addTooltip(d); + bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); + yyextra->tooltipManager.addTooltip(d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); @@ -2702,7 +2553,7 @@ static void setParameterList(yyscan_t yyscanner,const MemberDef *md) if (i!=-1) yyextra->parmType = yyextra->parmType.left(i); yyextra->parmType.stripPrefix("const "); yyextra->parmType=yyextra->parmType.stripWhiteSpace(); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + addVariable(yyscanner,yyextra->parmType,yyextra->parmName); } } @@ -2735,7 +2586,7 @@ static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,const Def return 0; } -static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) +static const MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) { if (name.isEmpty()) return 0; struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; @@ -2754,7 +2605,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) if (md) { //printf("name=%s scope=%s\n",locName.data(),scope.data()); - yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); + yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope()))); return md; } } @@ -2767,7 +2618,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) if (md) { //printf("name=%s scope=%s\n",locName.data(),scope.data()); - yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); + yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope()))); return md; } } @@ -2775,32 +2626,32 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) } const MemberName *mn; - const ClassDef *mcd = yyextra->theVarContext.findVariable(name); - if (mcd) // local variable + const ScopedTypeVariant *mcv = yyextra->theVarContext.findVariable(name); + if (mcv) { DBG_CTX((stderr,"local variable?\n")); - if (mcd!=VariableContext::dummyContext) + if (mcv->type()!=ScopedTypeVariant::Dummy) // locally found variable { - DBG_CTX((stderr,"local var '%s' mcd=%s\n",name.data(),mcd->name().data())); - yyextra->theCallContext.setScope(mcd); + DBG_CTX((stderr,"local var '%s' mcd=%s\n",name.data(),mcv.name().data())); + yyextra->theCallContext.setScope(*mcv); } } else { DBG_CTX((stderr,"class member? scope=%s\n",yyextra->classScope.data())); // look for a class member - mcd = getClass(yyextra->classScope); + const ClassDef *mcd = getClass(yyextra->classScope); if (mcd) { DBG_CTX((stderr,"Inside class %s\n",mcd->name().data())); - MemberDef *md=mcd->getMemberByName(name); + const MemberDef *md=mcd->getMemberByName(name); if (md) { DBG_CTX((stderr,"Found member %s\n",md->name().data())); if (yyextra->scopeStack.empty() || yyextra->scopeStack.top()!=CLASSBLOCK) { DBG_CTX((stderr,"class member '%s' mcd=%s\n",name.data(),mcd->name().data())); - yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); + yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope()))); } return md; } @@ -2816,7 +2667,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) const std::unique_ptr<MemberDef> &md=mn->front(); if (!md->isStatic() || md->getBodyDef()==yyextra->sourceFileDef) { - yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); + yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope()))); return md.get(); } return 0; @@ -2836,7 +2687,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) (yyextra->forceTagReference.isEmpty() || yyextra->forceTagReference==md->getReference()) ) { - yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); + yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope()))); //printf("returning member %s in source file %s\n",md->name().data(),yyextra->sourceFileDef->name().data()); return md.get(); } @@ -2850,7 +2701,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) static void updateCallContextForSmartPointer(yyscan_t yyscanner) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - const Definition *d = yyextra->theCallContext.getScope(); + const Definition *d = yyextra->theCallContext.getScope().globalDef(); //printf("updateCallContextForSmartPointer() cd=%s\n",cd ? d->name().data() : "<none>"); const MemberDef *md; if (d && d->definitionType()==Definition::TypeClass && (md=(dynamic_cast<const ClassDef*>(d))->isSmartPointer())) @@ -2858,7 +2709,7 @@ static void updateCallContextForSmartPointer(yyscan_t yyscanner) const ClassDef *ncd = stripClassName(yyscanner,md->typeString(),md->getOuterScope()); if (ncd) { - yyextra->theCallContext.setScope(ncd); + yyextra->theCallContext.setScope(ScopedTypeVariant(ncd)); //printf("Found smart pointer call %s->%s!\n",cd->name().data(),ncd->name().data()); } } @@ -2904,13 +2755,14 @@ static bool getLinkInScope(yyscan_t yyscanner, if (md->resolveAlias()->getGroupDef()) d = md->resolveAlias()->getGroupDef(); if (d && d->isLinkable()) { - yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); + yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope()))); //printf("yyextra->currentDefinition=%p yyextra->currentMemberDef=%p yyextra->insideBody=%d\n", // yyextra->currentDefinition,yyextra->currentMemberDef,yyextra->insideBody); if (yyextra->currentDefinition && yyextra->currentMemberDef && md!=yyextra->currentMemberDef && yyextra->insideBody && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); } //printf("d->getReference()='%s' d->getOutputBase()='%s' name='%s' member name='%s'\n",d->getReference().data(),d->getOutputFileBase().data(),d->name().data(),md->name().data()); @@ -2981,12 +2833,13 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, { className = substitute(className,".","::"); // for PHP namespaces } - const ClassDef *cd=0,*lcd=0; + const ScopedTypeVariant *lcd=0; + const ClassDef *cd=0; const MemberDef *md=0; bool isLocal=FALSE; //printf("generateClassOrGlobalLink(className=%s)\n",className.data()); - if (!yyextra->prefixed_with_this_keyword || (lcd=yyextra->theVarContext.findVariable(className))==0) // not a local variable + if (!yyextra->isPrefixedWithThis || (lcd=yyextra->theVarContext.findVariable(className))==0) // not a local variable { const Definition *d = yyextra->currentDefinition; //printf("d=%s yyextra->sourceFileDef=%s\n",d?d->name().data():"<none>",yyextra->sourceFileDef?yyextra->sourceFileDef->name().data():"<none>"); @@ -3006,7 +2859,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, const NamespaceDef *nd = getResolvedNamespace(className); if (nd && nd->isLinkable()) { - yyextra->theCallContext.setScope(nd); + yyextra->theCallContext.setScope(ScopedTypeVariant(nd)); addToSearchIndex(yyscanner,className); writeMultiLineCodeLink(yyscanner,*yyextra->code,nd,clName); return; @@ -3026,10 +2879,10 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, else { //printf("local variable!\n"); - if (lcd!=VariableContext::dummyContext) + if (lcd->type()!=ScopedTypeVariant::Dummy) { //printf("non-dummy context lcd=%s!\n",lcd->name().data()); - yyextra->theCallContext.setScope(lcd); + yyextra->theCallContext.setScope(*lcd); // to following is needed for links to a global variable, but is // no good for a link to a local variable that is also a global symbol. @@ -3042,7 +2895,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, isLocal=TRUE; DBG_CTX((stderr,"is a local variable cd=%p!\n",cd)); } - yyextra->prefixed_with_this_keyword = FALSE; // discard the "this" prefix for the next calls + yyextra->isPrefixedWithThis = FALSE; // discard the "this" prefix for the next calls if (cd && cd->isLinkable()) // is it a linkable class { @@ -3061,7 +2914,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, } writeMultiLineCodeLink(yyscanner,ol,cd,clName); addToSearchIndex(yyscanner,className); - yyextra->theCallContext.setScope(cd); + yyextra->theCallContext.setScope(ScopedTypeVariant(cd)); if (md) { const Definition *d = md->getOuterScope()==Doxygen::globalScope ? @@ -3070,6 +2923,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, if (d && d->isLinkable() && md->isLinkable() && yyextra->currentMemberDef && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); } } @@ -3081,18 +2935,19 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, { if (md==0) // not found as a typedef { + AccessStack accessStack; md = setCallContextForVar(yyscanner,clName); //printf("setCallContextForVar(%s) md=%p yyextra->currentDefinition=%p\n",clName,md,yyextra->currentDefinition); if (md && yyextra->currentDefinition) { DBG_CTX((stderr,"%s accessible from %s? %d md->getOuterScope=%s\n", md->name().data(),yyextra->currentDefinition->name().data(), - isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md), + isAccessibleFrom(accessStack,yyextra->currentDefinition,yyextra->sourceFileDef,md), md->getOuterScope()->name().data())); } if (md && yyextra->currentDefinition && - isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md)==-1) + isAccessibleFrom(accessStack,yyextra->currentDefinition,yyextra->sourceFileDef,md)==-1) { md=0; // variable not accessible } @@ -3123,6 +2978,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, addToSearchIndex(yyscanner,clName); if (yyextra->currentMemberDef && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); } return; @@ -3165,7 +3021,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner, const ClassDef *typeClass = stripClassName(yyscanner,removeAnonymousScopes(xmd->typeString()),xmd->getOuterScope()); DBG_CTX((stderr,"%s -> typeName=%p\n",xmd->typeString(),typeClass)); - yyextra->theCallContext.setScope(typeClass); + yyextra->theCallContext.setScope(ScopedTypeVariant(typeClass)); const Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ? xmd->getFileDef() : xmd->getOuterScope(); @@ -3183,6 +3039,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner, if (yyextra->currentDefinition && yyextra->currentMemberDef && /*xmd!=yyextra->currentMemberDef &&*/ yyextra->insideBody && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,xmd); } @@ -3216,7 +3073,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner, const Definition *innerDef = cd->findInnerCompound(memName); if (innerDef) { - yyextra->theCallContext.setScope(innerDef); + yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef)); addToSearchIndex(yyscanner,memName); writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName); return TRUE; @@ -3230,7 +3087,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner, const Definition *innerDef = nd->findInnerCompound(memName); if (innerDef) { - yyextra->theCallContext.setScope(innerDef); + yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef)); addToSearchIndex(yyscanner,memName); writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName); return TRUE; @@ -3251,23 +3108,22 @@ static void generateMemberLink(yyscan_t yyscanner, if (varName.isEmpty()) return; // look for the variable in the current context - const ClassDef *vcd = yyextra->theVarContext.findVariable(varName); - if (vcd) + const ScopedTypeVariant *stv = yyextra->theVarContext.findVariable(varName); + if (stv) { - if (vcd!=VariableContext::dummyContext) + if (stv->type()!=ScopedTypeVariant::Dummy) { //printf("Class found!\n"); - if (getLink(yyscanner,vcd->name(),memName,ol)) + if (getLink(yyscanner,stv->name(),memName,ol)) { //printf("Found result!\n"); return; } - if (vcd->baseClasses()) + if (stv->localDef() && !stv->localDef()->baseClasses().empty()) { - BaseClassListIterator bcli(*vcd->baseClasses()); - for ( ; bcli.current() ; ++bcli) + for (const auto &bcName : stv->localDef()->baseClasses()) { - if (getLink(yyscanner,bcli.current()->classDef->name(),memName,ol)) + if (getLink(yyscanner,bcName,memName,ol)) { //printf("Found result!\n"); return; @@ -3278,7 +3134,7 @@ static void generateMemberLink(yyscan_t yyscanner, } else // variable not in current context, maybe it is in a parent context { - vcd = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,yyextra->classScope); + const ClassDef *vcd = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,yyextra->classScope); if (vcd && vcd->isLinkable()) { //printf("Found class %s for variable '%s'\n",yyextra->classScope.data(),varName.data()); @@ -3350,7 +3206,6 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //CodeClassDef *ccd=0; - const ClassDef *ccd=0; QCString locScope=yyextra->classScope; QCString locFunc=removeRedundantWhiteSpace(funcName); if (yyextra->lang==SrcLangExt_PHP && locFunc.startsWith("self::")) locFunc=locFunc.mid(4); @@ -3416,37 +3271,31 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons auto it = yyextra->codeClassMap.find(fullScope.str()); if (it!=yyextra->codeClassMap.end()) { - ccd = it->second.get(); - } - if (ccd && ccd->baseClasses()) - { - BaseClassListIterator bcli(*ccd->baseClasses()); - for ( ; bcli.current() ; ++bcli) + ScopedTypeVariant ccd = it->second; + if (ccd.localDef() && !ccd.localDef()->baseClasses().empty()) { - if (getLink(yyscanner,bcli.current()->classDef->name(),locFunc,ol,funcName)) + for (const auto &bcName : ccd.localDef()->baseClasses()) { - goto exit; + if (getLink(yyscanner,bcName,locFunc,ol,funcName)) + { + goto exit; + } } } } } - if (!locScope.isEmpty()) + if (!locScope.isEmpty() && fullScope!=locScope) { auto it = yyextra->codeClassMap.find(locScope.str()); if (it!=yyextra->codeClassMap.end()) { - ccd = it->second.get(); - } - if (fullScope!=locScope && ccd) - { - //printf("using classScope %s\n",yyextra->classScope.data()); - if (ccd->baseClasses()) + ScopedTypeVariant ccd = it->second; + if (ccd.localDef() && !ccd.localDef()->baseClasses().empty()) { - BaseClassListIterator bcli(*ccd->baseClasses()); - for ( ; bcli.current() ; ++bcli) + for (const auto &bcName : ccd.localDef()->baseClasses()) { - if (getLink(yyscanner,bcli.current()->classDef->name(),funcWithScope,ol,funcName)) + if (getLink(yyscanner,bcName,funcWithScope,ol,funcName)) { goto exit; } @@ -3519,8 +3368,8 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) { //printf("Looking for object=%s method=%s\n",ctx->objectTypeOrName.data(), // ctx->methodName.data()); - const ClassDef *cd = yyextra->theVarContext.findVariable(ctx->objectTypeOrName); - if (cd==0) // not a local variable + const ScopedTypeVariant *stv = yyextra->theVarContext.findVariable(ctx->objectTypeOrName); + if (stv==0) // not a local variable { if (ctx->objectTypeOrName=="self") { @@ -3569,9 +3418,13 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) else // local variable { //printf(" object is local variable\n"); - if (cd!=VariableContext::dummyContext && !ctx->methodName.isEmpty()) + if (stv->globalDef() && !ctx->methodName.isEmpty()) { - ctx->method = cd->getMemberByName(ctx->methodName); + const ClassDef *cd = dynamic_cast<const ClassDef *>(stv->globalDef()); + if (cd) + { + ctx->method = cd->getMemberByName(ctx->methodName); + } //printf(" class=%p method=%p\n",cd,ctx->method); } } @@ -3606,6 +3459,7 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->method,name); if (yyextra->currentMemberDef && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(ctx->method)); } } @@ -3659,20 +3513,14 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) { cd = cd->categoryOf(); } - const BaseClassList *bcd = cd->baseClasses(); - if (bcd) // get direct base class (there should be only one) + for (const auto &bclass : cd->baseClasses()) { - BaseClassListIterator bli(*bcd); - BaseClassDef *bclass; - for (bli.toFirst();(bclass=bli.current());++bli) + if (bclass.classDef->compoundType()!=ClassDef::Protocol) { - if (bclass->classDef->compoundType()!=ClassDef::Protocol) + ctx->objectType = bclass.classDef; + if (ctx->objectType && !ctx->methodName.isEmpty()) { - ctx->objectType = bclass->classDef; - if (ctx->objectType && !ctx->methodName.isEmpty()) - { - ctx->method = ctx->objectType->getMemberByName(ctx->methodName); - } + ctx->method = ctx->objectType->getMemberByName(ctx->methodName); } } } @@ -3686,11 +3534,11 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->objectVar,object); if (yyextra->currentMemberDef && yyextra->collectXRefs) { + std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(ctx->objectVar)); } } else if (ctx->objectType && - ctx->objectType!=VariableContext::dummyContext && ctx->objectType->isLinkable() ) // object is class name { @@ -4059,6 +3907,8 @@ void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const delete yyextra->sourceFileDef; yyextra->sourceFileDef=0; } + // write the tooltips + yyextra->tooltipManager.writeTooltips(od); printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL); return; diff --git a/src/commentscan.l b/src/commentscan.l index ce495a1..ccf71f6 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -438,6 +438,8 @@ static void handleGuard(yyscan_t yyscanner,const QCString &expr); static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); static void addCite(yyscan_t yyscanner); +#define unput_string(yytext,yyleng) do { for (int i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); } while(0) + //----------------------------------------------------------------------------- #undef YY_INPUT @@ -872,9 +874,9 @@ RCSTAG "$"{ID}":"[^\n$]+"$" yyextra->briefEndsAtDot=FALSE; } } -<Comment>\n { // newline - addOutput(yyscanner,*yytext); - yyextra->lineNr++; +<Comment>{DOCNL} { // newline + addOutput(yyscanner,yytext); + if (*yytext == '\n') yyextra->lineNr++; } <Comment>. { // catch-all for anything else addOutput(yyscanner,*yytext); @@ -954,7 +956,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" warn(yyextra->fileName,yyextra->lineNr, "missing argument after \\enum." ); - unput('\n'); + unput_string(yytext,yyleng); //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); @@ -977,7 +979,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" "missing argument after " "\\namespace." ); - unput('\n'); + unput_string(yytext,yyleng); //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); @@ -1000,7 +1002,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" "missing argument after " "\\package." ); - unput('\n'); + unput_string(yytext,yyleng); //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; BEGIN( Comment ); @@ -1038,7 +1040,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ); //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <ClassDocArg1,CategoryDocArg1>. { // ignore other stuff @@ -1047,7 +1049,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <ClassDocArg2>{DOCNL} { //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <ClassDocArg2>{FILE}|"<>" { // second argument; include file @@ -1071,7 +1073,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" } <ClassDocArg3>{DOCNL} { //if (*yytext=='\n') yyextra->lineNr++; - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <ClassDocArg3>. { // ignore other stuff @@ -1102,7 +1104,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ); //addOutput(yyscanner,'\n'); //if (*yytext=='\n') yyextra->lineNr++; - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <GroupDocArg1>. { // ignore other stuff @@ -1125,7 +1127,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" "\\defgroup %s", yyextra->current->name.data() ); } - unput('\n'); + unput_string(yytext,yyleng); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); BEGIN( Comment ); @@ -1150,7 +1152,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" "missing argument after " "\\page." ); - unput('\n'); + unput_string(yytext,yyleng); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); BEGIN( Comment ); @@ -1158,7 +1160,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <PageDocArg1>. { // ignore other stuff } <PageDocArg2>{DOCNL} { // second argument; page title - unput('\n'); + unput_string(yytext,yyleng); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); BEGIN( Comment ); @@ -1192,7 +1194,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" /* --------- handle arguments of the file/dir/example command ------------ */ <FileDocArg1>{DOCNL} { // no file name specified - unput('\n'); + unput_string(yytext,yyleng); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); BEGIN( Comment ); @@ -1290,7 +1292,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" warn(yyextra->fileName,yyextra->lineNr, "Missing argument of '\\%s' command",yyextra->currentCmd.data() ); - unput('\n'); + unput_string(yytext,yyleng); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); BEGIN( Comment ); @@ -1304,7 +1306,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <LineParam>{DOCNL} { // end of argument //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <LineParam>{LC} { // line continuation @@ -1668,7 +1670,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <NameParam>{DOCNL} { // end of argument //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <NameParam>{LC} { // line continuation @@ -1706,7 +1708,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" } //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <InGroupParam>{LC} { // line continuation @@ -1724,7 +1726,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" { //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); yyextra->langParser->parsePrototype(yyextra->functionProto); BEGIN( Comment ); } @@ -1811,7 +1813,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <ExtendsParam>. { // ignore other stuff @@ -1848,7 +1850,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" ); //if (*yytext=='\n') yyextra->lineNr++; //addOutput(yyscanner,'\n'); - unput('\n'); + unput_string(yytext,yyleng); BEGIN( Comment ); } <CiteLabel>. { // invalid character for cite label @@ -2783,6 +2785,7 @@ static bool makeStructuralIndicator(yyscan_t yyscanner,Entry::Sections s) yyextra->current->section = s; yyextra->current->fileName = yyextra->fileName; yyextra->current->startLine = yyextra->lineNr; + yyextra->current->docLine = yyextra->lineNr; return FALSE; } } diff --git a/src/config.xml b/src/config.xml index d45b937..b90e243 100644 --- a/src/config.xml +++ b/src/config.xml @@ -660,7 +660,8 @@ Go to the <a href="commands.html">next</a> section or return to the <br>Note: For files without extension you can use `no_extension` as a placeholder. <br>Note that for custom extensions you also need to set \ref cfg_file_patterns "FILE_PATTERNS" otherwise the - files are not read by doxygen. + files are not read by doxygen. When specifying `no_extension` you should add `*` + to the \ref cfg_file_patterns "FILE_PATTERNS". ]]> </docs> </option> @@ -1739,10 +1740,10 @@ to disable this feature. <docs> <![CDATA[ If clang assisted parsing is enabled you can provide the clang parser with the - path to the directory containing a file called compile_commands.json. + path to the directory containing a file called `compile_commands.json`. This file is the <a href="http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html"> compilation database</a> containing the options used when the source files were built. - This is equivalent to specifying the "-p" option to a clang tool, such as clang-check. + This is equivalent to specifying the `-p` option to a clang tool, such as `clang-check`. These options will then be passed to the parser. Any options specified with \ref cfg_clang_options "CLANG_OPTIONS" will be added as well. diff --git a/src/configgen.py b/src/configgen.py index 4ffa8f8..063c1f4 100755 --- a/src/configgen.py +++ b/src/configgen.py @@ -62,7 +62,7 @@ def transformDocs(doc): # fallback for not handled doc = re.sub('\\\\ref', '', doc) #<a href="address">description</a> -> description (see: address) - doc = re.sub('<a +href="([^"]*)" *>([^<]*)</a>', '\\2 (see: \\1)', doc) + doc = re.sub('<a +href="([^"]*)" *>([^<]*)</a>', '\\2 (see: \n\\1)', doc) # LaTeX name as formula -> LaTeX doc = doc.replace("\\f$\\mbox{\\LaTeX}\\f$", "LaTeX") # Other formula's (now just 2) so explicitly mentioned. diff --git a/src/context.cpp b/src/context.cpp index ee394d4..394e857 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -4943,7 +4943,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> Cachable &cache = getCache(); if (!cache.sourceRefs) { - cache.sourceRefs.reset(MemberListContext::alloc(m_memberDef->getReferencesMembers(),TRUE)); + cache.sourceRefs.reset(MemberListContext::alloc(m_memberDef->getReferencesMembers())); } return cache.sourceRefs.get(); } @@ -4952,7 +4952,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> Cachable &cache = getCache(); if (!cache.sourceRefBys) { - cache.sourceRefBys.reset(MemberListContext::alloc(m_memberDef->getReferencedByMembers(),TRUE)); + cache.sourceRefBys.reset(MemberListContext::alloc(m_memberDef->getReferencedByMembers())); } return cache.sourceRefBys.get(); } @@ -6541,7 +6541,7 @@ class NestingContext::Private : public GenericNodeListContext if (!nd->isAnonymous() && (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) { - bool hasChildren = namespaceHasVisibleChild(nd,addClasses,false,ClassDef::Class); + bool hasChildren = namespaceHasNestedNamespace(nd); bool isLinkable = nd->isLinkableInProject(); if (isLinkable || hasChildren) { @@ -6670,14 +6670,11 @@ class NestingContext::Private : public GenericNodeListContext } } } - void addDerivedClasses(const BaseClassList *bcl,bool hideSuper) + void addDerivedClasses(const BaseClassList &bcl,bool hideSuper) { - if (bcl==0) return; - BaseClassListIterator bcli(*bcl); - BaseClassDef *bcd; - for (bcli.toFirst() ; (bcd=bcli.current()) ; ++bcli) + for (const auto &bcd : bcl) { - const ClassDef *cd=bcd->classDef; + const ClassDef *cd=bcd.classDef; if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) { continue; @@ -6815,7 +6812,7 @@ void NestingContext::addClassHierarchy(const ClassSDict &classSDict,bool rootOnl p->addClassHierarchy(classSDict,rootOnly); } -void NestingContext::addDerivedClasses(const BaseClassList *bcl,bool hideSuper) +void NestingContext::addDerivedClasses(const BaseClassList &bcl,bool hideSuper) { p->addDerivedClasses(bcl,hideSuper); } @@ -8536,29 +8533,24 @@ class InheritanceListContext::Private : public GenericNodeListContext } }; -InheritanceListContext::InheritanceListContext(const BaseClassList *list, bool baseClasses) : RefCountedContext("InheritanceListContext") +InheritanceListContext::InheritanceListContext(const BaseClassList &list, bool baseClasses) : RefCountedContext("InheritanceListContext") { p = new Private; - if (list) + for (const auto &bcd : list) { - BaseClassListIterator li(*list); - BaseClassDef *bcd; - for (li.toFirst();(bcd=li.current());++li) + const ClassDef *cd=bcd.classDef; + QCString name; + if (baseClasses) { - const ClassDef *cd=bcd->classDef; - QCString name; - if (baseClasses) - { - name = insertTemplateSpecifierInScope( - cd->displayName(),bcd->templSpecifiers); - } - else - { - name = cd->displayName(); - } - //printf("InheritanceListContext: adding %s baseClass=%d\n",name.data(),baseClasses); - p->addClass(cd,name); + name = insertTemplateSpecifierInScope( + cd->displayName(),bcd.templSpecifiers); + } + else + { + name = cd->displayName(); } + //printf("InheritanceListContext: adding %s baseClass=%d\n",name.data(),baseClasses); + p->addClass(cd,name); } } @@ -8589,7 +8581,7 @@ TemplateListIntf::ConstIterator *InheritanceListContext::createIterator() const class MemberListContext::Private : public GenericNodeListContext { public: - void addMember(MemberDef *md) + void addMember(const MemberDef *md) { append(MemberContext::alloc(md)); } @@ -8638,6 +8630,16 @@ MemberListContext::MemberListContext(MemberSDict *list,bool doSort) : RefCounted } } +MemberListContext::MemberListContext(std::vector<const MemberDef *> &&ml) : RefCountedContext("MemberListContext") +{ + p = new Private; + for (const auto &md : ml) + { + p->addMember(md); + } + ml.clear(); +} + MemberListContext::~MemberListContext() { delete p; @@ -9282,31 +9284,26 @@ class InheritedMemberInfoListContext::Private : public GenericNodeListContext int lt2, const QCString &title,bool additionalList, QPtrDict<void> *visitedClasses) { - if (cd->baseClasses()) + for (const auto &ibcd : cd->baseClasses()) { - BaseClassListIterator it(*cd->baseClasses()); - BaseClassDef *ibcd; - for (it.toFirst();(ibcd=it.current());++it) + ClassDef *icd=ibcd.classDef; + if (icd->isLinkable()) { - ClassDef *icd=ibcd->classDef; - if (icd->isLinkable()) + int lt1,lt3; + convertProtectionLevel(lt,ibcd.prot,<1,<3); + if (lt2==-1 && lt3!=-1) { - int lt1,lt3; - convertProtectionLevel(lt,ibcd->prot,<1,<3); - if (lt2==-1 && lt3!=-1) - { - lt2=lt3; - } - if (visitedClasses->find(icd)==0) + lt2=lt3; + } + if (visitedClasses->find(icd)==0) + { + visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance + if (lt1!=-1) { - visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance - if (lt1!=-1) - { - // add member info for members of cd with list type lt - addInheritedMembers(inheritedFrom,icd,lt,(MemberListType)lt1,lt2,title,additionalList); - // recurse down the inheritance tree - findInheritedMembers(inheritedFrom,icd,(MemberListType)lt1,lt2,title,additionalList,visitedClasses); - } + // add member info for members of cd with list type lt + addInheritedMembers(inheritedFrom,icd,lt,(MemberListType)lt1,lt2,title,additionalList); + // recurse down the inheritance tree + findInheritedMembers(inheritedFrom,icd,(MemberListType)lt1,lt2,title,additionalList,visitedClasses); } } } diff --git a/src/context.h b/src/context.h index 7256dc6..240e8fd 100644 --- a/src/context.h +++ b/src/context.h @@ -21,15 +21,12 @@ #include <qlist.h> #include <stdio.h> #include "dirdef.h" +#include "classdef.h" class Definition; -class ClassDef; -class ClassSDict; -class BaseClassList; class PageDef; class GroupDef; class NamespaceDef; -class BaseClassList; class NamespaceSDict; class FileDef; class FileList; @@ -455,7 +452,7 @@ class ClassInheritanceNodeContext : public RefCountedContext, public TemplateStr virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } - void addChildren(const BaseClassList *bcl,bool hideSuper); + void addChildren(const BaseClassList &bcl,bool hideSuper); private: ClassInheritanceNodeContext(const ClassDef *); @@ -553,7 +550,7 @@ class NestingContext : public RefCountedContext, public TemplateListIntf void addModules(const GroupSDict &modules); void addModules(const GroupList &modules); void addClassHierarchy(const ClassSDict &clDict,bool rootOnly); - void addDerivedClasses(const BaseClassList *bcl,bool hideSuper); + void addDerivedClasses(const BaseClassList &bcl,bool hideSuper); private: NestingContext(const NestingNodeContext *parent,int level); @@ -929,7 +926,7 @@ class InheritanceNodeContext : public RefCountedContext, public TemplateStructIn class InheritanceListContext : public RefCountedContext, public TemplateListIntf { public: - static InheritanceListContext *alloc(const BaseClassList *list,bool baseClasses) + static InheritanceListContext *alloc(const BaseClassList &list,bool baseClasses) { return new InheritanceListContext(list,baseClasses); } // TemplateListIntf @@ -940,7 +937,7 @@ class InheritanceListContext : public RefCountedContext, public TemplateListIntf virtual int release() { return RefCountedContext::release(); } private: - InheritanceListContext(const BaseClassList *list,bool baseClasses); + InheritanceListContext(const BaseClassList &list,bool baseClasses); ~InheritanceListContext(); class Private; Private *p; @@ -957,6 +954,8 @@ class MemberListContext : public RefCountedContext, public TemplateListIntf { return new MemberListContext(ml); } static MemberListContext *alloc(MemberSDict *ml,bool doSort) { return new MemberListContext(ml,doSort); } + static MemberListContext *alloc(std::vector<const MemberDef *> &&ml) + { return new MemberListContext(std::move(ml)); } // TemplateListIntf virtual uint count() const; @@ -969,6 +968,7 @@ class MemberListContext : public RefCountedContext, public TemplateListIntf MemberListContext(); MemberListContext(const MemberList *ml); MemberListContext(MemberSDict *ml,bool doSort); + MemberListContext(std::vector<const MemberDef *> &&ml); ~MemberListContext(); class Private; Private *p; diff --git a/src/defargs.l b/src/defargs.l index 6ecc7ff..e25c1fe 100644 --- a/src/defargs.l +++ b/src/defargs.l @@ -511,6 +511,8 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <FuncQual>"volatile" { yyextra->argList->setVolatileSpecifier(TRUE); } +<FuncQual>"override" { + } <FuncQual>"&" { yyextra->argList->setRefQualifier(RefQualifierLValue); } @@ -790,7 +792,7 @@ std::unique_ptr<ArgumentList> stringToArgumentList(SrcLangExt lang, const char * yyextra->argList->setNoParameters(TRUE); } if (extraTypeChars) *extraTypeChars=yyextra->extraTypeChars; - //printf("stringToArgumentList(%s) result=%s\n",argsString,argListToString(al).data()); + //printf("stringToArgumentList(%s) result=%s\n",argsString,argListToString(*al).data()); printlex(yy_flex_debug, FALSE, __FILE__, NULL); defargsYYlex_destroy(yyscanner); return al; diff --git a/src/defgen.cpp b/src/defgen.cpp index 02f51c5..82f7c26 100644 --- a/src/defgen.cpp +++ b/src/defgen.cpp @@ -243,71 +243,58 @@ void generateDEFForMember(MemberDef *md, //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers()); - MemberSDict *mdict = md->getReferencesMembers(); - if (mdict) + QCString refPrefix = " " + memPrefix + "ref-"; + auto refList = md->getReferencesMembers(); + for (const auto &rmd : refList) { - MemberSDict::Iterator mdi(*mdict); - MemberDef *rmd; - QCString refPrefix = " " + memPrefix + "ref-"; - - for (mdi.toFirst();(rmd=mdi.current());++mdi) + if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef()) { - if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef()) + t << memPrefix << "referenceto = {" << endl; + t << refPrefix << "id = '" + << rmd->getBodyDef()->getOutputFileBase() + << "_1" // encoded ':' character (see util.cpp:convertNameToFile) + << rmd->anchor() << "';" << endl; + + t << refPrefix << "line = '" + << rmd->getStartBodyLine() << "';" << endl; + + QCString scope = rmd->getScopeString(); + QCString name = rmd->name(); + if (!scope.isEmpty() && scope!=def->name()) { - t << memPrefix << "referenceto = {" << endl; - t << refPrefix << "id = '" - << rmd->getBodyDef()->getOutputFileBase() - << "_1" // encoded ':' character (see util.cpp:convertNameToFile) - << rmd->anchor() << "';" << endl; - - t << refPrefix << "line = '" - << rmd->getStartBodyLine() << "';" << endl; - - QCString scope = rmd->getScopeString(); - QCString name = rmd->name(); - if (!scope.isEmpty() && scope!=def->name()) - { - name.prepend(scope+"::"); - } - - t << refPrefix << "name = "; - writeDEFString(t,name); - t << ';' << endl << " };" << endl; + name.prepend(scope+"::"); } - } /* for (mdi.toFirst...) */ + + t << refPrefix << "name = "; + writeDEFString(t,name); + t << ';' << endl << " };" << endl; + } } - mdict = md->getReferencedByMembers(); - if (mdict) + auto refByList = md->getReferencedByMembers(); + for (const auto &rmd : refByList) { - MemberSDict::Iterator mdi(*mdict); - MemberDef *rmd; - QCString refPrefix = " " + memPrefix + "ref-"; - - for (mdi.toFirst();(rmd=mdi.current());++mdi) + if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef()) { - if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef()) + t << memPrefix << "referencedby = {" << endl; + t << refPrefix << "id = '" + << rmd->getBodyDef()->getOutputFileBase() + << "_1" // encoded ':' character (see util.cpp:convertNameToFile) + << rmd->anchor() << "';" << endl; + + t << refPrefix << "line = '" + << rmd->getStartBodyLine() << "';" << endl; + + QCString scope = rmd->getScopeString(); + QCString name = rmd->name(); + if (!scope.isEmpty() && scope!=def->name()) { - t << memPrefix << "referencedby = {" << endl; - t << refPrefix << "id = '" - << rmd->getBodyDef()->getOutputFileBase() - << "_1" // encoded ':' character (see util.cpp:convertNameToFile) - << rmd->anchor() << "';" << endl; - - t << refPrefix << "line = '" - << rmd->getStartBodyLine() << "';" << endl; - - QCString scope = rmd->getScopeString(); - QCString name = rmd->name(); - if (!scope.isEmpty() && scope!=def->name()) - { - name.prepend(scope+"::"); - } - - t << refPrefix << "name = "; - writeDEFString(t,name); - t << ';' << endl << " };" << endl; + name.prepend(scope+"::"); } - } /* for (mdi.toFirst...) */ + + t << refPrefix << "name = "; + writeDEFString(t,name); + t << ';' << endl << " };" << endl; + } } t << " }; /* " << Prefix << "-member */" << endl; @@ -358,60 +345,50 @@ void generateDEFForClass(ClassDef *cd,FTextStream &t) t << " cp-id = '" << cd->getOutputFileBase() << "';" << endl; t << " cp-name = '" << cd->name() << "';" << endl; - if (cd->baseClasses()) + for (const auto &bcd : cd->baseClasses()) { - BaseClassListIterator bcli(*cd->baseClasses()); - BaseClassDef *bcd; - for (bcli.toFirst();(bcd=bcli.current());++bcli) + t << " cp-ref = {" << endl << " ref-type = base;" << endl; + t << " ref-id = '" + << bcd.classDef->getOutputFileBase() << "';" << endl; + t << " ref-prot = "; + switch (bcd.prot) { - t << " cp-ref = {" << endl << " ref-type = base;" << endl; - t << " ref-id = '" - << bcd->classDef->getOutputFileBase() << "';" << endl; - t << " ref-prot = "; - switch (bcd->prot) - { - case Public: t << "public;" << endl; break; - case Package: // package scope is not possible - case Protected: t << "protected;" << endl; break; - case Private: t << "private;" << endl; break; - } - t << " ref-virt = "; - switch(bcd->virt) - { - case Normal: t << "non-virtual;"; break; - case Virtual: t << "virtual;"; break; - case Pure: t << "pure-virtual;"; break; - } - t << endl << " };" << endl; + case Public: t << "public;" << endl; break; + case Package: // package scope is not possible + case Protected: t << "protected;" << endl; break; + case Private: t << "private;" << endl; break; + } + t << " ref-virt = "; + switch(bcd.virt) + { + case Normal: t << "non-virtual;"; break; + case Virtual: t << "virtual;"; break; + case Pure: t << "pure-virtual;"; break; } + t << endl << " };" << endl; } - if (cd->subClasses()) + for (const auto &bcd : cd->subClasses()) { - BaseClassListIterator bcli(*cd->subClasses()); - BaseClassDef *bcd; - for (bcli.toFirst();(bcd=bcli.current());++bcli) + t << " cp-ref = {" << endl << " ref-type = derived;" << endl; + t << " ref-id = '" + << bcd.classDef->getOutputFileBase() << "';" << endl; + t << " ref-prot = "; + switch (bcd.prot) { - t << " cp-ref = {" << endl << " ref-type = derived;" << endl; - t << " ref-id = '" - << bcd->classDef->getOutputFileBase() << "';" << endl; - t << " ref-prot = "; - switch (bcd->prot) - { - case Public: t << "public;" << endl; break; - case Package: // packet scope is not possible! - case Protected: t << "protected;" << endl; break; - case Private: t << "private;" << endl; break; - } - t << " ref-virt = "; - switch(bcd->virt) - { - case Normal: t << "non-virtual;"; break; - case Virtual: t << "virtual;"; break; - case Pure: t << "pure-virtual;"; break; - } - t << endl << " };" << endl; + case Public: t << "public;" << endl; break; + case Package: // packet scope is not possible! + case Protected: t << "protected;" << endl; break; + case Private: t << "private;" << endl; break; + } + t << " ref-virt = "; + switch (bcd.virt) + { + case Normal: t << "non-virtual;"; break; + case Virtual: t << "virtual;"; break; + case Pure: t << "pure-virtual;"; break; } + t << endl << " };" << endl; } int numMembers = 0; diff --git a/src/definition.cpp b/src/definition.cpp index 9e78b74..355ef82 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -16,6 +16,10 @@ */ #include <algorithm> +#include <iterator> +#include <unordered_map> +#include <string> + #include <ctype.h> #include <qregexp.h> #include "md5.h" @@ -58,8 +62,8 @@ class DefinitionImpl::IMPL SectionRefs sectionRefs; - MemberSDict *sourceRefByDict = 0; - MemberSDict *sourceRefsDict = 0; + std::unordered_map<std::string,const MemberDef *> sourceRefByDict; + std::unordered_map<std::string,const MemberDef *> sourceRefsDict; RefItemVector xrefListItems; GroupList *partOfGroups = 0; @@ -100,8 +104,6 @@ class DefinitionImpl::IMPL DefinitionImpl::IMPL::~IMPL() { - delete sourceRefByDict; - delete sourceRefsDict; delete partOfGroups; delete brief; delete details; @@ -138,8 +140,8 @@ void DefinitionImpl::IMPL::init(const char *df, const char *n) details = 0; body = 0; inbodyDocs = 0; - sourceRefByDict = 0; - sourceRefsDict = 0; + sourceRefByDict.clear(); + sourceRefsDict.clear(); outerScope = Doxygen::globalScope; partOfGroups = 0; hidden = FALSE; @@ -314,33 +316,11 @@ DefinitionImpl::DefinitionImpl(const DefinitionImpl &d) { m_impl = new DefinitionImpl::IMPL; *m_impl = *d.m_impl; - m_impl->sourceRefByDict = 0; - m_impl->sourceRefsDict = 0; m_impl->partOfGroups = 0; m_impl->brief = 0; m_impl->details = 0; m_impl->body = 0; m_impl->inbodyDocs = 0; - if (d.m_impl->sourceRefByDict) - { - m_impl->sourceRefByDict = new MemberSDict; - MemberSDict::IteratorDict it(*d.m_impl->sourceRefByDict); - MemberDef *md; - for (it.toFirst();(md=it.current());++it) - { - m_impl->sourceRefByDict->append(it.currentKey(),md); - } - } - if (d.m_impl->sourceRefsDict) - { - m_impl->sourceRefsDict = new MemberSDict; - MemberSDict::IteratorDict it(*d.m_impl->sourceRefsDict); - MemberDef *md; - for (it.toFirst();(md=it.current());++it) - { - m_impl->sourceRefsDict->append(it.currentKey(),md); - } - } if (d.m_impl->partOfGroups) { GroupListIterator it(*d.m_impl->partOfGroups); @@ -1262,11 +1242,27 @@ void DefinitionImpl::writeInlineCode(OutputList &ol,const char *scopeName) const ol.popGeneratorState(); } +static inline std::vector<const MemberDef*> refMapToVector(const std::unordered_map<std::string,const MemberDef *> &map) +{ + // convert map to a vector of values + std::vector<const MemberDef *> result; + std::transform(map.begin(),map.end(), // iterate over map + std::back_inserter(result), // add results to vector + [](const auto &item) + { return item.second; } // extract value to add from map Key,Value pair + ); + // and sort it + std::sort(result.begin(),result.end(), + [](const auto &m1,const auto &m2) { return genericCompareMembers(m1,m2)<0; }); + return result; +} + /*! Write a reference to the source code fragments in which this * definition is used. */ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, - const QCString &text,MemberSDict *members,bool /*funcOnly*/) const + const QCString &text,const std::unordered_map<std::string,const MemberDef *> &membersMap, + bool /*funcOnly*/) const { static bool latexSourceCode = Config_getBool(LATEX_SOURCE_CODE); static bool docbookSourceCode = Config_getBool(DOCBOOK_PROGRAMLISTING); @@ -1274,15 +1270,15 @@ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); static bool refLinkSource = Config_getBool(REFERENCES_LINK_SOURCE); ol.pushGeneratorState(); - if (members) + if (!membersMap.empty()) { - members->sort(); + auto members = refMapToVector(membersMap); ol.startParagraph("reference"); ol.parseText(text); ol.docify(" "); - QCString ldefLine=theTranslator->trWriteList((int)members->count()); + QCString ldefLine=theTranslator->trWriteList((int)members.size()); QRegExp marker("@[0-9]+"); uint index=0; @@ -1294,7 +1290,7 @@ void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, bool ok; ol.parseText(ldefLine.mid(index,(uint)newIndex-index)); uint entryIndex = ldefLine.mid(newIndex+1,matchLen-1).toUInt(&ok); - MemberDef *md=members->at(entryIndex); + const MemberDef *md=members.at(entryIndex); if (ok && md) { QCString scope=md->getScopeString(); @@ -1466,14 +1462,7 @@ void DefinitionImpl::addSourceReferencedBy(const MemberDef *md) name.prepend(scope+"::"); } - if (m_impl->sourceRefByDict==0) - { - m_impl->sourceRefByDict = new MemberSDict; - } - if (m_impl->sourceRefByDict->find(name)==0) - { - m_impl->sourceRefByDict->append(name,md); - } + m_impl->sourceRefByDict.insert({name.str(),md}); } } @@ -1489,14 +1478,7 @@ void DefinitionImpl::addSourceReferences(const MemberDef *md) name.prepend(scope+"::"); } - if (m_impl->sourceRefsDict==0) - { - m_impl->sourceRefsDict = new MemberSDict; - } - if (m_impl->sourceRefsDict->find(name)==0) - { - m_impl->sourceRefsDict->append(name,md); - } + m_impl->sourceRefsDict.insert({name.str(),md}); } } @@ -1960,29 +1942,20 @@ QCString DefinitionImpl::briefDescription(bool abbr) const QCString(""); } -QCString DefinitionImpl::briefDescriptionAsTooltip() const +void DefinitionImpl::computeTooltip() { - if (m_impl->brief) + if (m_impl->brief && m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty()) { - if (m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty()) - { - static bool reentering=FALSE; - if (!reentering) - { - const MemberDef *md = definitionType()==TypeMember ? dynamic_cast<const MemberDef*>(this) : 0; - const Definition *scope = definitionType()==TypeMember ? getOuterScope() : this; - reentering=TRUE; // prevent requests for tooltips while parsing a tooltip - m_impl->brief->tooltip = parseCommentAsText( - scope,md, - m_impl->brief->doc, - m_impl->brief->file, - m_impl->brief->line); - reentering=FALSE; - } - } - return m_impl->brief->tooltip; + const MemberDef *md = definitionType()==TypeMember ? dynamic_cast<const MemberDef*>(this) : 0; + const Definition *scope = definitionType()==TypeMember ? getOuterScope() : this; + m_impl->brief->tooltip = parseCommentAsText(scope,md, + m_impl->brief->doc, m_impl->brief->file, m_impl->brief->line); } - return QCString(""); +} + +QCString DefinitionImpl::briefDescriptionAsTooltip() const +{ + return m_impl->brief ? m_impl->brief->tooltip : QCString(); } int DefinitionImpl::briefLine() const @@ -2100,16 +2073,49 @@ Definition *DefinitionImpl::getOuterScope() const return m_impl->outerScope; } -MemberSDict *DefinitionImpl::getReferencesMembers() const +std::vector<const MemberDef*> DefinitionImpl::getReferencesMembers() const +{ + return refMapToVector(m_impl->sourceRefsDict); +} + +std::vector<const MemberDef*> DefinitionImpl::getReferencedByMembers() const +{ + return refMapToVector(m_impl->sourceRefByDict); +} + +void DefinitionImpl::mergeReferences(const Definition *other) { - return m_impl->sourceRefsDict; + const DefinitionImpl *defImpl = dynamic_cast<const DefinitionImpl*>(other); + if (defImpl) + { + for (const auto &kv : defImpl->m_impl->sourceRefsDict) + { + auto it = m_impl->sourceRefsDict.find(kv.first); + if (it != m_impl->sourceRefsDict.end()) + { + m_impl->sourceRefsDict.insert(kv); + } + } + } } -MemberSDict *DefinitionImpl::getReferencedByMembers() const +void DefinitionImpl::mergeReferencedBy(const Definition *other) { - return m_impl->sourceRefByDict; + const DefinitionImpl *defImpl = dynamic_cast<const DefinitionImpl*>(other); + if (defImpl) + { + for (const auto &kv : defImpl->m_impl->sourceRefByDict) + { + auto it = m_impl->sourceRefByDict.find(kv.first); + if (it != m_impl->sourceRefByDict.end()) + { + m_impl->sourceRefByDict.insert({kv.first,kv.second}); + } + } + } } + void DefinitionImpl::setReference(const char *r) { m_impl->ref=r; diff --git a/src/definition.h b/src/definition.h index 8ad15b2..b3d7853 100644 --- a/src/definition.h +++ b/src/definition.h @@ -272,8 +272,8 @@ class Definition : public DefinitionIntf virtual Definition *findInnerCompound(const char *name) const = 0; virtual Definition *getOuterScope() const = 0; - virtual MemberSDict *getReferencesMembers() const = 0; - virtual MemberSDict *getReferencedByMembers() const = 0; + virtual std::vector<const MemberDef *> getReferencesMembers() const = 0; + virtual std::vector<const MemberDef *> getReferencedByMembers() const = 0; virtual bool hasSections() const = 0; virtual bool hasSources() const = 0; @@ -347,6 +347,9 @@ class Definition : public DefinitionIntf virtual void mergeRefItems(Definition *d) = 0; virtual void addInnerCompound(const Definition *d) = 0; virtual void addSectionsToIndex() = 0; + virtual void mergeReferences(const Definition *other) = 0; + virtual void mergeReferencedBy(const Definition *other) = 0; + virtual void computeTooltip() = 0; //----------------------------------------------------------------------------------- // --- writing output ---- diff --git a/src/definitionimpl.h b/src/definitionimpl.h index e91d989..c4e6e2a 100644 --- a/src/definitionimpl.h +++ b/src/definitionimpl.h @@ -18,6 +18,9 @@ #ifndef DEFINITIONIMPL_H #define DEFINITIONIMPL_H +#include <unordered_map> +#include <string> + #include "definition.h" class DefinitionImpl : virtual public Definition @@ -71,8 +74,8 @@ class DefinitionImpl : virtual public Definition virtual const RefItemVector &xrefListItems() const; virtual Definition *findInnerCompound(const char *name) const; virtual Definition *getOuterScope() const; - virtual MemberSDict *getReferencesMembers() const; - virtual MemberSDict *getReferencedByMembers() const; + virtual std::vector<const MemberDef *> getReferencesMembers() const; + virtual std::vector<const MemberDef *> getReferencedByMembers() const; virtual bool hasSections() const; virtual bool hasSources() const; virtual bool hasBriefDescription() const; @@ -92,6 +95,8 @@ class DefinitionImpl : virtual public Definition virtual void addSourceReferences(const MemberDef *d); virtual void setRefItems(const RefItemVector &sli); virtual void mergeRefItems(Definition *d); + virtual void mergeReferences(const Definition *other); + virtual void mergeReferencedBy(const Definition *other); virtual void addInnerCompound(const Definition *d); virtual void setOuterScope(Definition *d); virtual void setHidden(bool b); @@ -113,6 +118,7 @@ class DefinitionImpl : virtual public Definition virtual void writeToc(OutputList &ol, const LocalToc <) const; virtual void setCookie(Cookie *cookie) const; virtual Cookie *cookie() const; + virtual void computeTooltip(); protected: @@ -123,8 +129,8 @@ class DefinitionImpl : virtual public Definition virtual QCString _symbolName() const ; int _getXRefListId(const char *listName) const; - void _writeSourceRefList(OutputList &ol,const char *scopeName, - const QCString &text,MemberSDict *members,bool) const; + void _writeSourceRefList(OutputList &ol,const char *scopeName,const QCString &text, + const std::unordered_map<std::string,const MemberDef *> &members,bool) const; void _setBriefDescription(const char *b,const char *briefFile,int briefLine); void _setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace,bool atTop); void _setInbodyDocumentation(const char *d,const char *docFile,int docLine); @@ -222,9 +228,9 @@ class DefinitionAliasImpl : virtual public Definition { return m_def->findInnerCompound(name); } virtual Definition *getOuterScope() const { return const_cast<Definition*>(m_scope); } - virtual MemberSDict *getReferencesMembers() const + virtual std::vector<const MemberDef *> getReferencesMembers() const { return m_def->getReferencesMembers(); } - virtual MemberSDict *getReferencedByMembers() const + virtual std::vector<const MemberDef *> getReferencedByMembers() const { return m_def->getReferencedByMembers(); } virtual bool hasSections() const { return m_def->hasSections(); } @@ -254,6 +260,8 @@ class DefinitionAliasImpl : virtual public Definition virtual void addSourceReferences(const MemberDef *) {} virtual void setRefItems(const RefItemVector &) {} virtual void mergeRefItems(Definition *) {} + virtual void mergeReferences(const Definition *) {} + virtual void mergeReferencedBy(const Definition *) {} virtual void addInnerCompound(const Definition *) {} virtual void setOuterScope(Definition *) {} virtual void setHidden(bool) {} @@ -273,6 +281,7 @@ class DefinitionAliasImpl : virtual public Definition virtual void writeToc(OutputList &, const LocalToc &) const {} virtual void setCookie(Cookie *cookie) const { delete m_cookie; m_cookie = cookie; } virtual Cookie *cookie() const { return m_cookie; } + virtual void computeTooltip() {} protected: const Definition *getAlias() const { return m_def; } const Definition *getScope() const { return m_scope; } diff --git a/src/diagram.cpp b/src/diagram.cpp index d0b7a08..f2e48d8 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -1,13 +1,10 @@ /****************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -39,7 +36,7 @@ class DiagramItemList; /** Class representing a single node in the built-in class diagram */ -class DiagramItem +class DiagramItem { public: DiagramItem(DiagramItem *p,uint number,const ClassDef *cd, @@ -47,7 +44,7 @@ class DiagramItem ~DiagramItem(); QCString label() const; QCString fileName() const; - DiagramItem *parentItem() { return parent; } + DiagramItem *parentItem() { return parent; } DiagramItemList *getChildren() { return children; } void move(int dx,int dy) { x+=(uint)dx; y+=(uint)dy; } uint xPos() const { return x; } @@ -59,7 +56,7 @@ class DiagramItem Protection protection() const { return prot; } Specifier virtualness() const { return virt; } void putInList() { inList=TRUE; } - bool isInList() const { return inList; } + bool isInList() const { return inList; } const ClassDef *getClassDef() const { return classDef; } private: DiagramItemList *children; @@ -82,14 +79,14 @@ class DiagramItemList : public QList<DiagramItem> }; /** Class representing a row in the built-in class diagram */ -class DiagramRow : public QList<DiagramItem> +class DiagramRow : public QList<DiagramItem> { public: - DiagramRow(TreeDiagram *d,uint l) : QList<DiagramItem>() + DiagramRow(TreeDiagram *d,uint l) : QList<DiagramItem>() { - diagram=d; + diagram=d; level=l; - setAutoDelete(TRUE); + setAutoDelete(TRUE); } void insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases, Protection prot,Specifier virt,const char *ts); @@ -103,7 +100,7 @@ class DiagramRow : public QList<DiagramItem> class DiagramRowIterator : public QListIterator<DiagramRow> { public: - DiagramRowIterator(const QList<DiagramRow> &d) + DiagramRowIterator(const QList<DiagramRow> &d) : QListIterator<DiagramRow>(d) {} }; @@ -261,7 +258,7 @@ static void writeMapArea(FTextStream &t,const ClassDef *cd,QCString relPath, { QCString ref=cd->getReference(); t << "<area "; - if (!ref.isEmpty()) + if (!ref.isEmpty()) { t << externalLinkTarget(true); } @@ -278,7 +275,7 @@ static void writeMapArea(FTextStream &t,const ClassDef *cd,QCString relPath, { t << "title=\"" << convertToHtml(tooltip) << "\" "; } - t << "alt=\"" << convertToXML(cd->displayName()); + t << "alt=\"" << convertToXML(cd->displayName()); t << "\" shape=\"rect\" coords=\"" << x << "," << y << ","; t << (x+w) << "," << (y+h) << "\"/>" << endl; } @@ -286,7 +283,7 @@ static void writeMapArea(FTextStream &t,const ClassDef *cd,QCString relPath, //----------------------------------------------------------------------------- DiagramItem::DiagramItem(DiagramItem *p,uint number,const ClassDef *cd, - Protection pr,Specifier vi,const char *ts) + Protection pr,Specifier vi,const char *ts) { parent=p; x=y=0; @@ -299,7 +296,7 @@ DiagramItem::DiagramItem(DiagramItem *p,uint number,const ClassDef *cd, templSpec=ts; } -DiagramItem::~DiagramItem() +DiagramItem::~DiagramItem() { delete children; } @@ -360,24 +357,18 @@ void DiagramRow::insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases { //if (cd->visited) return; // the visit check does not work in case of // multiple inheritance of the same class! - DiagramItem *di=new DiagramItem(parent, diagram->at(level)->count(), + DiagramItem *di=new DiagramItem(parent, diagram->at(level)->count(), cd,prot,virt,ts); //cd->visited=TRUE; if (parent) parent->addChild(di); di->move((int)(count()*gridWidth),(int)(level*gridHeight)); append(di); - BaseClassList *bcl=doBases ? cd->baseClasses() : cd->subClasses(); int count=0; - if (bcl) + for (const auto &bcd : doBases ? cd->baseClasses() : cd->subClasses()) { /* there are base/sub classes */ - BaseClassListIterator it(*bcl); - BaseClassDef *bcd; - for (;(bcd=it.current());++it) - { - ClassDef *ccd=bcd->classDef; - if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/) count++; - } + ClassDef *ccd=bcd.classDef; + if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/) count++; } if (count>0 && (prot!=Private || !doBases)) { @@ -391,17 +382,14 @@ void DiagramRow::insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases { row=diagram->at(level+1); } - /* insert base classes in the next row */ - BaseClassListIterator it(*bcl); - BaseClassDef *bcd; - for (;(bcd=it.current());++it) + for (const auto &bcd : doBases ? cd->baseClasses() : cd->subClasses()) { - ClassDef *ccd=bcd->classDef; + ClassDef *ccd=bcd.classDef; if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/) { - row->insertClass(di,ccd,doBases,bcd->prot, - doBases?bcd->virt:Normal, - doBases?bcd->templSpecifiers.data():""); + row->insertClass(di,ccd,doBases,bcd.prot, + doBases?bcd.virt:Normal, + doBases?bcd.templSpecifiers.data():""); } } } @@ -409,7 +397,7 @@ void DiagramRow::insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases TreeDiagram::TreeDiagram(const ClassDef *root,bool doBases) { - setAutoDelete(TRUE); + setAutoDelete(TRUE); DiagramRow *row=new DiagramRow(this,0); append(row); row->insertClass(0,root,doBases,Public,Normal,0); @@ -437,7 +425,7 @@ bool TreeDiagram::layoutTree(DiagramItem *root,uint r) bool moved=FALSE; //printf("layoutTree(%s,%d)\n",root->label().data(),r); - DiagramItemList *dil=root->getChildren(); + DiagramItemList *dil=root->getChildren(); if (dil->count()>0) { uint k; @@ -543,7 +531,7 @@ uint TreeDiagram::computeRows() DiagramItem *di; for (;(di=rit.current());++rit) { - if (di->parentItem()!=opi) curListLen=1; else curListLen++; + if (di->parentItem()!=opi) curListLen=1; else curListLen++; if (curListLen>maxListLen) maxListLen=curListLen; opi=di->parentItem(); } @@ -574,7 +562,7 @@ void TreeDiagram::computeExtremes(uint *maxLabelLen,uint *maxXPos) if (maxXPos) *maxXPos=mx; } -void TreeDiagram::drawBoxes(FTextStream &t,Image *image, +void TreeDiagram::drawBoxes(FTextStream &t,Image *image, bool doBase,bool bitmap, uint baseRows,uint superRows, uint cellWidth,uint cellHeight, @@ -643,20 +631,20 @@ void TreeDiagram::drawBoxes(FTextStream &t,Image *image, } } opi=di->parentItem(); - + if (bitmap) { bool hasDocs=di->getClassDef()->isLinkable(); writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow, - hasDocs,di->getChildren()->count()>0); - if (!firstRow && generateMap) + hasDocs,di->getChildren()->count()>0); + if (!firstRow && generateMap) writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight); } else { writeVectorBox(t,di,xf,yf,di->getChildren()->count()>0); } - + if (doBase) --rit; else ++rit; } done=TRUE; @@ -681,8 +669,8 @@ void TreeDiagram::drawBoxes(FTextStream &t,Image *image, di->yPos()*(cellHeight+labelVertSpacing)/gridHeight; } bool hasDocs=di->getClassDef()->isLinkable(); - writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,hasDocs); - if (!firstRow && generateMap) + writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,hasDocs); + if (!firstRow && generateMap) writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight); } else @@ -754,12 +742,12 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, t << protToString(di->protection()) << endl; if (doBase) { - t << "1 " << (di->xPos()/(float)gridWidth) << " " + t << "1 " << (di->xPos()/(float)gridWidth) << " " << (di->yPos()/(float)gridHeight+superRows-1) << " in\n"; } else { - t << "0 " << (di->xPos()/(float)gridWidth) << " " + t << "0 " << (di->xPos()/(float)gridWidth) << " " << ((float)superRows-0.25f-di->yPos()/(float)gridHeight) << " in\n"; } @@ -919,12 +907,12 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, t << protToString(di->protection()) << endl; if (doBase) { - t << "1 " << di->xPos()/(float)gridWidth << " " + t << "1 " << di->xPos()/(float)gridWidth << " " << (di->yPos()/(float)gridHeight+superRows-1) << " in\n"; } else { - t << "0 " << di->xPos()/(float)gridWidth << " " + t << "0 " << di->xPos()/(float)gridWidth << " " << ((float)superRows-0.25f-di->yPos()/(float)gridHeight) << " in\n"; } @@ -959,12 +947,12 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, t << protToString(p) << endl; if (doBase) { - t << "0 " << di->xPos()/(float)gridWidth << " " + t << "0 " << di->xPos()/(float)gridWidth << " " << (di->yPos()/(float)gridHeight+superRows-1) << " out\n"; } else { - t << "1 " << di->xPos()/(float)gridWidth << " " + t << "1 " << di->xPos()/(float)gridWidth << " " << ((float)superRows-1.75f-di->yPos()/(float)gridHeight) << " out\n"; } @@ -979,14 +967,14 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, uint xs = first->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2; uint xe = last->xPos()*(cellWidth+labelHorSpacing)/gridWidth - + cellWidth/2; + + cellWidth/2; if (doBase) // base classes { - image->drawHorzLine(y,xs,xe,col,mask); + image->drawHorzLine(y,xs,xe,col,mask); } else // super classes { - image->drawHorzLine(y+labelVertSpacing/2,xs,xe,col,mask); + image->drawHorzLine(y+labelVertSpacing/2,xs,xe,col,mask); } } else @@ -994,14 +982,14 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image, t << protToString(p) << endl; if (doBase) { - t << first->xPos()/(float)gridWidth << " " + t << first->xPos()/(float)gridWidth << " " << last->xPos()/(float)gridWidth << " " - << (first->yPos()/(float)gridHeight+superRows-1) + << (first->yPos()/(float)gridHeight+superRows-1) << " conn\n"; } else { - t << first->xPos()/(float)gridWidth << " " + t << first->xPos()/(float)gridWidth << " " << last->xPos()/(float)gridWidth << " " << ((float)superRows-first->yPos()/(float)gridHeight) << " conn\n"; @@ -1066,22 +1054,22 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path, uint rows=baseRows+superRows-1; uint cols=(QMAX(baseMaxX,superMaxX)+gridWidth*2-1)/gridWidth; - + // Estimate the image aspect width and height in pixels. uint estHeight = rows*40; uint estWidth = cols*(20+QMAX(baseMaxLabelWidth,superMaxLabelWidth)); //printf("Estimated size %d x %d\n",estWidth,estHeight); - + const float pageWidth = 14.0f; // estimated page width in cm. // Somewhat lower to deal with estimation - // errors. - + // errors. + // compute the image height in centimeters based on the estimates float realHeight = QMIN(rows,12); // real height in cm float realWidth = realHeight * estWidth/(float)estHeight; if (realWidth>pageWidth) // assume that the page width is about 15 cm { - realHeight*=pageWidth/realWidth; + realHeight*=pageWidth/realWidth; realWidth=pageWidth; } @@ -1089,11 +1077,11 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path, output << "\\begin{figure}[H]\n" "\\begin{center}\n" "\\leavevmode\n"; - output << "\\includegraphics[height=" << realHeight << "cm]{" + output << "\\includegraphics[height=" << realHeight << "cm]{" << fileName << "}" << endl; output << "\\end{center}\n" "\\end{figure}\n"; - + //printf("writeFigure rows=%d cols=%d\n",rows,cols); QCString epsBaseName=(QCString)path+"/"+fileName; @@ -1105,11 +1093,11 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path, term("Could not open file %s for writing\n",f1.name().data()); } FTextStream t(&f1); - + //printf("writeEPS() rows=%d cols=%d\n",rows,cols); - + // generate EPS header and postscript variables and procedures - + t << "%!PS-Adobe-2.0 EPSF-2.0\n"; t << "%%Title: ClassName\n"; t << "%%Creator: Doxygen\n"; @@ -1322,11 +1310,11 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path, << " boxheight rows mul disty rows 1 sub mul add boundaspect mul \n" << " max def\n" << "boundx scalefactor div boundy scalefactor div scale\n"; - + t << "\n% ----- classes -----\n\n"; base->drawBoxes(t,0,TRUE,FALSE,baseRows,superRows,0,0); super->drawBoxes(t,0,FALSE,FALSE,baseRows,superRows,0,0); - + t << "\n% ----- relations -----\n\n"; base->drawConnectors(t,0,TRUE,FALSE,baseRows,superRows,0,0); super->drawConnectors(t,0,FALSE,FALSE,baseRows,superRows,0,0); @@ -1351,7 +1339,7 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path, void ClassDiagram::writeImage(FTextStream &t,const char *path, - const char *relPath,const char *fileName, + const char *relPath,const char *fileName, bool generateMap) const { uint baseRows=base->computeRows(); @@ -1361,7 +1349,7 @@ void ClassDiagram::writeImage(FTextStream &t,const char *path, uint lb,ls,xb,xs; base->computeExtremes(&lb,&xb); super->computeExtremes(&ls,&xs); - + uint cellWidth = QMAX(lb,ls)+labelHorMargin*2; uint maxXPos = QMAX(xb,xs); uint labelVertMargin = 6; //QMAX(6,(cellWidth-fontHeight)/6); // aspect at least 1:3 diff --git a/src/docparser.cpp b/src/docparser.cpp index b79f8c8..b908005 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -176,7 +176,7 @@ static void docParserPushContext(bool saveParamInfo=TRUE) ctx->initialStyleStack = g_initialStyleStack; ctx->copyStack = g_copyStack; ctx->fileName = g_fileName; - ctx->lineNo = doctokenizerYYlineno; + ctx->lineNo = getDoctokinizerLineNr(); ctx->relPath = g_relPath; if (saveParamInfo) @@ -217,7 +217,7 @@ static void docParserPopContext(bool keepParamInfo=FALSE) g_initialStyleStack = ctx->initialStyleStack; g_copyStack = ctx->copyStack; g_fileName = ctx->fileName; - doctokenizerYYlineno = ctx->lineNo; + setDoctokinizerLineNr(ctx->lineNo); g_relPath = ctx->relPath; if (!keepParamInfo) @@ -292,7 +292,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool text.sprintf("image file name %s is ambiguous.\n",qPrint(fileName)); text+="Possible candidates:\n"; text+=showFileDefMatches(Doxygen::imageNameLinkedMap,fileName); - warn_doc_error(g_fileName,doctokenizerYYlineno,"%s", text.data()); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"%s", text.data()); } QCString inputFile = fd->absFilePath(); @@ -331,7 +331,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool if (outfi.isSymLink()) { QFile::remove(outputFile); - warn_doc_error(g_fileName,doctokenizerYYlineno, + warn_doc_error(g_fileName,getDoctokinizerLineNr(), "destination of image %s is a symlink, replacing with image", qPrint(outputFile)); } @@ -349,19 +349,19 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool } else { - warn_doc_error(g_fileName,doctokenizerYYlineno, + warn_doc_error(g_fileName,getDoctokinizerLineNr(), "could not write output image %s",qPrint(outputFile)); } } //else //{ - // warn(g_fileName,doctokenizerYYlineno, + // warn(g_fileName,getDoctokinizerLineNr(), // "Prevented to copy file %s onto itself!\n",qPrint(inputFile)); //} } else { - warn_doc_error(g_fileName,doctokenizerYYlineno, + warn_doc_error(g_fileName,getDoctokinizerLineNr(), "could not open image %s",qPrint(fileName)); } @@ -389,7 +389,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool result=fileName; if (result.left(5)!="http:" && result.left(6)!="https:" && dowarn) { - warn_doc_error(g_fileName,doctokenizerYYlineno, + warn_doc_error(g_fileName,getDoctokinizerLineNr(), "image file %s is not found in IMAGE_PATH: " "assuming external image.",qPrint(fileName) ); @@ -812,16 +812,16 @@ inline void errorHandleDefaultToken(DocNode *parent,int tok, cmd_start = "@"; case TK_COMMAND_BS: children.append(new DocWord(parent,TK_COMMAND_CHAR(tok) + g_token->name)); - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Illegal command %s as part of a %s", qPrint(cmd_start + g_token->name),txt); break; case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found found as part of a %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unsupported symbol %s found found as part of a %s", qPrint(g_token->name), txt); break; default: children.append(new DocWord(parent,g_token->name)); - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s found as part of a %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected token %s found as part of a %s", tokToString(tok), txt); break; } @@ -841,7 +841,7 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(saveCmdName)); return tok; } @@ -910,22 +910,22 @@ static void handleStyleLeave(DocNode *parent,QList<DocNode> &children, { if (g_styleStack.isEmpty()) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found </%s> tag without matching <%s>", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found </%s> tag without matching <%s>", qPrint(tagName),qPrint(tagName)); } else if (g_styleStack.top()->tagName()!=tagNameLower) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found </%s> tag while expecting </%s>", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found </%s> tag while expecting </%s>", qPrint(tagName),qPrint(g_styleStack.top()->tagName())); } else if (g_styleStack.top()->style()!=s) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found </%s> tag while expecting </%s>", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found </%s> tag while expecting </%s>", qPrint(tagName),qPrint(g_styleStack.top()->tagName())); } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found </%s> at different nesting level (%d) than expected (%d)", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found </%s> at different nesting level (%d) than expected (%d)", qPrint(tagName),g_nodeStack.count(),g_styleStack.top()->position()); } } @@ -988,7 +988,7 @@ static int handleAHref(DocNode *parent,QList<DocNode> &children,const HtmlAttrib } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found <a> tag with name option but without value!"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found <a> tag with name option but without value!"); } } else if (opt->name=="href") // <a href=url>..</a> tag @@ -1042,7 +1042,7 @@ static void handleUnclosedStyleCommands() DocStyleChange *sc = g_initialStyleStack.top(); g_initialStyleStack.pop(); handleUnclosedStyleCommands(); - warn_doc_error(g_fileName,doctokenizerYYlineno, + warn_doc_error(g_fileName,getDoctokinizerLineNr(), "end of comment block while expecting " "command </%s>",qPrint(sc->tagName())); } @@ -1165,7 +1165,7 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor { if (g_token->name.left(1)=="#" || g_token->name.left(2)=="::") { - warn_doc_error(g_fileName,doctokenizerYYlineno,"explicit link request to '%s' could not be resolved",qPrint(name)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"explicit link request to '%s' could not be resolved",qPrint(name)); children.append(new DocWord(parent,g_token->name)); } else @@ -1205,7 +1205,7 @@ static DocInternalRef *handleInternalRef(DocNode *parent) QCString tokenName = g_token->name; if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(tokenName)); return 0; } @@ -1213,7 +1213,7 @@ static DocInternalRef *handleInternalRef(DocNode *parent) tok=doctokenizerYYlex(); // get the reference id if (tok!=TK_WORD && tok!=TK_LNKWORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of %s", tokToString(tok),qPrint(tokenName)); return 0; } @@ -1225,7 +1225,7 @@ static DocAnchor *handleAnchor(DocNode *parent) int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(g_token->name)); return 0; } @@ -1233,13 +1233,13 @@ static DocAnchor *handleAnchor(DocNode *parent) tok=doctokenizerYYlex(); if (tok==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment block while parsing the " "argument of command %s",qPrint(g_token->name)); return 0; } else if (tok!=TK_WORD && tok!=TK_LNKWORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of %s", tokToString(tok),qPrint(g_token->name)); return 0; } @@ -1301,7 +1301,7 @@ static void defaultHandleTitleAndSize(const int cmd, DocNode *parent, QList<DocN } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unknown option '%s' after \\%s command, expected 'width' or 'height'", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unknown option '%s' after \\%s command, expected 'width' or 'height'", qPrint(g_token->name), Mappers::cmdMapper->find(cmd).data()); break; } @@ -1330,7 +1330,7 @@ static void defaultHandleTitleAndSize(const int cmd, DocNode *parent, QList<DocN static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children,bool handleWord) { - DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno)); + DBG(("token %s at %d",tokToString(tok),getDoctokinizerLineNr())); if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || tok==TK_COMMAND_AT || tok==TK_COMMAND_BS || tok==TK_HTMLTAG ) @@ -1445,7 +1445,7 @@ reparsetoken: doctokenizerYYsetStateHtmlOnly(); tok = doctokenizerYYlex(); children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::HtmlOnly,g_isExample,g_exampleName,g_token->name=="block")); - if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"htmlonly section ended without end marker"); + if (tok==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"htmlonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -1454,7 +1454,7 @@ reparsetoken: doctokenizerYYsetStateManOnly(); tok = doctokenizerYYlex(); children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::ManOnly,g_isExample,g_exampleName)); - if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"manonly section ended without end marker"); + if (tok==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"manonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -1463,7 +1463,7 @@ reparsetoken: doctokenizerYYsetStateRtfOnly(); tok = doctokenizerYYlex(); children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::RtfOnly,g_isExample,g_exampleName)); - if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"rtfonly section ended without end marker"); + if (tok==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"rtfonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -1472,7 +1472,7 @@ reparsetoken: doctokenizerYYsetStateLatexOnly(); tok = doctokenizerYYlex(); children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::LatexOnly,g_isExample,g_exampleName)); - if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"latexonly section ended without end marker"); + if (tok==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"latexonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -1481,7 +1481,7 @@ reparsetoken: doctokenizerYYsetStateXmlOnly(); tok = doctokenizerYYlex(); children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::XmlOnly,g_isExample,g_exampleName)); - if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"xmlonly section ended without end marker"); + if (tok==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"xmlonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -1490,7 +1490,7 @@ reparsetoken: doctokenizerYYsetStateDbOnly(); tok = doctokenizerYYlex(); children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::DocbookOnly,g_isExample,g_exampleName)); - if (tok==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"docbookonly section ended without end marker"); + if (tok==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"docbookonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -1543,10 +1543,10 @@ reparsetoken: switch (Mappers::htmlTagMapper->map(tokenName)) { case HTML_DIV: - warn_doc_error(g_fileName,doctokenizerYYlineno,"found <div> tag in heading\n"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found <div> tag in heading\n"); break; case HTML_PRE: - warn_doc_error(g_fileName,doctokenizerYYlineno,"found <pre> tag in heading\n"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found <pre> tag in heading\n"); break; case HTML_BOLD: if (!g_token->endTag) @@ -1758,7 +1758,7 @@ static void handleImg(DocNode *parent,QList<DocNode> &children,const HtmlAttribL } if (!found) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"IMG tag does not have a SRC attribute!\n"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"IMG tag does not have a SRC attribute!\n"); } } @@ -1787,7 +1787,7 @@ DocEmoji::DocEmoji(DocNode *parent,const QCString &symName) : m_index = EmojiEntityMapper::instance()->symbol2index(m_symName); if (m_index==-1) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Found unsupported emoji symbol '%s'\n",qPrint(m_symName)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Found unsupported emoji symbol '%s'\n",qPrint(m_symName)); } } @@ -1867,7 +1867,7 @@ static void readTextFileByName(const QCString &file,QCString &text) text = fileToString(fd->absFilePath(),Config_getBool(FILTER_SOURCE_FILES)); if (ambig) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"included file name %s is ambiguous" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"included file name %s is ambiguous" "Possible candidates:\n%s",qPrint(file), qPrint(showFileDefMatches(Doxygen::exampleNameLinkedMap,file)) ); @@ -1875,7 +1875,7 @@ static void readTextFileByName(const QCString &file,QCString &text) } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"included file %s is not found. " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"included file %s is not found. " "Check your EXAMPLE_PATH",qPrint(file)); } } @@ -1918,7 +1918,7 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) m_parent = parent; if (id.isEmpty()) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Empty anchor label"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Empty anchor label"); return; } @@ -1934,7 +1934,7 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid cite anchor id '%s'",qPrint(id)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Invalid cite anchor id '%s'",qPrint(id)); m_anchor = "invalid"; m_file = "invalid"; } @@ -1954,7 +1954,7 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid anchor id '%s'",qPrint(id)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Invalid anchor id '%s'",qPrint(id)); m_anchor = "invalid"; m_file = "invalid"; } @@ -2015,7 +2015,7 @@ void DocInclude::parse() int count; if (!m_blockId.isEmpty() && (count=m_text.contains(m_blockId.data()))!=2) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"block marked with %s for \\snippet should appear twice in file %s, found it %d times\n", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"block marked with %s for \\snippet should appear twice in file %s, found it %d times\n", m_blockId.data(),m_file.data(),count); } break; @@ -2033,7 +2033,7 @@ void DocIncOperator::parse() { if (g_includeFileName.isEmpty()) { - warn_doc_error(g_fileName,doctokenizerYYlineno, + warn_doc_error(g_fileName,getDoctokinizerLineNr(), "No previous '\\include' or '\\dontinclude' command for '\\%s' present", typeAsString()); } @@ -2225,7 +2225,7 @@ DocFormula::DocFormula(DocNode *parent,int id) : } else // wrong \_form#<n> command { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Wrong formula id %d",id); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Wrong formula id %d",id); m_id = -1; } } @@ -2287,13 +2287,13 @@ void DocSecRefItem::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"reference to unknown section %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"reference to unknown section %s", qPrint(m_target)); } } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"reference to empty target"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"reference to empty target"); } DBG(("DocSecRefItem::parse() end\n")); @@ -2324,13 +2324,13 @@ void DocSecRefList::parse() tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\refitem command"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\refitem command"); break; } tok=doctokenizerYYlex(); if (tok!=TK_WORD && tok!=TK_LNKWORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of \\refitem", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of \\refitem", tokToString(tok)); break; } @@ -2343,7 +2343,7 @@ void DocSecRefList::parse() case CMD_ENDSECREFLIST: goto endsecreflist; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\secreflist", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Illegal command %s as part of a \\secreflist", qPrint(cmd_start + g_token->name)); goto endsecreflist; } @@ -2354,7 +2354,7 @@ void DocSecRefList::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s inside section reference list", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected token %s inside section reference list", tokToString(tok)); goto endsecreflist; } @@ -2494,7 +2494,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : } } m_text = target; - warn_doc_error(g_fileName,doctokenizerYYlineno,"unable to resolve reference to '%s' for \\ref command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unable to resolve reference to '%s' for \\ref command", qPrint(target)); } @@ -2589,16 +2589,16 @@ DocCite::DocCite(DocNode *parent,const QCString &target,const QCString &) //cont m_text = target; if (numBibFiles==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"\\cite command found but no bib files specified via CITE_BIB_FILES!"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"\\cite command found but no bib files specified via CITE_BIB_FILES!"); } else if (cite==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unable to resolve reference to '%s' for \\cite command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unable to resolve reference to '%s' for \\cite command", qPrint(target)); } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"\\cite command to '%s' does not have an associated number", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"\\cite command to '%s' does not have an associated number", qPrint(target)); } } @@ -2636,7 +2636,7 @@ DocLink::DocLink(DocNode *parent,const QCString &target) } // bogus link target - warn_doc_error(g_fileName,doctokenizerYYlineno,"unable to resolve link to '%s' for \\link command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unable to resolve link to '%s' for \\link command", qPrint(target)); } @@ -2664,23 +2664,23 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink) case CMD_ENDLINK: if (isJavaLink) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"{@link.. ended with @endlink command"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"{@link.. ended with @endlink command"); } goto endlink; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\link", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Illegal command %s as part of a \\link", qPrint(cmd_start + g_token->name)); break; } break; case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found as part of a \\link", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unsupported symbol %s found as part of a \\link", qPrint(g_token->name)); break; case TK_HTMLTAG: if (g_token->name!="see" || !isXmlLink) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected xml/html command %s found as part of a \\link", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected xml/html command %s found as part of a \\link", qPrint(g_token->name)); } goto endlink; @@ -2708,7 +2708,7 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink) m_children.append(new DocWord(this,g_token->name)); break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected token %s", tokToString(tok)); break; } @@ -2716,7 +2716,7 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink) } if (tok==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected end of comment while inside" " link command\n"); } endlink: @@ -2759,7 +2759,7 @@ bool DocDotFile::parse() ok = true; if (ambig) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"included dot file name %s is ambiguous.\n" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"included dot file name %s is ambiguous.\n" "Possible candidates:\n%s",qPrint(m_name), qPrint(showFileDefMatches(Doxygen::dotFileNameLinkedMap,m_name)) ); @@ -2767,7 +2767,7 @@ bool DocDotFile::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"included dot file %s is not found " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"included dot file %s is not found " "in any of the paths specified via DOTFILE_DIRS!",qPrint(m_name)); } return ok; @@ -2796,7 +2796,7 @@ bool DocMscFile::parse() ok = true; if (ambig) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"included msc file name %s is ambiguous.\n" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"included msc file name %s is ambiguous.\n" "Possible candidates:\n%s",qPrint(m_name), qPrint(showFileDefMatches(Doxygen::mscFileNameLinkedMap,m_name)) ); @@ -2804,7 +2804,7 @@ bool DocMscFile::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"included msc file %s is not found " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"included msc file %s is not found " "in any of the paths specified via MSCFILE_DIRS!",qPrint(m_name)); } return ok; @@ -2835,7 +2835,7 @@ bool DocDiaFile::parse() ok = true; if (ambig) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"included dia file name %s is ambiguous.\n" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"included dia file name %s is ambiguous.\n" "Possible candidates:\n%s",qPrint(m_name), qPrint(showFileDefMatches(Doxygen::diaFileNameLinkedMap,m_name)) ); @@ -2843,7 +2843,7 @@ bool DocDiaFile::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"included dia file %s is not found " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"included dia file %s is not found " "in any of the paths specified via DIAFILE_DIRS!",qPrint(m_name)); } return ok; @@ -2930,7 +2930,7 @@ int DocHtmlHeader::parse() { if (m_level!=1) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h1>", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"<h%d> ended with </h1>", m_level); } goto endheader; @@ -2939,7 +2939,7 @@ int DocHtmlHeader::parse() { if (m_level!=2) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h2>", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"<h%d> ended with </h2>", m_level); } goto endheader; @@ -2948,7 +2948,7 @@ int DocHtmlHeader::parse() { if (m_level!=3) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h3>", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"<h%d> ended with </h3>", m_level); } goto endheader; @@ -2957,7 +2957,7 @@ int DocHtmlHeader::parse() { if (m_level!=4) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h4>", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"<h%d> ended with </h4>", m_level); } goto endheader; @@ -2966,7 +2966,7 @@ int DocHtmlHeader::parse() { if (m_level!=5) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h5>", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"<h%d> ended with </h5>", m_level); } goto endheader; @@ -2975,7 +2975,7 @@ int DocHtmlHeader::parse() { if (m_level!=6) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"<h%d> ended with </h6>", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"<h%d> ended with </h6>", m_level); } goto endheader; @@ -2994,7 +2994,7 @@ int DocHtmlHeader::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected html tag <%s%s> found within <h%d> context", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected html tag <%s%s> found within <h%d> context", g_token->endTag?"/":"",qPrint(g_token->name),m_level); } } @@ -3008,7 +3008,7 @@ int DocHtmlHeader::parse() } if (tok==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected end of comment while inside" " <h%d> tag\n",m_level); } endheader: @@ -3043,7 +3043,7 @@ int DocHRef::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected html tag <%s%s> found within <a href=...> context", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected html tag <%s%s> found within <a href=...> context", g_token->endTag?"/":"",qPrint(g_token->name)); } } @@ -3056,7 +3056,7 @@ int DocHRef::parse() } if (tok==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected end of comment while inside" " <a href=...> tag"); } endhref: @@ -3094,7 +3094,7 @@ int DocInternal::parse(int level) } if (retval==TK_LISTITEM) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid list item found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Invalid list item found"); } } while (retval!=0 && retval!=RetVal_Section && @@ -3120,7 +3120,7 @@ int DocInternal::parse(int level) if (retval==RetVal_Internal) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"\\internal command found inside internal section"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"\\internal command found inside internal section"); } DBG(("DocInternal::parse() end: retval=%x\n",retval)); @@ -3139,7 +3139,7 @@ int DocIndexEntry::parse() int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\addindex command"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\addindex command"); goto endindexentry; } doctokenizerYYsetStateTitle(); @@ -3177,7 +3177,7 @@ int DocIndexEntry::parse() case DocSymbol::Sym_ndash: m_entry+="--"; break; case DocSymbol::Sym_mdash: m_entry+="---"; break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected symbol found as argument of \\addindex"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected symbol found as argument of \\addindex"); break; } } @@ -3204,13 +3204,13 @@ int DocIndexEntry::parse() case CMD_MINUS: m_entry+='-'; break; case CMD_EQUAL: m_entry+='='; break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected command %s found as argument of \\addindex", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected command %s found as argument of \\addindex", qPrint(g_token->name)); break; } break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected token %s", tokToString(tok)); break; } @@ -3245,7 +3245,7 @@ DocHtmlCaption::DocHtmlCaption(DocNode *parent,const HtmlAttribList &attribs) } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid caption id '%s'",qPrint(opt->value)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Invalid caption id '%s'",qPrint(opt->value)); } } else // copy attribute @@ -3278,7 +3278,7 @@ int DocHtmlCaption::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected html tag <%s%s> found within <caption> context", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected html tag <%s%s> found within <caption> context", g_token->endTag?"/":"",qPrint(g_token->name)); } } @@ -3291,7 +3291,7 @@ int DocHtmlCaption::parse() } if (tok==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected end of comment while inside" " <caption> tag"); } endcaption: @@ -3478,7 +3478,7 @@ int DocHtmlRow::parse() } else // found some other tag { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <td> or <th> tag but " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <td> or <th> tag but " "found <%s> instead!",qPrint(g_token->name)); doctokenizerYYpushBackHtmlTag(g_token->name); goto endrow; @@ -3486,13 +3486,13 @@ int DocHtmlRow::parse() } else if (tok==0) // premature end of comment { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment while looking" " for a html description title"); goto endrow; } else // token other than html token { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <td> or <th> tag but found %s token instead!", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <td> or <th> tag but found %s token instead!", tokToString(tok)); goto endrow; } @@ -3542,7 +3542,7 @@ int DocHtmlRow::parseXml(bool isHeading) } else // found some other tag { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <term> or <description> tag but " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <term> or <description> tag but " "found <%s> instead!",qPrint(g_token->name)); doctokenizerYYpushBackHtmlTag(g_token->name); goto endrow; @@ -3550,13 +3550,13 @@ int DocHtmlRow::parseXml(bool isHeading) } else if (tok==0) // premature end of comment { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment while looking" " for a html description title"); goto endrow; } else // token other than html token { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <td> or <th> tag but found %s token instead!", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <td> or <th> tag but found %s token instead!", tokToString(tok)); goto endrow; } @@ -3605,7 +3605,7 @@ getrow: { if (m_caption) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"table already has a caption, found another one"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"table already has a caption, found another one"); } else { @@ -3620,18 +3620,18 @@ getrow: } else // found wrong token { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <tr> or <caption> tag but " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <tr> or <caption> tag but " "found <%s%s> instead!", g_token->endTag ? "/" : "", qPrint(g_token->name)); } } else if (tok==0) // premature end of comment { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment while looking" " for a <tr> or <caption> tag"); } else // token other than html token { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <tr> tag but found %s token instead!", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <tr> tag but found %s token instead!", tokToString(tok)); } @@ -3813,7 +3813,7 @@ int DocHtmlDescTitle::parse() tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(g_token->name)); } else @@ -3822,7 +3822,7 @@ int DocHtmlDescTitle::parse() tok=doctokenizerYYlex(); // get the reference id if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of \\%s command", tokToString(tok),qPrint(cmdName)); } else @@ -3843,7 +3843,7 @@ int DocHtmlDescTitle::parse() tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(cmdName)); } else @@ -3852,7 +3852,7 @@ int DocHtmlDescTitle::parse() tok=doctokenizerYYlex(); if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of \\%s command", tokToString(tok),qPrint(cmdName)); } else @@ -3871,13 +3871,13 @@ int DocHtmlDescTitle::parse() break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s found as part of a <dt> tag", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Illegal command %s found as part of a <dt> tag", qPrint(cmd_start + g_token->name)); } } break; case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol \\%s found as part of a <dt> tag", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unsupported symbol \\%s found as part of a <dt> tag", qPrint(g_token->name)); break; case TK_HTMLTAG: @@ -3912,13 +3912,13 @@ int DocHtmlDescTitle::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected html tag <%s%s> found within <dt> context", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected html tag <%s%s> found within <dt> context", g_token->endTag?"/":"",qPrint(g_token->name)); } } break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s found as part of a <dt> tag", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected token %s found as part of a <dt> tag", tokToString(tok)); break; } @@ -3926,7 +3926,7 @@ int DocHtmlDescTitle::parse() } if (tok==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end of comment while inside" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected end of comment while inside" " <dt> tag"); } endtitle: @@ -3986,7 +3986,7 @@ int DocHtmlDescList::parse() } else // found some other tag { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <dt> tag but " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <dt> tag but " "found <%s> instead!",qPrint(g_token->name)); doctokenizerYYpushBackHtmlTag(g_token->name); goto enddesclist; @@ -3994,13 +3994,13 @@ int DocHtmlDescList::parse() } else if (tok==0) // premature end of comment { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment while looking" " for a html description title"); goto enddesclist; } else // token other than html token { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <dt> tag but found %s token instead!", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <dt> tag but found %s token instead!", tokToString(tok)); goto enddesclist; } @@ -4025,7 +4025,7 @@ int DocHtmlDescList::parse() if (retval==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while inside <dl> block"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment while inside <dl> block"); } enddesclist: @@ -4125,7 +4125,7 @@ int DocHtmlList::parse() { // add dummy item to obtain valid HTML m_children.append(new DocHtmlListItem(this,HtmlAttribList(),1)); - warn_doc_error(g_fileName,doctokenizerYYlineno,"empty list!"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"empty list!"); retval = RetVal_EndList; goto endlist; } @@ -4133,7 +4133,7 @@ int DocHtmlList::parse() { // add dummy item to obtain valid HTML m_children.append(new DocHtmlListItem(this,HtmlAttribList(),1)); - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <li> tag but " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <li> tag but " "found <%s%s> instead!",g_token->endTag?"/":"",qPrint(g_token->name)); doctokenizerYYpushBackHtmlTag(g_token->name); goto endlist; @@ -4143,7 +4143,7 @@ int DocHtmlList::parse() { // add dummy item to obtain valid HTML m_children.append(new DocHtmlListItem(this,HtmlAttribList(),1)); - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment while looking" " for a html list item"); goto endlist; } @@ -4151,7 +4151,7 @@ int DocHtmlList::parse() { // add dummy item to obtain valid HTML m_children.append(new DocHtmlListItem(this,HtmlAttribList(),1)); - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <li> tag but found %s token instead!", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <li> tag but found %s token instead!", tokToString(tok)); goto endlist; } @@ -4165,7 +4165,7 @@ int DocHtmlList::parse() if (retval==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while inside <%cl> block", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment while inside <%cl> block", m_type==Unordered ? 'u' : 'o'); } @@ -4198,7 +4198,7 @@ int DocHtmlList::parseXml() } else // found some other tag { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <item> tag but " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <item> tag but " "found <%s> instead!",qPrint(g_token->name)); doctokenizerYYpushBackHtmlTag(g_token->name); goto endlist; @@ -4206,13 +4206,13 @@ int DocHtmlList::parseXml() } else if (tok==0) // premature end of comment { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while looking" + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment while looking" " for a html list item"); goto endlist; } else // token other than html token { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected <item> tag but found %s token instead!", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected <item> tag but found %s token instead!", tokToString(tok)); goto endlist; } @@ -4228,7 +4228,7 @@ int DocHtmlList::parseXml() if (retval==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment while inside <list type=\"%s\"> block", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment while inside <list type=\"%s\"> block", m_type==Unordered ? "bullet" : "number"); } @@ -4616,7 +4616,7 @@ int DocParamList::parse(const QCString &cmdName) int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(saveCmdName)); retval=0; goto endparamlist; @@ -4654,14 +4654,14 @@ int DocParamList::parse(const QCString &cmdName) doctokenizerYYsetStatePara(); if (tok==0) /* premature end of comment block */ { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment block while parsing the " "argument of command %s",qPrint(saveCmdName)); retval=0; goto endparamlist; } if (tok!=TK_WHITESPACE) /* premature end of comment block */ { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token in comment block while parsing the " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token in comment block while parsing the " "argument of command %s",qPrint(saveCmdName)); retval=0; goto endparamlist; @@ -4734,7 +4734,7 @@ int DocParamList::parseXml(const QCString ¶mName) if (retval==0) /* premature end of comment block */ { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unterminated param or exception tag"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unterminated param or exception tag"); } else { @@ -4853,7 +4853,7 @@ void DocPara::handleCite() int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint("cite")); return; } @@ -4861,13 +4861,13 @@ void DocPara::handleCite() tok=doctokenizerYYlex(); if (tok==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment block while parsing the " "argument of command %s\n", qPrint("cite")); return; } else if (tok!=TK_WORD && tok!=TK_LNKWORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of %s", tokToString(tok),qPrint("cite")); return; } @@ -4885,7 +4885,7 @@ void DocPara::handleEmoji() int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint("emoji")); return; } @@ -4893,13 +4893,13 @@ void DocPara::handleEmoji() tok=doctokenizerYYlex(); if (tok==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment block while parsing the " "argument of command %s\n", qPrint("emoji")); return; } else if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of %s", tokToString(tok),qPrint("emoji")); return; } @@ -4937,7 +4937,7 @@ void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(saveCmdName)); return; } @@ -4946,13 +4946,13 @@ void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type doctokenizerYYsetStatePara(); if (tok==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment block while parsing the " "argument of command %s", qPrint(saveCmdName)); return; } else if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of %s", tokToString(tok),qPrint(saveCmdName)); return; } @@ -5001,7 +5001,7 @@ void DocPara::handleImage(const QCString &cmdName) { if (g_token->name.lower() != "inline") { - warn_doc_error(g_fileName,doctokenizerYYlineno,"currently only 'inline' supported as option of %s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"currently only 'inline' supported as option of %s command", qPrint(saveCmdName)); } else @@ -5012,14 +5012,14 @@ void DocPara::handleImage(const QCString &cmdName) } if (!((tok==TK_WORD) && (g_token->name == "}"))) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected closing '}' at option of %s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected closing '}' at option of %s command", qPrint(saveCmdName)); return; } tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command with option", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command with option", qPrint(saveCmdName)); return; } @@ -5027,7 +5027,7 @@ void DocPara::handleImage(const QCString &cmdName) } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(saveCmdName)); return; } @@ -5035,14 +5035,14 @@ void DocPara::handleImage(const QCString &cmdName) tok=doctokenizerYYlex(); if (tok!=TK_WORD && tok!=TK_LNKWORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of %s", tokToString(tok),qPrint(saveCmdName)); return; } tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(saveCmdName)); return; } @@ -5054,7 +5054,7 @@ void DocPara::handleImage(const QCString &cmdName) else if (imgType=="rtf") t=DocImage::Rtf; else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"output format %s specified as the first argument of " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"output format %s specified as the first argument of " "%s command is not valid", qPrint(imgType),qPrint(saveCmdName)); return; @@ -5064,7 +5064,7 @@ void DocPara::handleImage(const QCString &cmdName) doctokenizerYYsetStatePara(); if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of %s", tokToString(tok),qPrint(saveCmdName)); return; } @@ -5081,7 +5081,7 @@ void DocPara::handleFile(const QCString &cmdName) int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(saveCmdName)); return; } @@ -5090,7 +5090,7 @@ void DocPara::handleFile(const QCString &cmdName) doctokenizerYYsetStatePara(); if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of %s", tokToString(tok),qPrint(saveCmdName)); return; } @@ -5119,7 +5119,7 @@ void DocPara::handleLink(const QCString &cmdName,bool isJavaLink) int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(saveCmdName)); return; } @@ -5127,7 +5127,7 @@ void DocPara::handleLink(const QCString &cmdName,bool isJavaLink) tok=doctokenizerYYlex(); if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"%s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"%s as the argument of %s", tokToString(tok),qPrint(saveCmdName)); return; } @@ -5148,7 +5148,7 @@ void DocPara::handleRef(const QCString &cmdName) int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(saveCmdName)); return; } @@ -5157,7 +5157,7 @@ void DocPara::handleRef(const QCString &cmdName) DocRef *ref=0; if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of %s", tokToString(tok),qPrint(saveCmdName)); goto endref; } @@ -5212,7 +5212,7 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) } else if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(saveCmdName)); return; } @@ -5221,13 +5221,13 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) doctokenizerYYsetStatePara(); if (tok==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment block while parsing the " "argument of command %s",qPrint(saveCmdName)); return; } else if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of %s", tokToString(tok),qPrint(saveCmdName)); return; } @@ -5241,7 +5241,7 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) doctokenizerYYsetStatePara(); if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected block identifier, but found token %s instead while parsing the %s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected block identifier, but found token %s instead while parsing the %s command", tokToString(tok),qPrint(saveCmdName)); return; } @@ -5262,7 +5262,7 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) } docParserPushContext(); g_fileName = fileName; - doctokenizerYYlineno=inc_line; + setDoctokinizerLineNr(inc_line); internalValidatingParseDoc(this,m_children,inc_text); docParserPopContext(); } @@ -5281,20 +5281,20 @@ void DocPara::handleSection(const QCString &cmdName) int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"expected whitespace after \\%s command", qPrint(saveCmdName)); return; } tok=doctokenizerYYlex(); if (tok==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected end of comment block while parsing the " "argument of command %s\n", qPrint(saveCmdName)); return; } else if (tok!=TK_WORD && tok!=TK_LNKWORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected token %s as the argument of %s", tokToString(tok),qPrint(saveCmdName)); return; } @@ -5341,7 +5341,7 @@ int DocPara::handleStartCode() i++; } m_children.append(new DocVerbatim(this,g_context,stripIndentation(g_token->verb.mid(li)),DocVerbatim::Code,g_isExample,g_exampleName,FALSE,lang)); - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"code section ended without end marker"); + if (retval==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"code section ended without end marker"); doctokenizerYYsetStatePara(); return retval; } @@ -5384,7 +5384,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) { case CMD_UNKNOWN: m_children.append(new DocWord(this,TK_COMMAND_CHAR(tok) + cmdName)); - warn_doc_error(g_fileName,doctokenizerYYlineno,"Found unknown command '%c%s'",TK_COMMAND_CHAR(tok),qPrint(cmdName)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Found unknown command '%c%s'",TK_COMMAND_CHAR(tok),qPrint(cmdName)); break; case CMD_EMPHASIS: m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,cmdName,TRUE)); @@ -5551,7 +5551,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) doctokenizerYYsetStateHtmlOnly(); retval = doctokenizerYYlex(); m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::HtmlOnly,g_isExample,g_exampleName,g_token->name=="block")); - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"htmlonly section ended without end marker"); + if (retval==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"htmlonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -5560,7 +5560,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) doctokenizerYYsetStateManOnly(); retval = doctokenizerYYlex(); m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::ManOnly,g_isExample,g_exampleName)); - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"manonly section ended without end marker"); + if (retval==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"manonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -5569,7 +5569,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) doctokenizerYYsetStateRtfOnly(); retval = doctokenizerYYlex(); m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::RtfOnly,g_isExample,g_exampleName)); - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"rtfonly section ended without end marker"); + if (retval==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"rtfonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -5578,7 +5578,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) doctokenizerYYsetStateLatexOnly(); retval = doctokenizerYYlex(); m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::LatexOnly,g_isExample,g_exampleName)); - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"latexonly section ended without end marker"); + if (retval==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"latexonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -5587,7 +5587,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) doctokenizerYYsetStateXmlOnly(); retval = doctokenizerYYlex(); m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::XmlOnly,g_isExample,g_exampleName)); - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"xmlonly section ended without end marker"); + if (retval==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"xmlonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -5596,7 +5596,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) doctokenizerYYsetStateDbOnly(); retval = doctokenizerYYlex(); m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::DocbookOnly,g_isExample,g_exampleName)); - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"docbookonly section ended without end marker"); + if (retval==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"docbookonly section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -5605,7 +5605,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) doctokenizerYYsetStateVerbatim(); retval = doctokenizerYYlex(); m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::Verbatim,g_isExample,g_exampleName)); - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"verbatim section ended without end marker"); + if (retval==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"verbatim section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -5621,7 +5621,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) dv->setWidth(width); dv->setHeight(height); m_children.append(dv); - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"dot section ended without end marker"); + if (retval==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"dot section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -5637,7 +5637,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) dv->setWidth(width); dv->setHeight(height); m_children.append(dv); - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"msc section ended without end marker"); + if (retval==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"msc section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -5659,14 +5659,14 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) dv->setHeight(height); if (jarPath.isEmpty()) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"ignoring \\startuml command because PLANTUML_JAR_PATH is not set"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"ignoring \\startuml command because PLANTUML_JAR_PATH is not set"); delete dv; } else { m_children.append(dv); } - if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"startuml section ended without end marker"); + if (retval==0) warn_doc_error(g_fileName,getDoctokinizerLineNr(),"startuml section ended without end marker"); doctokenizerYYsetStatePara(); } break; @@ -5685,7 +5685,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) case CMD_ENDDOT: case CMD_ENDMSC: case CMD_ENDUML: - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected command %s",qPrint(g_token->name)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected command %s",qPrint(g_token->name)); break; case CMD_PARAM: retval = handleParamSection(cmdName,DocParamSect::Param,FALSE,g_token->paramDir); @@ -5838,10 +5838,10 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) } break; case CMD_SECREFITEM: - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected command %s",qPrint(g_token->name)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected command %s",qPrint(g_token->name)); break; case CMD_ENDSECREFLIST: - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected command %s",qPrint(g_token->name)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected command %s",qPrint(g_token->name)); break; case CMD_FORMULA: { @@ -5853,7 +5853,7 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) // retval = handleLanguageSwitch(); // break; case CMD_INTERNALREF: - //warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected command %s",qPrint(g_token->name)); + //warn_doc_error(g_fileName,getDoctokinizerLineNr(),"unexpected command %s",qPrint(g_token->name)); { DocInternalRef *ref = handleInternalRef(this); if (ref) @@ -5908,7 +5908,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta if (g_token->emptyTag && !(tagId&XML_CmdMask) && tagId!=HTML_UNKNOWN && tagId!=HTML_IMG && tagId!=HTML_BR && tagId!=HTML_HR && tagId!=HTML_P) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"HTML tag ('<%s/>') may not use the 'empty tag' XHTML syntax.", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"HTML tag ('<%s/>') may not use the 'empty tag' XHTML syntax.", tagName.data()); } switch (tagId) @@ -5933,7 +5933,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta if (g_token->emptyTag) break; if (!insideUL(this) && !insideOL(this)) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"lonely <li> tag found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"lonely <li> tag found"); } else { @@ -6014,7 +6014,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta retval = RetVal_DescTitle; break; case HTML_DD: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag <dd> found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected tag <dd> found"); break; case HTML_TABLE: if (!g_token->emptyTag) @@ -6034,7 +6034,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta retval = RetVal_TableHCell; break; case HTML_CAPTION: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag <caption> found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected tag <caption> found"); break; case HTML_BR: { @@ -6115,7 +6115,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta { if (Config_getBool(WARN_NO_PARAMDOC)) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"empty 'name' attribute for <param%s> tag.",tagId==XML_PARAM?"":"type"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"empty 'name' attribute for <param%s> tag.",tagId==XML_PARAM?"":"type"); } } else @@ -6127,7 +6127,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing 'name' attribute from <param%s> tag.",tagId==XML_PARAM?"":"type"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Missing 'name' attribute from <param%s> tag.",tagId==XML_PARAM?"":"type"); } } break; @@ -6145,7 +6145,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing 'name' attribute from <param%sref> tag.",tagId==XML_PARAMREF?"":"type"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Missing 'name' attribute from <param%sref> tag.",tagId==XML_PARAMREF?"":"type"); } } break; @@ -6160,7 +6160,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing 'cref' attribute from <exception> tag."); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Missing 'cref' attribute from <exception> tag."); } } break; @@ -6176,7 +6176,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"lonely <item> tag found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"lonely <item> tag found"); } break; case XML_RETURNS: @@ -6237,7 +6237,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing 'cref' or 'langword' attribute from <see> tag."); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Missing 'cref' or 'langword' attribute from <see> tag."); } } break; @@ -6271,7 +6271,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing 'cref' attribute from <seealso> tag."); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Missing 'cref' attribute from <seealso> tag."); } } break; @@ -6305,7 +6305,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta g_xmlComment=TRUE; break; case HTML_UNKNOWN: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported xml/html tag <%s> found", qPrint(tagName)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unsupported xml/html tag <%s> found", qPrint(tagName)); m_children.append(new DocWord(this, "<"+tagName+g_token->attribsStr+">")); break; case XML_INHERITDOC: @@ -6329,7 +6329,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) case HTML_UL: if (!insideUL(this)) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found </ul> tag without matching <ul>"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found </ul> tag without matching <ul>"); } else { @@ -6339,7 +6339,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) case HTML_OL: if (!insideOL(this)) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found </ol> tag without matching <ol>"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found </ol> tag without matching <ol>"); } else { @@ -6349,7 +6349,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) case HTML_LI: if (!insideLI(this)) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found </li> tag without matching <li>"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found </li> tag without matching <li>"); } else { @@ -6362,7 +6362,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) //case HTML_PRE: // if (!insidePRE(this)) // { - // warn_doc_error(g_fileName,doctokenizerYYlineno,"found </pre> tag without matching <pre>"); + // warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found </pre> tag without matching <pre>"); // } // else // { @@ -6441,37 +6441,37 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) // ignore </th> tag break; case HTML_CAPTION: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </caption> found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected tag </caption> found"); break; case HTML_BR: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal </br> tag found\n"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Illegal </br> tag found\n"); break; case HTML_H1: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h1> found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected tag </h1> found"); break; case HTML_H2: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h2> found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected tag </h2> found"); break; case HTML_H3: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h3> found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected tag </h3> found"); break; case HTML_H4: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h4> found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected tag </h4> found"); break; case HTML_H5: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h5> found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected tag </h5> found"); break; case HTML_H6: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </h6> found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected tag </h6> found"); break; case HTML_IMG: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </img> found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected tag </img> found"); break; case HTML_HR: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal </hr> tag found\n"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Illegal </hr> tag found\n"); break; case HTML_A: - //warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected tag </a> found"); + //warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected tag </a> found"); // ignore </a> tag (can be part of <a name=...></a> break; @@ -6506,12 +6506,12 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) // These tags are defined in .Net but are currently unsupported break; case HTML_UNKNOWN: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported xml/html tag </%s> found", qPrint(tagName)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unsupported xml/html tag </%s> found", qPrint(tagName)); m_children.append(new DocWord(this,"</"+tagName+">")); break; default: // we should not get here! - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected end tag %s\n",qPrint(tagName)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected end tag %s\n",qPrint(tagName)); ASSERT(0); break; } @@ -6529,7 +6529,7 @@ int DocPara::parse() while ((tok=doctokenizerYYlex())) // get the next token { reparsetoken: - DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno)); + DBG(("token %s at %d",tokToString(tok),getDoctokinizerLineNr())); if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || tok==TK_COMMAND_AT || tok == TK_COMMAND_BS || tok==TK_HTMLTAG ) @@ -6651,7 +6651,7 @@ reparsetoken: } break; case TK_ENDLIST: - DBG(("Found end of list inside of paragraph at line %d\n",doctokenizerYYlineno)); + DBG(("Found end of list inside of paragraph at line %d\n",getDoctokinizerLineNr())); if (parent()->kind()==DocNode::Kind_AutoListItem) { ASSERT(parent()->parent()->kind()==DocNode::Kind_AutoList); @@ -6664,13 +6664,13 @@ reparsetoken: } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"End of list marker found " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"End of list marker found " "has invalid indent level"); } } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"End of list marker found without any preceding " + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"End of list marker found without any preceding " "list items"); } break; @@ -6783,7 +6783,7 @@ reparsetoken: } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unsupported symbol %s found", qPrint(g_token->name)); } break; @@ -6818,7 +6818,7 @@ reparsetoken: } break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno, + warn_doc_error(g_fileName,getDoctokinizerLineNr(), "Found unexpected token (id=%x)\n",tok); break; } @@ -6880,7 +6880,7 @@ int DocSection::parse() } if (retval==TK_LISTITEM) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid list item found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Invalid list item found"); } if (retval==RetVal_Internal) { @@ -6921,7 +6921,7 @@ int DocSection::parse() else if (retval==RetVal_Subsubsection && m_level<=Doxygen::subpageNestingLevel+2) { if ((m_level<=1+Doxygen::subpageNestingLevel) && !g_token->sectionId.startsWith("autotoc_md")) - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected subsubsection command found inside %s!",sectionLevelToName[m_level]); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected subsubsection command found inside %s!",sectionLevelToName[m_level]); // then parse any number of nested sections while (retval==RetVal_Subsubsection) // more sections follow { @@ -6935,7 +6935,7 @@ int DocSection::parse() else if (retval==RetVal_Paragraph && m_level<=QMIN(5,Doxygen::subpageNestingLevel+3)) { if ((m_level<=2+Doxygen::subpageNestingLevel) && !g_token->sectionId.startsWith("autotoc_md")) - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected paragraph command found inside %s!",sectionLevelToName[m_level]); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected paragraph command found inside %s!",sectionLevelToName[m_level]); // then parse any number of nested sections while (retval==RetVal_Paragraph) // more sections follow { @@ -6995,7 +6995,7 @@ void DocText::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unsupported symbol %s found", qPrint(g_token->name)); } } @@ -7057,13 +7057,13 @@ void DocText::parse() m_children.append(new DocSymbol(this,DocSymbol::Sym_Equal)); break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected command '%s' found", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected command '%s' found", qPrint(g_token->name)); break; } break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Unexpected token %s", tokToString(tok)); break; } @@ -7107,7 +7107,7 @@ void DocRoot::parse() { if (!g_token->sectionId.startsWith("autotoc_md")) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found paragraph command (id: '%s') outside of subsubsection context!",qPrint(g_token->sectionId)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found paragraph command (id: '%s') outside of subsubsection context!",qPrint(g_token->sectionId)); } while (retval==RetVal_Paragraph) { @@ -7123,13 +7123,13 @@ void DocRoot::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid paragraph id '%s'; ignoring paragraph",qPrint(g_token->sectionId)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Invalid paragraph id '%s'; ignoring paragraph",qPrint(g_token->sectionId)); retval = 0; } } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing id for paragraph; ignoring paragraph"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Missing id for paragraph; ignoring paragraph"); retval = 0; } } @@ -7137,7 +7137,7 @@ void DocRoot::parse() if (retval==RetVal_Subsubsection) { if (!(g_token->sectionId.startsWith("autotoc_md"))) - warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsubsection command (id: '%s') outside of subsection context!",qPrint(g_token->sectionId)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found subsubsection command (id: '%s') outside of subsection context!",qPrint(g_token->sectionId)); while (retval==RetVal_Subsubsection) { if (!g_token->sectionId.isEmpty()) @@ -7152,13 +7152,13 @@ void DocRoot::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid subsubsection id '%s'; ignoring subsubsection",qPrint(g_token->sectionId)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Invalid subsubsection id '%s'; ignoring subsubsection",qPrint(g_token->sectionId)); retval = 0; } } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing id for subsubsection; ignoring subsubsection"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Missing id for subsubsection; ignoring subsubsection"); retval = 0; } } @@ -7167,7 +7167,7 @@ void DocRoot::parse() { if (!g_token->sectionId.startsWith("autotoc_md")) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsection command (id: '%s') outside of section context!",qPrint(g_token->sectionId)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"found subsection command (id: '%s') outside of section context!",qPrint(g_token->sectionId)); } while (retval==RetVal_Subsection) { @@ -7183,20 +7183,20 @@ void DocRoot::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid subsection id '%s'; ignoring subsection",qPrint(g_token->sectionId)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Invalid subsection id '%s'; ignoring subsection",qPrint(g_token->sectionId)); retval = 0; } } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing id for subsection; ignoring subsection"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Missing id for subsection; ignoring subsection"); retval = 0; } } } if (retval==TK_LISTITEM) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid list item found"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Invalid list item found"); } if (retval==RetVal_Internal) { @@ -7223,13 +7223,13 @@ void DocRoot::parse() } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid section id '%s'; ignoring section",qPrint(g_token->sectionId)); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Invalid section id '%s'; ignoring section",qPrint(g_token->sectionId)); retval = 0; } } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing id for section; ignoring section"); + warn_doc_error(g_fileName,getDoctokinizerLineNr(),"Missing id for section; ignoring section"); retval = 0; } } @@ -7397,14 +7397,14 @@ static QCString processCopyDoc(const char *data,uint &len) } else { - warn_doc_error(g_fileName,doctokenizerYYlineno, + warn_doc_error(g_fileName,getDoctokinizerLineNr(), "Found recursive @copy%s or @copydoc relation for argument '%s'.\n", isBrief?"brief":"details",id.data()); } } else { - warn_doc_error(g_fileName,doctokenizerYYlineno, + warn_doc_error(g_fileName,getDoctokinizerLineNr(), "@copy%s or @copydoc target '%s' not found", isBrief?"brief":"details", id.data()); } @@ -7727,7 +7727,7 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, g_markdownSupport = markdownSupport; //printf("Starting comment block at %s:%d\n",g_fileName.data(),startLine); - doctokenizerYYlineno=startLine; + setDoctokinizerLineNr(startLine); uint inpLen=qstrlen(input); QCString inpStr = processCopyDoc(input,inpLen); if (inpStr.isEmpty() || inpStr.at(inpStr.length()-1)!='\n') @@ -7802,7 +7802,7 @@ DocText *validatingParseText(const char *input) if (input) { - doctokenizerYYlineno=1; + setDoctokinizerLineNr(1); doctokenizerYYinit(input,g_fileName,Config_getBool(MARKDOWN_SUPPORT)); // build abstract syntax tree diff --git a/src/doctokenizer.h b/src/doctokenizer.h index f43cd07..235b403 100644 --- a/src/doctokenizer.h +++ b/src/doctokenizer.h @@ -115,12 +115,14 @@ struct TokenInfo // globals extern TokenInfo *g_token; -extern int doctokenizerYYlineno; extern FILE *doctokenizerYYin; // helper functions const char *tokToString(int token); +void setDoctokinizerLineNr(int lineno); +int getDoctokinizerLineNr(void); + // operations on the scanner void doctokenizerYYFindSections(const char *input,const Definition *d, const char *fileName); diff --git a/src/doctokenizer.l b/src/doctokenizer.l index c20ae1a..5b72b77 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -82,6 +82,11 @@ struct DocLexerContext static QStack<DocLexerContext> g_lexerStack; +static int g_yyLineNr = 0; + +#define lineCount(s,len) do { for(int i=0;i<(int)len;i++) if (s[i]=='\n') g_yyLineNr++; } while(0) + + #if USE_STATE2STRING static const char *stateToString(int state); #endif @@ -187,7 +192,7 @@ static void processSection() } else { - warn(g_fileName,yylineno,"Found section/anchor %s without context\n",g_secLabel.data()); + warn(g_fileName,g_yyLineNr,"Found section/anchor %s without context\n",g_secLabel.data()); } SectionInfo *si = SectionManager::instance().find(g_secLabel); if (si) @@ -439,9 +444,9 @@ REFWORD4_NOCV (({SCOPEPRE}*"operator"{OPMASKOP2})|(("::"|"#"){SCOPEPRE}*"operat REFWORD4 {REFWORD4_NOCV}{CVSPEC}? REFWORD {FILEMASK}|{LABELID}|{REFWORD2}|{REFWORD3}|{REFWORD4} REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} +RCSID "$"("Author"|"Date"|"Header"|"Id"|"Locker"|"Log"|"Name"|"RCSfile"|"Revision"|"Source"|"State")":"[^:\n$][^\n$]*"$" %option noyywrap -%option yylineno %x St_Para %x St_Comment @@ -494,6 +499,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} %% <St_Para>\r /* skip carriage return */ <St_Para>^{LISTITEM} { /* list item */ + lineCount(yytext,yyleng); QCString text=yytext; int dashPos = text.findRev('-'); g_token->isEnumList = text.at(dashPos+1)=='#'; @@ -508,6 +514,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } else { + lineCount(yytext,yyleng); QCString text=yytext; static QRegExp re("[*+]"); int listPos = text.findRev(re); @@ -535,6 +542,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } } <St_Para>{BLANK}*(\n|"\\ilinebr"){LISTITEM} { /* list item on next line */ + lineCount(yytext,yyleng); QCString text=extractPartAfterNewLine(yytext); int dashPos = text.findRev('-'); g_token->isEnumList = text.at(dashPos+1)=='#'; @@ -549,6 +557,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } else { + lineCount(yytext,yyleng); QCString text=extractPartAfterNewLine(yytext); static QRegExp re("[*+]"); int markPos = text.findRev(re); @@ -565,6 +574,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } else { + lineCount(yytext,yyleng); QCString text=extractPartAfterNewLine(yytext); static QRegExp re("[1-9]"); int digitPos = text.find(re); @@ -576,11 +586,13 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } } <St_Para>^{ENDLIST} { /* end list */ + lineCount(yytext,yyleng); int dotPos = QCString(yytext).findRev('.'); g_token->indent = computeIndent(yytext,dotPos); return TK_ENDLIST; } <St_Para>{BLANK}*(\n|"\\ilinebr"){ENDLIST} { /* end list on next line */ + lineCount(yytext,yyleng); QCString text=extractPartAfterNewLine(yytext); int dotPos = text.findRev('.'); g_token->indent = computeIndent(text,dotPos); @@ -595,7 +607,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} return TK_COMMAND_AT; } <St_Para>"@_fakenl" { // artificial new line - //yylineno++; + //g_yyLineNr++; } <St_Para>{SPCMD3} { g_token->name = "_form"; @@ -605,7 +617,8 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} return TK_COMMAND_SEL(); } <St_Para>{CMD}"n"\n { /* \n followed by real newline */ - //yylineno++; + lineCount(yytext,yyleng); + //g_yyLineNr++; g_token->name = yytext+1; g_token->name = g_token->name.stripWhiteSpace(); g_token->paramDir=TokenInfo::Unspecified; @@ -681,7 +694,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->name=yytext; return TK_WORD; } -<St_Para>"$"{ID}":"[^:\n$][^\n$]*"$" { /* RCS tag */ +<St_Para>{RCSID} { /* RCS tag */ QCString tagName(yytext+1); int index=tagName.find(':'); g_token->name = tagName.left(index); @@ -704,6 +717,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} for (int i=value.length()-1;i>=0;i--) unput(value.at(i)); } <St_Para>{HTMLTAG} { /* html tag */ + lineCount(yytext,yyleng); handleHtmlTag(); return TK_HTMLTAG; } @@ -739,6 +753,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_Para,St_Text>[\-+0-9] | <St_Para,St_Text>{WORD1} | <St_Para,St_Text>{WORD2} { /* function call */ + lineCount(yytext,yyleng); if (yytext[0]=='%') // strip % if present g_token->name = &yytext[1]; else @@ -765,6 +780,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_Para,St_Text>{BLANK}+ | <St_Para,St_Text>{BLANK}*\n{BLANK}* { /* white space */ + lineCount(yytext,yyleng); g_token->chars=yytext; return TK_WHITESPACE; } @@ -777,20 +793,24 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} { REJECT; } + lineCount(yytext,yyleng); } <St_Para>({BLANK}*\n)+{BLANK}*\n/{MLISTITEM} { /* skip trailing paragraph followed by new list item */ if (!g_markdownSupport || g_insidePre || g_autoListLevel==0) { REJECT; } + lineCount(yytext,yyleng); } <St_Para>({BLANK}*\n)+{BLANK}*\n/{OLISTITEM} { /* skip trailing paragraph followed by new list item */ if (!g_markdownSupport || g_insidePre || g_autoListLevel==0) { REJECT; } + lineCount(yytext,yyleng); } <St_Para>({BLANK}*\n)+{BLANK}*\n{BLANK}* { + lineCount(yytext,yyleng); g_token->indent=computeIndent(yytext,(int)yyleng); int i; // put back the indentation (needed for list items) @@ -817,14 +837,17 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} BEGIN(St_Code); } <St_Code>{WS}*{CMD}"endcode" { + lineCount(yytext,yyleng); return RetVal_OK; } <St_XmlCode>{WS}*"</code>" { + lineCount(yytext,yyleng); return RetVal_OK; } <St_Code,St_XmlCode>[^\\@\n<]+ | <St_Code,St_XmlCode>\n | <St_Code,St_XmlCode>. { + lineCount(yytext,yyleng); g_token->verb+=yytext; } <St_HtmlOnlyOption>" [block]" { // the space is added in commentscan.l @@ -845,6 +868,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_HtmlOnly>[^\\@\n$]+ | <St_HtmlOnly>\n | <St_HtmlOnly>. { + lineCount(yytext,yyleng); g_token->verb+=yytext; } <St_ManOnly>{CMD}"endmanonly" { @@ -853,6 +877,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_ManOnly>[^\\@\n$]+ | <St_ManOnly>\n | <St_ManOnly>. { + lineCount(yytext,yyleng); g_token->verb+=yytext; } <St_RtfOnly>{CMD}"endrtfonly" { @@ -861,6 +886,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_RtfOnly>[^\\@\n$]+ | <St_RtfOnly>\n | <St_RtfOnly>. { + lineCount(yytext,yyleng); g_token->verb+=yytext; } <St_LatexOnly>{CMD}"endlatexonly" { @@ -869,6 +895,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_LatexOnly>[^\\@\n]+ | <St_LatexOnly>\n | <St_LatexOnly>. { + lineCount(yytext,yyleng); g_token->verb+=yytext; } <St_XmlOnly>{CMD}"endxmlonly" { @@ -877,6 +904,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_XmlOnly>[^\\@\n]+ | <St_XmlOnly>\n | <St_XmlOnly>. { + lineCount(yytext,yyleng); g_token->verb+=yytext; } <St_DbOnly>{CMD}"enddocbookonly" { @@ -885,6 +913,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_DbOnly>[^\\@\n]+ | <St_DbOnly>\n | <St_DbOnly>. { + lineCount(yytext,yyleng); g_token->verb+=yytext; } <St_Verbatim>{CMD}"endverbatim" { @@ -894,6 +923,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_Verbatim>[^\\@\n]+ | <St_Verbatim>\n | <St_Verbatim>. { /* Verbatim text */ + lineCount(yytext,yyleng); g_token->verb+=yytext; } <St_Dot>{CMD}"enddot" { @@ -902,6 +932,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_Dot>[^\\@\n]+ | <St_Dot>\n | <St_Dot>. { /* dot text */ + lineCount(yytext,yyleng); g_token->verb+=yytext; } <St_Msc>{CMD}("endmsc") { @@ -910,6 +941,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_Msc>[^\\@\n]+ | <St_Msc>\n | <St_Msc>. { /* msc text */ + lineCount(yytext,yyleng); g_token->verb+=yytext; } <St_PlantUMLOpt>{BLANK}*"{"[^}]*"}" { // case 1: file name is specified as {filename} @@ -947,6 +979,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_PlantUML>[^\\@\n]+ | <St_PlantUML>\n | <St_PlantUML>. { /* plantuml text */ + lineCount(yytext,yyleng); g_token->verb+=yytext; } <St_Title>"\"" { // quoted title @@ -973,6 +1006,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} return TK_SYMBOL; } <St_TitleN>{HTMLTAG} { + lineCount(yytext,yyleng); } <St_TitleN>\n { /* new line => end of title */ unput(*yytext); @@ -998,6 +1032,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_TitleN>[\-+0-9] | <St_TitleN>{WORD1} | <St_TitleN>{WORD2} { /* word */ + lineCount(yytext,yyleng); if (yytext[0]=='%') // strip % if present g_token->name = &yytext[1]; else @@ -1041,6 +1076,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} BEGIN(St_TitleV); } <St_TitleV>[^ \t\r\n]+ { // attribute value + lineCount(yytext,yyleng); g_token->chars = yytext; BEGIN(St_TitleN); return TK_WORD; @@ -1055,6 +1091,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } <St_Anchor>{LABELID}{WS}? { // anchor + lineCount(yytext,yyleng); g_token->name = QCString(yytext).stripWhiteSpace(); return TK_WORD; } @@ -1103,6 +1140,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} return 0; } <St_Ref>{WS}+"\""{WS}* { // white space following by quoted string + lineCount(yytext,yyleng); BEGIN(St_Ref2); } <St_Ref>(\n|"\\ilinebr") { // new line @@ -1153,6 +1191,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} return TK_SYMBOL; } <St_Ref2>"\""|\n|"\\ilinebr" { /* " or \n => end of title */ + lineCount(yytext,yyleng); return 0; } <St_Ref2>{SPCMD1} | @@ -1193,6 +1232,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} return TK_WORD; } <St_Param>({PHPTYPE}{BLANK}*("["{BLANK}*"]")*{BLANK}*"|"{BLANK}*)*{PHPTYPE}{BLANK}*("["{BLANK}*"]")*{WS}+("&")?"$"{LABELID} { + lineCount(yytext,yyleng); QCString params = yytext; int j = params.find('&'); int i = params.find('$'); @@ -1211,6 +1251,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } <St_Param>{WS}*","{WS}* /* param separator */ <St_Param>{WS} { + lineCount(yytext,yyleng); g_token->chars=yytext; return TK_WHITESPACE; } @@ -1219,6 +1260,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } <St_Options>{WS}*","{WS}* <St_Options>{WS} { /* option separator */ + lineCount(yytext,yyleng); g_token->name+=","; } <St_Options>"}" { @@ -1254,6 +1296,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} return TK_WORD; } <St_Pattern>\n { + lineCount(yytext,yyleng); g_token->name = g_token->name.stripWhiteSpace(); return TK_WORD; } @@ -1273,13 +1316,17 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} /* State for skipping title (all chars until the end of the line) */ <St_SkipTitle>. -<St_SkipTitle>(\n|"\\ilinebr") { return 0; } +<St_SkipTitle>(\n|"\\ilinebr") { + lineCount(yytext,yyleng); + return 0; + } /* State for the pass used to find the anchors and sections */ <St_Sections>[^\n@\\<]+ <St_Sections>{CMD}("<"|{CMD}) <St_Sections>"<"{CAPTION}({WS}+{ATTRIB})*">" { + lineCount(yytext,yyleng); QCString tag=yytext; int s=tag.find("id="); if (s!=-1) // command has id attribute @@ -1383,6 +1430,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} <St_Sections>. <St_Sections>(\n|"\\ilinebr") <St_SecLabel1>{LABELID} { + lineCount(yytext,yyleng); g_secLabel = yytext; processSection(); BEGIN(St_Sections); @@ -1395,6 +1443,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} } <St_SecTitle>[^\n]+ | <St_SecTitle>[^\n]*\n { + lineCount(yytext,yyleng); g_secTitle = yytext; g_secTitle = g_secTitle.stripWhiteSpace(); if (g_secTitle.right(8)=="\\ilinebr") @@ -1405,7 +1454,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} BEGIN(St_Sections); } <St_SecTitle,St_SecLabel1,St_SecLabel2>. { - warn(g_fileName,yylineno,"Unexpected character '%s' while looking for section label or title",yytext); + warn(g_fileName,g_yyLineNr,"Unexpected character '%s' while looking for section label or title",yytext); } <St_Snippet>[^\\\n]+ { @@ -1415,23 +1464,25 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->name += yytext; } <St_Snippet>(\n|"\\ilinebr") { + lineCount(yytext,yyleng); g_token->name = g_token->name.stripWhiteSpace(); return TK_WORD; } /* Generic rules that work for all states */ <*>\n { - warn(g_fileName,yylineno,"Unexpected new line character"); + lineCount(yytext,yyleng); + warn(g_fileName,g_yyLineNr,"Unexpected new line character"); } <*>"\\ilinebr" { } <*>[\\@<>&$#%~"=] { /* unescaped special character */ - //warn(g_fileName,yylineno,"Unexpected character '%s', assuming command \\%s was meant.",yytext,yytext); + //warn(g_fileName,g_yyLineNr,"Unexpected character '%s', assuming command \\%s was meant.",yytext,yytext); g_token->name = yytext; return TK_COMMAND_SEL(); } <*>. { - warn(g_fileName,yylineno,"Unexpected character '%s'",yytext); + warn(g_fileName,g_yyLineNr,"Unexpected character '%s'",yytext); } %% @@ -1448,7 +1499,7 @@ void doctokenizerYYFindSections(const char *input,const Definition *d, g_definition = d; g_fileName = fileName; BEGIN(St_Sections); - doctokenizerYYlineno = 1; + g_yyLineNr = 1; doctokenizerYYlex(); printlex(yy_flex_debug, FALSE, __FILE__, fileName); } @@ -1686,6 +1737,17 @@ void doctokenizerYYendAutoList() // return retval; //} +void setDoctokinizerLineNr(int lineno) +{ + g_yyLineNr = lineno; +} + +int getDoctokinizerLineNr(void) +{ + return g_yyLineNr; +} + + #if USE_STATE2STRING #include "doctokenizer.l.h" #endif diff --git a/src/docvisitor.cpp b/src/docvisitor.cpp index 17aefc2..d46d8c0 100644 --- a/src/docvisitor.cpp +++ b/src/docvisitor.cpp @@ -40,7 +40,7 @@ CodeParserInterface &DocVisitor::getCodeParser(const char *extension) { std::string ext(extension?extension:""); // for each extension we create a code parser once per visitor, so that - // the context of the same parser object is reused thoughout multiple passes for instance + // the context of the same parser object is reused throughout multiple passes for instance // for code fragments shown via dontinclude. auto it = m_p->parserFactoryMap.find(ext); if (it==m_p->parserFactoryMap.end()) diff --git a/src/dotcallgraph.cpp b/src/dotcallgraph.cpp index 5e13f8e..ef89627 100644 --- a/src/dotcallgraph.cpp +++ b/src/dotcallgraph.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * -* Copyright (C) 1997-2019 by Dimitri van Heesch. +* Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby @@ -34,51 +34,45 @@ static QCString getUniqueId(const MemberDef *md) void DotCallGraph::buildGraph(DotNode *n,const MemberDef *md,int distance) { - MemberSDict *refs = m_inverse ? md->getReferencedByMembers() : md->getReferencesMembers(); - if (refs) + auto refs = m_inverse ? md->getReferencedByMembers() : md->getReferencesMembers(); + for (const auto &rmd : refs) { - refs->sort(); - MemberSDict::Iterator mri(*refs); - MemberDef *rmd; - for (;(rmd=mri.current());++mri) + if (rmd->showInCallGraph()) { - if (rmd->showInCallGraph()) + QCString uniqueId = getUniqueId(rmd); + DotNode *bn = m_usedNodes->find(uniqueId); + if (bn) // file is already a node in the graph { - QCString uniqueId = getUniqueId(rmd); - DotNode *bn = m_usedNodes->find(uniqueId); - if (bn) // file is already a node in the graph + n->addChild(bn,0,0,0); + bn->addParent(n); + bn->setDistance(distance); + } + else + { + QCString name; + if (HIDE_SCOPE_NAMES) { - n->addChild(bn,0,0,0); - bn->addParent(n); - bn->setDistance(distance); + name = rmd->getOuterScope()==m_scope ? + rmd->name() : rmd->qualifiedName(); } else { - QCString name; - if (HIDE_SCOPE_NAMES) - { - name = rmd->getOuterScope()==m_scope ? - rmd->name() : rmd->qualifiedName(); - } - else - { - name = rmd->qualifiedName(); - } - QCString tooltip = rmd->briefDescriptionAsTooltip(); - bn = new DotNode( + name = rmd->qualifiedName(); + } + QCString tooltip = rmd->briefDescriptionAsTooltip(); + bn = new DotNode( getNextNodeNumber(), linkToText(rmd->getLanguage(),name,FALSE), tooltip, uniqueId, 0 //distance - ); - n->addChild(bn,0,0,0); - bn->addParent(n); - bn->setDistance(distance); - m_usedNodes->insert(uniqueId,bn); + ); + n->addChild(bn,0,0,0); + bn->addParent(n); + bn->setDistance(distance); + m_usedNodes->insert(uniqueId,bn); - buildGraph(bn,rmd,distance+1); - } + buildGraph(bn,rmd,distance+1); } } } @@ -121,9 +115,9 @@ void DotCallGraph::determineTruncatedNodes(QList<DotNode> &queue) const DotNode *dn; for (li.toFirst();(dn=li.current());++li) { - if (!dn->isVisible()) + if (!dn->isVisible()) truncated = TRUE; - else + else queue.append(dn); } } @@ -198,7 +192,7 @@ QCString DotCallGraph::getMapLabel() const } QCString DotCallGraph::writeGraph( - FTextStream &out, + FTextStream &out, GraphOutputFormat graphFormat, EmbeddedOutputFormat textFormat, const char *path, diff --git a/src/dotclassgraph.cpp b/src/dotclassgraph.cpp index 84b7962..e157ec3 100644 --- a/src/dotclassgraph.cpp +++ b/src/dotclassgraph.cpp @@ -266,18 +266,11 @@ void DotClassGraph::buildGraph(const ClassDef *cd,DotNode *n,bool base,int dista if (m_graphType == Inheritance || m_graphType==Collaboration) { - BaseClassList *bcl = base ? cd->baseClasses() : cd->subClasses(); - if (bcl) + for (const auto &bcd : base ? cd->baseClasses() : cd->subClasses()) { - BaseClassListIterator bcli(*bcl); - BaseClassDef *bcd; - for ( ; (bcd=bcli.current()) ; ++bcli ) - { - //printf("-------- inheritance relation %s->%s templ='%s'\n", - // cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data()); - addClass(bcd->classDef,n,bcd->prot,0,bcd->usedName, - bcd->templSpecifiers,base,distance); - } + //printf("-------- inheritance relation %s->%s templ='%s'\n", + // cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data()); + addClass(bcd.classDef,n,bcd.prot,0,bcd.usedName,bcd.templSpecifiers,base,distance); } } if (m_graphType == Collaboration) diff --git a/src/dotgfxhierarchytable.cpp b/src/dotgfxhierarchytable.cpp index 3d56de8..ddd9410 100644 --- a/src/dotgfxhierarchytable.cpp +++ b/src/dotgfxhierarchytable.cpp @@ -43,14 +43,14 @@ void DotGfxHierarchyTable::computeTheGraph() md5stream << " rankdir=\"LR\";" << endl; for (dnli2.toFirst();(node=dnli2.current());++dnli2) { - if (node->subgraphId()==m_rootSubgraphNode->subgraphId()) + if (node->subgraphId()==m_rootSubgraphNode->subgraphId()) { node->clearWriteFlag(); } } for (dnli2.toFirst();(node=dnli2.current());++dnli2) { - if (node->subgraphId()==m_rootSubgraphNode->subgraphId()) + if (node->subgraphId()==m_rootSubgraphNode->subgraphId()) { node->write(md5stream,Hierarchy,GOF_BITMAP,FALSE,TRUE,TRUE); } @@ -107,71 +107,66 @@ void DotGfxHierarchyTable::writeGraph(FTextStream &out, void DotGfxHierarchyTable::addHierarchy(DotNode *n,const ClassDef *cd,bool hideSuper) { //printf("addHierarchy '%s' baseClasses=%d\n",cd->name().data(),cd->baseClasses()->count()); - if (cd->subClasses()) + for (const auto &bcd : cd->subClasses()) { - BaseClassListIterator bcli(*cd->subClasses()); - BaseClassDef *bcd; - for ( ; (bcd=bcli.current()) ; ++bcli ) + ClassDef *bClass=bcd.classDef; + //printf(" Trying sub class='%s' usedNodes=%d\n",bClass->name().data(),m_usedNodes->count()); + if (bClass->isVisibleInHierarchy() && hasVisibleRoot(bClass->baseClasses())) { - ClassDef *bClass=bcd->classDef; - //printf(" Trying sub class='%s' usedNodes=%d\n",bClass->name().data(),m_usedNodes->count()); - if (bClass->isVisibleInHierarchy() && hasVisibleRoot(bClass->baseClasses())) + DotNode *bn; + //printf(" Node '%s' Found visible class='%s'\n",n->label().data(), + // bClass->name().data()); + if ((bn=m_usedNodes->find(bClass->name()))) // node already present { - DotNode *bn; - //printf(" Node '%s' Found visible class='%s'\n",n->label().data(), - // bClass->name().data()); - if ((bn=m_usedNodes->find(bClass->name()))) // node already present + if (n->children()==0 || n->children()->findRef(bn)==-1) // no arrow yet { - if (n->children()==0 || n->children()->findRef(bn)==-1) // no arrow yet - { - n->addChild(bn,bcd->prot); - bn->addParent(n); - //printf(" Adding node %s to existing base node %s (c=%d,p=%d)\n", - // n->label().data(), - // bn->label().data(), - // bn->children() ? bn->children()->count() : 0, - // bn->parents() ? bn->parents()->count() : 0 - // ); - } - //else - //{ - // printf(" Class already has an arrow!\n"); - //} + n->addChild(bn,bcd.prot); + bn->addParent(n); + //printf(" Adding node %s to existing base node %s (c=%d,p=%d)\n", + // n->label().data(), + // bn->label().data(), + // bn->children() ? bn->children()->count() : 0, + // bn->parents() ? bn->parents()->count() : 0 + // ); } - else + //else + //{ + // printf(" Class already has an arrow!\n"); + //} + } + else + { + QCString tmp_url=""; + if (bClass->isLinkable() && !bClass->isHidden()) { - QCString tmp_url=""; - if (bClass->isLinkable() && !bClass->isHidden()) + tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase(); + if (!bClass->anchor().isEmpty()) { - tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase(); - if (!bClass->anchor().isEmpty()) - { - tmp_url+="#"+bClass->anchor(); - } + tmp_url+="#"+bClass->anchor(); } - QCString tooltip = bClass->briefDescriptionAsTooltip(); - bn = new DotNode(getNextNodeNumber(), + } + QCString tooltip = bClass->briefDescriptionAsTooltip(); + bn = new DotNode(getNextNodeNumber(), bClass->displayName(), tooltip, tmp_url.data() - ); - n->addChild(bn,bcd->prot); - bn->addParent(n); - //printf(" Adding node %s to new base node %s (c=%d,p=%d)\n", - // n->label().data(), - // bn->label().data(), - // bn->children() ? bn->children()->count() : 0, - // bn->parents() ? bn->parents()->count() : 0 - // ); - //printf(" inserting %s (%p)\n",bClass->name().data(),bn); - m_usedNodes->insert(bClass->name(),bn); // add node to the used list - } - if (!bClass->isVisited() && !hideSuper && bClass->subClasses()) - { - bool wasVisited=bClass->isVisited(); - bClass->setVisited(TRUE); - addHierarchy(bn,bClass,wasVisited); - } + ); + n->addChild(bn,bcd.prot); + bn->addParent(n); + //printf(" Adding node %s to new base node %s (c=%d,p=%d)\n", + // n->label().data(), + // bn->label().data(), + // bn->children() ? bn->children()->count() : 0, + // bn->parents() ? bn->parents()->count() : 0 + // ); + //printf(" inserting %s (%p)\n",bClass->name().data(),bn); + m_usedNodes->insert(bClass->name(),bn); // add node to the used list + } + if (!bClass->isVisited() && !hideSuper && !bClass->subClasses().empty()) + { + bool wasVisited=bClass->isVisited(); + bClass->setVisited(TRUE); + addHierarchy(bn,bClass,wasVisited); } } } @@ -200,7 +195,7 @@ void DotGfxHierarchyTable::addClassList(const ClassSDict *cl) ) // root node in the forest { QCString tmp_url=""; - if (cd->isLinkable() && !cd->isHidden()) + if (cd->isLinkable() && !cd->isHidden()) { tmp_url=cd->getReference()+"$"+cd->getOutputFileBase(); if (!cd->anchor().isEmpty()) @@ -217,8 +212,8 @@ void DotGfxHierarchyTable::addClassList(const ClassSDict *cl) //m_usedNodes->clear(); m_usedNodes->insert(cd->name(),n); - m_rootNodes->insert(0,n); - if (!cd->isVisited() && cd->subClasses()) + m_rootNodes->insert(0,n); + if (!cd->isVisited() && !cd->subClasses().empty()) { addHierarchy(n,cd,cd->isVisited()); cd->setVisited(TRUE); @@ -232,7 +227,7 @@ DotGfxHierarchyTable::DotGfxHierarchyTable(const char *prefix,ClassDef::Compound , m_classType(ct) { m_rootNodes = new QList<DotNode>; - m_usedNodes = new QDict<DotNode>(1009); + m_usedNodes = new QDict<DotNode>(1009); m_usedNodes->setAutoDelete(TRUE); m_rootSubgraphs = new DotNodeList; @@ -245,7 +240,7 @@ DotGfxHierarchyTable::DotGfxHierarchyTable(const char *prefix,ClassDef::Compound // m_usedNodes now contains all nodes in the graph // color the graph into a set of independent subgraphs - bool done=FALSE; + bool done=FALSE; int curColor=0; QListIterator<DotNode> dnli(*m_rootNodes); while (!done) // there are still nodes to color @@ -263,7 +258,7 @@ DotGfxHierarchyTable::DotGfxHierarchyTable(const char *prefix,ClassDef::Compound n->colorConnectedNodes(curColor); curColor++; const DotNode *dn=n->findDocNode(); - if (dn!=0) + if (dn!=0) m_rootSubgraphs->inSort(dn); else m_rootSubgraphs->inSort(n); diff --git a/src/dotgraph.cpp b/src/dotgraph.cpp index 1ad85e1..287793e 100644 --- a/src/dotgraph.cpp +++ b/src/dotgraph.cpp @@ -239,7 +239,7 @@ void DotGraph::generateCode(FTextStream &t) t << "<img src=\"" << relImgName() << "\" border=\"0\" usemap=\"#" << correctId(getMapLabel()) << "\" alt=\"" << getImgAltText() << "\"/>"; if (!m_noDivTag) t << "</div>"; t << endl; - if (m_regenerate || !insertMapFile(t, absMapName(), m_relPath, getMapLabel())) + if (m_regenerate || !insertMapFile(t, absMapName(), m_relPath, correctId(getMapLabel()))) { int mapId = DotManager::instance()-> createFilePatcher(m_fileName.data())-> diff --git a/src/doxygen.cpp b/src/doxygen.cpp index d442857..1a70e61 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -347,7 +347,9 @@ static void addRelatedPage(Entry *root) } PageDef *pd = addRelatedPage(root->name,root->args,doc, - root->docFile,root->docLine, + root->docFile, + root->docLine, + root->startLine, root->sli, gd,root->tagInfo(), FALSE, @@ -3707,59 +3709,10 @@ static void transferFunctionReferences() ) ) /* match found */ { - MemberSDict *defDict = mdef->getReferencesMembers(); - MemberSDict *decDict = mdec->getReferencesMembers(); - if (defDict!=0) - { - MemberSDict::IteratorDict msdi(*defDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) - { - if (decDict==0 || decDict->find(rmd->name())==0) - { - mdec->addSourceReferences(rmd); - } - } - } - if (decDict!=0) - { - MemberSDict::IteratorDict msdi(*decDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) - { - if (defDict==0 || defDict->find(rmd->name())==0) - { - mdef->addSourceReferences(rmd); - } - } - } - - defDict = mdef->getReferencedByMembers(); - decDict = mdec->getReferencedByMembers(); - if (defDict!=0) - { - MemberSDict::IteratorDict msdi(*defDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) - { - if (decDict==0 || decDict->find(rmd->name())==0) - { - mdec->addSourceReferencedBy(rmd); - } - } - } - if (decDict!=0) - { - MemberSDict::IteratorDict msdi(*decDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) - { - if (defDict==0 || defDict->find(rmd->name())==0) - { - mdef->addSourceReferencedBy(rmd); - } - } - } + mdef->mergeReferences(mdec); + mdec->mergeReferences(mdef); + mdef->mergeReferencedBy(mdec); + mdec->mergeReferencedBy(mdef); } } } @@ -4109,7 +4062,7 @@ static bool findTemplateInstanceRelation(const Entry *root, //printf("\n"); bool existingClass = (templSpec == - tempArgListToString(templateClass->templateArguments(),root->lang) + tempArgListToString(templateClass->templateArguments(),root->lang,false) ); if (existingClass) return TRUE; @@ -4380,7 +4333,7 @@ static bool findClassRelation( // instance (for instance if a class // derived from a template argument) { - //printf("baseClass=%p templSpec=%s\n",baseClass,templSpec.data()); + //printf("baseClass=%s templSpec=%s\n",baseClass->name().data(),templSpec.data()); ClassDef *templClass=getClass(baseClass->name()+templSpec); if (templClass) { @@ -4467,7 +4420,7 @@ static bool findClassRelation( if (baseClassTypeDef==0) { //printf(" => findTemplateInstanceRelation: %p\n",baseClassTypeDef); - findTemplateInstanceRelation(root,context,baseClass,templSpec,templateNames,isArtificial); + findTemplateInstanceRelation(root,context,baseClass,templSpec,templateNames,baseClass->isArtificial()); } } else if (mode==DocumentedOnly || mode==Undocumented) @@ -7346,18 +7299,17 @@ static void computeMemberRelations() if (md!=bmd) { const ClassDef *mcd = md->getClassDef(); - if (mcd && mcd->baseClasses()) + if (mcd && !mcd->baseClasses().empty()) { const ClassDef *bmcd = bmd->getClassDef(); //printf("Check relation between '%s'::'%s' (%p) and '%s'::'%s' (%p)\n", - // mcd->name().data(),md->name().data(),md, - // bmcd->name().data(),bmd->name().data(),bmd + // mcd->name().data(),md->name().data(),md.get(), + // bmcd->name().data(),bmd->name().data(),bmd.get() // ); if (bmcd && mcd && bmcd!=mcd && - (bmd->virtualness()!=Normal || bmd->getLanguage()==SrcLangExt_Python || - bmd->getLanguage()==SrcLangExt_Java || bmd->getLanguage()==SrcLangExt_PHP || - bmcd->compoundType()==ClassDef::Interface || - bmcd->compoundType()==ClassDef::Protocol + (bmd->virtualness()!=Normal || + bmd->getLanguage()==SrcLangExt_Python || bmd->getLanguage()==SrcLangExt_Java || bmd->getLanguage()==SrcLangExt_PHP || + bmcd->compoundType()==ClassDef::Interface || bmcd->compoundType()==ClassDef::Protocol ) && md->isFunction() && mcd->isLinkable() && @@ -7368,8 +7320,8 @@ static void computeMemberRelations() const ArgumentList &bmdAl = bmd->argumentList(); const ArgumentList &mdAl = md->argumentList(); //printf(" Base argList='%s'\n Super argList='%s'\n", - // argListToString(bmdAl.pointer()).data(), - // argListToString(mdAl.pointer()).data() + // argListToString(bmdAl).data(), + // argListToString(mdAl).data() // ); if ( matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),&bmdAl, @@ -7378,6 +7330,7 @@ static void computeMemberRelations() ) ) { + //printf("match!\n"); MemberDef *rmd; if ((rmd=md->reimplements())==0 || minClassDistance(mcd,bmcd)<minClassDistance(mcd,rmd->getClassDef()) @@ -7389,6 +7342,10 @@ static void computeMemberRelations() //printf("%s: add reimplementedBy member %s\n",bmcd->name().data(),mcd->name().data()); bmd->insertReimplementedBy(md.get()); } + else + { + //printf("no match!\n"); + } } } } @@ -7467,8 +7424,8 @@ static void buildCompleteMemberLists() for (cli.toFirst();(cd=cli.current());++cli) { if (// !cd->isReference() && // not an external class - cd->subClasses()==0 && // is a root of the hierarchy - cd->baseClasses()) // and has at least one base class + cd->subClasses().empty() && // is a root of the hierarchy + !cd->baseClasses().empty()) // and has at least one base class { //printf("*** merging members for %s\n",cd->name().data()); cd->mergeMembers(); @@ -7507,7 +7464,11 @@ static void generateFileSources() { for (const auto &fd : *fn) { - if (fd->isSource() && !fd->isReference()) + if (fd->isSource() && !fd->isReference() && + ((fd->generateSourceFile() && !g_useOutputTemplate) || + (!fd->isReference() && Doxygen::parseSourcesNeeded) + ) + ) { auto clangParser = ClangParser::instance()->createTUParser(fd.get()); if (fd->generateSourceFile() && !g_useOutputTemplate) // sources need to be shown in the output @@ -7565,9 +7526,9 @@ static void generateFileSources() { if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed { - auto clangParser = ClangParser::instance()->createTUParser(fd.get()); if (fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate) // sources need to be shown in the output { + auto clangParser = ClangParser::instance()->createTUParser(fd.get()); msg("Generating code for file %s...\n",fd->docName().data()); clangParser->parse(); fd->writeSourceHeader(*g_outputList); @@ -7577,6 +7538,7 @@ static void generateFileSources() else if (!fd->isReference() && Doxygen::parseSourcesNeeded) // we needed to parse the sources even if we do not show them { + auto clangParser = ClangParser::instance()->createTUParser(fd.get()); msg("Parsing code for file %s...\n",fd->docName().data()); clangParser->parse(); fd->writeSourceHeader(*g_outputList); @@ -7642,13 +7604,12 @@ static void generateFileSources() } for (auto &f : results) { - std::shared_ptr<SourceContext> ctx = f.get(); + auto ctx = f.get(); if (ctx->generateSourceFile) { ctx->fd->writeSourceFooter(ctx->ol); } } - #else // single threaded version for (const auto &fn : *Doxygen::inputNameLinkedMap) { @@ -7849,6 +7810,32 @@ static void sortMemberLists() //---------------------------------------------------------------------------- +void computeTooltipTexts() +{ + QDictIterator<DefinitionIntf> di(*Doxygen::symbolMap); + DefinitionIntf *intf; + for (;(intf=di.current());++di) + { + if (intf->definitionType()==DefinitionIntf::TypeSymbolList) // list of symbols + { + DefinitionListIterator dli(*(DefinitionList*)intf); + Definition *d; + // for each symbol + for (dli.toFirst();(d=dli.current());++dli) + { + d->computeTooltip(); + } + } + else // single symbol + { + Definition *d = (Definition *)intf; + if (d!=Doxygen::globalScope) d->computeTooltip(); + } + } +} + +//---------------------------------------------------------------------------- + static void setAnonymousEnumType() { ClassSDict::Iterator cli(*Doxygen::classSDict); @@ -7940,7 +7927,8 @@ static void inheritDocumentation() { for (const auto &md : *mn) { - //printf("%04d Member '%s'\n",count++,md->name().data()); + //static int count=0; + //printf("%04d Member '%s'\n",count++,md->qualifiedName().data()); if (md->documentation().isEmpty() && md->briefDescription().isEmpty()) { // no documentation yet MemberDef *bmd = md->reimplements(); @@ -8437,6 +8425,7 @@ static void findMainPage(Entry *root) { if (Doxygen::mainPage==0 && root->tagInfo()==0) { + //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine); //printf("Found main page! \n======\n%s\n=======\n",root->doc.data()); QCString title=root->args.stripWhiteSpace(); //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index"; @@ -8445,6 +8434,7 @@ static void findMainPage(Entry *root) indexName, root->brief+root->doc+root->inbodyDocs,title); //setFileNameForSections(root->anchors,"index",Doxygen::mainPage); Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine); + Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1); Doxygen::mainPage->setFileName(indexName); Doxygen::mainPage->setLocalToc(root->localToc); addPageToContext(Doxygen::mainPage,root); @@ -8480,7 +8470,7 @@ static void findMainPage(Entry *root) { warn(root->fileName,root->startLine, "found more than one \\mainpage comment block! (first occurrence: %s, line %d), Skipping current block!", - Doxygen::mainPage->docFile().data(),Doxygen::mainPage->docLine()); + Doxygen::mainPage->docFile().data(),Doxygen::mainPage->getStartBodyLine()); } } for (const auto &e : root->children()) findMainPage(e.get()); @@ -9101,8 +9091,8 @@ static void generateDiskNames() // as the common prefix between the first and last entry const FileEntry &first = fileEntries[0]; const FileEntry &last = fileEntries[size-1]; - int first_path_size = static_cast<int>(first.path.size()); - int last_path_size = static_cast<int>(last.path.size()); + int first_path_size = static_cast<int>(first.path.size())-1; // -1 to skip trailing slash + int last_path_size = static_cast<int>(last.path.size())-1; // -1 to skip trailing slash int j=0; for (int i=0;i<first_path_size && i<last_path_size;i++) { @@ -10519,7 +10509,7 @@ void adjustConfiguration() } else { - msg("Adding custom extension mapping: .%s will be treated as language %s\n", + msg("Adding custom extension mapping: '%s' will be treated as language '%s'\n", ext.data(),language.data()); } } @@ -11429,6 +11419,10 @@ void parseInput() vhdlCorrectMemberProperties(); g_s.end(); + g_s.begin("Computing tooltip texts...\n"); + computeTooltipTexts(); + g_s.end(); + if (Config_getBool(SORT_GROUP_NAMES)) { Doxygen::groupSDict->sort(); @@ -11582,6 +11576,8 @@ void generateOutput() generateExampleDocs(); g_s.end(); + warn_flush(); + g_s.begin("Generating file sources...\n"); generateFileSources(); g_s.end(); @@ -11686,6 +11682,8 @@ void generateOutput() if (g_useOutputTemplate) generateOutputViaTemplate(); + warn_flush(); + if (generateRtf) { g_s.begin("Combining RTF output...\n"); @@ -11696,10 +11694,14 @@ void generateOutput() g_s.end(); } + warn_flush(); + g_s.begin("Running plantuml with JAVA...\n"); PlantumlManager::instance()->run(); g_s.end(); + warn_flush(); + if (Config_getBool(HAVE_DOT)) { g_s.begin("Running dot...\n"); @@ -11747,6 +11749,9 @@ void generateOutput() QDir::setCurrent(oldDir); g_s.end(); } + + warn_flush(); + if ( generateHtml && Config_getBool(GENERATE_QHP) && !Config_getString(QHG_LOCATION).isEmpty()) diff --git a/src/formula.cpp b/src/formula.cpp index ca50c9c..8ba9729 100644 --- a/src/formula.cpp +++ b/src/formula.cpp @@ -148,7 +148,7 @@ void FormulaManager::generateImages(const char *path,Format format,HighDPI hd) c // store the original directory if (!d.exists()) { - term("Output dir %s does not exist!\n",path); + term("Output directory '%s' does not exist!\n",path); } QCString oldDir = QDir::currentDirPath().utf8(); QCString macroFile = Config_getString(FORMULA_MACROFILE); @@ -167,7 +167,6 @@ void FormulaManager::generateImages(const char *path,Format format,HighDPI hd) c QCString texName="_formulas.tex"; IntVector formulasToGenerate; QFile f(texName); - bool formulaError=FALSE; if (f.open(IO_WriteOnly)) { FTextStream t(&f); @@ -214,8 +213,9 @@ void FormulaManager::generateImages(const char *path,Format format,HighDPI hd) c { err("Problems running latex. Check your installation or look " "for typos in _formulas.tex and check _formulas.log!\n"); - formulaError=TRUE; - //return; + Portable::sysTimerStop(); + QDir::setCurrent(oldDir); + return; } Portable::sysTimerStop(); //printf("Running dvips...\n"); @@ -439,12 +439,12 @@ void FormulaManager::generateImages(const char *path,Format format,HighDPI hd) c if (RM_TMP_FILES) { thisDir.remove("_formulas.dvi"); - if (!formulaError) thisDir.remove("_formulas.log"); // keep file in case of errors + thisDir.remove("_formulas.log"); // keep file in case of errors thisDir.remove("_formulas.aux"); } } // remove the latex file itself - if (RM_TMP_FILES && !formulaError) thisDir.remove("_formulas.tex"); + if (RM_TMP_FILES) thisDir.remove("_formulas.tex"); // write/update the formula repository so we know what text the // generated images represent (we use this next time to avoid regeneration diff --git a/src/fortrancode.l b/src/fortrancode.l index f2b0ee8..6b278cc 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -172,6 +172,7 @@ struct fortrancodeYY_state int inTypeDecl = 0; bool endComment = false; + TooltipManager tooltipManager; }; #if USE_STATE2STRING @@ -1012,7 +1013,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); - TooltipManager::instance()->addTooltip(d); + yyextra->tooltipManager.addTooltip(d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); @@ -1514,6 +1515,10 @@ void FortranCodeParser::parseCode(CodeOutputInterface & codeOutIntf, } if (yyextra->hasContLine) free(yyextra->hasContLine); yyextra->hasContLine = NULL; + + // write the tooltips + yyextra->tooltipManager.writeTooltips(codeOutIntf); + printlex(yy_flex_debug, FALSE, __FILE__, fileDef ? fileDef->fileName().data(): NULL); } diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp index 6fc14bf..b34f644 100644 --- a/src/ftvhelp.cpp +++ b/src/ftvhelp.cpp @@ -167,7 +167,7 @@ void FTVHelp::finalize() */ void FTVHelp::incContentsDepth() { - //printf("incContentsDepth() indent=%d\n",m_indent); + //printf("%p: incContentsDepth() indent=%d\n",this,m_indent); m_indent++; ASSERT(m_indent<MAX_INDENT); } @@ -178,7 +178,7 @@ void FTVHelp::incContentsDepth() */ void FTVHelp::decContentsDepth() { - //printf("decContentsDepth() indent=%d\n",m_indent); + //printf("%p: decContentsDepth() indent=%d\n",this,m_indent); ASSERT(m_indent>0); if (m_indent>0) { diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index ea4d895..e1358a7 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -1231,9 +1231,6 @@ void HtmlGenerator::writePageFooter(FTextStream &t,const QCString &lastTitle, void HtmlGenerator::writeFooter(const char *navPath) { - // Currently only tooltips in HTML - TooltipManager::instance()->writeTooltips(m_codeGen); - writePageFooter(t,m_lastTitle,m_relPath,navPath); } diff --git a/src/index.cpp b/src/index.cpp index 12f35f2..c4fda05 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -307,7 +307,6 @@ void endFile(OutputList &ol,bool skipNavIndex,bool skipEndContents, ol.writeFooter(navPath); // write the footer ol.popGeneratorState(); ol.endFile(); - TooltipManager::instance()->clearTooltips(); // Only clear after the last is written } void endFileWithNavPath(const Definition *d,OutputList &ol) @@ -326,6 +325,66 @@ void endFileWithNavPath(const Definition *d,OutputList &ol) } //---------------------------------------------------------------------- + +static bool memberVisibleInIndex(const MemberDef *md) +{ + bool isAnonymous = md->isAnonymous(); + bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); + bool extractStatic = Config_getBool(EXTRACT_STATIC); + return (!isAnonymous && + (!hideUndocMembers || md->hasDocumentation()) && + (!md->isStatic() || extractStatic) + ); +} + +static void writeMemberToIndex(const Definition *def,const MemberDef *md,bool addToIndex) +{ + bool isAnonymous = md->isAnonymous(); + bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); + const MemberList *enumList = md->enumFieldList(); + bool isDir = enumList!=0 && md->isEnumerate(); + if (md->getOuterScope()==def || md->getOuterScope()==Doxygen::globalScope) + { + Doxygen::indexList->addContentsItem(isDir, + md->name(),md->getReference(),md->getOutputFileBase(),md->anchor(),FALSE,addToIndex); + } + else // inherited member + { + Doxygen::indexList->addContentsItem(isDir, + md->name(),def->getReference(),def->getOutputFileBase(),md->anchor(),FALSE,addToIndex); + } + if (isDir) + { + if (!isAnonymous) + { + Doxygen::indexList->incContentsDepth(); + } + MemberListIterator emli(*enumList); + MemberDef *emd; + for (emli.toFirst();(emd=emli.current());++emli) + { + if (!hideUndocMembers || emd->hasDocumentation()) + { + if (emd->getOuterScope()==def || emd->getOuterScope()==Doxygen::globalScope) + { + Doxygen::indexList->addContentsItem(FALSE, + emd->name(),emd->getReference(),emd->getOutputFileBase(),emd->anchor(),FALSE,addToIndex); + } + else // inherited member + { + Doxygen::indexList->addContentsItem(FALSE, + emd->name(),def->getReference(),def->getOutputFileBase(),emd->anchor(),FALSE,addToIndex); + } + } + } + if (!isAnonymous) + { + Doxygen::indexList->decContentsDepth(); + } + } +} + +//---------------------------------------------------------------------- template<class T> void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, const QCString &name,const QCString &anchor, @@ -366,55 +425,9 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, MemberDef *md; for (mi.toFirst();(md=mi.current());++mi) { - const MemberList *enumList = md->enumFieldList(); - bool isDir = enumList!=0 && md->isEnumerate(); - bool isAnonymous = md->isAnonymous(); - static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); - static bool extractStatic = Config_getBool(EXTRACT_STATIC); - if (!isAnonymous && - (!hideUndocMembers || md->hasDocumentation()) && - (!md->isStatic() || extractStatic) - ) + if (memberVisibleInIndex(md)) { - if (md->getOuterScope()==def || md->getOuterScope()==Doxygen::globalScope) - { - Doxygen::indexList->addContentsItem(isDir, - md->name(),md->getReference(),md->getOutputFileBase(),md->anchor(),FALSE,addToIndex); - } - else // inherited member - { - Doxygen::indexList->addContentsItem(isDir, - md->name(),def->getReference(),def->getOutputFileBase(),md->anchor(),FALSE,addToIndex); - } - } - if (isDir) - { - if (!isAnonymous) - { - Doxygen::indexList->incContentsDepth(); - } - MemberListIterator emli(*enumList); - MemberDef *emd; - for (emli.toFirst();(emd=emli.current());++emli) - { - if (!hideUndocMembers || emd->hasDocumentation()) - { - if (emd->getOuterScope()==def || emd->getOuterScope()==Doxygen::globalScope) - { - Doxygen::indexList->addContentsItem(FALSE, - emd->name(),emd->getReference(),emd->getOutputFileBase(),emd->anchor(),FALSE,addToIndex); - } - else // inherited member - { - Doxygen::indexList->addContentsItem(FALSE, - emd->name(),def->getReference(),def->getOutputFileBase(),emd->anchor(),FALSE,addToIndex); - } - } - } - if (!isAnonymous) - { - Doxygen::indexList->decContentsDepth(); - } + writeMemberToIndex(def,md,addToIndex); } } } @@ -451,14 +464,13 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, //---------------------------------------------------------------------------- /*! Generates HTML Help tree of classes */ -static void writeClassTree(OutputList &ol,const BaseClassList *bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex) +static void writeClassTree(OutputList &ol,const BaseClassList &bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex) { - if (bcl==0) return; - BaseClassListIterator bcli(*bcl); + if (bcl.empty()) return; bool started=FALSE; - for ( ; bcli.current() ; ++bcli) + for (const auto &bcd : bcl) { - ClassDef *cd=bcli.current()->classDef; + ClassDef *cd=bcd.classDef; if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) { continue; @@ -513,7 +525,7 @@ static void writeClassTree(OutputList &ol,const BaseClassList *bcl,bool hideSupe { if (cd->getLanguage()==SrcLangExt_VHDL) { - ftv->addContentsItem(hasChildren,bcli.current()->usedName,cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd); + ftv->addContentsItem(hasChildren,bcd.usedName,cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd); } else { @@ -963,7 +975,7 @@ static int countClassesInTreeList(const ClassSDict &cl, ClassDef::CompoundType c { if (cd->isVisibleInHierarchy()) // should it be visible { - if (cd->subClasses()) // should have sub classes + if (!cd->subClasses().empty()) // should have sub classes { count++; } @@ -1555,7 +1567,7 @@ static int countNamespaces() //---------------------------------------------------------------------------- -void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly,ClassDef::CompoundType ct) +static void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly,ClassDef::CompoundType ct) { static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); if (clDict) @@ -1606,9 +1618,7 @@ void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalO { ftv->addContentsItem(count>0,cd->displayName(FALSE),cd->getReference(), cd->getOutputFileBase(),cd->anchor(),FALSE,TRUE,cd); - if (addToIndex && - /*cd->partOfGroups()==0 &&*/ - (cd->getOuterScope()==0 || + if ((cd->getOuterScope()==0 || cd->getOuterScope()->definitionType()!=Definition::TypeClass ) ) @@ -1616,7 +1626,7 @@ void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalO addMembersToIndex(cd,LayoutDocManager::Class, cd->displayName(FALSE), cd->anchor(), - cd->partOfGroups()==0 && !cd->isSimple()); + addToIndex && cd->partOfGroups()==0 && !cd->isSimple()); } if (count>0) { @@ -1630,10 +1640,64 @@ void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalO } } +static int countVisibleMembers(const NamespaceDef *nd) +{ + int count=0; + QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace)); + LayoutDocEntry *lde; + for (eli.toFirst();(lde=eli.current());++eli) + { + if (lde->kind()==LayoutDocEntry::MemberDef) + { + LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; + MemberList *ml = nd->getMemberList(lmd->type); + if (ml) + { + MemberListIterator mi(*ml); + MemberDef *md; + for (mi.toFirst();(md=mi.current());++mi) + { + if (memberVisibleInIndex(md)) + { + count++; + } + } + } + } + } + return count; +} + +static void writeNamespaceMembers(const NamespaceDef *nd,bool addToIndex) +{ + QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace)); + LayoutDocEntry *lde; + for (eli.toFirst();(lde=eli.current());++eli) + { + if (lde->kind()==LayoutDocEntry::MemberDef) + { + LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; + MemberList *ml = nd->getMemberList(lmd->type); + if (ml) + { + MemberListIterator mi(*ml); + MemberDef *md; + for (mi.toFirst();(md=mi.current());++mi) + { + //printf(" member %s visible=%d\n",md->name().data(),memberVisibleInIndex(md)); + if (memberVisibleInIndex(md)) + { + writeMemberToIndex(nd,md,addToIndex); + } + } + } + } + } +} + static void writeNamespaceTree(const NamespaceSDict *nsDict,FTVHelp *ftv, - bool rootOnly,bool showClasses,bool addToIndex,ClassDef::CompoundType ct) + bool rootOnly,bool addToIndex) { - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); if (nsDict) { NamespaceSDict::Iterator nli(*nsDict); @@ -1644,8 +1708,12 @@ static void writeNamespaceTree(const NamespaceSDict *nsDict,FTVHelp *ftv, (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) { - bool hasChildren = namespaceHasVisibleChild(nd,showClasses,sliceOpt,ct); + bool hasChildren = namespaceHasNestedNamespace(nd) || + namespaceHasNestedClass(nd,false,ClassDef::Class); bool isLinkable = nd->isLinkableInProject(); + int visibleMembers = countVisibleMembers(nd); + + //printf("namespace %s hasChildren=%d visibleMembers=%d\n",nd->name().data(),hasChildren,visibleMembers); QCString ref; QCString file; @@ -1659,45 +1727,114 @@ static void writeNamespaceTree(const NamespaceSDict *nsDict,FTVHelp *ftv, } } - if ((isLinkable && !showClasses) || hasChildren) + bool isDir = hasChildren || visibleMembers>0; + if ((isLinkable) || isDir) { ftv->addContentsItem(hasChildren,nd->localName(),ref,file,0,FALSE,TRUE,nd); if (addToIndex) { - Doxygen::indexList->addContentsItem(hasChildren,nd->localName(),ref,file,QCString(), + Doxygen::indexList->addContentsItem(isDir,nd->localName(),ref,file,QCString(), hasChildren && !file.isEmpty(),addToIndex); } + if (addToIndex && isDir) + { + Doxygen::indexList->incContentsDepth(); + } - //printf("*** writeNamespaceTree count=%d addToIndex=%d showClasses=%d classCount=%d\n", - // count,addToIndex,showClasses,classCount); - if (hasChildren) + //printf("*** writeNamespaceTree count=%d addToIndex=%d false=%d classCount=%d\n", + // count,addToIndex,false,classCount); + if (isDir) { - if (addToIndex) Doxygen::indexList->incContentsDepth(); ftv->incContentsDepth(); - writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,showClasses,addToIndex,ct); - if (showClasses) + writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,addToIndex); + writeClassTree(nd->getClassSDict(),ftv,FALSE,FALSE,ClassDef::Class); + writeNamespaceMembers(nd,addToIndex); + ftv->decContentsDepth(); + } + if (addToIndex && isDir) + { + Doxygen::indexList->decContentsDepth(); + } + } + } + } + } +} + +static void writeClassTreeInsideNamespace(const NamespaceSDict *nsDict,FTVHelp *ftv, + bool rootOnly,bool addToIndex,ClassDef::CompoundType ct) +{ + static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); + if (nsDict) + { + NamespaceSDict::Iterator nli(*nsDict); + const NamespaceDef *nd; + for (nli.toFirst();(nd=nli.current());++nli) + { + if (!nd->isAnonymous() && + (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) + { + bool isDir = namespaceHasNestedClass(nd,sliceOpt,ct); + bool isLinkable = nd->isLinkableInProject(); + + //printf("namespace %s isDir=%d\n",nd->name().data(),isDir); + + QCString ref; + QCString file; + if (isLinkable) + { + ref = nd->getReference(); + file = nd->getOutputFileBase(); + if (nd->getLanguage()==SrcLangExt_VHDL) // UGLY HACK + { + file=file.replace(0,qstrlen("namespace"),"class"); + } + } + + if (isDir) + { + ftv->addContentsItem(isDir,nd->localName(),ref,file,0,FALSE,TRUE,nd); + + if (addToIndex) + { + // the namespace entry is already shown under the namespace list so don't + // add it to the nav index and don't create a separate index file for it otherwise + // it will overwrite the one written for the namespace list. + Doxygen::indexList->addContentsItem(isDir,nd->localName(),ref,file,QCString(), + false, // separateIndex + false // addToNavIndex + ); + } + if (addToIndex) + { + Doxygen::indexList->incContentsDepth(); + } + + ftv->incContentsDepth(); + writeClassTreeInsideNamespace(nd->getNamespaceSDict(),ftv,FALSE,addToIndex,ct); + ClassSDict *d = nd->getClassSDict(); + if (sliceOpt) + { + if (ct == ClassDef::Interface) { - ClassSDict *d = nd->getClassSDict(); - if (sliceOpt) - { - if (ct == ClassDef::Interface) - { - d = nd->getInterfaceSDict(); - } - else if (ct == ClassDef::Struct) - { - d = nd->getStructSDict(); - } - else if (ct == ClassDef::Exception) - { - d = nd->getExceptionSDict(); - } - } - writeClassTree(d,ftv,addToIndex,FALSE,ct); + d = nd->getInterfaceSDict(); + } + else if (ct == ClassDef::Struct) + { + d = nd->getStructSDict(); + } + else if (ct == ClassDef::Exception) + { + d = nd->getExceptionSDict(); } - ftv->decContentsDepth(); - if (addToIndex) Doxygen::indexList->decContentsDepth(); + } + writeClassTree(d,ftv,addToIndex,FALSE,ct); + ftv->decContentsDepth(); + + if (addToIndex) + { + Doxygen::indexList->decContentsDepth(); } } } @@ -1795,7 +1932,7 @@ static void writeNamespaceIndex(OutputList &ol) Doxygen::indexList->incContentsDepth(); } FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,FALSE,addToIndex,ClassDef::Class); + writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,addToIndex); QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); @@ -2425,26 +2562,50 @@ static void writeAlphabeticalExceptionIndex(OutputList &ol) //---------------------------------------------------------------------------- -static void writeAnnotatedIndex(OutputList &ol) +struct AnnotatedIndexContext +{ + AnnotatedIndexContext(int numAnno,int numPrint, + LayoutNavEntry::Kind lk,LayoutNavEntry::Kind fk, + const QCString &title,const QCString &intro, + ClassDef::CompoundType ct, + const QCString &fn, + HighlightedItem hi) : + numAnnotated(numAnno), numPrinted(numPrint), + listKind(lk), fallbackKind(fk), + listDefaultTitleText(title), listDefaultIntroText(intro), + compoundType(ct),fileBaseName(fn), + hiItem(hi) { } + + const int numAnnotated; + const int numPrinted; + const LayoutNavEntry::Kind listKind; + const LayoutNavEntry::Kind fallbackKind; + const QCString listDefaultTitleText; + const QCString listDefaultIntroText; + const ClassDef::CompoundType compoundType; + const QCString fileBaseName; + const HighlightedItem hiItem; +}; + +static void writeAnnotatedIndexGeneric(OutputList &ol,const AnnotatedIndexContext ctx) { //printf("writeAnnotatedIndex: count=%d printed=%d\n", // annotatedClasses,annotatedClassesPrinted); - if (annotatedClasses==0) return; + if (ctx.numAnnotated==0) return; ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); - if (annotatedClassesPrinted==0) + if (ctx.numPrinted==0) { ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); } - LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList); - if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes); // fall back - QCString title = lne ? lne->title() : theTranslator->trCompoundList(); + LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(ctx.listKind); + if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(ctx.fallbackKind); // fall back + QCString title = lne ? lne->title() : ctx.listDefaultTitleText; bool addToIndex = lne==0 || lne->visible(); - - startFile(ol,"annotated",0,title,HLI_AnnotatedClasses); + startFile(ol,ctx.fileBaseName,0,title,ctx.hiItem); startTitle(ol,0); ol.parseText(title); @@ -2453,7 +2614,7 @@ static void writeAnnotatedIndex(OutputList &ol) ol.startContents(); ol.startTextBlock(); - ol.parseText(lne ? lne->intro() : theTranslator->trCompoundListDescription()); + ol.parseText(lne ? lne->intro() : ctx.listDefaultIntroText); ol.endTextBlock(); // --------------- @@ -2463,7 +2624,7 @@ static void writeAnnotatedIndex(OutputList &ol) ol.disable(OutputGenerator::Html); Doxygen::indexList->disable(); - writeAnnotatedClassList(ol, ClassDef::Class); + writeAnnotatedClassList(ol, ctx.compoundType); Doxygen::indexList->enable(); ol.popGeneratorState(); @@ -2477,17 +2638,16 @@ static void writeAnnotatedIndex(OutputList &ol) { if (addToIndex) { - Doxygen::indexList->addContentsItem(TRUE,title,0,"annotated",0,TRUE,TRUE); + Doxygen::indexList->addContentsItem(TRUE,title,0,ctx.fileBaseName,0,TRUE,TRUE); Doxygen::indexList->incContentsDepth(); } - FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Class); - writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Class); + FTVHelp ftv(false); + writeClassTreeInsideNamespace(Doxygen::namespaceSDict,&ftv,TRUE,addToIndex,ctx.compoundType); + writeClassTree(Doxygen::classSDict,&ftv,addToIndex,TRUE,ctx.compoundType); QGString outStr; FTextStream t(&outStr); - ftv->generateTreeViewInline(t); + ftv.generateTreeViewInline(t); ol.writeString(outStr); - delete ftv; if (addToIndex) { Doxygen::indexList->decContentsDepth(); @@ -2503,233 +2663,58 @@ static void writeAnnotatedIndex(OutputList &ol) //---------------------------------------------------------------------------- -static void writeAnnotatedInterfaceIndex(OutputList &ol) +static void writeAnnotatedIndex(OutputList &ol) { - //printf("writeAnnotatedInterfaceIndex: count=%d printed=%d\n", - // annotatedInterfaces,annotatedInterfacesPrinted); - if (annotatedInterfaces==0) return; + writeAnnotatedIndexGeneric(ol, + AnnotatedIndexContext(annotatedClasses,annotatedClassesPrinted, + LayoutNavEntry::ClassList,LayoutNavEntry::Classes, + theTranslator->trCompoundList(),theTranslator->trCompoundListDescription(), + ClassDef::Class, + "annotated", + HLI_AnnotatedClasses)); - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Man); - if (annotatedInterfacesPrinted==0) - { - ol.disable(OutputGenerator::Latex); - ol.disable(OutputGenerator::RTF); - } - LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::InterfaceList); - if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Interfaces); // fall back - QCString title = lne ? lne->title() : theTranslator->trInterfaceList(); - bool addToIndex = lne==0 || lne->visible(); - - startFile(ol,"annotatedinterfaces",0,title,HLI_AnnotatedInterfaces); - - startTitle(ol,0); - ol.parseText(title); - endTitle(ol,0,0); - - ol.startContents(); - - ol.startTextBlock(); - ol.parseText(lne ? lne->intro() : theTranslator->trInterfaceListDescription()); - ol.endTextBlock(); - - // --------------- - // Linear interface index for Latex/RTF - // --------------- - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Html); - Doxygen::indexList->disable(); - - writeAnnotatedClassList(ol, ClassDef::Interface); - - Doxygen::indexList->enable(); - ol.popGeneratorState(); - - // --------------- - // Hierarchical interface index for HTML - // --------------- - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::Html); +} - { - if (addToIndex) - { - Doxygen::indexList->addContentsItem(TRUE,title,0,"annotatedinterfaces",0,TRUE,TRUE); - Doxygen::indexList->incContentsDepth(); - } - FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Interface); - writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Interface); - QGString outStr; - FTextStream t(&outStr); - ftv->generateTreeViewInline(t); - ol.writeString(outStr); - delete ftv; - if (addToIndex) - { - Doxygen::indexList->decContentsDepth(); - } - } +//---------------------------------------------------------------------------- - ol.popGeneratorState(); - // ------ +static void writeAnnotatedInterfaceIndex(OutputList &ol) +{ + writeAnnotatedIndexGeneric(ol, + AnnotatedIndexContext(annotatedInterfaces,annotatedInterfacesPrinted, + LayoutNavEntry::InterfaceList,LayoutNavEntry::Interfaces, + theTranslator->trInterfaceList(),theTranslator->trInterfaceListDescription(), + ClassDef::Interface, + "annotatedinterfaces", + HLI_AnnotatedInterfaces)); - endFile(ol); // contains ol.endContents() - ol.popGeneratorState(); } //---------------------------------------------------------------------------- static void writeAnnotatedStructIndex(OutputList &ol) { - //printf("writeAnnotatedStructIndex: count=%d printed=%d\n", - // annotatedStructs,annotatedStructsPrinted); - if (annotatedStructs==0) return; - - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Man); - if (annotatedStructsPrinted==0) - { - ol.disable(OutputGenerator::Latex); - ol.disable(OutputGenerator::RTF); - } - LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::StructList); - if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Structs); // fall back - QCString title = lne ? lne->title() : theTranslator->trStructList(); - bool addToIndex = lne==0 || lne->visible(); - - startFile(ol,"annotatedstructs",0,title,HLI_AnnotatedStructs); - - startTitle(ol,0); - ol.parseText(title); - endTitle(ol,0,0); - - ol.startContents(); - - ol.startTextBlock(); - ol.parseText(lne ? lne->intro() : theTranslator->trStructListDescription()); - ol.endTextBlock(); - - // --------------- - // Linear struct index for Latex/RTF - // --------------- - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Html); - Doxygen::indexList->disable(); - - writeAnnotatedClassList(ol, ClassDef::Struct); - - Doxygen::indexList->enable(); - ol.popGeneratorState(); - - // --------------- - // Hierarchical struct index for HTML - // --------------- - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::Html); - - { - if (addToIndex) - { - Doxygen::indexList->addContentsItem(TRUE,title,0,"annotatedstructs",0,TRUE,TRUE); - Doxygen::indexList->incContentsDepth(); - } - FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Struct); - writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Struct); - QGString outStr; - FTextStream t(&outStr); - ftv->generateTreeViewInline(t); - ol.writeString(outStr); - delete ftv; - if (addToIndex) - { - Doxygen::indexList->decContentsDepth(); - } - } + writeAnnotatedIndexGeneric(ol, + AnnotatedIndexContext(annotatedStructs,annotatedStructsPrinted, + LayoutNavEntry::StructList,LayoutNavEntry::Structs, + theTranslator->trStructList(),theTranslator->trStructListDescription(), + ClassDef::Struct, + "annotatedstructs", + HLI_AnnotatedStructs)); - ol.popGeneratorState(); - // ------ - - endFile(ol); // contains ol.endContents() - ol.popGeneratorState(); } //---------------------------------------------------------------------------- static void writeAnnotatedExceptionIndex(OutputList &ol) { - //printf("writeAnnotatedExceptionIndex: count=%d printed=%d\n", - // annotatedExceptions,annotatedExceptionsPrinted); - if (annotatedExceptions==0) return; - - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Man); - if (annotatedExceptionsPrinted==0) - { - ol.disable(OutputGenerator::Latex); - ol.disable(OutputGenerator::RTF); - } - LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ExceptionList); - if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Exceptions); // fall back - QCString title = lne ? lne->title() : theTranslator->trExceptionList(); - bool addToIndex = lne==0 || lne->visible(); - - startFile(ol,"annotatedexceptions",0,title,HLI_AnnotatedExceptions); - - startTitle(ol,0); - ol.parseText(title); - endTitle(ol,0,0); - - ol.startContents(); - - ol.startTextBlock(); - ol.parseText(lne ? lne->intro() : theTranslator->trExceptionListDescription()); - ol.endTextBlock(); - - // --------------- - // Linear interface index for Latex/RTF - // --------------- - ol.pushGeneratorState(); - ol.disable(OutputGenerator::Html); - Doxygen::indexList->disable(); - - writeAnnotatedClassList(ol, ClassDef::Exception); + writeAnnotatedIndexGeneric(ol, + AnnotatedIndexContext(annotatedExceptions,annotatedExceptionsPrinted, + LayoutNavEntry::ExceptionList,LayoutNavEntry::Exceptions, + theTranslator->trExceptionList(),theTranslator->trExceptionListDescription(), + ClassDef::Exception, + "annotatedexceptions", + HLI_AnnotatedExceptions)); - Doxygen::indexList->enable(); - ol.popGeneratorState(); - - // --------------- - // Hierarchical interface index for HTML - // --------------- - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::Html); - - { - if (addToIndex) - { - Doxygen::indexList->addContentsItem(TRUE,title,0,"annotatedexceptions",0,TRUE,TRUE); - Doxygen::indexList->incContentsDepth(); - } - FTVHelp* ftv = new FTVHelp(FALSE); - writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex,ClassDef::Exception); - writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE,ClassDef::Exception); - QGString outStr; - FTextStream t(&outStr); - ftv->generateTreeViewInline(t); - ol.writeString(outStr); - delete ftv; - if (addToIndex) - { - Doxygen::indexList->decContentsDepth(); - } - } - - ol.popGeneratorState(); - // ------ - - endFile(ol); // contains ol.endContents() - ol.popGeneratorState(); } //---------------------------------------------------------------------------- @@ -4499,7 +4484,7 @@ static void writeIndex(OutputList &ol) { ol.startHeaderSection(); ol.startTitleHead(0); - ol.generateDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->docLine(), + ol.generateDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine(), Doxygen::mainPage,0,Doxygen::mainPage->title(),TRUE,FALSE, 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)); headerWritten = TRUE; diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 3343c1a..418afa7 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -666,19 +666,24 @@ static void writeDefaultHeaderPart1(FTextStream &t) t << "% Headers & footers\n" "\\usepackage{fancyhdr}\n" "\\pagestyle{fancyplain}\n" - "\\fancyhead[LE]{\\fancyplain{}{\\bfseries\\thepage}}\n" - "\\fancyhead[CE]{\\fancyplain{}{}}\n" - "\\fancyhead[RE]{\\fancyplain{}{\\bfseries\\leftmark}}\n" - "\\fancyhead[LO]{\\fancyplain{}{\\bfseries\\rightmark}}\n" - "\\fancyhead[CO]{\\fancyplain{}{}}\n" - "\\fancyhead[RO]{\\fancyplain{}{\\bfseries\\thepage}}\n" - "\\fancyfoot[LE]{\\fancyplain{}{}}\n" - "\\fancyfoot[CE]{\\fancyplain{}{}}\n" - "\\fancyfoot[RE]{\\fancyplain{}{\\bfseries\\scriptsize " << genString << " Doxygen }}\n" - "\\fancyfoot[LO]{\\fancyplain{}{\\bfseries\\scriptsize " << genString << " Doxygen }}\n" - "\\fancyfoot[CO]{\\fancyplain{}{}}\n" - "\\fancyfoot[RO]{\\fancyplain{}{}}\n" - "\\renewcommand{\\footrulewidth}{0.4pt}\n"; + "\\renewcommand{\\footrulewidth}{0.4pt}\n" + "%\n" + "\\fancypagestyle{fancyplain}{\n" + "\\fancyhf{}\n" + "\\fancyhead[LE, RO]{\\bfseries\\thepage}\n" + "\\fancyhead[LO]{\\bfseries\\rightmark}\n" + "\\fancyhead[RE]{\\bfseries\\leftmark}\n" + "\\fancyfoot[LO, RE]{\\bfseries\\scriptsize " << genString << " Doxygen }\n" + "}\n" + "%\n" + "\\fancypagestyle{plain}{\n" + "\\fancyhf{}\n" + "\\fancyfoot[LO, RE]{\\bfseries\\scriptsize " << genString << " Doxygen }\n" + "\\renewcommand{\\headrulewidth}{0pt}}\n" + "%\n" + "\\pagestyle{fancyplain}\n" + "%\n"; + if (!Config_getBool(COMPACT_LATEX)) { t << "\\renewcommand{\\chaptermark}[1]{%\n" @@ -769,7 +774,8 @@ static void writeDefaultHeaderPart1(FTextStream &t) // End of preamble, now comes the document contents t << "%===== C O N T E N T S =====\n" "\n" - "\\begin{document}\n"; + "\\begin{document}\n" + "\\raggedbottom\n"; QCString documentPre = theTranslator->latexDocumentPre(); if (!documentPre.isEmpty()) { diff --git a/src/markdown.cpp b/src/markdown.cpp index e268c48..930efd6 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -59,7 +59,7 @@ #ifdef ENABLE_TRACING #define IOSTREAM stdout #define DATA_BUFSIZE 20 -#if defined(_WIN32) && !defined(CYGWIN) +#if defined(_WIN32) && !defined(CYGWIN) && !defined(__MINGW32__) #define PRETTY_FUNC __FUNCSIG__ #else #define PRETTY_FUNC __PRETTY_FUNCTION__ @@ -808,6 +808,7 @@ int Markdown::processLink(const char *data,int,int size) } contentStart=i; int level=1; + int nlTotal=0; int nl=0; // find the matching ] while (i<size) @@ -831,6 +832,8 @@ int Markdown::processLink(const char *data,int,int size) } i++; } + nlTotal += nl; + nl = 0; if (i>=size) return 0; // premature end of comment -> no link contentEnd=i; convertStringFragment(content,data+contentStart,contentEnd-contentStart); @@ -843,9 +846,12 @@ int Markdown::processLink(const char *data,int,int size) if (i<size && data[i]=='\n') // one newline allowed here { i++; + nl++; // skip more whitespace while (i<size && data[i]==' ') i++; } + nlTotal += nl; + nl = 0; bool explicitTitle=FALSE; if (i<size && data[i]=='(') // inline link @@ -854,7 +860,6 @@ int Markdown::processLink(const char *data,int,int size) while (i<size && data[i]==' ') i++; if (i<size && data[i]=='<') i++; linkStart=i; - nl=0; int braceCount=1; while (i<size && data[i]!='\'' && data[i]!='"' && braceCount>0) { @@ -876,6 +881,8 @@ int Markdown::processLink(const char *data,int,int size) i++; } } + nlTotal += nl; + nl = 0; if (i>=size || data[i]=='\n') return 0; convertStringFragment(link,data+linkStart,i-linkStart); link = link.stripWhiteSpace(); @@ -985,6 +992,8 @@ int Markdown::processLink(const char *data,int,int size) { return 0; } + nlTotal += nl; + nl = 0; if (isToc) // special case for [TOC] { int toc_level = Config_getInt(TOC_INCLUDE_HEADINGS); @@ -1066,6 +1075,7 @@ int Markdown::processLink(const char *data,int,int size) m_out.addStr("<a href=\""); m_out.addStr(link); m_out.addStr("\""); + for (int ii = 0; ii < nlTotal; ii++) m_out.addStr("\n"); if (!title.isEmpty()) { m_out.addStr(" title=\""); @@ -2130,6 +2140,7 @@ int Markdown::writeCodeBlock(const char *data,int size,int refIndent) TRACE(data); int i=0,end; //printf("writeCodeBlock: data={%s}\n",QCString(data).left(size).data()); + // no need for \ilinebr here as the prvious like was empty and was skipped m_out.addStr("@verbatim\n"); int emptyLines=0; while (i<size) @@ -2164,7 +2175,7 @@ int Markdown::writeCodeBlock(const char *data,int size,int refIndent) break; } } - m_out.addStr("@endverbatim\n"); + m_out.addStr("@endverbatim\\ilinebr "); while (emptyLines>0) // write skipped empty lines { // add empty line @@ -2491,18 +2502,20 @@ static bool isExplicitPage(const QCString &docs) return FALSE; } -QCString Markdown::extractPageTitle(QCString &docs,QCString &id) +QCString Markdown::extractPageTitle(QCString &docs,QCString &id, int &prepend) { TRACE(docs.data()); - int ln=0; // first first non-empty line + prepend = 0; QCString title; - const char *data = docs.data(); int i=0; int size=docs.size(); + QCString docs_org(docs); + const char *data = docs_org.data(); + docs = ""; while (i<size && (data[i]==' ' || data[i]=='\n')) { - if (data[i]=='\n') ln++; + if (data[i]=='\n') prepend++; i++; } if (i>=size) return ""; @@ -2512,16 +2525,13 @@ QCString Markdown::extractPageTitle(QCString &docs,QCString &id) // first line from i..end1 if (end1<size) { - ln++; // second line form end1..end2 int end2=end1+1; while (end2<size && data[end2-1]!='\n') end2++; if (isHeaderline(data+end1,size-end1,FALSE)) { convertStringFragment(title,data+i,end1-i-1); - QCString lns; - lns.fill('\n',ln); - docs=lns+docs.mid(end2); + docs+="\n\n"+docs_org.mid(end2); id = extractTitleId(title, 0); //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data()); return title; @@ -2529,10 +2539,12 @@ QCString Markdown::extractPageTitle(QCString &docs,QCString &id) } if (i<end1 && isAtxHeader(data+i,end1-i,title,id,FALSE)>0) { - docs=docs.mid(end1); + docs+="\n"; + docs+=docs_org.mid(end1); } else { + docs=docs_org; id = extractTitleId(title, 0); } //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data()); @@ -2661,7 +2673,7 @@ QCString markdownFileNameToId(const QCString &fileName) QCString baseFn = stripFromPath(QFileInfo(fileName).absFilePath().utf8()); int i = baseFn.findRev('.'); if (i!=-1) baseFn = baseFn.left(i); - QCString baseName = substitute(substitute(substitute(baseFn," ","_"),"/","_"),":","_"); + QCString baseName = substitute(substitute(substitute(substitute(baseFn," ","_"),"/","_"),":","_"),"@","_"); //printf("markdownFileNameToId(%s)=md_%s\n",qPrint(fileName),qPrint(baseName)); return "md_"+baseName; } @@ -2687,6 +2699,7 @@ void MarkdownOutlineParser::parseInput(const char *fileName, ClangTUParser* /*clangParser*/) { std::shared_ptr<Entry> current = std::make_shared<Entry>(); + int prepend = 0; // number of empty lines in front current->lang = SrcLangExt_Markdown; current->fileName = fileName; current->docFile = fileName; @@ -2694,7 +2707,7 @@ void MarkdownOutlineParser::parseInput(const char *fileName, QCString docs = fileBuf; QCString id; Markdown markdown(fileName,1,0); - QCString title=markdown.extractPageTitle(docs,id).stripWhiteSpace(); + QCString title=markdown.extractPageTitle(docs,id,prepend).stripWhiteSpace(); if (id.startsWith("autotoc_md")) id = ""; int indentLevel=title.isEmpty() ? 0 : -1; markdown.setIndentLevel(indentLevel); @@ -2711,21 +2724,22 @@ void MarkdownOutlineParser::parseInput(const char *fileName, QFileInfo(mdfileAsMainPage).absFilePath()) // file reference with path ) { - docs.prepend("@anchor " + id + "\n"); - docs.prepend("@mainpage "+title+"\n"); + docs.prepend("@anchor " + id + "\\ilinebr "); + docs.prepend("@mainpage "+title+"\\ilinebr "); } else if (id=="mainpage" || id=="index") { if (title.isEmpty()) title = titleFn; - docs.prepend("@anchor " + id + "\n"); - docs.prepend("@mainpage "+title+"\n"); + docs.prepend("@anchor " + id + "\\ilinebr "); + docs.prepend("@mainpage "+title+"\\ilinebr "); } else { - if (title.isEmpty()) title = titleFn; - if (!wasEmpty) docs.prepend("@anchor " + markdownFileNameToId(fileName) + "\n"); - docs.prepend("@page "+id+" "+title+"\n"); + if (title.isEmpty()) {title = titleFn;prepend=0;} + if (!wasEmpty) docs.prepend("@anchor " + markdownFileNameToId(fileName) + "\\ilinebr "); + docs.prepend("@page "+id+" "+title+"\\ilinebr "); } + for (int i = 0; i < prepend; i++) docs.prepend("\n"); } int lineNr=1; diff --git a/src/markdown.h b/src/markdown.h index 1210967..dd4ff73 100644 --- a/src/markdown.h +++ b/src/markdown.h @@ -34,7 +34,7 @@ class Markdown public: Markdown(const char *fileName,int lineNr,int indentLevel=0); QCString process(const QCString &input, int &startNewlines); - QCString extractPageTitle(QCString &docs,QCString &id); + QCString extractPageTitle(QCString &docs,QCString &id,int &prepend); void setIndentLevel(int level) { m_indentLevel = level; } private: diff --git a/src/memberdef.cpp b/src/memberdef.cpp index c3c420a..cae209c 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -4343,11 +4343,9 @@ MemberDef *MemberDefImpl::createTemplateInstanceMember( const ArgumentList &formalArgs,const std::unique_ptr<ArgumentList> &actualArgs) const { //printf(" Member %s %s %s\n",typeString(),name().data(),argsString()); - std::unique_ptr<ArgumentList> actualArgList; + std::unique_ptr<ArgumentList> actualArgList = std::make_unique<ArgumentList>(m_impl->defArgList); if (!m_impl->defArgList.empty()) { - actualArgList = std::make_unique<ArgumentList>(m_impl->defArgList); - // replace formal arguments with actuals for (Argument &arg : *actualArgList) { @@ -4356,10 +4354,6 @@ MemberDef *MemberDefImpl::createTemplateInstanceMember( actualArgList->setTrailingReturnType( substituteTemplateArgumentsInString(actualArgList->trailingReturnType(),formalArgs,actualArgs)); } - else - { - actualArgList = std::make_unique<ArgumentList>(); - } QCString methodName=name(); if (methodName.left(9)=="operator ") // conversion operator diff --git a/src/memberlist.cpp b/src/memberlist.cpp index b8e5e89..0c608ff 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -63,7 +63,7 @@ MemberList::~MemberList() delete memberGroupList; } -static int genericCompareMembers(const MemberDef *c1,const MemberDef *c2) +int genericCompareMembers(const MemberDef *c1,const MemberDef *c2) { bool sortConstructorsFirst = Config_getBool(SORT_MEMBERS_CTORS_1ST); if (sortConstructorsFirst) diff --git a/src/memberlist.h b/src/memberlist.h index 4038453..b8c723b 100644 --- a/src/memberlist.h +++ b/src/memberlist.h @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -105,7 +105,7 @@ class MemberList : private QList<MemberDef> int m_dictCnt; int m_protoCnt; int m_defCnt; - int m_friendCnt; + int m_friendCnt; */ int m_numDecMembers; // number of members in the brief part of the memberlist int m_numDecEnumValues; @@ -145,5 +145,6 @@ class MemberSDict : public SDict<MemberDef> int compareValues(const MemberDef *item1,const MemberDef *item2) const; }; +int genericCompareMembers(const MemberDef *c1,const MemberDef *c2); #endif diff --git a/src/message.cpp b/src/message.cpp index 984a00f..e107139 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -161,7 +161,7 @@ static void format_warn(const char *file,int line,const char *text) } } -static void handle_warn_as_error(void) +static void handle_warn_as_error() { static bool warnAsError = Config_getBool(WARN_AS_ERROR); if (warnAsError) @@ -279,6 +279,12 @@ void term(const char *fmt, ...) exit(1); } +void warn_flush() +{ + fflush(warnFile); +} + + void printlex(int dbg, bool enter, const char *lexName, const char *fileName) { const char *enter_txt = "entering"; diff --git a/src/message.h b/src/message.h index e84344b..dd9eeeb 100644 --- a/src/message.h +++ b/src/message.h @@ -35,6 +35,7 @@ extern void err(const char *fmt, ...) PRINTFLIKE(1, 2); extern void err_full(const char *file,int line,const char *fmt, ...) PRINTFLIKE(3, 4); extern void term(const char *fmt, ...) PRINTFLIKE(1, 2); void initWarningFormat(); +void warn_flush(); extern void printlex(int dbg, bool enter, const char *lexName, const char *fileName); diff --git a/src/pagedef.cpp b/src/pagedef.cpp index 75e50ed..12a7bdc 100644 --- a/src/pagedef.cpp +++ b/src/pagedef.cpp @@ -230,7 +230,7 @@ void PageDefImpl::writeDocumentation(OutputList &ol) if (si->title() != manPageName) { - ol.generateDoc(docFile(),docLine(),this,0,si->title(),TRUE,FALSE, + ol.generateDoc(docFile(),getStartBodyLine(),this,0,si->title(),TRUE,FALSE, 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)); ol.endSection(si->label(),si->type()); } @@ -250,7 +250,7 @@ void PageDefImpl::writeDocumentation(OutputList &ol) ol.startPageDoc(si->title()); //ol.startSection(si->label,si->title,si->type); startTitle(ol,getOutputFileBase(),this); - ol.generateDoc(docFile(),docLine(),this,0,si->title(),TRUE,FALSE, + ol.generateDoc(docFile(),getStartBodyLine(),this,0,si->title(),TRUE,FALSE, 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)); //stringToSearchIndex(getOutputFileBase(), // theTranslator->trPage(TRUE,TRUE)+" "+si->title, diff --git a/src/pagedef.h b/src/pagedef.h index e4d0268..a1f08a5 100644 --- a/src/pagedef.h +++ b/src/pagedef.h @@ -1,12 +1,10 @@ /****************************************************************************** * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp index a6e9f22..ffb0fed 100644 --- a/src/perlmodgen.cpp +++ b/src/perlmodgen.cpp @@ -1831,31 +1831,31 @@ void PerlModGenerator::generatePerlModForClass(const ClassDef *cd) m_output.openHash() .addFieldQuotedString("name", cd->name()); - if (cd->baseClasses()) + if (!cd->baseClasses().empty()) { m_output.openList("base"); - BaseClassListIterator bcli(*cd->baseClasses()); - BaseClassDef *bcd; - for (bcli.toFirst();(bcd=bcli.current());++bcli) + for (const auto &bcd : cd->baseClasses()) + { m_output.openHash() - .addFieldQuotedString("name", bcd->classDef->displayName()) - .addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt)) - .addFieldQuotedString("protection", getProtectionName(bcd->prot)) + .addFieldQuotedString("name", bcd.classDef->displayName()) + .addFieldQuotedString("virtualness", getVirtualnessName(bcd.virt)) + .addFieldQuotedString("protection", getProtectionName(bcd.prot)) .closeHash(); + } m_output.closeList(); } - if (cd->subClasses()) + if (!cd->subClasses().empty()) { m_output.openList("derived"); - BaseClassListIterator bcli(*cd->subClasses()); - BaseClassDef *bcd; - for (bcli.toFirst();(bcd=bcli.current());++bcli) + for (const auto &bcd : cd->subClasses()) + { m_output.openHash() - .addFieldQuotedString("name", bcd->classDef->displayName()) - .addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt)) - .addFieldQuotedString("protection", getProtectionName(bcd->prot)) + .addFieldQuotedString("name", bcd.classDef->displayName()) + .addFieldQuotedString("virtualness", getVirtualnessName(bcd.virt)) + .addFieldQuotedString("protection", getProtectionName(bcd.prot)) .closeHash(); + } m_output.closeList(); } diff --git a/src/portable.cpp b/src/portable.cpp index d3799c7..0ffbd49 100644 --- a/src/portable.cpp +++ b/src/portable.cpp @@ -196,7 +196,7 @@ int Portable::system(const char *command,const char *args,bool commandHasConsole } -unsigned int Portable::pid(void) +unsigned int Portable::pid() { unsigned int pid; #if !defined(_WIN32) || defined(__CYGWIN__) @@ -322,7 +322,7 @@ FILE *Portable::fopen(const char *fileName,const char *mode) #endif } -char Portable::pathSeparator(void) +char Portable::pathSeparator() { #if defined(_WIN32) && !defined(__CYGWIN__) return '\\'; @@ -331,7 +331,7 @@ char Portable::pathSeparator(void) #endif } -char Portable::pathListSeparator(void) +char Portable::pathListSeparator() { #if defined(_WIN32) && !defined(__CYGWIN__) return ';'; @@ -386,7 +386,7 @@ bool Portable::checkForExecutable(const char *fileName) #endif } -const char *Portable::ghostScriptCommand(void) +const char *Portable::ghostScriptCommand() { #if defined(_WIN32) && !defined(__CYGWIN__) static char *gsexe = NULL; @@ -410,7 +410,7 @@ const char *Portable::ghostScriptCommand(void) #endif } -const char *Portable::commandExtension(void) +const char *Portable::commandExtension() { #if defined(_WIN32) && !defined(__CYGWIN__) return ".exe"; @@ -419,7 +419,7 @@ const char *Portable::commandExtension(void) #endif } -bool Portable::fileSystemIsCaseSensitive(void) +bool Portable::fileSystemIsCaseSensitive() { #if defined(_WIN32) || defined(macintosh) || defined(__MACOSX__) || defined(__APPLE__) || defined(__CYGWIN__) return FALSE; @@ -446,17 +446,17 @@ int Portable::pclose(FILE *stream) #endif } -void Portable::sysTimerStart(void) +void Portable::sysTimerStart() { g_time.start(); } -void Portable::sysTimerStop(void) +void Portable::sysTimerStop() { g_sysElapsedTime+=((double)g_time.elapsed())/1000.0; } -double Portable::getSysElapsedTime(void) +double Portable::getSysElapsedTime() { return g_sysElapsedTime; } @@ -492,7 +492,7 @@ bool Portable::isAbsolutePath(const char *fileName) * * This routine was inspired by the cause for bug 766059 was that in the Windows path there were forward slashes. */ -void Portable::correct_path(void) +void Portable::correct_path() { #if defined(_WIN32) && !defined(__CYGWIN__) const char *p = Portable::getenv("PATH"); @@ -511,7 +511,7 @@ void Portable::unlink(const char *fileName) #endif } -void Portable::setShortDir(void) +void Portable::setShortDir() { #if defined(_WIN32) && !defined(__CYGWIN__) long length = 0; diff --git a/src/portable.h b/src/portable.h index bf6cfea..d2b3036 100644 --- a/src/portable.h +++ b/src/portable.h @@ -20,7 +20,7 @@ typedef off_t portable_off_t; namespace Portable { int system(const char *command,const char *args,bool commandHasConsole=true); - unsigned int pid(void); + unsigned int pid(); const char * getenv(const char *variable); void setenv(const char *variable,const char *value); void unsetenv(const char *variable); @@ -28,20 +28,20 @@ namespace Portable portable_off_t ftell(FILE *f); FILE * fopen(const char *fileName,const char *mode); void unlink(const char *fileName); - char pathSeparator(void); - char pathListSeparator(void); - const char * ghostScriptCommand(void); - const char * commandExtension(void); + char pathSeparator(); + char pathListSeparator(); + const char * ghostScriptCommand(); + const char * commandExtension(); bool fileSystemIsCaseSensitive(); FILE * popen(const char *name,const char *type); int pclose(FILE *stream); - void sysTimerStart(void); - void sysTimerStop(void); - double getSysElapsedTime(void); + void sysTimerStart(); + void sysTimerStop(); + double getSysElapsedTime(); void sleep(int ms); bool isAbsolutePath(const char *fileName); - void correct_path(void); - void setShortDir(void); + void correct_path(); + void setShortDir(); const char * strnstr(const char *haystack, const char *needle, size_t haystack_len); const char * devNull(); bool checkForExecutable(const char *fileName); @@ -2416,6 +2416,10 @@ static bool expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in expanded = expandExpression(yyscanner,resultExpr,&restExpr,0,level+1); state->expandedDict.erase(toStdString(macroName)); } + else if (def && def->nonRecursive) + { + expanded = true; + } if (expanded) { expr=expr.left(p)+resultExpr+restExpr; diff --git a/src/pycode.l b/src/pycode.l index 68ec265..bcba42f 100644 --- a/src/pycode.l +++ b/src/pycode.l @@ -52,6 +52,7 @@ #include "filedef.h" #include "namespacedef.h" #include "tooltip.h" +#include "scopedtypevariant.h" // Toggle for some debugging info //#define DBG_CTX(x) fprintf x @@ -62,103 +63,10 @@ #define USE_STATE2STRING 0 -/*! Represents a stack of variable to class mappings as found in the - * code. Each scope is enclosed in pushScope() and popScope() calls. - * Variables are added by calling addVariables() and one can search - * for variable using findVariable(). - */ -class PyVariableContext -{ - public: - static const ClassDef *dummyContext; - - using Scope = std::unordered_map<std::string,const ClassDef *>; - - void pushScope() - { - m_scopes.push_back(Scope()); - } - - void popScope() - { - if (!m_scopes.empty()) - { - m_scopes.pop_back(); - } - } - - void clear() - { - m_scopes.clear(); - m_globalScope.clear(); - } - - void clearExceptGlobal() - { - m_scopes.clear(); - } - - void addVariable(yyscan_t yyscanner, const QCString &type,const QCString &name); - const ClassDef *findVariable(const QCString &name); - - private: - Scope m_globalScope; - std::vector<Scope> m_scopes; -}; - -class PyCallContext -{ - public: - struct Ctx - { - Ctx(QCString name_,QCString type_) : name(name_), type(type_) {} - QCString name; - QCString type; - const ClassDef *cd = 0; - }; - - PyCallContext() - { - clear(); - } - - void setClass(const ClassDef *cd) - { - Ctx &ctx = m_classList.back(); - ctx.cd=cd; - } - void pushScope(const QCString &name_,const QCString type_) - { - m_classList.push_back(Ctx(name_,type_)); - } - void popScope(QCString &name_,QCString &type_) - { - if (m_classList.size()>1) - { - const Ctx &ctx = m_classList.back(); - name_ = ctx.name; - type_ = ctx.type; - m_classList.pop_back(); - } - } - void clear() - { - m_classList.clear(); - m_classList.push_back(Ctx("","")); - } - const ClassDef *getClass() const - { - return m_classList.back().cd; - } - - private: - std::vector<Ctx> m_classList; -}; - struct pycodeYY_state { - std::unordered_map< std::string, std::unique_ptr<ClassDef> > codeClassMap; + std::unordered_map< std::string, ScopedTypeVariant > codeClassMap; QCString curClassName; QStrList curClassBases; @@ -196,8 +104,9 @@ struct pycodeYY_state QCString docBlock; //!< contents of all lines of a documentation block bool endComment = FALSE; - PyVariableContext theVarContext; - PyCallContext theCallContext; + VariableContext theVarContext; + CallContext theCallContext; + TooltipManager tooltipManager; }; @@ -205,9 +114,6 @@ struct pycodeYY_state static const char *stateToString(int state); #endif -const ClassDef *PyVariableContext::dummyContext = (ClassDef*)0x8; - - static void startCodeLine(yyscan_t yyscanner); static int countLines(yyscan_t yyscanner); static void setCurrentDoc(yyscan_t yyscanner, const QCString &anchor); @@ -235,6 +141,15 @@ static void findMemberLink(yyscan_t yyscanner, CodeOutputInterface &ol, static void adjustScopesAndSuites(yyscan_t yyscanner,unsigned indentLength); static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); +#if 0 // TODO: call me to store local variables and get better syntax highlighting, see code.l +static void addVariable(yyscan_t yyscanner, QCString type, QCString name); +#endif + +//------------------------------------------------------------------- + +static std::mutex g_searchIndexMutex; + +//------------------------------------------------------------------- #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size); @@ -253,6 +168,8 @@ EXPCHAR [#(){}\[\],:.%/\\=`*~|&<>!;+-] NONEMPTYEXP [^ \t\n:] PARAMNONEMPTY [^ \t\n():] IDENTIFIER ({LETTER}|"_")({LETTER}|{DIGIT}|"_")* +SCOPE {IDENTIFIER}("."{IDENTIFIER})* +CALLANY "("[^)]*")" BORDER ([^A-Za-z0-9]) POUNDCOMMENT "##" @@ -426,6 +343,11 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU codify(yyscanner,"cls."); findMemberLink(yyscanner,*yyextra->code,&yytext[4]); } + "@"{SCOPE}{CALLANY}? { // decorator + startFontClass(yyscanner,"preprocessor"); + codify(yyscanner,yytext); + endFontClass(yyscanner); + } } <ClassDec>{IDENTIFIER} { @@ -471,6 +393,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU // Push a class scope std::unique_ptr<ClassDef> classDefToAdd { createClassDef("<code>",1,1,yyextra->curClassName,ClassDef::Class,0,0,FALSE) }; + ScopedTypeVariant var(yyextra->curClassName); char *s=yyextra->curClassBases.first(); while (s) { @@ -479,7 +402,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU auto it = yyextra->codeClassMap.find(s); if (it != yyextra->codeClassMap.end()) { - baseDefToAdd = it->second.get(); + baseDefToAdd = dynamic_cast<const ClassDef*>(it->second.globalDef()); } // Try to find class in global scope if (baseDefToAdd==0) @@ -487,14 +410,14 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU baseDefToAdd=getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,s); } - if (baseDefToAdd && baseDefToAdd!=classDefToAdd.get()) + if (baseDefToAdd && baseDefToAdd->name()!=yyextra->curClassName) { - classDefToAdd->insertBaseClass(const_cast<ClassDef*>(baseDefToAdd),s,Public,Normal); + var.localDef()->insertBaseClass(baseDefToAdd->name()); } s=yyextra->curClassBases.next(); } - yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(classDefToAdd))); + yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(var))); // Reset class-parsing variables. yyextra->curClassName.resize(0); @@ -892,63 +815,36 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU /*@ ---------------------------------------------------------------------------- */ -void PyVariableContext::addVariable(yyscan_t yyscanner, const QCString &type,const QCString &name) +#if 0 // TODO: call me to store local variables and get better syntax highlighting, see code.l +static void addVariable(yyscan_t yyscanner, QCString type, QCString name) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //printf("PyVariableContext::addVariable(%s,%s)\n",type.data(),name.data()); QCString ltype = type.simplifyWhiteSpace(); QCString lname = name.simplifyWhiteSpace(); - Scope *scope = m_scopes.empty() ? &m_globalScope : &m_scopes.back(); - const ClassDef *varType = 0; auto it = yyextra->codeClassMap.find(ltype.str()); if (it!=yyextra->codeClassMap.end()) { - varType = it->second.get(); - } - if (varType==0) - { - varType = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,ltype); // look for global class definitions - } - if (varType) - { - scope->emplace(std::make_pair(lname.str(),varType)); // add it to a list + yyextra->theVarContext.addVariable(lname,std::move(it->second)); } else { - if (!m_scopes.empty()) // for local variable add a dummy entry to avoid linking to a global that is - // shadowed. + const ClassDef *varType = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,ltype); // look for global class definitions + if (varType) { - scope->emplace(std::make_pair(lname.str(),dummyContext)); + yyextra->theVarContext.addVariable(lname,ScopedTypeVariant(varType)); } - } -} - -const ClassDef *PyVariableContext::findVariable(const QCString &name) -{ - if (name.isEmpty()) return 0; - const ClassDef *result = 0; - - // search from inner to outer scope - auto it = std::rbegin(m_scopes); - while (it != std::rend(m_scopes)) - { - auto it2 = it->find(name.str()); - if (it2 != std::end(*it)) + else { - result = it2->second; - return result; + if (!yyextra->theVarContext.atGlobalScope()) // for local variable add a dummy entry to avoid linking to a global that is shadowed. + { + yyextra->theVarContext.addVariable(lname.str(),ScopedTypeVariant()); + } } - ++it; } - // nothing found -> also try the global scope - auto it2 = m_globalScope.find(name.str()); - if (it2 != m_globalScope.end()) - { - result = it2->second; - } - return result; } +#endif //------------------------------------------------------------------------------- @@ -1031,6 +927,7 @@ static void setCurrentDoc(yyscan_t yyscanner, const QCString &anchor) struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (Doxygen::searchIndex) { + std::lock_guard<std::mutex> lock(g_searchIndexMutex); if (yyextra->searchCtx) { yyextra->code->setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),FALSE); @@ -1049,6 +946,7 @@ static void addToSearchIndex(yyscan_t yyscanner, const char *text) struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (Doxygen::searchIndex) { + std::lock_guard<std::mutex> lock(g_searchIndexMutex); yyextra->code->addWord(text,FALSE); } } @@ -1189,7 +1087,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner, { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); - TooltipManager::instance()->addTooltip(d); + yyextra->tooltipManager.addTooltip(d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); @@ -1310,7 +1208,7 @@ static bool getLinkInScope(yyscan_t yyscanner, if (md->getGroupDef()) d = md->getGroupDef(); if (d && d->isLinkable()) { - yyextra->theCallContext.setClass(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); + yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope()))); //printf("yyextra->currentDefinition=%p yyextra->currentMemberDef=%p\n", // yyextra->currentDefinition,yyextra->currentMemberDef); @@ -1372,8 +1270,9 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, DBG_CTX((stderr,"generateClassOrGlobalLink(className=%s)\n",className.data())); - const ClassDef *cd=0,*lcd=0; /** Class def that we may find */ - const MemberDef *md=0; /** Member def that we may find */ + const ScopedTypeVariant *lcd = 0; + const ClassDef *cd=0; // Class def that we may find + const MemberDef *md=0; // Member def that we may find //bool isLocal=FALSE; if ((lcd=yyextra->theVarContext.findVariable(className))==0) // not a local variable @@ -1405,9 +1304,9 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, } else { - if (lcd!=PyVariableContext::dummyContext) + if (lcd->type()!=ScopedTypeVariant::Dummy) { - yyextra->theCallContext.setClass(lcd); + yyextra->theCallContext.setScope(*lcd); } //isLocal=TRUE; DBG_CTX((stderr,"is a local variable cd=%p!\n",cd)); @@ -1443,7 +1342,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, MemberDef *mmd = mcd->getMemberByName(locName); if (mmd) { - yyextra->theCallContext.setClass(stripClassName(yyscanner,mmd->typeString(),mmd->getOuterScope())); + yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,mmd->typeString(),mmd->getOuterScope()))); writeMultiLineCodeLink(yyscanner,ol,mmd,clName); addToSearchIndex(yyscanner,className); const Definition *d = mmd->getOuterScope()==Doxygen::globalScope ? @@ -1466,7 +1365,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, if (mmd) { //printf("name=%s scope=%s\n",locName.data(),scope.data()); - yyextra->theCallContext.setClass(stripClassName(yyscanner,mmd->typeString(),mmd->getOuterScope())); + yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,mmd->typeString(),mmd->getOuterScope()))); writeMultiLineCodeLink(yyscanner,ol,mmd,clName); addToSearchIndex(yyscanner,className); const Definition *d = mmd->getOuterScope()==Doxygen::globalScope ? @@ -1503,8 +1402,7 @@ static void generateFunctionLink(yyscan_t yyscanner, const char *funcName) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; - const ClassDef *ccd=0; - QCString locScope=yyextra->classScope.copy(); + QCString locScope=yyextra->classScope; QCString locFunc=removeRedundantWhiteSpace(funcName); DBG_CTX((stdout,"*** locScope=%s locFunc=%s\n",locScope.data(),locFunc.data())); int i=locFunc.findRev("::"); @@ -1519,17 +1417,16 @@ static void generateFunctionLink(yyscan_t yyscanner, auto it = yyextra->codeClassMap.find(locScope.str()); if (it!=yyextra->codeClassMap.end()) { - ccd = it->second.get(); - } - //printf("using classScope %s\n",yyextra->classScope.data()); - if (ccd && ccd->baseClasses()) - { - BaseClassListIterator bcli(*ccd->baseClasses()); - for ( ; bcli.current() ; ++bcli) + ScopedTypeVariant ccd = it->second; + //printf("using classScope %s\n",yyextra->classScope.data()); + if (ccd.localDef() && !ccd.localDef()->baseClasses().empty()) { - if (getLink(yyscanner,bcli.current()->classDef->name(),locFunc,ol,funcName)) + for (const auto &bcName : ccd.localDef()->baseClasses()) { - return; + if (getLink(yyscanner,bcName,locFunc,ol,funcName)) + { + return; + } } } } @@ -1729,6 +1626,8 @@ void PythonCodeParser::parseCode(CodeOutputInterface &codeOutIntf, delete yyextra->sourceFileDef; yyextra->sourceFileDef=0; } + // write the tooltips + yyextra->tooltipManager.writeTooltips(codeOutIntf); printlex(yy_flex_debug, FALSE, __FILE__, fileDef ? fileDef->fileName().data(): NULL); } diff --git a/src/pyscanner.l b/src/pyscanner.l index a136b52..4a9552e 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -113,6 +113,7 @@ struct pyscannerYY_state int search_count = 0; QCString argType; bool funcParamsEnd = FALSE; + std::vector<QCString> decorators; }; //----------------------------------------------------------------------------- @@ -175,6 +176,7 @@ NONEMPTYEXP [^ \t\n:] PARAMNONEMPTY [^ \t\n():] IDENTIFIER ({LETTER}|"_")({LETTER}|{DIGIT}|"_")* SCOPE {IDENTIFIER}("."{IDENTIFIER})* +CALL "("[^)]*")" BORDER ([^A-Za-z0-9]) TRISINGLEQUOTE {STRINGPREFIX}?"'''"(!)? @@ -335,6 +337,8 @@ STARTDOCSYMS "##" "@staticmethod" { yyextra->stat=TRUE; } + "@"{SCOPE}{CALL}? { // decorator + } {SCRIPTCOMMENT} { // Unix type script comment if (yyextra->yyLineNr != 1) REJECT; } diff --git a/src/reflist.cpp b/src/reflist.cpp index ed26818..5840138 100644 --- a/src/reflist.cpp +++ b/src/reflist.cpp @@ -124,6 +124,6 @@ void RefList::generatePage() //printf("generatePage('%s')\n",doc.data()); if (cnt>0) { - addRelatedPage(m_listName,m_pageTitle,doc,m_fileName,1,RefItemVector(),0,0,TRUE); + addRelatedPage(m_listName,m_pageTitle,doc,m_fileName,1,1,RefItemVector(),0,0,TRUE); } } diff --git a/src/scopedtypevariant.h b/src/scopedtypevariant.h new file mode 100644 index 0000000..2648a3a --- /dev/null +++ b/src/scopedtypevariant.h @@ -0,0 +1,292 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2020 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef SCOPEDTYPEVARIANT_H +#define SCOPEDTYPEVARIANT_H + +#include <utility> +#include <vector> +#include <qcstring.h> +#include "definition.h" + +//! Class representing a local class definition found while +//! generating syntax highlighted code. +class LocalDef +{ + public: + void insertBaseClass(QCString name) { m_baseClasses.push_back(name); } + std::vector<QCString> baseClasses() const { return m_baseClasses; } + private: + std::vector<QCString> m_baseClasses; +}; + +//----------------------------------------------------------------------------- + +/*! Variant class for a scoped type. + * + * Variants: + * - Dummy: a type used for hiding a global type. + * - Local: a locally defined type (e.g. found inside a function) + * - Global: a globally defined type (processed by doxygen in an earlier pass). + */ +class ScopedTypeVariant +{ + public: + //! possible variant types + enum Variant + { + Global, + Local, + Dummy + }; + //! default constructor for creating a variant of type Dummy + ScopedTypeVariant() : m_variant(Dummy) + { + m_u.globalDef = 0; + } + //! constructor for creating a variant of type Global + explicit ScopedTypeVariant(const Definition *d) + { + if (d) + { + m_name = d->name(); + m_variant = Global; + m_u.globalDef = d; + } + else + { + m_variant = Dummy; + m_u.globalDef = 0; + } + } + //! constructor for creating a variant of type Local + explicit ScopedTypeVariant(QCString name) + { + m_name = name; + m_variant = Local; + m_u.localDef = new LocalDef; + } + //! copy constructor + ScopedTypeVariant(const ScopedTypeVariant &stv) + { + m_variant = stv.m_variant; + m_name = stv.m_name; + if (m_variant==Local) + { + m_u.localDef = new LocalDef(*stv.m_u.localDef); + } + else if (m_variant==Global) + { + m_u.globalDef = stv.m_u.globalDef; + } + } + //! move constructor + ScopedTypeVariant(ScopedTypeVariant && stv) noexcept : ScopedTypeVariant() + { + swap(*this,stv); + } + //! assignment operator + ScopedTypeVariant &operator=(ScopedTypeVariant stv) + { + swap(*this,stv); + return *this; + } + //! destructor + ~ScopedTypeVariant() + { + if (m_variant==Local) + { + delete m_u.localDef; + } + } + //! swap function + friend void swap(ScopedTypeVariant &first,ScopedTypeVariant &second) + { + using std::swap; // enable ADL + swap(first.m_variant,second.m_variant); + swap(first.m_name,second.m_name); + swap(first.m_u.globalDef,second.m_u.globalDef); + } + //! Turn the variant into a Global type + void setGlobal(const Definition *def) + { + if (m_variant==Local) + { + delete m_u.localDef; + } + m_variant = Global; + m_name = def->name(); + m_u.globalDef = def; + } + //! Turn the variant into a Local type + LocalDef *setLocal(QCString name) + { + if (m_variant==Local) + { + delete m_u.localDef; + } + m_variant = Local; + m_name = name; + m_u.localDef = new LocalDef; + return m_u.localDef; + } + //! Turn the variant into a Dummy type + void setDummy() + { + if (m_variant==Local) + { + delete m_u.localDef; + } + m_variant = Dummy; + m_name = ""; + m_u.localDef=0; + } + Variant type() const { return m_variant; } + QCString name() const { return m_name; } + LocalDef *localDef() const { return m_variant==Local ? m_u.localDef : 0; } + const Definition *globalDef() const { return m_variant==Global ? m_u.globalDef : 0; } + + private: + Variant m_variant; + QCString m_name; + union + { + const Definition *globalDef; + LocalDef *localDef; + } m_u; +}; + +//----------------------------------------------------------------------------- + +/*! Represents a stack of variable to class mappings as found in the + * code. Each scope is enclosed in pushScope() and popScope() calls. + * Variables are added by calling addVariables() and one can search + * for variable using findVariable(). + */ +class VariableContext +{ + public: + using Scope = std::unordered_map<std::string,ScopedTypeVariant>; + + void pushScope() + { + m_scopes.push_back(Scope()); + } + void popScope() + { + if (!m_scopes.empty()) + { + m_scopes.pop_back(); + } + } + void clear() + { + m_scopes.clear(); + m_globalScope.clear(); + } + void clearExceptGlobal() + { + m_scopes.clear(); + } + void addVariable(QCString name,ScopedTypeVariant stv) + { + Scope *scope = m_scopes.empty() ? &m_globalScope : &m_scopes.back(); + scope->emplace(std::make_pair(name.str(),std::move(stv))); // add it to a list + } + const ScopedTypeVariant *findVariable(QCString name) + { + const ScopedTypeVariant *result = 0; + if (name.isEmpty()) return result; + + // search from inner to outer scope + auto it = std::rbegin(m_scopes); + while (it != std::rend(m_scopes)) + { + auto it2 = it->find(name.str()); + if (it2 != std::end(*it)) + { + result = &it2->second; + return result; + } + ++it; + } + // nothing found -> also try the global scope + auto it2 = m_globalScope.find(name.str()); + if (it2 != m_globalScope.end()) + { + result = &it2->second; + } + return result; + } + bool atGlobalScope() const { return m_scopes.empty(); } + + private: + Scope m_globalScope; + std::vector<Scope> m_scopes; +}; + +//----------------------------------------------------------------------------- + +/** Represents the call context */ +class CallContext +{ + public: + struct Ctx + { + Ctx(QCString name_,QCString type_) : name(name_), type(type_) {} + QCString name; + QCString type; + ScopedTypeVariant stv; + }; + + CallContext() + { + clear(); + } + void setScope(ScopedTypeVariant stv) + { + Ctx &ctx = m_stvList.back(); + ctx.stv=std::move(stv); + } + void pushScope(const QCString &name_,const QCString type_) + { + m_stvList.push_back(Ctx(name_,type_)); + } + void popScope(QCString &name_,QCString &type_) + { + if (m_stvList.size()>1) + { + const Ctx &ctx = m_stvList.back(); + name_ = ctx.name; + type_ = ctx.type; + m_stvList.pop_back(); + } + } + void clear() + { + m_stvList.clear(); + m_stvList.push_back(Ctx("","")); + } + const ScopedTypeVariant getScope() const + { + return m_stvList.back().stv; + } + + private: + std::vector<Ctx> m_stvList; +}; + + +#endif diff --git a/src/searchindex.cpp b/src/searchindex.cpp index d9e5c99..3045385 100644 --- a/src/searchindex.cpp +++ b/src/searchindex.cpp @@ -37,6 +37,8 @@ #include "filename.h" #include "membername.h" #include "resourcemgr.h" +#include "namespacedef.h" +#include "classdef.h" // file format: (all multi-byte values are stored in big endian format) // 4 byte header @@ -49,41 +51,33 @@ // (4 bytes index to url string + 4 bytes frequency counter) // for each url: a \0 terminated string -const int numIndexEntries = 256*256; +const size_t numIndexEntries = 256*256; //-------------------------------------------------------------------- -IndexWord::IndexWord(const char *word) : m_word(word), m_urls(17) +IndexWord::IndexWord(QCString word) : m_word(word) { - m_urls.setAutoDelete(TRUE); //printf("IndexWord::IndexWord(%s)\n",word); } void IndexWord::addUrlIndex(int idx,bool hiPriority) { //printf("IndexWord::addUrlIndex(%d,%d)\n",idx,hiPriority); - URLInfo *ui = m_urls.find(idx); - if (ui==0) + auto it = m_urls.find(idx); + if (it==m_urls.end()) { //printf("URLInfo::URLInfo(%d)\n",idx); - ui=new URLInfo(idx,0); - m_urls.insert(idx,ui); + it = m_urls.insert(std::make_pair(idx,URLInfo(idx,0))).first; } - ui->freq+=2; - if (hiPriority) ui->freq|=1; // mark as high priority document + it->second.freq+=2; + if (hiPriority) it->second.freq|=1; // mark as high priority document } //-------------------------------------------------------------------- -SearchIndex::SearchIndex() : SearchIndexIntf(Internal), - m_words(328829), m_index(numIndexEntries), m_url2IdMap(10007), m_urls(10007), m_urlIndex(-1) +SearchIndex::SearchIndex() : SearchIndexIntf(Internal) { - int i; - m_words.setAutoDelete(TRUE); - m_url2IdMap.setAutoDelete(TRUE); - m_urls.setAutoDelete(TRUE); - m_index.setAutoDelete(TRUE); - for (i=0;i<numIndexEntries;i++) m_index.insert(i,new QList<IndexWord>); + m_index.resize(numIndexEntries); } void SearchIndex::setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile) @@ -167,16 +161,16 @@ void SearchIndex::setCurrentDoc(const Definition *ctx,const char *anchor,bool is } } - int *pIndex = m_url2IdMap.find(baseUrl); - if (pIndex==0) + auto it = m_url2IdMap.find(baseUrl.str()); + if (it == m_url2IdMap.end()) { ++m_urlIndex; - m_url2IdMap.insert(baseUrl,new int(m_urlIndex)); - m_urls.insert(m_urlIndex,new URL(name,url)); + m_url2IdMap.insert(std::make_pair(baseUrl.str(),m_urlIndex)); + m_urls.insert(std::make_pair(m_urlIndex,URL(name,url))); } else { - m_urls.insert(*pIndex,new URL(name,url)); + m_urls.insert(std::make_pair(it->second,URL(name,url))); } } @@ -208,17 +202,16 @@ void SearchIndex::addWord(const char *word,bool hiPriority,bool recurse) if (word==0 || word[0]=='\0') return; QCString wStr = QCString(word).lower(); //printf("SearchIndex::addWord(%s,%d) wStr=%s\n",word,hiPriority,wStr.data()); - IndexWord *w = m_words[wStr]; - if (w==0) + int idx=charsToIndex(wStr); + if (idx<0 || idx>=static_cast<int>(m_index.size())) return; + auto it = m_words.find(wStr.str()); + if (it==m_words.end()) { - int idx=charsToIndex(wStr); //fprintf(stderr,"addWord(%s) at index %d\n",word,idx); - if (idx<0) return; - w = new IndexWord(wStr); - m_index[idx]->append(w); - m_words.insert(wStr,w); + m_index[idx].push_back(IndexWord(wStr)); + it = m_words.insert({ wStr.str(), static_cast<int>(m_index[idx].size())-1 }).first; } - w->addUrlIndex(m_urlIndex,hiPriority); + m_index[idx][it->second].addUrlIndex(m_urlIndex,hiPriority); int i; bool found=FALSE; if (!recurse) // the first time we check if we can strip the prefix @@ -244,12 +237,12 @@ void SearchIndex::addWord(const char *word,bool hiPriority) addWord(word,hiPriority,FALSE); } -static void writeInt(QFile &f,int index) +static void writeInt(QFile &f,size_t index) { - f.putch(((uint)index)>>24); - f.putch((((uint)index)>>16)&0xff); - f.putch((((uint)index)>>8)&0xff); - f.putch(((uint)index)&0xff); + f.putch(static_cast<int>(index>>24)); + f.putch(static_cast<int>((index>>16)&0xff)); + f.putch(static_cast<int>((index>>8)&0xff)); + f.putch(static_cast<int>(index&0xff)); } static void writeString(QFile &f,const char *s) @@ -261,21 +254,19 @@ static void writeString(QFile &f,const char *s) void SearchIndex::write(const char *fileName) { - int i; - int size=4; // for the header + size_t i; + size_t size=4; // for the header size+=4*numIndexEntries; // for the index - int wordsOffset = size; + size_t wordsOffset = size; // first pass: compute the size of the wordlist for (i=0;i<numIndexEntries;i++) { - QList<IndexWord> *wlist = m_index[i]; - if (!wlist->isEmpty()) + const auto &wlist = m_index[i]; + if (!wlist.empty()) { - QListIterator<IndexWord> iwi(*wlist); - IndexWord *iw; - for (iwi.toFirst();(iw=iwi.current());++iwi) + for (const auto &iw : wlist) { - int ws = iw->word().length()+1; + int ws = iw.word().length()+1; size+=ws+4; // word + url info list offset } size+=1; // zero list terminator @@ -283,19 +274,17 @@ void SearchIndex::write(const char *fileName) } // second pass: compute the offsets in the index - int indexOffsets[numIndexEntries]; - int offset=wordsOffset; + size_t indexOffsets[numIndexEntries]; + size_t offset=wordsOffset; for (i=0;i<numIndexEntries;i++) { - QList<IndexWord> *wlist = m_index[i]; - if (!wlist->isEmpty()) + const auto &wlist = m_index[i]; + if (!wlist.empty()) { indexOffsets[i]=offset; - QListIterator<IndexWord> iwi(*wlist); - IndexWord *iw; - for (iwi.toFirst();(iw=iwi.current());++iwi) + for (const auto &iw : wlist) { - offset+= iw->word().length()+1; + offset+= iw.word().length()+1; offset+=4; // word + offset to url info array } offset+=1; // zero list terminator @@ -305,42 +294,36 @@ void SearchIndex::write(const char *fileName) indexOffsets[i]=0; } } - int padding = size; + size_t padding = size; size = (size+3)&~3; // round up to 4 byte boundary padding = size - padding; - //int statsOffset = size; - //IndexWord *iw; - int *wordStatOffsets = new int[m_words.count()]; + std::vector<size_t> wordStatOffsets(m_words.size()); int count=0; // third pass: compute offset to stats info for each word for (i=0;i<numIndexEntries;i++) { - QList<IndexWord> *wlist = m_index[i]; - if (!wlist->isEmpty()) + const auto &wlist = m_index[i]; + if (!wlist.empty()) { - QListIterator<IndexWord> iwi(*wlist); - IndexWord *iw; - for (iwi.toFirst();(iw=iwi.current());++iwi) + for (const auto &iw : wlist) { //printf("wordStatOffsets[%d]=%d\n",count,size); wordStatOffsets[count++] = size; - size+=4+iw->urls().count()*8; // count + (url_index,freq) per url + size+=4 + iw.urls().size() * 8; // count + (url_index,freq) per url } } } - int *urlOffsets = new int[m_urls.count()]; - //int urlsOffset = size; - QIntDictIterator<URL> udi(m_urls); - URL *url; - for (udi.toFirst();(url=udi.current());++udi) + std::vector<size_t> urlOffsets(m_urls.size()); + for (const auto &udi : m_urls) { - urlOffsets[udi.currentKey()]=size; - size+=url->name.length()+1+ - url->url.length()+1; + urlOffsets[udi.first]=size; + size+=udi.second.name.length()+1+ + udi.second.url.length()+1; } + //printf("Total size %x bytes (word=%x stats=%x urls=%x)\n",size,wordsOffset,statsOffset,urlsOffset); QFile f(fileName); if (f.open(IO_WriteOnly)) @@ -356,14 +339,12 @@ void SearchIndex::write(const char *fileName) count=0; for (i=0;i<numIndexEntries;i++) { - QList<IndexWord> *wlist = m_index[i]; - if (!wlist->isEmpty()) + const auto &wlist = m_index[i]; + if (!wlist.empty()) { - QListIterator<IndexWord> iwi(*wlist); - IndexWord *iw; - for (iwi.toFirst();(iw=iwi.current());++iwi) + for (const auto &iw : wlist) { - writeString(f,iw->word()); + writeString(f,iw.word()); writeInt(f,wordStatOffsets[count++]); } f.putch(0); @@ -374,35 +355,29 @@ void SearchIndex::write(const char *fileName) // write word statistics for (i=0;i<numIndexEntries;i++) { - QList<IndexWord> *wlist = m_index[i]; - if (!wlist->isEmpty()) + const auto &wlist = m_index[i]; + if (!wlist.empty()) { - QListIterator<IndexWord> iwi(*wlist); - IndexWord *iw; - for (iwi.toFirst();(iw=iwi.current());++iwi) + for (const auto &iw : wlist) { - int numUrls = iw->urls().count(); + size_t numUrls = iw.urls().size(); writeInt(f,numUrls); - QIntDictIterator<URLInfo> uli(iw->urls()); - URLInfo *ui; - for (uli.toFirst();(ui=uli.current());++uli) + for (const auto &ui : iw.urls()) { - writeInt(f,urlOffsets[ui->urlIdx]); - writeInt(f,ui->freq); + writeInt(f,urlOffsets[ui.second.urlIdx]); + writeInt(f,ui.second.freq); } } } } // write urls - for (udi.toFirst();(url=udi.current());++udi) + for (const auto &udi : m_urls) { - writeString(f,url->name); - writeString(f,url->url); + writeString(f,udi.second.name); + writeString(f,udi.second.url); } } - delete[] urlOffsets; - delete[] wordStatOffsets; } @@ -422,22 +397,12 @@ struct SearchDocEntry struct SearchIndexExternal::Private { - Private() : docEntries(12251) {} - SDict<SearchDocEntry> docEntries; + std::map<std::string,SearchDocEntry> docEntries; SearchDocEntry *current = 0; }; -SearchIndexExternal::SearchIndexExternal() : SearchIndexIntf(External) -{ - p = new SearchIndexExternal::Private; - p->docEntries.setAutoDelete(TRUE); - p->current=0; -} - -SearchIndexExternal::~SearchIndexExternal() +SearchIndexExternal::SearchIndexExternal() : SearchIndexIntf(External), p(std::make_unique<Private>()) { - //printf("p->docEntries.count()=%d\n",p->docEntries.count()); - delete p; } static QCString definitionToName(const Definition *ctx) @@ -497,29 +462,28 @@ static QCString definitionToName(const Definition *ctx) void SearchIndexExternal::setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile) { - QCString extId = stripPath(Config_getString(EXTERNAL_SEARCH_ID)); + static QCString extId = stripPath(Config_getString(EXTERNAL_SEARCH_ID)); QCString baseName = isSourceFile ? (dynamic_cast<const FileDef*>(ctx))->getSourceFileBase() : ctx->getOutputFileBase(); QCString url = baseName + Doxygen::htmlFileExtension; if (anchor) url+=QCString("#")+anchor; QCString key = extId+";"+url; - p->current = p->docEntries.find(key); - //printf("setCurrentDoc(url=%s,isSourceFile=%d) current=%p\n",url.data(),isSourceFile,p->current); - if (!p->current) + auto it = p->docEntries.find(key.str()); + if (it == p->docEntries.end()) { - SearchDocEntry *e = new SearchDocEntry; - e->type = isSourceFile ? QCString("source") : definitionToName(ctx); - e->name = ctx->qualifiedName(); + SearchDocEntry e; + e.type = isSourceFile ? QCString("source") : definitionToName(ctx); + e.name = ctx->qualifiedName(); if (ctx->definitionType()==Definition::TypeMember) { - e->args = (dynamic_cast<const MemberDef*>(ctx))->argsString(); + e.args = (dynamic_cast<const MemberDef*>(ctx))->argsString(); } - e->extId = extId; - e->url = url; - p->current = e; - p->docEntries.append(key,e); + e.extId = extId; + e.url = url; + it = p->docEntries.insert({key.str(),e}).first; //printf("searchIndexExt %s : %s\n",e->name.data(),e->url.data()); } + p->current = &it->second; } void SearchIndexExternal::addWord(const char *word,bool hiPriority) @@ -539,26 +503,25 @@ void SearchIndexExternal::write(const char *fileName) FTextStream t(&f); t << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl; t << "<add>" << endl; - SDict<SearchDocEntry>::Iterator it(p->docEntries); - SearchDocEntry *doc; - for (it.toFirst();(doc=it.current());++it) + for (auto &kv : p->docEntries) { - doc->normalText.addChar(0); // make sure buffer ends with a 0 terminator - doc->importantText.addChar(0); // make sure buffer ends with a 0 terminator + SearchDocEntry &doc = kv.second; + doc.normalText.addChar(0); // make sure buffer ends with a 0 terminator + doc.importantText.addChar(0); // make sure buffer ends with a 0 terminator t << " <doc>" << endl; - t << " <field name=\"type\">" << doc->type << "</field>" << endl; - t << " <field name=\"name\">" << convertToXML(doc->name) << "</field>" << endl; - if (!doc->args.isEmpty()) + t << " <field name=\"type\">" << doc.type << "</field>" << endl; + t << " <field name=\"name\">" << convertToXML(doc.name) << "</field>" << endl; + if (!doc.args.isEmpty()) { - t << " <field name=\"args\">" << convertToXML(doc->args) << "</field>" << endl; + t << " <field name=\"args\">" << convertToXML(doc.args) << "</field>" << endl; } - if (!doc->extId.isEmpty()) + if (!doc.extId.isEmpty()) { - t << " <field name=\"tag\">" << convertToXML(doc->extId) << "</field>" << endl; + t << " <field name=\"tag\">" << convertToXML(doc.extId) << "</field>" << endl; } - t << " <field name=\"url\">" << convertToXML(doc->url) << "</field>" << endl; - t << " <field name=\"keywords\">" << convertToXML(doc->importantText.get()) << "</field>" << endl; - t << " <field name=\"text\">" << convertToXML(doc->normalText.get()) << "</field>" << endl; + t << " <field name=\"url\">" << convertToXML(doc.url) << "</field>" << endl; + t << " <field name=\"keywords\">" << convertToXML(doc.importantText.get()) << "</field>" << endl; + t << " <field name=\"text\">" << convertToXML(doc.normalText.get()) << "</field>" << endl; t << " </doc>" << endl; } t << "</add>" << endl; @@ -572,14 +535,6 @@ void SearchIndexExternal::write(const char *fileName) //--------------------------------------------------------------------------- // the following part is for the javascript based search engine -#include "memberdef.h" -#include "namespacedef.h" -#include "pagedef.h" -#include "classdef.h" -#include "filedef.h" -#include "language.h" -#include "doxygen.h" -#include "message.h" static SearchIndexInfo g_searchIndexInfo[NUM_SEARCH_INDICES]; diff --git a/src/searchindex.h b/src/searchindex.h index 923973c..71c1ce1 100644 --- a/src/searchindex.h +++ b/src/searchindex.h @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -18,11 +18,15 @@ #ifndef _SEARCHINDEX_H #define _SEARCHINDEX_H +#include <memory> +#include <vector> +#include <map> +#include <unordered_map> +#include <string> + #include <qintdict.h> #include <qlist.h> -#include <qdict.h> #include <qintdict.h> -#include <qvector.h> #include "sortdict.h" #include "definition.h" #include "util.h" @@ -40,7 +44,7 @@ void finalizeSearchIndexer(); struct URL { - URL(const char *n,const char *u) : name(n), url(u) {} + URL(QCString n,QCString u) : name(n), url(u) {} QCString name; QCString url; }; @@ -56,14 +60,15 @@ struct URLInfo class IndexWord { public: - IndexWord(const char *word); + using URLInfoMap = std::unordered_map<int,URLInfo>; + IndexWord(QCString word); void addUrlIndex(int,bool); - const QIntDict<URLInfo> &urls() const { return m_urls; } + URLInfoMap urls() const { return m_urls; } QCString word() const { return m_word; } private: QCString m_word; - QIntDict<URLInfo> m_urls; + URLInfoMap m_urls; }; class SearchIndexIntf @@ -84,16 +89,16 @@ class SearchIndex : public SearchIndexIntf { public: SearchIndex(); - void setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile); - void addWord(const char *word,bool hiPriority); - void write(const char *file); + void setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile) override; + void addWord(const char *word,bool hiPriority) override; + void write(const char *file) override; private: void addWord(const char *word,bool hiPrio,bool recurse); - QDict<IndexWord> m_words; - QVector< QList<IndexWord> > m_index; - QDict<int> m_url2IdMap; - QIntDict<URL> m_urls; - int m_urlIndex; + std::unordered_map<std::string,int> m_words; + std::vector< std::vector< IndexWord> > m_index; + std::unordered_map<std::string,int> m_url2IdMap; + std::map<int,URL> m_urls; + int m_urlIndex = -1; }; @@ -102,12 +107,11 @@ class SearchIndexExternal : public SearchIndexIntf struct Private; public: SearchIndexExternal(); - ~SearchIndexExternal(); void setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile); void addWord(const char *word,bool hiPriority); void write(const char *file); private: - Private *p; + std::unique_ptr<Private> p; }; //------- client side search index ---------------------- diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp index 2f72221..76ac77d 100644 --- a/src/sqlite3gen.cpp +++ b/src/sqlite3gen.cpp @@ -1619,26 +1619,16 @@ static void generateSqlite3ForMember(const MemberDef *md, struct Refid scope_ref // + source references // The cross-references in initializers only work when both the src and dst // are defined. - MemberSDict *mdict = md->getReferencesMembers(); - if (mdict!=0) + auto refList = md->getReferencesMembers(); + for (const auto &rmd : refList) { - MemberSDict::IteratorDict mdi(*mdict); - const MemberDef *rmd; - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - insertMemberReference(md,rmd, "inline"); - } + insertMemberReference(md,rmd, "inline"); } // + source referenced by - mdict = md->getReferencedByMembers(); - if (mdict!=0) + auto refByList = md->getReferencedByMembers(); + for (const auto &rmd : refByList) { - MemberSDict::IteratorDict mdi(*mdict); - const MemberDef *rmd; - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - insertMemberReference(rmd,md, "inline"); - } + insertMemberReference(rmd,md, "inline"); } return; } @@ -1856,24 +1846,16 @@ static void generateSqlite3ForMember(const MemberDef *md, struct Refid scope_ref // + source references // The cross-references in initializers only work when both the src and dst // are defined. - MemberSDict *mdict = md->getReferencesMembers(); - if (mdict!=0) + auto refList = md->getReferencesMembers(); + for (const auto &refmd : refList) { - MemberSDict::IteratorDict mdi(*mdict); - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - insertMemberReference(md,rmd, "inline"); - } + insertMemberReference(md,refmd, "inline"); } // + source referenced by - mdict = md->getReferencedByMembers(); - if (mdict!=0) + auto refByList = md->getReferencedByMembers(); + for (const auto &refmd : refByList) { - MemberSDict::IteratorDict mdi(*mdict); - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - insertMemberReference(rmd,md, "inline"); - } + insertMemberReference(refmd,md, "inline"); } } @@ -2012,37 +1994,27 @@ static void generateSqlite3ForClass(const ClassDef *cd) step(compounddef_insert); // + list of direct super classes - if (cd->baseClasses()) + for (const auto &bcd : cd->baseClasses()) { - BaseClassListIterator bcli(*cd->baseClasses()); - const BaseClassDef *bcd; - for (bcli.toFirst();(bcd=bcli.current());++bcli) - { - struct Refid base_refid = insertRefid(bcd->classDef->getOutputFileBase()); - struct Refid derived_refid = insertRefid(cd->getOutputFileBase()); - bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid); - bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid); - bindIntParameter(compoundref_insert,":prot",bcd->prot); - bindIntParameter(compoundref_insert,":virt",bcd->virt); - step(compoundref_insert); - } + struct Refid base_refid = insertRefid(bcd.classDef->getOutputFileBase()); + struct Refid derived_refid = insertRefid(cd->getOutputFileBase()); + bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid); + bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid); + bindIntParameter(compoundref_insert,":prot",bcd.prot); + bindIntParameter(compoundref_insert,":virt",bcd.virt); + step(compoundref_insert); } // + list of direct sub classes - if (cd->subClasses()) - { - BaseClassListIterator bcli(*cd->subClasses()); - const BaseClassDef *bcd; - for (bcli.toFirst();(bcd=bcli.current());++bcli) - { - struct Refid derived_refid = insertRefid(bcd->classDef->getOutputFileBase()); - struct Refid base_refid = insertRefid(cd->getOutputFileBase()); - bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid); - bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid); - bindIntParameter(compoundref_insert,":prot",bcd->prot); - bindIntParameter(compoundref_insert,":virt",bcd->virt); - step(compoundref_insert); - } + for (const auto &bcd : cd->subClasses()) + { + struct Refid derived_refid = insertRefid(bcd.classDef->getOutputFileBase()); + struct Refid base_refid = insertRefid(cd->getOutputFileBase()); + bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid); + bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid); + bindIntParameter(compoundref_insert,":prot",bcd.prot); + bindIntParameter(compoundref_insert,":virt",bcd.virt); + step(compoundref_insert); } // + list of inner classes diff --git a/src/template.cpp b/src/template.cpp index 66347c4..58188fe 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -338,7 +338,7 @@ int TemplateList::release() uint TemplateList::count() const { - return p->elems.size(); + return static_cast<uint>(p->elems.size()); } void TemplateList::append(const TemplateVariant &v) diff --git a/src/tooltip.cpp b/src/tooltip.cpp index 8cc1f87..32b43fa 100644 --- a/src/tooltip.cpp +++ b/src/tooltip.cpp @@ -1,10 +1,10 @@ /****************************************************************************** * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -13,7 +13,8 @@ * */ -#include <qdict.h> +#include <map> +#include <string> #include "tooltip.h" #include "definition.h" @@ -26,34 +27,15 @@ class TooltipManager::Private { public: - Private() : tooltipInfo(10007) {} - QDict<Definition> tooltipInfo; + std::map<std::string,const Definition*> tooltipInfo; }; -TooltipManager *TooltipManager::s_theInstance = 0; - -TooltipManager::TooltipManager() +TooltipManager::TooltipManager() : p(std::make_unique<Private>()) { - p = new Private; } TooltipManager::~TooltipManager() { - delete p; -} - -TooltipManager *TooltipManager::instance() -{ - if (!s_theInstance) - { - s_theInstance = new TooltipManager; - } - return s_theInstance; -} - -void TooltipManager::clearTooltips() -{ - p->tooltipInfo.clear(); } static QCString escapeId(const char *s) @@ -70,7 +52,7 @@ static QCString escapeId(const char *s) void TooltipManager::addTooltip(const Definition *d) { - static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); + bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); if (!sourceTooltips) return; QCString id = d->getOutputFileBase(); int i=id.findRev('/'); @@ -85,18 +67,14 @@ void TooltipManager::addTooltip(const Definition *d) id+="_"+anc; } id = "a" + id; - if (p->tooltipInfo.find(id)==0) - { - p->tooltipInfo.insert(id,d); - } + p->tooltipInfo.insert({id.str(),d}); } void TooltipManager::writeTooltips(CodeOutputInterface &ol) { - QDictIterator<Definition> di(p->tooltipInfo); - Definition *d; - for (di.toFirst();(d=di.current());++di) + for (const auto &kv : p->tooltipInfo) { + const Definition *d = kv.second; DocLinkInfo docInfo; docInfo.name = d->qualifiedName(); docInfo.ref = d->getReference(); @@ -114,13 +92,13 @@ void TooltipManager::writeTooltips(CodeOutputInterface &ol) QCString decl; if (d->definitionType()==Definition::TypeMember) { - MemberDef *md = dynamic_cast<MemberDef*>(d); + const MemberDef *md = dynamic_cast<const MemberDef*>(d); if (!md->isAnonymous()) { decl = md->declaration(); } } - ol.writeTooltip(di.currentKey(), // id + ol.writeTooltip(kv.first.c_str(), // id docInfo, // symName decl, // decl d->briefDescriptionAsTooltip(), // desc diff --git a/src/tooltip.h b/src/tooltip.h index 170ea3c..3517b5d 100644 --- a/src/tooltip.h +++ b/src/tooltip.h @@ -1,10 +1,10 @@ /****************************************************************************** * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -15,23 +15,27 @@ #ifndef TOOLTIP_H #define TOOLTIP_H +#include <memory> + class Definition; class CodeOutputInterface; +//! Class that manages the tooltips for a source file class TooltipManager { public: - static TooltipManager *instance(); - void clearTooltips(); + TooltipManager(); + ~TooltipManager(); + + /** add a tooltip for a given symbol definition */ void addTooltip(const Definition *d); + + /** write the list of all collected tooltip to the given outputs */ void writeTooltips(CodeOutputInterface &ol); private: class Private; - Private *p; - TooltipManager(); - ~TooltipManager(); - static TooltipManager *s_theInstance; + std::unique_ptr<Private> p; }; #endif diff --git a/src/translator_br.h b/src/translator_br.h index 5be0282..29a0e20 100644 --- a/src/translator_br.h +++ b/src/translator_br.h @@ -267,6 +267,10 @@ class TranslatorBrazilian : public TranslatorAdapter_1_8_19 { return "Aqui estão as estruturas de dados, uniões e suas respectivas descrições:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Aqui estão as classes e suas respectivas descrições:"; + } else { return "Aqui estão as classes, estruturas, uniões e interfaces e suas respectivas descrições:"; diff --git a/src/translator_ca.h b/src/translator_ca.h index a608ff0..7a7e79a 100644 --- a/src/translator_ca.h +++ b/src/translator_ca.h @@ -251,6 +251,10 @@ class TranslatorCatalan : public TranslatorAdapter_1_8_0 { return "Aquestes són les estructures de dades acompanyades amb breus descripcions:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Aquestes són les classes acompanyades amb breus descripcions:"; + } else { return "Aquestes són les classes, estructures, " diff --git a/src/translator_de.h b/src/translator_de.h index 63b0802..be51653 100644 --- a/src/translator_de.h +++ b/src/translator_de.h @@ -348,13 +348,17 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15 { if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { - return "Hier folgt die Aufzählung aller Datenstrukturen " - "mit einer Kurzbeschreibung:"; + return "Hier folgt die Aufzählung aller Datenstrukturen " + "mit einer Kurzbeschreibung:"; + } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Hier folgt die Aufzählung aller Klassen mit einer Kurzbeschreibung:"; } else { - return "Hier folgt die Aufzählung aller Klassen, Strukturen, " - "Varianten und Schnittstellen mit einer Kurzbeschreibung:"; + return "Hier folgt die Aufzählung aller Klassen, Strukturen, " + "Varianten und Schnittstellen mit einer Kurzbeschreibung:"; } } diff --git a/src/translator_dk.h b/src/translator_dk.h index 2e9f7d0..fa1db9a 100644 --- a/src/translator_dk.h +++ b/src/translator_dk.h @@ -284,6 +284,8 @@ class TranslatorDanish : public TranslatorAdapter_1_8_0 if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) { return "Her er datastrukturerne med korte beskrivelser:"; + } else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) { + return "Her er klasserne med korte beskrivelser:"; } else { return "Her er klasserne, datastrukturerne, " "unionerne og grænsefladerne med korte beskrivelser:"; diff --git a/src/translator_eo.h b/src/translator_eo.h index 3ab9f8a..4ae6ee9 100644 --- a/src/translator_eo.h +++ b/src/translator_eo.h @@ -252,6 +252,10 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4 { return "Jen datumstrukturoj kun mallongaj priskriboj:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Jen la klasoj kun mallongaj priskriboj:"; + } else { return "Jen la klasoj, strukturoj, kunigoj kaj interfacoj " diff --git a/src/translator_es.h b/src/translator_es.h index e4b35f3..554c487 100644 --- a/src/translator_es.h +++ b/src/translator_es.h @@ -243,6 +243,10 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15 { return "Lista de estructuras con una breve descripción:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Lista de las clases con una breve descripción:"; + } else { return "Lista de las clases, estructuras, " diff --git a/src/translator_fi.h b/src/translator_fi.h index bc6cbd9..dd2d38c 100644 --- a/src/translator_fi.h +++ b/src/translator_fi.h @@ -311,6 +311,11 @@ class TranslatorFinnish : public TranslatorAdapter_1_6_0 { return "Tässä ovat tietueet lyhyen selitteen kanssa:"; // "Here are the data structures with brief descriptions:" } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Tässä ovat luokat " // "Here are the classes + "lyhyen selitteen kanssa:"; // "with brief descriptions:" + } else { return "Tässä ovat luokat, tietueet ja " // "Here are the classes, structs and " diff --git a/src/translator_gr.h b/src/translator_gr.h index c4af814..a0511b7 100644 --- a/src/translator_gr.h +++ b/src/translator_gr.h @@ -247,6 +247,10 @@ class TranslatorGreek : public TranslatorAdapter_1_8_15 { return "Ακολουθούν οι δομές δεδομένων με σύντομες περιγραφές:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Ακολουθούν οι κλάσεις με σύντομες περιγραφές:"; + } else { return "Ακολουθούν οι κλάσεις, οι δομές, " diff --git a/src/translator_hu.h b/src/translator_hu.h index f7d9788..ae2e169 100644 --- a/src/translator_hu.h +++ b/src/translator_hu.h @@ -276,6 +276,10 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15 { return "Az összes adatszerkezet listája rövid leírásokkal:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Az összes osztály listája rövid leírásokkal:"; + } else { return "Az összes osztály, struktúra, unió és interfész " diff --git a/src/translator_id.h b/src/translator_id.h index 05d36ee..4b5626a 100644 --- a/src/translator_id.h +++ b/src/translator_id.h @@ -234,6 +234,10 @@ class TranslatorIndonesian : public TranslatorAdapter_1_8_0 { return "Berikut ini daftar struktur data, dengan penjelasan singkat:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Berikut ini daftar kelas, dengan penjelasan singkat:"; + } else { return "Berikut ini daftar kelas, struct, union, dan interface, dengan penjelasan singkat:"; diff --git a/src/translator_it.h b/src/translator_it.h index f7f3534..4b12dae 100644 --- a/src/translator_it.h +++ b/src/translator_it.h @@ -291,6 +291,10 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15 { return "Queste sono le strutture dati con una loro breve descrizione:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Queste sono le classi con una loro breve descrizione:"; + } else { return "Queste sono le classi, le struct, le union e le interfacce con una loro breve descrizione:"; diff --git a/src/translator_lt.h b/src/translator_lt.h index b491080..1be20d2 100644 --- a/src/translator_lt.h +++ b/src/translator_lt.h @@ -241,6 +241,10 @@ class TranslatorLithuanian : public TranslatorAdapter_1_4_6 { return "Duomenų struktūros su trumpais aprašymais:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Klasės su trumpais aprašymais:"; + } else { return "Klasės, struktūros, " diff --git a/src/translator_lv.h b/src/translator_lv.h index 36cd78a..8dcc45b 100644 --- a/src/translator_lv.h +++ b/src/translator_lv.h @@ -256,6 +256,10 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4 { return "Šeit ir visas datu struktūras ar īsu aprakstu:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Šeit ir visas klases ar īsu aprakstu:"; + } else { return "Šeit ir visas klases, struktūras, " diff --git a/src/translator_mk.h b/src/translator_mk.h index ea5c3c8..97a55dc 100644 --- a/src/translator_mk.h +++ b/src/translator_mk.h @@ -236,6 +236,10 @@ class TranslatorMacedonian : public TranslatorAdapter_1_6_0 { return "Список на структури со кратки описи:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Список на класи со кратки описи:"; + } else { return "Список на класи, структури, унии и интерфејси " diff --git a/src/translator_nl.h b/src/translator_nl.h index 07e90ae..413d353 100644 --- a/src/translator_nl.h +++ b/src/translator_nl.h @@ -111,8 +111,22 @@ class TranslatorDutch : public Translator return result; } QCString trCompoundListDescription() - { return "Hieronder volgen de klassen, structs en " - "unions met voor elk een korte beschrijving:"; + { + if (Config_getBool(OPTIMIZE_OUTPUT_FOR_C)) + { + return "Hieronder volgen de structs " + "met voor elk een korte beschrijving:"; + } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Hieronder volgen de klassen " + "met voor elk een korte beschrijving:"; + } + else + { + return "Hieronder volgen de klassen, structs en " + "unions met voor elk een korte beschrijving:"; + } } QCString trCompoundMembersDescription(bool extractAll) { diff --git a/src/translator_no.h b/src/translator_no.h index 1dc331a..dee96d0 100755 --- a/src/translator_no.h +++ b/src/translator_no.h @@ -255,6 +255,10 @@ class TranslatorNorwegian : public TranslatorAdapter_1_4_6 { return "Her er datastrukturene med korte beskrivelser:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Her er klasser med korte beskrivelser:"; + } else { return "Her er klasser, struct'er, " diff --git a/src/translator_pl.h b/src/translator_pl.h index 096e9b0..86bc72b 100644 --- a/src/translator_pl.h +++ b/src/translator_pl.h @@ -234,6 +234,10 @@ class TranslatorPolish : public TranslatorAdapter_1_8_2 { return "Tutaj znajdują się struktury danych wraz z ich krótkimi opisami:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Tutaj znajdują się klasy wraz z ich krótkimi opisami:"; + } else { return "Tutaj znajdują się klasy, struktury, " diff --git a/src/translator_pt.h b/src/translator_pt.h index 0185aea..3456aad 100644 --- a/src/translator_pt.h +++ b/src/translator_pt.h @@ -267,6 +267,10 @@ class TranslatorPortuguese : public TranslatorAdapter_1_8_19 { return "Lista das estruturas de dados com uma breve descrição:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Lista de classes com uma breve descrição:"; + } else { return "Lista de classes, estruturas, uniões e interfaces com uma breve descrição:"; diff --git a/src/translator_ro.h b/src/translator_ro.h index edb82bf..01765a6 100644 --- a/src/translator_ro.h +++ b/src/translator_ro.h @@ -254,6 +254,10 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15 { return "Lista structurilor de date, cu scurte descrieri:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Lista claselor, cu scurte descrieri:"; + } else { return "Lista claselor, structurilor, uniunilor şi interfeţelor" diff --git a/src/translator_ru.h b/src/translator_ru.h index aafae90..3e3f7dc 100644 --- a/src/translator_ru.h +++ b/src/translator_ru.h @@ -212,6 +212,10 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15 { return "Структуры данных с их кратким описанием."; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Классы с их кратким описанием."; + } else { return "Классы с их кратким описанием."; diff --git a/src/translator_sc.h b/src/translator_sc.h index 5217948..b8b5b42 100644 --- a/src/translator_sc.h +++ b/src/translator_sc.h @@ -254,6 +254,10 @@ class TranslatorSerbianCyrillic : public TranslatorAdapter_1_6_0 { return "Овде су структуре са кратким описима:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Овде су класе са кратким описима:"; + } else { return "Овде су класе, структуре, " diff --git a/src/translator_sr.h b/src/translator_sr.h index bfd32f6..cb080ea 100644 --- a/src/translator_sr.h +++ b/src/translator_sr.h @@ -235,6 +235,10 @@ class TranslatorSerbian : public TranslatorAdapter_1_6_0 { return "Spisak struktura sa kratkim opisima:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Spisak klasa sa kratkim opisima:"; + } else { return "Spisak klasa, struktura, unija i interfejsa sa kratkim opisima:"; diff --git a/src/translator_sv.h b/src/translator_sv.h index bc63870..853e265 100644 --- a/src/translator_sv.h +++ b/src/translator_sv.h @@ -353,6 +353,10 @@ class TranslatorSwedish : public Translator { return "Här följer datastrukturerna med korta beskrivningar:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Här följer klasserna med korta beskrivningar:"; + } else { return "Här följer klasserna, strukterna, unionerna och " diff --git a/src/translator_ua.h b/src/translator_ua.h index 2c5047c..e24136c 100644 --- a/src/translator_ua.h +++ b/src/translator_ua.h @@ -208,6 +208,10 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4 { return "Структури даних з коротким описом." ; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Класи з коротким описом." ; + } else { return "Класи, структури, об'єднання та інтерфейси з коротким описом." ; diff --git a/src/translator_vi.h b/src/translator_vi.h index 50c0a01..272dedd 100644 --- a/src/translator_vi.h +++ b/src/translator_vi.h @@ -270,6 +270,10 @@ class TranslatorVietnamese : public TranslatorAdapter_1_6_0 { return "Đây là cấu trúc cơ sở dữ liệu với mô tả tóm tắt:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Đây là các classes với các mô tả tóm tắt:"; + } else { return "Đây là các classes, structs, " diff --git a/src/translator_za.h b/src/translator_za.h index fdf3e6a..8fc847e 100644 --- a/src/translator_za.h +++ b/src/translator_za.h @@ -235,6 +235,10 @@ class TranslatorAfrikaans : public TranslatorAdapter_1_6_0 { return " Data strukture met kort beskrywings:"; } + else if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) + { + return "Klasse met kort beskrywings:"; + } else { return "Klasse, structs, " diff --git a/src/util.cpp b/src/util.cpp index 8310862..dd25284 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -429,7 +429,8 @@ QCString resolveTypeDef(const Definition *context,const QCString &qualifiedName, // tmd->getOuterScope()->name().data(), mContext); if (tmd->isTypedef() /*&& tmd->getOuterScope()==resScope*/) { - int dist=isAccessibleFrom(resScope,0,tmd); + AccessStack accessStack; + int dist=isAccessibleFrom(accessStack,resScope,0,tmd); if (dist!=-1 && (md==0 || dist<minDist)) { md = tmd; @@ -506,7 +507,6 @@ NamespaceDef *getResolvedNamespace(const char *name) } static QDict<MemberDef> g_resolvedTypedefs; -static QDict<Definition> g_visitedNamespaces; // forward declaration static const ClassDef *getResolvedClassRec(const Definition *scope, @@ -516,8 +516,6 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, QCString *pTemplSpec, QCString *pResolvedType ); -int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScope,const Definition *item, - const QCString &explicitScopePart); /*! Returns the class representing the value of the typedef represented by \a md * within file \a fileScope. @@ -685,8 +683,10 @@ static QCString substTypedef(const Definition *scope,const FileDef *fileScope,co MemberDef *md = dynamic_cast<MemberDef *>(d); if (md->isTypedef()) // d is a typedef { + VisitedNamespaces visitedNamespaces; + AccessStack accessStack; // test accessibility of typedef within scope. - int distance = isAccessibleFromWithExpScope(scope,fileScope,d,""); + int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,""); if (distance!=-1 && distance<minDistance) // definition is accessible and a better match { @@ -705,7 +705,9 @@ static QCString substTypedef(const Definition *scope,const FileDef *fileScope,co if (md->isTypedef()) // d is a typedef { // test accessibility of typedef within scope. - int distance = isAccessibleFromWithExpScope(scope,fileScope,d,""); + VisitedNamespaces visitedNamespaces; + AccessStack accessStack; + int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,""); if (distance!=-1) // definition is accessible { bestMatch = md; @@ -824,12 +826,12 @@ bool accessibleViaUsingClass(const SDict<Definition> *cl, return FALSE; } -bool accessibleViaUsingNamespace(const NamespaceSDict *nl, +bool accessibleViaUsingNamespace(StringUnorderedSet &visited, + const NamespaceSDict *nl, const FileDef *fileScope, const Definition *item, const QCString &explicitScopePart="") { - static QDict<void> visitedDict; if (nl) // check used namespaces for the class { NamespaceSDict::Iterator nli(*nl); @@ -848,17 +850,17 @@ bool accessibleViaUsingNamespace(const NamespaceSDict *nl, if (item->getLanguage()==SrcLangExt_Cpp) { QCString key=und->name(); - if (und->getUsedNamespaces() && visitedDict.find(key)==0) + if (und->getUsedNamespaces() && visited.find(key.str())==visited.end()) { - visitedDict.insert(key,(void *)0x08); + visited.insert(key.str()); - if (accessibleViaUsingNamespace(und->getUsedNamespaces(),fileScope,item,explicitScopePart)) + if (accessibleViaUsingNamespace(visited,und->getUsedNamespaces(),fileScope,item,explicitScopePart)) { //printf("] found it via recursion\n"); return TRUE; } - visitedDict.remove(key); + visited.erase(key.str()); } } //printf("] Try via used namespace done\n"); @@ -867,89 +869,15 @@ bool accessibleViaUsingNamespace(const NamespaceSDict *nl, return FALSE; } -const int MAX_STACK_SIZE = 1000; - -/** Helper class representing the stack of items considered while resolving - * the scope. - */ -class AccessStack -{ - public: - AccessStack() : m_index(0) {} - void push(const Definition *scope,const FileDef *fileScope,const Definition *item) - { - if (m_index<MAX_STACK_SIZE) - { - m_elements[m_index].scope = scope; - m_elements[m_index].fileScope = fileScope; - m_elements[m_index].item = item; - m_index++; - } - } - void push(const Definition *scope,const FileDef *fileScope,const Definition *item,const QCString &expScope) - { - if (m_index<MAX_STACK_SIZE) - { - m_elements[m_index].scope = scope; - m_elements[m_index].fileScope = fileScope; - m_elements[m_index].item = item; - m_elements[m_index].expScope = expScope; - m_index++; - } - } - void pop() - { - if (m_index>0) m_index--; - } - bool find(const Definition *scope,const FileDef *fileScope, const Definition *item) - { - int i=0; - for (i=0;i<m_index;i++) - { - AccessElem *e = &m_elements[i]; - if (e->scope==scope && e->fileScope==fileScope && e->item==item) - { - return TRUE; - } - } - return FALSE; - } - bool find(const Definition *scope,const FileDef *fileScope, const Definition *item,const QCString &expScope) - { - int i=0; - for (i=0;i<m_index;i++) - { - AccessElem *e = &m_elements[i]; - if (e->scope==scope && e->fileScope==fileScope && e->item==item && e->expScope==expScope) - { - return TRUE; - } - } - return FALSE; - } - - private: - /** Element in the stack. */ - struct AccessElem - { - const Definition *scope; - const FileDef *fileScope; - const Definition *item; - QCString expScope; - }; - int m_index; - AccessElem m_elements[MAX_STACK_SIZE]; -}; /* Returns the "distance" (=number of levels up) from item to scope, or -1 * if item in not inside scope. */ -int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Definition *item) +int isAccessibleFrom(AccessStack &accessStack,const Definition *scope,const FileDef *fileScope,const Definition *item) { //printf("<isAccessibleFrom(scope=%s,item=%s itemScope=%s)\n", // scope->name().data(),item->name().data(),item->getOuterScope()->name().data()); - static AccessStack accessStack; if (accessStack.find(scope,fileScope,item)) { return -1; @@ -991,7 +919,8 @@ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Defi goto done; } NamespaceSDict *nl = fileScope->getUsedNamespaces(); - if (accessibleViaUsingNamespace(nl,fileScope,item)) + StringUnorderedSet visited; + if (accessibleViaUsingNamespace(visited,nl,fileScope,item)) { //printf("> found via used namespace\n"); goto done; @@ -1014,14 +943,15 @@ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Defi goto done; } const NamespaceSDict *nl = nscope->getUsedNamespaces(); - if (accessibleViaUsingNamespace(nl,fileScope,item)) + StringUnorderedSet visited; + if (accessibleViaUsingNamespace(visited,nl,fileScope,item)) { //printf("> found via used namespace\n"); goto done; } } // repeat for the parent scope - i=isAccessibleFrom(scope->getOuterScope(),fileScope,item); + i=isAccessibleFrom(accessStack,scope->getOuterScope(),fileScope,item); //printf("> result=%d\n",i); result= (i==-1) ? -1 : i+2; } @@ -1046,16 +976,16 @@ done: * not found and then A::I is searched in the global scope, which matches and * thus the result is 1. */ -int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScope, - const Definition *item,const QCString &explicitScopePart) +int isAccessibleFromWithExpScope(VisitedNamespaces &visitedNamespaces, + AccessStack &accessStack, const Definition *scope,const FileDef *fileScope, + const Definition *item,const QCString &explicitScopePart) { if (explicitScopePart.isEmpty()) { // handle degenerate case where there is no explicit scope. - return isAccessibleFrom(scope,fileScope,item); + return isAccessibleFrom(accessStack,scope,fileScope,item); } - static AccessStack accessStack; if (accessStack.find(scope,fileScope,item,explicitScopePart)) { return -1; @@ -1104,7 +1034,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop int i=-1; if (newScope->definitionType()==Definition::TypeNamespace) { - g_visitedNamespaces.insert(newScope->name(),newScope); + visitedNamespaces.insert({newScope->name().str(),newScope}); // this part deals with the case where item is a class // A::B::C but is explicit referenced as A::C, where B is imported // in A via a using directive. @@ -1132,10 +1062,10 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { - if (g_visitedNamespaces.find(nd->name())==0) + if (visitedNamespaces.find(nd->name().str())==visitedNamespaces.end()) { //printf("Trying for namespace %s\n",nd->name().data()); - i = isAccessibleFromWithExpScope(scope,fileScope,item,nd->name()); + i = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,item,nd->name()); if (i!=-1) { //printf("> found via explicit scope of used namespace\n"); @@ -1148,7 +1078,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop // repeat for the parent scope if (scope!=Doxygen::globalScope) { - i = isAccessibleFromWithExpScope(scope->getOuterScope(),fileScope, + i = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope->getOuterScope(),fileScope, item,explicitScopePart); } //printf(" | result=%d\n",i); @@ -1162,7 +1092,8 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop { const NamespaceDef *nscope = dynamic_cast<const NamespaceDef*>(scope); const NamespaceSDict *nl = nscope->getUsedNamespaces(); - if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) + StringUnorderedSet visited; + if (accessibleViaUsingNamespace(visited,nl,fileScope,item,explicitScopePart)) { //printf("> found in used namespace\n"); goto done; @@ -1173,7 +1104,8 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop if (fileScope) { const NamespaceSDict *nl = fileScope->getUsedNamespaces(); - if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) + StringUnorderedSet visited; + if (accessibleViaUsingNamespace(visited,nl,fileScope,item,explicitScopePart)) { //printf("> found in used namespace\n"); goto done; @@ -1184,7 +1116,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop } else // continue by looking into the parent scope { - int i=isAccessibleFromWithExpScope(scope->getOuterScope(),fileScope, + int i=isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope->getOuterScope(),fileScope, item,explicitScopePart); //printf("> result=%d\n",i); result= (i==-1) ? -1 : i+2; @@ -1225,9 +1157,10 @@ static void getResolvedSymbol(const Definition *scope, ) ) { - g_visitedNamespaces.clear(); + VisitedNamespaces visitedNamespaces; + AccessStack accessStack; // test accessibility of definition within scope. - int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart); + int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,explicitScopePart); //printf(" %s; distance %s (%p) is %d\n",scope->name().data(),d->name().data(),d,distance); if (distance!=-1) // definition is accessible { @@ -2267,55 +2200,57 @@ QCString argListToString(const ArgumentList &al,bool useCanonicalType,bool showD return removeRedundantWhiteSpace(result); } -QCString tempArgListToString(const ArgumentList &al,SrcLangExt lang) +QCString tempArgListToString(const ArgumentList &al,SrcLangExt lang,bool includeDefault) { QCString result; if (al.empty()) return result; result="<"; - auto it = al.begin(); - while (it!=al.end()) + bool first=true; + for (const auto &a : al) { - Argument a = *it; - if (!a.name.isEmpty()) // add template argument name + if (a.defval.isEmpty() || includeDefault) { - if (a.type.left(4)=="out") // C# covariance - { - result+="out "; - } - else if (a.type.left(3)=="in") // C# contravariance + if (!first) result+=", "; + if (!a.name.isEmpty()) // add template argument name { - result+="in "; - } - if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp) - { - result+=a.type+" "; + if (a.type.left(4)=="out") // C# covariance + { + result+="out "; + } + else if (a.type.left(3)=="in") // C# contravariance + { + result+="in "; + } + if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp) + { + result+=a.type+" "; + } + result+=a.name; } - result+=a.name; - } - else // extract name from type - { - int i=a.type.length()-1; - while (i>=0 && isId(a.type.at(i))) i--; - if (i>0) + else // extract name from type { - result+=a.type.right(a.type.length()-i-1); - if (a.type.find("...")!=-1) + int i=a.type.length()-1; + while (i>=0 && isId(a.type.at(i))) i--; + if (i>0) { - result+="..."; + result+=a.type.right(a.type.length()-i-1); + if (a.type.find("...")!=-1) + { + result+="..."; + } + } + else // nothing found -> take whole name + { + result+=a.type; } } - else // nothing found -> take whole name + if (!a.typeConstraint.isEmpty() && lang==SrcLangExt_Java) { - result+=a.type; + result+=" extends "; // TODO: now Java specific, C# has where... + result+=a.typeConstraint; } + first=false; } - if (!a.typeConstraint.isEmpty() && lang==SrcLangExt_Java) - { - result+=" extends "; // TODO: now Java specific, C# has where... - result+=a.typeConstraint; - } - ++it; - if (it!=al.end()) result+=", "; } result+=">"; return removeRedundantWhiteSpace(result); @@ -2621,16 +2556,11 @@ int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level) return -1; } int m=maxInheritanceDepth; - if (cd->baseClasses()) + for (const auto &bcdi : cd->baseClasses()) { - BaseClassListIterator bcli(*cd->baseClasses()); - BaseClassDef *bcdi; - for (;(bcdi=bcli.current());++bcli) - { - int mc=minClassDistance(bcdi->classDef,bcd,level+1); - if (mc<m) m=mc; - if (m<0) break; - } + int mc=minClassDistance(bcdi.classDef,bcd,level+1); + if (mc<m) m=mc; + if (m<0) break; } return m; } @@ -2651,14 +2581,12 @@ Protection classInheritedProtectionLevel(const ClassDef *cd,const ClassDef *bcd, err("Internal inconsistency: found class %s seem to have a recursive " "inheritance relation! Please send a bug report to doxygen@gmail.com\n",cd->name().data()); } - else if (cd->baseClasses()) + else if (prot!=Private) { - BaseClassListIterator bcli(*cd->baseClasses()); - const BaseClassDef *bcdi; - for (;(bcdi=bcli.current()) && prot!=Private;++bcli) + for (const auto &bcdi : cd->baseClasses()) { - Protection baseProt = classInheritedProtectionLevel(bcdi->classDef,bcd,bcdi->prot,level+1); - if (baseProt==Private) prot=Private; + Protection baseProt = classInheritedProtectionLevel(bcdi.classDef,bcd,bcdi.prot,level+1); + if (baseProt==Private) prot=Private; else if (baseProt==Protected) prot=Protected; } } @@ -2667,14 +2595,12 @@ exit: return prot; } -void trimBaseClassScope(BaseClassList *bcl,QCString &s,int level=0) +void trimBaseClassScope(const BaseClassList &bcl,QCString &s,int level=0) { //printf("trimBaseClassScope level=%d '%s'\n",level,s.data()); - BaseClassListIterator bcli(*bcl); - BaseClassDef *bcd; - for (;(bcd=bcli.current());++bcli) + for (const auto &bcd : bcl) { - ClassDef *cd=bcd->classDef; + ClassDef *cd=bcd.classDef; //printf("Trying class %s\n",cd->name().data()); int spos=s.find(cd->name()+"::"); if (spos!=-1) @@ -2684,8 +2610,10 @@ void trimBaseClassScope(BaseClassList *bcl,QCString &s,int level=0) ); } //printf("base class '%s'\n",cd->name().data()); - if (cd->baseClasses()) + if (!cd->baseClasses().empty()) + { trimBaseClassScope(cd->baseClasses(),s,level+1); + } } } @@ -2888,8 +2816,10 @@ static QCString getCanonicalTypeForIdentifier( { symName=word; } - //printf("getCanonicalTypeForIdentifier(%s,[%s->%s]) start\n", - // word.data(),tSpec?tSpec->data():"<none>",templSpec.data()); + //printf("getCanonicalTypeForIdentifier(%s d=%s fs=%s ,[%s->%s]) start\n", + // word.data(), + // d ? d->name().data() : "<null>",fs ? fs->name().data() : "<null>", + // tSpec?tSpec->data():"<none>",templSpec.data()); const ClassDef *cd = 0; const MemberDef *mType = 0; @@ -2982,7 +2912,13 @@ static QCString getCanonicalTypeForIdentifier( //printf("word=%s typeString=%s\n",word.data(),mType->typeString()); if (word!=mType->typeString()) { - result = getCanonicalTypeForIdentifier(d,fs,mType->typeString(),tSpec,count+1); + QCString type = mType->typeString(); + if (type.startsWith("typename ")) + { + type.stripPrefix("typename "); + type = stripTemplateSpecifiersFromScope(type,FALSE); + } + result = getCanonicalTypeForIdentifier(d,fs,type,tSpec,count+1); } else { @@ -3035,7 +2971,6 @@ static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCStr //printf(" i=%d p=%d\n",i,p); if (i>pp) canType += type.mid(pp,i-pp); - QCString ct = getCanonicalTypeForIdentifier(d,fs,word,&templSpec); // in case the ct is empty it means that "word" represents scope "d" @@ -3106,9 +3041,9 @@ static bool matchArgument2( { //printf(">> match argument: %s::'%s|%s' (%s) <-> %s::'%s|%s' (%s)\n", // srcScope ? srcScope->name().data() : "", - // srcA->type.data(),srcA->name.data(),srcA->canType.data(), + // srcA.type.data(),srcA.name.data(),srcA.canType.data(), // dstScope ? dstScope->name().data() : "", - // dstA->type.data(),dstA->name.data(),dstA->canType.data()); + // dstA.type.data(),dstA.name.data(),dstA.canType.data()); //if (srcA->array!=dstA->array) // nomatch for char[] against char //{ @@ -4646,14 +4581,12 @@ int getPrefixIndex(const QCString &name) //---------------------------------------------------------------------------- -static void initBaseClassHierarchy(BaseClassList *bcl) +static void initBaseClassHierarchy(const BaseClassList &bcl) { - if (bcl==0) return; - BaseClassListIterator bcli(*bcl); - for ( ; bcli.current(); ++bcli) + for (const auto &bcd : bcl) { - ClassDef *cd=bcli.current()->classDef; - if (cd->baseClasses()==0) // no base classes => new root + ClassDef *cd = bcd.classDef; + if (cd->baseClasses().empty()) // no base classes => new root { initBaseClassHierarchy(cd->baseClasses()); } @@ -4664,23 +4597,22 @@ static void initBaseClassHierarchy(BaseClassList *bcl) bool classHasVisibleChildren(const ClassDef *cd) { - BaseClassList *bcl; + BaseClassList bcl; if (cd->getLanguage()==SrcLangExt_VHDL) // reverse baseClass/subClass relation { - if (cd->baseClasses()==0) return FALSE; + if (cd->baseClasses().empty()) return FALSE; bcl=cd->baseClasses(); } else { - if (cd->subClasses()==0) return FALSE; + if (cd->subClasses().empty()) return FALSE; bcl=cd->subClasses(); } - BaseClassListIterator bcli(*bcl); - for ( ; bcli.current() ; ++bcli) + for (const auto &bcd : bcl) { - if (bcli.current()->classDef->isVisibleInHierarchy()) + if (bcd.classDef->isVisibleInHierarchy()) { return TRUE; } @@ -4704,17 +4636,13 @@ void initClassHierarchy(ClassSDict *cl) //---------------------------------------------------------------------------- -bool hasVisibleRoot(const BaseClassList *bcl) +bool hasVisibleRoot(const BaseClassList &bcl) { - if (bcl) + for (const auto &bcd : bcl) { - BaseClassListIterator bcli(*bcl); - for ( ; bcli.current(); ++bcli) - { - const ClassDef *cd=bcli.current()->classDef; - if (cd->isVisibleInHierarchy()) return TRUE; - hasVisibleRoot(cd->baseClasses()); - } + const ClassDef *cd=bcd.classDef; + if (cd->isVisibleInHierarchy()) return TRUE; + hasVisibleRoot(cd->baseClasses()); } return FALSE; } @@ -6004,7 +5932,9 @@ found: PageDef *addRelatedPage(const char *name,const QCString &ptitle, const QCString &doc, - const char *fileName,int startLine, + const char *fileName, + int docLine, + int startLine, const RefItemVector &sli, GroupDef *gd, const TagInfo *tagInfo, @@ -6017,9 +5947,9 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, if ((pd=Doxygen::pageSDict->find(name)) && !tagInfo) { if (!xref) warn(fileName,startLine,"multiple use of page label '%s', (other occurrence: %s, line: %d)", - name,pd->docFile().data(),pd->docLine()); + name,pd->docFile().data(),pd->getStartBodyLine()); // append documentation block to the page. - pd->setDocumentation(doc,fileName,startLine); + pd->setDocumentation(doc,fileName,docLine); //printf("Adding page docs '%s' pi=%p name=%s\n",doc.data(),pd,name); // append (x)refitems to the page. pd->setRefItems(sli); @@ -6033,7 +5963,8 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length()); QCString title=ptitle.stripWhiteSpace(); - pd=createPageDef(fileName,startLine,baseName,doc,title); + pd=createPageDef(fileName,docLine,baseName,doc,title); + pd->setBodySegment(startLine,startLine,-1); pd->setRefItems(sli); pd->setLanguage(lang); @@ -6055,24 +5986,29 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, // a page name is a label as well! QCString file; + QCString orgFile; + int line = -1; if (gd) { file=gd->getOutputFileBase(); + orgFile=gd->getOutputFileBase(); } else { file=pd->getOutputFileBase(); + orgFile=pd->docFile(); + line = pd->getStartBodyLine(); } const SectionInfo *si = SectionManager::instance().find(pd->name()); if (si) { if (si->lineNr() != -1) { - warn(file,-1,"multiple use of section label '%s', (first occurrence: %s, line %d)",pd->name().data(),si->fileName().data(),si->lineNr()); + warn(orgFile,line,"multiple use of section label '%s', (first occurrence: %s, line %d)",pd->name().data(),si->fileName().data(),si->lineNr()); } else { - warn(file,-1,"multiple use of section label '%s', (first occurrence: %s)",pd->name().data(),si->fileName().data()); + warn(orgFile,line,"multiple use of section label '%s', (first occurrence: %s)",pd->name().data(),si->fileName().data()); } } else @@ -6842,8 +6778,9 @@ MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fileScope, { if (d->definitionType()==Definition::TypeMember) { - g_visitedNamespaces.clear(); - int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart); + VisitedNamespaces visitedNamespaces; + AccessStack accessStack; + int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,explicitScopePart); if (distance!=-1 && distance<minDistance) { minDistance = distance; @@ -6857,8 +6794,9 @@ MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fileScope, { //printf("unique match!\n"); Definition *d = (Definition *)di; - g_visitedNamespaces.clear(); - int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart); + VisitedNamespaces visitedNamespaces; + AccessStack accessStack; + int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,explicitScopePart); if (distance!=-1 && distance<minDistance) { minDistance = distance; @@ -8093,54 +8031,65 @@ uint getUtf8CodeToUpper( const QCString& s, int idx ) } //-------------------------------------------------------------------------------------- +// +bool namespaceHasNestedNamespace(const NamespaceDef *nd) +{ + NamespaceSDict::Iterator cnli(*nd->getNamespaceSDict()); + const NamespaceDef *cnd; + for (cnli.toFirst();(cnd=cnli.current());++cnli) + { + if (cnd->isLinkableInProject() && !cnd->isAnonymous()) + { + return true; + } + } + return false; +} -bool namespaceHasVisibleChild(const NamespaceDef *nd,bool includeClasses,bool filterClasses,ClassDef::CompoundType ct) +bool namespaceHasNestedClass(const NamespaceDef *nd,bool filterClasses,ClassDef::CompoundType ct) { + //printf(">namespaceHasVisibleChild(%s,includeClasses=%d)\n",nd->name().data(),includeClasses); if (nd->getNamespaceSDict()) { NamespaceSDict::Iterator cnli(*nd->getNamespaceSDict()); const NamespaceDef *cnd; for (cnli.toFirst();(cnd=cnli.current());++cnli) { - if (cnd->isLinkableInProject() && !cnd->isAnonymous()) - { - return TRUE; - } - else if (namespaceHasVisibleChild(cnd,includeClasses,filterClasses,ct)) + if (namespaceHasNestedClass(cnd,filterClasses,ct)) { + //printf("<namespaceHasVisibleChild(%s,includeClasses=%d): case2\n",nd->name().data(),includeClasses); return TRUE; } } } - if (includeClasses) + + const ClassSDict *d = nd->getClassSDict(); + if (filterClasses) { - const ClassSDict *d = nd->getClassSDict(); - if (filterClasses) + if (ct == ClassDef::Interface) { - if (ct == ClassDef::Interface) - { - d = nd->getInterfaceSDict(); - } - else if (ct == ClassDef::Struct) - { - d = nd->getStructSDict(); - } - else if (ct == ClassDef::Exception) - { - d = nd->getExceptionSDict(); - } + d = nd->getInterfaceSDict(); + } + else if (ct == ClassDef::Struct) + { + d = nd->getStructSDict(); + } + else if (ct == ClassDef::Exception) + { + d = nd->getExceptionSDict(); } + } - if (d) + if (d) + { + ClassSDict::Iterator cli(*d); + const ClassDef *cd; + for (;(cd=cli.current());++cli) { - ClassSDict::Iterator cli(*d); - const ClassDef *cd; - for (;(cd=cli.current());++cli) + if (cd->isLinkableInProject() && cd->templateMaster()==0) { - if (cd->isLinkableInProject() && cd->templateMaster()==0) - { - return TRUE; - } + //printf("<namespaceHasVisibleChild(%s,includeClasses=%d): case3\n",nd->name().data(),includeClasses); + return TRUE; } } } @@ -8376,7 +8325,7 @@ bool mainPageHasTitle() return Doxygen::mainPage!=0 && Doxygen::mainPage->hasTitle(); } -QCString getDotImageExtension(void) +QCString getDotImageExtension() { QCString imgExt = Config_getEnum(DOT_IMAGE_FORMAT); int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format @@ -23,6 +23,8 @@ */ #include <memory> +#include <unordered_map> +#include <algorithm> #include <qlist.h> #include <ctype.h> @@ -46,7 +48,6 @@ class OutputDocInterface; class MemberDef; class ExampleSDict; class ClassSDict; -class BaseClassList; class GroupDef; class NamespaceSDict; class ClassList; @@ -119,6 +120,56 @@ class LetterToIndexMap : public SIntDict<T> //-------------------------------------------------------------------- +const int MAX_STACK_SIZE = 100; + +/** Helper class representing the stack of items considered while resolving + * the scope. + */ +class AccessStack +{ + /** Element in the stack. */ + struct AccessElem + { + AccessElem(const Definition *d,const FileDef *f,const Definition *i,QCString e = QCString()) : scope(d), fileScope(f), item(i), expScope(e) {} + const Definition *scope; + const FileDef *fileScope; + const Definition *item; + QCString expScope; + }; + public: + void push(const Definition *scope,const FileDef *fileScope,const Definition *item) + { + m_elements.push_back(AccessElem(scope,fileScope,item)); + } + void push(const Definition *scope,const FileDef *fileScope,const Definition *item,const QCString &expScope) + { + m_elements.push_back(AccessElem(scope,fileScope,item,expScope)); + } + void pop() + { + if (!m_elements.empty()) m_elements.pop_back(); + } + bool find(const Definition *scope,const FileDef *fileScope, const Definition *item) + { + auto it = std::find_if(m_elements.begin(),m_elements.end(), + [&](const AccessElem &e) { return e.scope==scope && e.fileScope==fileScope && e.item==item; }); + return it!=m_elements.end(); + } + bool find(const Definition *scope,const FileDef *fileScope, const Definition *item,const QCString &expScope) + { + auto it = std::find_if(m_elements.begin(),m_elements.end(), + [&](const AccessElem &e) { return e.scope==scope && e.fileScope==fileScope && e.item==item && e.expScope==expScope; }); + return it!=m_elements.end(); + } + + private: + std::vector<AccessElem> m_elements; +}; + +using VisitedNamespaces = std::unordered_map<std::string,const Definition *>; + +//-------------------------------------------------------------------- + QCString langToString(SrcLangExt lang); QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope=FALSE); @@ -232,7 +283,7 @@ QCString removeRedundantWhiteSpace(const QCString &s); QCString argListToString(const ArgumentList &al,bool useCanonicalType=FALSE,bool showDefVals=TRUE); -QCString tempArgListToString(const ArgumentList &al,SrcLangExt lang); +QCString tempArgListToString(const ArgumentList &al,SrcLangExt lang,bool includeDefaults=true); QCString generateMarker(int id); @@ -259,9 +310,10 @@ QCString replaceAnonymousScopes(const QCString &s,const char *replacement=0); void initClassHierarchy(ClassSDict *cl); -bool hasVisibleRoot(const BaseClassList *bcl); +bool hasVisibleRoot(const BaseClassList &bcl); bool classHasVisibleChildren(const ClassDef *cd); -bool namespaceHasVisibleChild(const NamespaceDef *nd,bool includeClasses,bool filterClasses,ClassDef::CompoundType ct); +bool namespaceHasNestedNamespace(const NamespaceDef *nd); +bool namespaceHasNestedClass(const NamespaceDef *nd,bool filterClasses,ClassDef::CompoundType ct); bool classVisibleInIndex(const ClassDef *cd); int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level=0); @@ -337,7 +389,9 @@ void addRefItem(const RefItemVector &sli, PageDef *addRelatedPage(const char *name, const QCString &ptitle, const QCString &doc, - const char *fileName,int startLine, + const char *fileName, + int docLine, + int startLine, const RefItemVector &sli = RefItemVector(), GroupDef *gd=0, const TagInfo *tagInfo=0, @@ -376,10 +430,17 @@ QCString stripExtension(const char *fName); void replaceNamespaceAliases(QCString &scope,int i); -int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Definition *item); +int isAccessibleFrom(AccessStack &accessStack, + const Definition *scope, + const FileDef *fileScope, + const Definition *item); -int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScope,const Definition *item, - const QCString &explicitScopePart); +int isAccessibleFromWithExpScope(VisitedNamespaces &visitedNamespaces, + AccessStack &accessStack, + const Definition *scope, + const FileDef *fileScope, + const Definition *item, + const QCString &explicitScopePart); int computeQualifiedIndex(const QCString &name); @@ -475,7 +536,7 @@ bool protectionLevelVisible(Protection prot); QCString stripIndentation(const QCString &s); void stripIndentation(QCString &doc,const int indentationLevel); -QCString getDotImageExtension(void); +QCString getDotImageExtension(); bool fileVisibleInIndex(const FileDef *fd,bool &genSourceFile); diff --git a/src/vhdlcode.l b/src/vhdlcode.l index cecf9fb..7610c9a 100644 --- a/src/vhdlcode.l +++ b/src/vhdlcode.l @@ -109,6 +109,7 @@ struct vhdlcodeYY_state bool lexInit = false; int braceCount = 0; + TooltipManager tooltipManager; }; @@ -1229,7 +1230,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); - TooltipManager::instance()->addTooltip(d); + yyextra->tooltipManager.addTooltip(d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); @@ -1656,6 +1657,10 @@ void VHDLCodeParser::parseCode(CodeOutputInterface &od, yyextra->sourceFileDef=0; } yyextra->startCode=false; + + // write the tooltips + yyextra->tooltipManager.writeTooltips(od); + printlex(yy_flex_debug, false, __FILE__, fd ? fd->fileName().data(): NULL); } diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index 12cab2d..ddb22f6 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -234,22 +234,16 @@ void VhdlDocGen::writeOverview() writeVhdlEntityToolTip(t,cd); delete port; - BaseClassList *bl=cd->baseClasses(); - if (bl) - { - BaseClassListIterator bcli(*bl); - BaseClassDef *bcd; - for ( ; (bcd=bcli.current()) ; ++bcli ) - { - ClassDef *bClass=bcd->classDef; - QCString dotn=cd->name()+":"; - dotn+=cd->name(); - QCString csc=bClass->name()+":"; - csc+=bClass->name(); - // fprintf(stderr,"\n <%s| %s>",dotn.data(),csc.data()); - writeVhdlDotLink(t,dotn,csc,0); - } - }// if bl + for (const auto &bcd : cd->baseClasses()) + { + ClassDef *bClass=bcd.classDef; + QCString dotn=cd->name()+":"; + dotn+=cd->name(); + QCString csc=bClass->name()+":"; + csc+=bClass->name(); + // fprintf(stderr,"\n <%s| %s>",dotn.data(),csc.data()); + writeVhdlDotLink(t,dotn,csc,0); + } }// for endDot(t); @@ -2846,24 +2840,20 @@ bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int return FALSE; } - if (cd->subClasses()) + for (const auto &bcd :cd->subClasses()) { - BaseClassListIterator bcli(*cd->subClasses()); - for ( ; bcli.current() && !found ; ++bcli) + const ClassDef *ccd=bcd.classDef; + if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster(); + //printf("isSubClass() subclass %s\n",ccd->name().data()); + if (ccd==scd) { - const ClassDef *ccd=bcli.current()->classDef; - if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster(); - //printf("isSubClass() subclass %s\n",ccd->name().data()); - if (ccd==scd) - { - found=TRUE; - } - else + found=TRUE; + } + else + { + if (level <256) { - if (level <256) - { - found=ccd->isBaseClass(scd,followInstances,level+1); - } + found=ccd->isBaseClass(scd,followInstances,level+1); } } } @@ -2872,35 +2862,33 @@ bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int void VhdlDocGen::addBaseClass(ClassDef* cd,ClassDef *ent) { - if (cd->baseClasses()) + BaseClassList bcl = cd->baseClasses(); + for (auto &bcd : bcl) { - BaseClassListIterator bcli(*cd->baseClasses()); - for ( ; bcli.current() ; ++bcli) + ClassDef *ccd = bcd.classDef; + if (ccd==ent) { - ClassDef *ccd=bcli.current()->classDef; - if (ccd==ent) + QCString n = bcd.usedName; + int i = n.find('('); + if(i<0) { - QCString n = bcli.current()->usedName; - int i = n.find('('); - if(i<0) - { - bcli.current()->usedName.append("(2)"); - return; - } - static QRegExp reg("[0-9]+"); - QCString s=n.left(i); - QCString r=n.right(n.length()-i); - QCString t=r; - VhdlDocGen::deleteAllChars(r,')'); - VhdlDocGen::deleteAllChars(r,'('); - r.setNum(r.toInt()+1); - t.replace(reg,r.data()); - s.append(t.data()); - bcli.current()->usedName=s; - bcli.current()->templSpecifiers=t; + bcd.usedName.append("(2)"); + return; } + static QRegExp reg("[0-9]+"); + QCString s=n.left(i); + QCString r=n.right(n.length()-i); + QCString t=r; + VhdlDocGen::deleteAllChars(r,')'); + VhdlDocGen::deleteAllChars(r,'('); + r.setNum(r.toInt()+1); + t.replace(reg,r.data()); + s.append(t.data()); + bcd.usedName=s; + bcd.templSpecifiers=t; } } + cd->updateBaseClasses(bcl); } diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index 5cad4ed..1993c1e 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -1021,23 +1021,15 @@ static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream } //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers()); - MemberSDict *mdict = md->getReferencesMembers(); - if (mdict) + auto refList = md->getReferencesMembers(); + for (const auto &refmd : refList) { - MemberSDict::Iterator mdi(*mdict); - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - writeMemberReference(t,def,rmd,"references"); - } + writeMemberReference(t,def,refmd,"references"); } - mdict = md->getReferencedByMembers(); - if (mdict) + auto refByList = md->getReferencedByMembers(); + for (const auto &refmd : refByList) { - MemberSDict::Iterator mdi(*mdict); - for (mdi.toFirst();(rmd=mdi.current());++mdi) - { - writeMemberReference(t,def,rmd,"referencedby"); - } + writeMemberReference(t,def,refmd,"referencedby"); } t << " </memberdef>" << endl; @@ -1294,73 +1286,63 @@ static void generateXMLForClass(const ClassDef *cd,FTextStream &ti) t << " <compoundname>"; writeXMLString(t,cd->name()); t << "</compoundname>" << endl; - if (cd->baseClasses()) + for (const auto &bcd : cd->baseClasses()) { - BaseClassListIterator bcli(*cd->baseClasses()); - BaseClassDef *bcd; - for (bcli.toFirst();(bcd=bcli.current());++bcli) + t << " <basecompoundref "; + if (bcd.classDef->isLinkable()) { - t << " <basecompoundref "; - if (bcd->classDef->isLinkable()) - { - t << "refid=\"" << classOutputFileBase(bcd->classDef) << "\" "; - } - t << "prot=\""; - switch (bcd->prot) - { - case Public: t << "public"; break; - case Protected: t << "protected"; break; - case Private: t << "private"; break; - case Package: ASSERT(0); break; - } - t << "\" virt=\""; - switch(bcd->virt) - { - case Normal: t << "non-virtual"; break; - case Virtual: t << "virtual"; break; - case Pure: t <<"pure-virtual"; break; - } - t << "\">"; - if (!bcd->templSpecifiers.isEmpty()) - { - t << convertToXML( - insertTemplateSpecifierInScope( - bcd->classDef->name(),bcd->templSpecifiers) - ); - } - else - { - t << convertToXML(bcd->classDef->displayName()); - } - t << "</basecompoundref>" << endl; + t << "refid=\"" << classOutputFileBase(bcd.classDef) << "\" "; + } + t << "prot=\""; + switch (bcd.prot) + { + case Public: t << "public"; break; + case Protected: t << "protected"; break; + case Private: t << "private"; break; + case Package: ASSERT(0); break; } + t << "\" virt=\""; + switch(bcd.virt) + { + case Normal: t << "non-virtual"; break; + case Virtual: t << "virtual"; break; + case Pure: t <<"pure-virtual"; break; + } + t << "\">"; + if (!bcd.templSpecifiers.isEmpty()) + { + t << convertToXML( + insertTemplateSpecifierInScope( + bcd.classDef->name(),bcd.templSpecifiers) + ); + } + else + { + t << convertToXML(bcd.classDef->displayName()); + } + t << "</basecompoundref>" << endl; } - if (cd->subClasses()) + for (const auto &bcd : cd->subClasses()) { - BaseClassListIterator bcli(*cd->subClasses()); - BaseClassDef *bcd; - for (bcli.toFirst();(bcd=bcli.current());++bcli) + t << " <derivedcompoundref refid=\"" + << classOutputFileBase(bcd.classDef) + << "\" prot=\""; + switch (bcd.prot) { - t << " <derivedcompoundref refid=\"" - << classOutputFileBase(bcd->classDef) - << "\" prot=\""; - switch (bcd->prot) - { - case Public: t << "public"; break; - case Protected: t << "protected"; break; - case Private: t << "private"; break; - case Package: ASSERT(0); break; - } - t << "\" virt=\""; - switch(bcd->virt) - { - case Normal: t << "non-virtual"; break; - case Virtual: t << "virtual"; break; - case Pure: t << "pure-virtual"; break; - } - t << "\">" << convertToXML(bcd->classDef->displayName()) - << "</derivedcompoundref>" << endl; + case Public: t << "public"; break; + case Protected: t << "protected"; break; + case Private: t << "private"; break; + case Package: ASSERT(0); break; + } + t << "\" virt=\""; + switch (bcd.virt) + { + case Normal: t << "non-virtual"; break; + case Virtual: t << "virtual"; break; + case Pure: t << "pure-virtual"; break; } + t << "\">" << convertToXML(bcd.classDef->displayName()) + << "</derivedcompoundref>" << endl; } IncludeInfo *ii=cd->includeInfo(); |