diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-10-15 10:55:23 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-10-15 10:55:23 +0900 |
commit | 1ec16d649a01d369eecae2f1225c0ffa1caaf640 (patch) | |
tree | ed6cfed60d2438db244a7cddec6d4f0cf5fa93f6 /src | |
parent | 5e552810bc3dfc820036b4b16ae53561bb7cf3c6 (diff) | |
download | doxygen-1ec16d649a01d369eecae2f1225c0ffa1caaf640.tar.gz doxygen-1ec16d649a01d369eecae2f1225c0ffa1caaf640.tar.bz2 doxygen-1ec16d649a01d369eecae2f1225c0ffa1caaf640.zip |
Imported Upstream version 1.8.16upstream/1.8.16
Diffstat (limited to 'src')
197 files changed, 16552 insertions, 19091 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4dc31fa..7233052 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,10 @@ include_directories( ${CMAKE_SOURCE_DIR}/qtools ${CMAKE_SOURCE_DIR}/libmd5 - ${CMAKE_SOURCE_DIR}/vhdlparser/ + ${CMAKE_SOURCE_DIR}/liblodepng + ${CMAKE_SOURCE_DIR}/libmscgen + ${CMAKE_SOURCE_DIR}/libversion + ${CMAKE_SOURCE_DIR}/vhdlparser ${CMAKE_SOURCE_DIR}/src ${CLANG_INCLUDEDIR} ${GENERATED_SRC} @@ -14,7 +17,7 @@ file(MAKE_DIRECTORY ${GENERATED_SRC}) file(GLOB LANGUAGE_FILES "${CMAKE_SOURCE_DIR}/src/translator_??.h") # instead of increasebuffer.py -add_definitions(-DYY_BUF_SIZE=262144 -DYY_READ_BUF_SIZE=262144) +add_definitions(-DYY_BUF_SIZE=${enlarge_lex_buffers} -DYY_READ_BUF_SIZE=${enlarge_lex_buffers}) # generate settings.h file(GENERATE OUTPUT ${GENERATED_SRC}/settings.h @@ -30,12 +33,6 @@ CONTENT "#ifndef SETTINGS_H set_source_files_properties(${GENERATED_SRC}/settings.h PROPERTIES GENERATED 1) -# generate version.cpp -file(GENERATE OUTPUT ${GENERATED_SRC}/version.cpp - CONTENT "char versionString[]=\"${VERSION}\";" -) -set_source_files_properties(${GENERATED_SRC}/version.cpp PROPERTIES GENERATED 1) - # configvalues.h add_custom_command( COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/src/configgen.py -maph ${CMAKE_SOURCE_DIR}/src/config.xml > ${GENERATED_SRC}/configvalues.h @@ -43,6 +40,10 @@ add_custom_command( OUTPUT ${GENERATED_SRC}/configvalues.h ) set_source_files_properties(${GENERATED_SRC}/configvalues.h PROPERTIES GENERATED 1) +add_custom_target( + generate_configvalues_header + DEPENDS ${GENERATED_SRC}/configvalues.h +) # configvalues.cpp add_custom_command( @@ -136,7 +137,6 @@ add_library(_doxygen STATIC ${GENERATED_SRC}/lang_cfg.h ${GENERATED_SRC}/settings.h ${GENERATED_SRC}/layout_default.xml.h - ${GENERATED_SRC}/version.cpp ${GENERATED_SRC}/ce_parse.h ${GENERATED_SRC}/configvalues.h ${GENERATED_SRC}/resources.cpp @@ -181,6 +181,16 @@ add_library(_doxygen STATIC docparser.cpp docsets.cpp dot.cpp + dotcallgraph.cpp + dotclassgraph.cpp + dotdirdeps.cpp + dotfilepatcher.cpp + dotgfxhierarchytable.cpp + dotgraph.cpp + dotgroupcollaboration.cpp + dotincldepgraph.cpp + dotnode.cpp + dotrunner.cpp doxygen.cpp eclipsehelp.cpp emoji.cpp @@ -203,13 +213,10 @@ add_library(_doxygen STATIC latexdocvisitor.cpp latexgen.cpp layout.cpp - lodepng.cpp - logos.cpp mandocvisitor.cpp mangen.cpp sqlite3gen.cpp markdown.cpp - marshal.cpp memberdef.cpp membergroup.cpp memberlist.cpp @@ -230,7 +237,6 @@ add_library(_doxygen STATIC rtfgen.cpp rtfstyle.cpp searchindex.cpp - store.cpp tagreader.cpp template.cpp textdocvisitor.cpp @@ -242,6 +248,7 @@ add_library(_doxygen STATIC xmlgen.cpp docbookvisitor.cpp docbookgen.cpp + docgroup.cpp ) add_executable(doxygen main.cpp) @@ -271,6 +278,9 @@ target_link_libraries(doxygen doxycfg qtools md5 + lodepng + mscgen + doxygen_version vhdlparser ${SQLITE3_LIBRARIES} ${ICONV_LIBRARIES} diff --git a/src/arguments.cpp b/src/arguments.cpp index a828dab..6d3e13b 100644 --- a/src/arguments.cpp +++ b/src/arguments.cpp @@ -1,5 +1,4 @@ #include "arguments.h" -#include "marshal.h" #include <assert.h> /*! the argument list is documented if one of its @@ -38,67 +37,3 @@ ArgumentList *ArgumentList::deepCopy() const return argList; } -ArgumentList *ArgumentList::unmarshal(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; // null list - ArgumentList *result = new ArgumentList; - assert(count<1000000); - //printf("unmarshalArgumentList: %d\n",count); - for (i=0;i<count;i++) - { - Argument *a = new Argument; - a->attrib = unmarshalQCString(s); - a->type = unmarshalQCString(s); - a->canType = unmarshalQCString(s); - a->name = unmarshalQCString(s); - a->array = unmarshalQCString(s); - a->defval = unmarshalQCString(s); - a->docs = unmarshalQCString(s); - a->typeConstraint = unmarshalQCString(s); - result->append(a); - } - result->constSpecifier = unmarshalBool(s); - result->volatileSpecifier = unmarshalBool(s); - result->pureSpecifier = unmarshalBool(s); - result->trailingReturnType = unmarshalQCString(s); - result->isDeleted = unmarshalBool(s); - result->refQualifier = (RefQualifierType)unmarshalInt(s); - return result; -} - -void ArgumentList::marshal(StorageIntf *s,ArgumentList *argList) -{ - if (argList==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,argList->count()); - if (argList->count()>0) - { - ArgumentListIterator ali(*argList); - Argument *a; - for (ali.toFirst();(a=ali.current());++ali) - { - marshalQCString(s,a->attrib); - marshalQCString(s,a->type); - marshalQCString(s,a->canType); - marshalQCString(s,a->name); - marshalQCString(s,a->array); - marshalQCString(s,a->defval); - marshalQCString(s,a->docs); - marshalQCString(s,a->typeConstraint); - } - } - marshalBool(s,argList->constSpecifier); - marshalBool(s,argList->volatileSpecifier); - marshalBool(s,argList->pureSpecifier); - marshalQCString(s,argList->trailingReturnType); - marshalBool(s,argList->isDeleted); - marshalInt(s,(int)argList->refQualifier); - } -} - diff --git a/src/arguments.h b/src/arguments.h index 3af7134..7ef9642 100644 --- a/src/arguments.h +++ b/src/arguments.h @@ -115,9 +115,6 @@ class ArgumentList : public QList<Argument> bool isDeleted; /*! C++11 ref qualifier */ RefQualifierType refQualifier; - - static ArgumentList *unmarshal(StorageIntf *s); - static void marshal(StorageIntf *s,ArgumentList *argList); }; typedef QListIterator<Argument> ArgumentListIterator; diff --git a/src/cite.cpp b/src/cite.cpp index 4f88611..fd7b0e4 100644 --- a/src/cite.cpp +++ b/src/cite.cpp @@ -22,11 +22,13 @@ #include "language.h" #include "ftextstream.h" #include "resourcemgr.h" +#include "doxygen.h" #include <qdir.h> //-------------------------------------------------------------------------- const QCString CiteConsts::fileName("citelist"); +/* when changing this also take doxygen.bst into account */ const QCString CiteConsts::anchorPrefix("CITEREF_"); const QCString bibTmpFile("bibTmpFile_"); const QCString bibTmpDir("bibTmpDir/"); @@ -118,8 +120,58 @@ void CiteDict::generatePage() const // do not generate an empty citations page if (isEmpty()) return; // nothing to cite - // 1. generate file with markers and citations to OUTPUT_DIRECTORY + // 0. add cross references from the bib files to the cite dictionary QFile f; + QStrList &citeDataList = Config_getList(CITE_BIB_FILES); + const char *bibdata = citeDataList.first(); + while (bibdata) + { + QCString bibFile = bibdata; + if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; + QFileInfo fi(bibFile); + if (fi.exists()) + { + if (!bibFile.isEmpty()) + { + f.setName(bibFile); + if (!f.open(IO_ReadOnly)) + { + err("could not open file %s for reading\n",bibFile.data()); + } + QCString doc; + QFileInfo fi(bibFile); + QCString input(fi.size()+1); + f.readBlock(input.rawData(),fi.size()); + f.close(); + input.at(fi.size())='\0'; + int p=0,s; + while ((s=input.find('\n',p))!=-1) + { + QCString line = input.mid(p,s-p); + p=s+1; + + int i; + if ((i = line.find("crossref")) != -1) /* assumption crosreference is on one line and the only item */ + { + int j=line.find("{",i); + int k=line.find("}",i); + if (j!=-1 && k!=-1) + { + QCString label = line.mid(j+1,k-j-1); + if (!m_entries.find(label)) Doxygen::citeDict->insert(label.data()); + } + } + } + } + } + else if (!fi.exists()) + { + err("bib file %s not found!\n",bibFile.data()); + } + bibdata = citeDataList.next(); + } + + // 1. generate file with markers and citations to OUTPUT_DIRECTORY QCString outputDir = Config_getString(OUTPUT_DIRECTORY); QCString citeListFile = outputDir+"/citelist.doc"; f.setName(citeListFile); @@ -154,12 +206,11 @@ void CiteDict::generatePage() const // so bibtex can find them without path (bibtex doesn't support paths or // filenames with spaces!) // Strictly not required when only latex is generated - QStrList &citeDataList = Config_getList(CITE_BIB_FILES); QCString bibOutputDir = outputDir+"/"+bibTmpDir; QCString bibOutputFiles = ""; QDir thisDir; thisDir.mkdir(bibOutputDir); - const char *bibdata = citeDataList.first(); + bibdata = citeDataList.first(); int i = 0; while (bibdata) { @@ -175,10 +226,6 @@ void CiteDict::generatePage() const bibOutputFiles = bibOutputFiles + " " + bibTmpDir + bibTmpFile + QCString().setNum(i) + ".bib"; } } - else if (!fi.exists()) - { - err("bib file %s not found!\n",bibFile.data()); - } bibdata = citeDataList.next(); } diff --git a/src/clangparser.cpp b/src/clangparser.cpp index c22d5c5..271b99f 100644 --- a/src/clangparser.cpp +++ b/src/clangparser.cpp @@ -782,7 +782,7 @@ void ClangParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd, g_currentMemberDef && d->definitionType()==Definition::TypeMember && (g_currentMemberDef!=d || g_currentLine<line)) // avoid self-reference { - addDocCrossReference(g_currentMemberDef,(MemberDef*)d); + addDocCrossReference(g_currentMemberDef,dynamic_cast<MemberDef *>(d)); } writeMultiLineCodeLink(ol,fd,line,column,d,text); } @@ -825,7 +825,6 @@ static void detectFunctionBody(const char *s) void ClangParser::writeSources(CodeOutputInterface &ol,FileDef *fd) { - TooltipManager::instance()->clearTooltips(); // (re)set global parser state g_currentDefinition=0; g_currentMemberDef=0; @@ -934,7 +933,6 @@ void ClangParser::writeSources(CodeOutputInterface &ol,FileDef *fd) clang_disposeString(tokenString); } ol.endCodeLine(); - TooltipManager::instance()->writeTooltips(ol); } ClangParser::ClangParser() diff --git a/src/classdef.cpp b/src/classdef.cpp index e9d39d5..856ab05 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -33,6 +33,8 @@ #include "example.h" #include "outputlist.h" #include "dot.h" +#include "dotclassgraph.h" +#include "dotrunner.h" #include "defargs.h" #include "debug.h" #include "docparser.h" @@ -45,15 +47,501 @@ #include "filedef.h" #include "namespacedef.h" #include "membergroup.h" +#include "definitionimpl.h" //----------------------------------------------------------------------------- -/** Private data associated with a ClassDef object. */ -class ClassDefImpl + +/** Implementation of the ClassDef interface */ +class ClassDefImpl : public DefinitionImpl, public ClassDef { public: - ClassDefImpl(); + ClassDefImpl(const char *fileName,int startLine,int startColumn, + const char *name,CompoundType ct, + const char *ref=0,const char *fName=0, + bool isSymbol=TRUE,bool isJavaEnum=FALSE); + /** Destroys a compound definition. */ ~ClassDefImpl(); + + virtual ClassDef *resolveAlias() { return this; } + virtual DefType definitionType() const { return TypeClass; } + virtual QCString getOutputFileBase() const; + virtual QCString getInstanceOutputFileBase() const; + virtual QCString getSourceFileBase() const; + virtual QCString getReference() const; + virtual bool isReference() const; + virtual bool isLocal() const; + virtual ClassSDict *getClassSDict() const; + virtual bool hasDocumentation() const; + virtual bool hasDetailedDescription() const; + virtual QCString collaborationGraphFileName() const; + virtual QCString inheritanceGraphFileName() const; + virtual QCString displayName(bool includeScope=TRUE) const; + virtual CompoundType compoundType() const; + virtual QCString compoundTypeString() const; + virtual BaseClassList *baseClasses() const; + virtual BaseClassList *subClasses() const; + virtual MemberNameInfoSDict *memberNameInfoSDict() const; + virtual Protection protection() const; + virtual bool isLinkableInProject() const; + virtual bool isLinkable() const; + virtual bool isVisibleInHierarchy() const; + virtual bool visibleInParentsDeclList() const; + virtual ArgumentList *templateArguments() const; + virtual NamespaceDef *getNamespaceDef() const; + virtual FileDef *getFileDef() const; + virtual MemberDef *getMemberByName(const QCString &) const; + virtual bool isBaseClass(const ClassDef *bcd,bool followInstances,int level=0) const; + virtual bool isSubClass(ClassDef *bcd,int level=0) const; + virtual bool isAccessibleMember(const MemberDef *md) const; + virtual QDict<ClassDef> *getTemplateInstances() const; + virtual const ClassDef *templateMaster() const; + virtual bool isTemplate() const; + virtual IncludeInfo *includeInfo() const; + virtual UsesClassDict *usedImplementationClasses() const; + virtual UsesClassDict *usedByImplementationClasses() const; + virtual UsesClassDict *usedInterfaceClasses() const; + virtual ConstraintClassDict *templateTypeConstraints() const; + virtual bool isTemplateArgument() const; + virtual Definition *findInnerCompound(const char *name) const; + virtual void getTemplateParameterLists(QList<ArgumentList> &lists) const; + virtual QCString qualifiedNameWithTemplateParameters( + QList<ArgumentList> *actualParams=0,int *actualParamIndex=0) const; + virtual bool isAbstract() const; + virtual bool isObjectiveC() const; + virtual bool isFortran() const; + virtual bool isCSharp() const; + virtual bool isFinal() const; + virtual bool isSealed() const; + virtual bool isPublished() const; + virtual bool isExtension() const; + virtual bool isForwardDeclared() const; + virtual bool isInterface() const; + virtual ClassDef *categoryOf() const; + virtual QCString className() const; + virtual MemberList *getMemberList(MemberListType lt) const; + virtual const QList<MemberList> &getMemberLists() const; + virtual MemberGroupSDict *getMemberGroupSDict() const; + virtual QDict<int> *getTemplateBaseClassNames() const; + virtual ClassDef *getVariableInstance(const char *templSpec) const; + virtual bool isUsedOnly() const; + virtual QCString anchor() const; + virtual bool isEmbeddedInOuterScope() const; + virtual bool isSimple() const; + virtual const ClassList *taggedInnerClasses() const; + virtual ClassDef *tagLessReference() const; + virtual MemberDef *isSmartPointer() const; + virtual bool isJavaEnum() const; + virtual bool isGeneric() const; + virtual bool isAnonymous() const; + virtual const ClassSDict *innerClasses() const; + virtual QCString title() const; + virtual QCString generatedFromFiles() const; + virtual const FileList &usedFiles() const; + virtual const ArgumentList *typeConstraints() const; + virtual const ExampleSDict *exampleList() const; + virtual bool hasExamples() const; + virtual QCString getMemberListFileName() const; + virtual bool subGrouping() const; + virtual bool isSliceLocal() const; + virtual bool hasNonReferenceSuperClass() const; + virtual ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn, + const QCString &templSpec,bool &freshInstance) const; + + virtual void insertBaseClass(ClassDef *,const char *name,Protection p,Specifier s,const char *t=0); + virtual void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0); + virtual void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force); + virtual void insertMember(MemberDef *); + virtual void insertUsedFile(FileDef *); + virtual bool addExample(const char *anchor,const char *name, const char *file); + virtual void mergeCategory(ClassDef *category); + virtual void setNamespace(NamespaceDef *nd); + virtual void setFileDef(FileDef *fd); + virtual void setSubGrouping(bool enabled); + virtual void setProtection(Protection p); + virtual void setGroupDefForAllMembers(GroupDef *g,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs); + virtual void addInnerCompound(const Definition *d); + virtual void addUsedClass(ClassDef *cd,const char *accessName,Protection prot); + virtual void addUsedByClass(ClassDef *cd,const char *accessName,Protection prot); + virtual void setIsStatic(bool b); + virtual void setCompoundType(CompoundType t); + virtual void setClassName(const char *name); + virtual void setClassSpecifier(uint64 spec); + virtual void setTemplateArguments(ArgumentList *al); + virtual void setTemplateBaseClassNames(QDict<int> *templateNames); + virtual void setTemplateMaster(const ClassDef *tm); + virtual void setTypeConstraints(ArgumentList *al); + virtual void addMembersToTemplateInstance(const ClassDef *cd,const char *templSpec); + virtual void makeTemplateArgument(bool b=TRUE); + virtual void setCategoryOf(ClassDef *cd); + virtual void setUsedOnly(bool b); + virtual void addTaggedInnerClass(ClassDef *cd); + virtual void setTagLessReference(ClassDef *cd); + virtual void setName(const char *name); + virtual void setMetaData(const char *md); + virtual void findSectionsInDocumentation(); + virtual void addMembersToMemberGroup(); + virtual void addListReferences(); + virtual void addTypeConstraints(); + virtual void computeAnchors(); + virtual void mergeMembers(); + virtual void sortMemberLists(); + virtual void distributeMemberGroupDocumentation(); + virtual void writeDocumentation(OutputList &ol) const; + virtual void writeDocumentationForInnerClasses(OutputList &ol) const; + virtual void writeMemberPages(OutputList &ol) const; + virtual void writeMemberList(OutputList &ol) const; + virtual void writeDeclaration(OutputList &ol,const MemberDef *md,bool inGroup, + const ClassDef *inheritedFrom,const char *inheritId) const; + virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *md) const; + virtual void writeSummaryLinks(OutputList &ol) const; + virtual void reclassifyMember(MemberDef *md,MemberType t); + virtual void writeInlineDocumentation(OutputList &ol) const; + virtual void writeDeclarationLink(OutputList &ol,bool &found, + const char *header,bool localNames) const; + virtual void removeMemberFromLists(MemberDef *md); + virtual void setAnonymousEnumType(); + virtual void countMembers(); + + virtual void addGroupedInheritedMembers(OutputList &ol,MemberListType lt, + const ClassDef *inheritedFrom,const QCString &inheritId) const; + virtual void writeTagFile(FTextStream &); + + virtual void setVisited(bool visited) const { m_visited = visited; } + virtual bool isVisited() const { return m_visited; } + virtual int countMembersIncludingGrouped(MemberListType lt,const ClassDef *inheritedFrom,bool additional) const; + virtual int countInheritanceNodes() const; + virtual int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom, + int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const; + virtual void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title, + const char *subTitle=0,bool showInline=FALSE,const ClassDef *inheritedFrom=0, + int lt2=-1,bool invert=FALSE,bool showAlways=FALSE, + QPtrDict<void> *visitedClasses=0) const; + + private: + mutable bool m_visited; + void addUsedInterfaceClasses(MemberDef *md,const char *typeStr); + void showUsedFiles(OutputList &ol) const; + + void writeDocumentationContents(OutputList &ol,const QCString &pageTitle) const; + void internalInsertMember(MemberDef *md,Protection prot,bool addToAllList); + void addMemberToList(MemberListType lt,MemberDef *md,bool isBrief); + MemberList *createMemberList(MemberListType lt); + void writeInheritedMemberDeclarations(OutputList &ol,MemberListType lt,int lt2,const QCString &title, + const ClassDef *inheritedFrom,bool invert, + bool showAlways,QPtrDict<void> *visitedClasses) const; + void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title,bool showInline=FALSE) const; + void writeSimpleMemberDocumentation(OutputList &ol,MemberListType lt) const; + void writePlainMemberDeclaration(OutputList &ol,MemberListType lt,bool inGroup,const ClassDef *inheritedFrom,const char *inheritId) const; + void writeBriefDescription(OutputList &ol,bool exampleFlag) const; + void writeDetailedDescription(OutputList &ol,const QCString &pageType,bool exampleFlag, + const QCString &title,const QCString &anchor=QCString()) const; + void writeIncludeFiles(OutputList &ol) const; + void writeIncludeFilesForSlice(OutputList &ol) const; + //void writeAllMembersLink(OutputList &ol); + void writeInheritanceGraph(OutputList &ol) const; + void writeCollaborationGraph(OutputList &ol) const; + void writeMemberGroups(OutputList &ol,bool showInline=FALSE) const; + void writeNestedClasses(OutputList &ol,const QCString &title) const; + void writeInlineClasses(OutputList &ol) const; + void startMemberDeclarations(OutputList &ol) const; + void endMemberDeclarations(OutputList &ol) const; + void startMemberDocumentation(OutputList &ol) const; + void endMemberDocumentation(OutputList &ol) const; + void writeAuthorSection(OutputList &ol) const; + void writeMoreLink(OutputList &ol,const QCString &anchor) const; + void writeDetailedDocumentationBody(OutputList &ol) const; + + int countAdditionalInheritedMembers() const; + void writeAdditionalInheritedMembers(OutputList &ol) const; + void addClassAttributes(OutputList &ol) const; + int countInheritedDecMembers(MemberListType lt, + const ClassDef *inheritedFrom,bool invert,bool showAlways, + QPtrDict<void> *visitedClasses) const; + void getTitleForMemberListType(MemberListType type, + QCString &title,QCString &subtitle) const; + QCString includeStatement() const; + void addTypeConstraint(const QCString &typeConstraint,const QCString &type); + + // PIMPL idiom + class IMPL; + IMPL *m_impl; +}; + +ClassDef *createClassDef( + const char *fileName,int startLine,int startColumn, + const char *name,ClassDef::CompoundType ct, + const char *ref,const char *fName, + bool isSymbol,bool isJavaEnum) +{ + return new ClassDefImpl(fileName,startLine,startColumn,name,ct,ref,fName,isSymbol,isJavaEnum); +} +//----------------------------------------------------------------------------- + +class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef +{ + public: + ClassDefAliasImpl(const Definition *newScope,const ClassDef *cd) : DefinitionAliasImpl(newScope,cd) {} + virtual ~ClassDefAliasImpl() {} + virtual DefType definitionType() const { return TypeClass; } + + const ClassDef *getCdAlias() const { return dynamic_cast<const ClassDef*>(getAlias()); } + virtual ClassDef *resolveAlias() { return const_cast<ClassDef*>(getCdAlias()); } + + virtual QCString getOutputFileBase() const + { return getCdAlias()->getOutputFileBase(); } + virtual QCString getInstanceOutputFileBase() const + { return getCdAlias()->getInstanceOutputFileBase(); } + virtual QCString getSourceFileBase() const + { return getCdAlias()->getSourceFileBase(); } + virtual QCString getReference() const + { return getCdAlias()->getReference(); } + virtual bool isReference() const + { return getCdAlias()->isReference(); } + virtual bool isLocal() const + { return getCdAlias()->isLocal(); } + virtual ClassSDict *getClassSDict() const + { return getCdAlias()->getClassSDict(); } + virtual bool hasDocumentation() const + { return getCdAlias()->hasDocumentation(); } + virtual bool hasDetailedDescription() const + { return getCdAlias()->hasDetailedDescription(); } + virtual QCString collaborationGraphFileName() const + { return getCdAlias()->collaborationGraphFileName(); } + virtual QCString inheritanceGraphFileName() const + { return getCdAlias()->inheritanceGraphFileName(); } + virtual QCString displayName(bool includeScope=TRUE) const + { return getCdAlias()->displayName(includeScope); } + virtual CompoundType compoundType() const + { return getCdAlias()->compoundType(); } + virtual QCString compoundTypeString() const + { return getCdAlias()->compoundTypeString(); } + virtual BaseClassList *baseClasses() const + { return getCdAlias()->baseClasses(); } + virtual BaseClassList *subClasses() const + { return getCdAlias()->subClasses(); } + virtual MemberNameInfoSDict *memberNameInfoSDict() const + { return getCdAlias()->memberNameInfoSDict(); } + virtual Protection protection() const + { return getCdAlias()->protection(); } + virtual bool isLinkableInProject() const + { return getCdAlias()->isLinkableInProject(); } + virtual bool isLinkable() const + { return getCdAlias()->isLinkable(); } + virtual bool isVisibleInHierarchy() const + { return getCdAlias()->isVisibleInHierarchy(); } + virtual bool visibleInParentsDeclList() const + { return getCdAlias()->visibleInParentsDeclList(); } + virtual ArgumentList *templateArguments() const + { return getCdAlias()->templateArguments(); } + virtual NamespaceDef *getNamespaceDef() const + { return getCdAlias()->getNamespaceDef(); } + virtual FileDef *getFileDef() const + { return getCdAlias()->getFileDef(); } + virtual MemberDef *getMemberByName(const QCString &s) const + { return getCdAlias()->getMemberByName(s); } + virtual bool isBaseClass(const ClassDef *bcd,bool followInstances,int level=0) const + { return getCdAlias()->isBaseClass(bcd,followInstances,level); } + virtual bool isSubClass(ClassDef *bcd,int level=0) const + { return getCdAlias()->isSubClass(bcd,level); } + virtual bool isAccessibleMember(const MemberDef *md) const + { return getCdAlias()->isAccessibleMember(md); } + virtual QDict<ClassDef> *getTemplateInstances() const + { return getCdAlias()->getTemplateInstances(); } + virtual const ClassDef *templateMaster() const + { return getCdAlias()->templateMaster(); } + virtual bool isTemplate() const + { return getCdAlias()->isTemplate(); } + virtual IncludeInfo *includeInfo() const + { return getCdAlias()->includeInfo(); } + virtual UsesClassDict *usedImplementationClasses() const + { return getCdAlias()->usedImplementationClasses(); } + virtual UsesClassDict *usedByImplementationClasses() const + { return getCdAlias()->usedByImplementationClasses(); } + virtual UsesClassDict *usedInterfaceClasses() const + { return getCdAlias()->usedInterfaceClasses(); } + virtual ConstraintClassDict *templateTypeConstraints() const + { return getCdAlias()->templateTypeConstraints(); } + virtual bool isTemplateArgument() const + { return getCdAlias()->isTemplateArgument(); } + virtual Definition *findInnerCompound(const char *name) const + { return getCdAlias()->findInnerCompound(name); } + virtual void getTemplateParameterLists(QList<ArgumentList> &lists) const + { return getCdAlias()->getTemplateParameterLists(lists); } + virtual QCString qualifiedNameWithTemplateParameters( + QList<ArgumentList> *actualParams=0,int *actualParamIndex=0) const + { return getCdAlias()->qualifiedNameWithTemplateParameters(actualParams,actualParamIndex); } + virtual bool isAbstract() const + { return getCdAlias()->isAbstract(); } + virtual bool isObjectiveC() const + { return getCdAlias()->isObjectiveC(); } + virtual bool isFortran() const + { return getCdAlias()->isFortran(); } + virtual bool isCSharp() const + { return getCdAlias()->isCSharp(); } + virtual bool isFinal() const + { return getCdAlias()->isFinal(); } + virtual bool isSealed() const + { return getCdAlias()->isSealed(); } + virtual bool isPublished() const + { return getCdAlias()->isPublished(); } + virtual bool isExtension() const + { return getCdAlias()->isExtension(); } + virtual bool isForwardDeclared() const + { return getCdAlias()->isForwardDeclared(); } + virtual bool isInterface() const + { return getCdAlias()->isInterface(); } + virtual ClassDef *categoryOf() const + { return getCdAlias()->categoryOf(); } + virtual QCString className() const + { return getCdAlias()->className(); } + virtual MemberList *getMemberList(MemberListType lt) const + { return getCdAlias()->getMemberList(lt); } + virtual const QList<MemberList> &getMemberLists() const + { return getCdAlias()->getMemberLists(); } + virtual MemberGroupSDict *getMemberGroupSDict() const + { return getCdAlias()->getMemberGroupSDict(); } + virtual QDict<int> *getTemplateBaseClassNames() const + { return getCdAlias()->getTemplateBaseClassNames(); } + virtual ClassDef *getVariableInstance(const char *templSpec) const + { return getCdAlias()->getVariableInstance(templSpec); } + virtual bool isUsedOnly() const + { return getCdAlias()->isUsedOnly(); } + virtual QCString anchor() const + { return getCdAlias()->anchor(); } + virtual bool isEmbeddedInOuterScope() const + { return getCdAlias()->isEmbeddedInOuterScope(); } + virtual bool isSimple() const + { return getCdAlias()->isSimple(); } + virtual const ClassList *taggedInnerClasses() const + { return getCdAlias()->taggedInnerClasses(); } + virtual ClassDef *tagLessReference() const + { return getCdAlias()->tagLessReference(); } + virtual MemberDef *isSmartPointer() const + { return getCdAlias()->isSmartPointer(); } + virtual bool isJavaEnum() const + { return getCdAlias()->isJavaEnum(); } + virtual bool isGeneric() const + { return getCdAlias()->isGeneric(); } + virtual bool isAnonymous() const + { return getCdAlias()->isAnonymous(); } + virtual const ClassSDict *innerClasses() const + { return getCdAlias()->innerClasses(); } + virtual QCString title() const + { return getCdAlias()->title(); } + virtual QCString generatedFromFiles() const + { return getCdAlias()->generatedFromFiles(); } + virtual const FileList &usedFiles() const + { return getCdAlias()->usedFiles(); } + virtual const ArgumentList *typeConstraints() const + { return getCdAlias()->typeConstraints(); } + virtual const ExampleSDict *exampleList() const + { return getCdAlias()->exampleList(); } + virtual bool hasExamples() const + { return getCdAlias()->hasExamples(); } + virtual QCString getMemberListFileName() const + { return getCdAlias()->getMemberListFileName(); } + virtual bool subGrouping() const + { return getCdAlias()->subGrouping(); } + virtual bool isSliceLocal() const + { return getCdAlias()->isSliceLocal(); } + virtual bool hasNonReferenceSuperClass() const + { return getCdAlias()->hasNonReferenceSuperClass(); } + virtual ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn, + const QCString &templSpec,bool &freshInstance) const + { return getCdAlias()->insertTemplateInstance(fileName,startLine,startColumn,templSpec,freshInstance); } + + virtual void insertBaseClass(ClassDef *,const char *name,Protection p,Specifier s,const char *t=0) { } + virtual void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0) { } + virtual void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force) {} + virtual void insertMember(MemberDef *) {} + virtual void insertUsedFile(FileDef *) {} + virtual bool addExample(const char *anchor,const char *name, const char *file) { return FALSE; } + virtual void mergeCategory(ClassDef *category) {} + virtual void setNamespace(NamespaceDef *nd) {} + virtual void setFileDef(FileDef *fd) {} + virtual void setSubGrouping(bool enabled) {} + virtual void setProtection(Protection p) {} + virtual void setGroupDefForAllMembers(GroupDef *g,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs) {} + virtual void addInnerCompound(const Definition *d) {} + virtual void addUsedClass(ClassDef *cd,const char *accessName,Protection prot) {} + virtual void addUsedByClass(ClassDef *cd,const char *accessName,Protection prot) {} + virtual void setIsStatic(bool b) {} + virtual void setCompoundType(CompoundType t) {} + virtual void setClassName(const char *name) {} + virtual void setClassSpecifier(uint64 spec) {} + virtual void setTemplateArguments(ArgumentList *al) {} + virtual void setTemplateBaseClassNames(QDict<int> *templateNames) {} + virtual void setTemplateMaster(const ClassDef *tm) {} + virtual void setTypeConstraints(ArgumentList *al) {} + virtual void addMembersToTemplateInstance(const ClassDef *cd,const char *templSpec) {} + virtual void makeTemplateArgument(bool b=TRUE) {} + virtual void setCategoryOf(ClassDef *cd) {} + virtual void setUsedOnly(bool b) {} + virtual void addTaggedInnerClass(ClassDef *cd) {} + virtual void setTagLessReference(ClassDef *cd) {} + virtual void setName(const char *name) {} + virtual void setMetaData(const char *md) {} + virtual void findSectionsInDocumentation() {} + virtual void addMembersToMemberGroup() {} + virtual void addListReferences() {} + virtual void addTypeConstraints() {} + virtual void computeAnchors() {} + virtual void mergeMembers() {} + virtual void sortMemberLists() {} + virtual void distributeMemberGroupDocumentation() {} + virtual void writeDocumentation(OutputList &ol) const {} + virtual void writeDocumentationForInnerClasses(OutputList &ol) const {} + virtual void writeMemberPages(OutputList &ol) const {} + virtual void writeMemberList(OutputList &ol) const {} + virtual void writeDeclaration(OutputList &ol,const MemberDef *md,bool inGroup, + const ClassDef *inheritedFrom,const char *inheritId) const {} + virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *md) const {} + virtual void writeSummaryLinks(OutputList &ol) const {} + virtual void reclassifyMember(MemberDef *md,MemberType t) {} + virtual void writeInlineDocumentation(OutputList &ol) const {} + virtual void writeDeclarationLink(OutputList &ol,bool &found, + const char *header,bool localNames) const + { getCdAlias()->writeDeclarationLink(ol,found,header,localNames); } + virtual void removeMemberFromLists(MemberDef *md) {} + virtual void setAnonymousEnumType() {} + virtual void countMembers() {} + virtual void addGroupedInheritedMembers(OutputList &ol,MemberListType lt, + const ClassDef *inheritedFrom,const QCString &inheritId) const {} + virtual void writeTagFile(FTextStream &) {} + + virtual void setVisited(bool visited) const { m_visited = visited; } + virtual bool isVisited() const { return m_visited; } + virtual int countMembersIncludingGrouped(MemberListType lt,const ClassDef *inheritedFrom,bool additional) const + { return getCdAlias()->countMembersIncludingGrouped(lt,inheritedFrom,additional); } + virtual int countInheritanceNodes() const + { return getCdAlias()->countInheritanceNodes(); } + virtual int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom, + int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const + { return getCdAlias()->countMemberDeclarations(lt,inheritedFrom,lt2,invert,showAlways,visitedClasses); } + virtual void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title, + const char *subTitle=0,bool showInline=FALSE,const ClassDef *inheritedFrom=0, + int lt2=-1,bool invert=FALSE,bool showAlways=FALSE, + QPtrDict<void> *visitedClasses=0) const {} + + private: + mutable bool m_visited; +}; + + +ClassDef *createClassDefAlias(const Definition *newScope,const ClassDef *cd) +{ + return new ClassDefAliasImpl(newScope,cd); +} + +//----------------------------------------------------------------------------- + +/** Private data associated with a ClassDef object. */ +class ClassDefImpl::IMPL +{ + public: + IMPL(); + ~IMPL(); void init(const char *defFileName, const char *name, const QCString &ctStr, const char *fName); @@ -133,18 +621,18 @@ class ClassDefImpl /*! Template instances that exists of this class, the key in the * dictionary is the template argument list. */ - QDict<ClassDef> *templateInstances; + mutable QDict<ClassDef> *templateInstances; /*! Template instances that exists of this class, as defined by variables. * We do NOT want to document these individually. The key in the * dictionary is the template argument list. */ - QDict<ClassDef> *variableInstances; + mutable QDict<ClassDef> *variableInstances; QDict<int> *templBaseClassNames; /*! The class this class is an instance of. */ - ClassDef *templateMaster; + const ClassDef *templateMaster; /*! local class name which could be a typedef'ed alias name. */ QCString className; @@ -206,7 +694,7 @@ class ClassDefImpl QCString metaData; }; -void ClassDefImpl::init(const char *defFileName, const char *name, +void ClassDefImpl::IMPL::init(const char *defFileName, const char *name, const QCString &ctStr, const char *fName) { if (fName) @@ -268,12 +756,12 @@ void ClassDefImpl::init(const char *defFileName, const char *name, isAnonymous = QCString(name).find('@')!=-1; } -ClassDefImpl::ClassDefImpl() : vhdlSummaryTitles(17) +ClassDefImpl::IMPL::IMPL() : vhdlSummaryTitles(17) { vhdlSummaryTitles.setAutoDelete(TRUE); } -ClassDefImpl::~ClassDefImpl() +ClassDefImpl::IMPL::~IMPL() { delete inherits; delete inheritedBy; @@ -294,17 +782,19 @@ ClassDefImpl::~ClassDefImpl() delete taggedInnerClasses; } +//------------------------------------------------------------------------------------------- + // constructs a new class definition -ClassDef::ClassDef( +ClassDefImpl::ClassDefImpl( const char *defFileName,int defLine,int defColumn, const char *nm,CompoundType ct, const char *lref,const char *fName, bool isSymbol,bool isJavaEnum) - : Definition(defFileName,defLine,defColumn,removeRedundantWhiteSpace(nm),0,0,isSymbol) + : DefinitionImpl(defFileName,defLine,defColumn,removeRedundantWhiteSpace(nm),0,0,isSymbol) { - visited=FALSE; + m_visited=FALSE; setReference(lref); - m_impl = new ClassDefImpl; + m_impl = new ClassDefImpl::IMPL; m_impl->compType = ct; m_impl->isJavaEnum = isJavaEnum; m_impl->init(defFileName,name(),compoundTypeString(),fName); @@ -318,17 +808,17 @@ ClassDef::ClassDef( } // destroy the class definition -ClassDef::~ClassDef() +ClassDefImpl::~ClassDefImpl() { delete m_impl; } -QCString ClassDef::getMemberListFileName() const +QCString ClassDefImpl::getMemberListFileName() const { return m_impl->memberListFileName; } -QCString ClassDef::displayName(bool includeScope) const +QCString ClassDefImpl::displayName(bool includeScope) const { //static bool optimizeOutputForJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); SrcLangExt lang = getLanguage(); @@ -362,7 +852,7 @@ QCString ClassDef::displayName(bool includeScope) const //{ // n = n.left(n.length()-2); //} - //printf("ClassDef::displayName()=%s\n",n.data()); + //printf("ClassDefImpl::displayName()=%s\n",n.data()); if (n.find('@')!=-1) { return removeAnonymousScopes(n); @@ -374,7 +864,7 @@ QCString ClassDef::displayName(bool includeScope) const } // inserts a base/super class in the inheritance list -void ClassDef::insertBaseClass(ClassDef *cd,const char *n,Protection p, +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()); @@ -389,7 +879,7 @@ void ClassDef::insertBaseClass(ClassDef *cd,const char *n,Protection p, } // inserts a derived/sub class in the inherited-by list -void ClassDef::insertSubClass(ClassDef *cd,Protection p, +void ClassDefImpl::insertSubClass(ClassDef *cd,Protection p, Specifier s,const char *t) { //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data()); @@ -404,7 +894,7 @@ void ClassDef::insertSubClass(ClassDef *cd,Protection p, m_impl->isSimple = FALSE; } -void ClassDef::addMembersToMemberGroup() +void ClassDefImpl::addMembersToMemberGroup() { QListIterator<MemberList> mli(m_impl->memberLists); MemberList *ml; @@ -433,7 +923,7 @@ void ClassDef::addMembersToMemberGroup() } // adds new member definition to the class -void ClassDef::internalInsertMember(MemberDef *md, +void ClassDefImpl::internalInsertMember(MemberDef *md, Protection prot, bool addToAllList ) @@ -620,6 +1110,10 @@ void ClassDef::internalInsertMember(MemberDef *md, { addMemberToList(MemberListType_relatedMembers,md,FALSE); } + else if (md->isFunction() && md->protection()==Private && md->virtualness()!=Normal && Config_getBool(EXTRACT_PRIV_VIRTUAL)) + { + addMemberToList(MemberListType_functionMembers,md,FALSE); + } else { switch (md->memberType()) @@ -735,13 +1229,13 @@ void ClassDef::internalInsertMember(MemberDef *md, } } -void ClassDef::insertMember(MemberDef *md) +void ClassDefImpl::insertMember(MemberDef *md) { internalInsertMember(md,md->protection(),TRUE); } // compute the anchors for all members -void ClassDef::computeAnchors() +void ClassDefImpl::computeAnchors() { //ClassDef *context = Config_getBool(INLINE_INHERITED_MEMB) ? this : 0; //const char *letters = "abcdefghijklmnopqrstuvwxyz0123456789"; @@ -767,7 +1261,7 @@ void ClassDef::computeAnchors() } } -void ClassDef::distributeMemberGroupDocumentation() +void ClassDefImpl::distributeMemberGroupDocumentation() { if (m_impl->memberGroupSDict) { @@ -780,7 +1274,7 @@ void ClassDef::distributeMemberGroupDocumentation() } } -void ClassDef::findSectionsInDocumentation() +void ClassDefImpl::findSectionsInDocumentation() { docFindSections(documentation(),this,0,docFile()); if (m_impl->memberGroupSDict) @@ -805,7 +1299,7 @@ void ClassDef::findSectionsInDocumentation() // add a file name to the used files set -void ClassDef::insertUsedFile(FileDef *fd) +void ClassDefImpl::insertUsedFile(FileDef *fd) { if (fd==0) return; if (m_impl->files.find(fd)==-1) m_impl->files.append(fd); @@ -842,10 +1336,10 @@ static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd) } } -void ClassDef::setIncludeFile(FileDef *fd, +void ClassDefImpl::setIncludeFile(FileDef *fd, const char *includeName,bool local, bool force) { - //printf("ClassDef::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force); + //printf("ClassDefImpl::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force); if (!m_impl->incInfo) m_impl->incInfo=new IncludeInfo; if ((includeName && m_impl->incInfo->includeName.isEmpty()) || (fd!=0 && m_impl->incInfo->fileDef==0) @@ -864,7 +1358,7 @@ void ClassDef::setIncludeFile(FileDef *fd, } // TODO: fix this: a nested template class can have multiple outer templates -//ArgumentList *ClassDef::outerTemplateArguments() const +//ArgumentList *ClassDefImpl::outerTemplateArguments() const //{ // int ti; // ClassDef *pcd=0; @@ -881,7 +1375,7 @@ void ClassDef::setIncludeFile(FileDef *fd, // return 0; //} -static void searchTemplateSpecs(/*in*/ Definition *d, +static void searchTemplateSpecs(/*in*/ const Definition *d, /*out*/ QList<ArgumentList> &result, /*out*/ QCString &name, /*in*/ SrcLangExt lang) @@ -892,7 +1386,7 @@ static void searchTemplateSpecs(/*in*/ Definition *d, { searchTemplateSpecs(d->getOuterScope(),result,name,lang); } - ClassDef *cd=(ClassDef *)d; + const ClassDef *cd=dynamic_cast<const ClassDef *>(d); if (!name.isEmpty()) name+="::"; QCString clName = d->localName(); if (/*clName.right(2)=="-g" ||*/ clName.right(2)=="-p") @@ -916,7 +1410,7 @@ static void searchTemplateSpecs(/*in*/ Definition *d, } } -static void writeTemplateSpec(OutputList &ol,Definition *d, +static void writeTemplateSpec(OutputList &ol,const Definition *d, const QCString &type,SrcLangExt lang) { QList<ArgumentList> specs; @@ -958,7 +1452,7 @@ static void writeTemplateSpec(OutputList &ol,Definition *d, } } -void ClassDef::writeBriefDescription(OutputList &ol,bool exampleFlag) +void ClassDefImpl::writeBriefDescription(OutputList &ol,bool exampleFlag) const { if (hasBriefDescription()) { @@ -985,7 +1479,7 @@ void ClassDef::writeBriefDescription(OutputList &ol,bool exampleFlag) ol.writeSynopsis(); } -void ClassDef::writeDetailedDocumentationBody(OutputList &ol) +void ClassDefImpl::writeDetailedDocumentationBody(OutputList &ol) const { static bool repeatBrief = Config_getBool(REPEAT_BRIEF); @@ -1033,7 +1527,7 @@ void ClassDef::writeDetailedDocumentationBody(OutputList &ol) ol.endTextBlock(); } -bool ClassDef::hasDetailedDescription() const +bool ClassDefImpl::hasDetailedDescription() const { static bool repeatBrief = Config_getBool(REPEAT_BRIEF); static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); @@ -1043,8 +1537,8 @@ bool ClassDef::hasDetailedDescription() const } // write the detailed description for this class -void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &/*pageType*/, bool exampleFlag, - const QCString &title,const QCString &anchor) +void ClassDefImpl::writeDetailedDescription(OutputList &ol, const QCString &/*pageType*/, bool exampleFlag, + const QCString &title,const QCString &anchor) const { if (hasDetailedDescription() || exampleFlag) { @@ -1079,7 +1573,7 @@ void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &/*pageTy } } -QCString ClassDef::generatedFromFiles() const +QCString ClassDefImpl::generatedFromFiles() const { QCString result; SrcLangExt lang = getLanguage(); @@ -1110,7 +1604,7 @@ QCString ClassDef::generatedFromFiles() const return result; } -void ClassDef::showUsedFiles(OutputList &ol) +void ClassDefImpl::showUsedFiles(OutputList &ol) const { ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); @@ -1190,7 +1684,7 @@ void ClassDef::showUsedFiles(OutputList &ol) ol.popGeneratorState(); } -int ClassDef::countInheritanceNodes() +int ClassDefImpl::countInheritanceNodes() const { int count=0; BaseClassDef *ibcd; @@ -1215,7 +1709,7 @@ int ClassDef::countInheritanceNodes() return count; } -void ClassDef::writeInheritanceGraph(OutputList &ol) +void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const { // count direct inheritance relations const int count=countInheritanceNodes(); @@ -1225,8 +1719,12 @@ void ClassDef::writeInheritanceGraph(OutputList &ol) (Config_getBool(CLASS_DIAGRAMS) || Config_getBool(CLASS_GRAPH))) // write class diagram using dot { - DotClassGraph inheritanceGraph(this,DotNode::Inheritance); - if (!inheritanceGraph.isTrivial() && !inheritanceGraph.isTooBig()) + DotClassGraph inheritanceGraph(this,Inheritance); + if (inheritanceGraph.isTooBig()) + { + warn_uncond("Inheritance graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",name().data()); + } + else if (!inheritanceGraph.isTrivial()) { ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); @@ -1340,11 +1838,11 @@ void ClassDef::writeInheritanceGraph(OutputList &ol) } } -void ClassDef::writeCollaborationGraph(OutputList &ol) +void ClassDefImpl::writeCollaborationGraph(OutputList &ol) const { if (Config_getBool(HAVE_DOT) /*&& Config_getBool(COLLABORATION_GRAPH)*/) { - DotClassGraph usageImplGraph(this,DotNode::Collaboration); + DotClassGraph usageImplGraph(this,Collaboration); if (!usageImplGraph.isTrivial()) { ol.pushGeneratorState(); @@ -1357,7 +1855,7 @@ void ClassDef::writeCollaborationGraph(OutputList &ol) } } -QCString ClassDef::includeStatement() const +QCString ClassDefImpl::includeStatement() const { SrcLangExt lang = getLanguage(); bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java; @@ -1375,7 +1873,7 @@ QCString ClassDef::includeStatement() const } } -void ClassDef::writeIncludeFilesForSlice(OutputList &ol) +void ClassDefImpl::writeIncludeFilesForSlice(OutputList &ol) const { if (m_impl->incInfo) { @@ -1485,15 +1983,15 @@ void ClassDef::writeIncludeFilesForSlice(OutputList &ol) else { // Must be a class. - bool implements = false; + bool implements = FALSE; BaseClassListIterator it(*m_impl->inherits); BaseClassDef *ibcd; for (;(ibcd=it.current());++it) { ClassDef *icd = ibcd->classDef; - if (icd->m_impl->spec & Entry::Interface) + if (icd->isInterface()) { - implements = true; + implements = TRUE; } else { @@ -1504,11 +2002,11 @@ void ClassDef::writeIncludeFilesForSlice(OutputList &ol) if (implements) { ol.docify(" implements "); - bool first = true; + bool first = TRUE; for (ibcd=it.toFirst();(ibcd=it.current());++it) { ClassDef *icd = ibcd->classDef; - if (icd->m_impl->spec & Entry::Interface) + if (icd->isInterface()) { if (!first) { @@ -1516,7 +2014,7 @@ void ClassDef::writeIncludeFilesForSlice(OutputList &ol) } else { - first = false; + first = FALSE; } ol.docify(icd->name()); } @@ -1529,7 +2027,7 @@ void ClassDef::writeIncludeFilesForSlice(OutputList &ol) ol.endParagraph(); } -void ClassDef::writeIncludeFiles(OutputList &ol) +void ClassDefImpl::writeIncludeFiles(OutputList &ol) const { if (m_impl->incInfo /*&& Config_getBool(SHOW_INCLUDE_FILES)*/) { @@ -1576,7 +2074,7 @@ void ClassDef::writeIncludeFiles(OutputList &ol) } #if 0 -void ClassDef::writeAllMembersLink(OutputList &ol) +void ClassDefImpl::writeAllMembersLink(OutputList &ol) { // write link to list of all members (HTML only) if (m_impl->allMemberNameInfoSDict && @@ -1596,7 +2094,7 @@ void ClassDef::writeAllMembersLink(OutputList &ol) } #endif -void ClassDef::writeMemberGroups(OutputList &ol,bool showInline) +void ClassDefImpl::writeMemberGroups(OutputList &ol,bool showInline) const { // write user defined member groups if (m_impl->memberGroupSDict) @@ -1619,7 +2117,7 @@ void ClassDef::writeMemberGroups(OutputList &ol,bool showInline) } } -void ClassDef::writeNestedClasses(OutputList &ol,const QCString &title) +void ClassDefImpl::writeNestedClasses(OutputList &ol,const QCString &title) const { // nested classes if (m_impl->innerClasses) @@ -1628,7 +2126,7 @@ void ClassDef::writeNestedClasses(OutputList &ol,const QCString &title) } } -void ClassDef::writeInlineClasses(OutputList &ol) +void ClassDefImpl::writeInlineClasses(OutputList &ol) const { if (m_impl->innerClasses) { @@ -1636,9 +2134,9 @@ void ClassDef::writeInlineClasses(OutputList &ol) } } -void ClassDef::startMemberDocumentation(OutputList &ol) +void ClassDefImpl::startMemberDocumentation(OutputList &ol) const { - //printf("%s: ClassDef::startMemberDocumentation()\n",name().data()); + //printf("%s: ClassDefImpl::startMemberDocumentation()\n",name().data()); if (Config_getBool(SEPARATE_MEMBER_PAGES)) { ol.disable(OutputGenerator::Html); @@ -1646,9 +2144,9 @@ void ClassDef::startMemberDocumentation(OutputList &ol) } } -void ClassDef::endMemberDocumentation(OutputList &ol) +void ClassDefImpl::endMemberDocumentation(OutputList &ol) const { - //printf("%s: ClassDef::endMemberDocumentation()\n",name().data()); + //printf("%s: ClassDefImpl::endMemberDocumentation()\n",name().data()); if (Config_getBool(SEPARATE_MEMBER_PAGES)) { ol.enable(OutputGenerator::Html); @@ -1656,15 +2154,15 @@ void ClassDef::endMemberDocumentation(OutputList &ol) } } -void ClassDef::startMemberDeclarations(OutputList &ol) +void ClassDefImpl::startMemberDeclarations(OutputList &ol) const { - //printf("%s: ClassDef::startMemberDeclarations()\n",name().data()); + //printf("%s: ClassDefImpl::startMemberDeclarations()\n",name().data()); ol.startMemberSections(); } -void ClassDef::endMemberDeclarations(OutputList &ol) +void ClassDefImpl::endMemberDeclarations(OutputList &ol) const { - //printf("%s: ClassDef::endMemberDeclarations()\n",name().data()); + //printf("%s: ClassDefImpl::endMemberDeclarations()\n",name().data()); static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); if (!inlineInheritedMembers && countAdditionalInheritedMembers()>0) { @@ -1676,7 +2174,7 @@ void ClassDef::endMemberDeclarations(OutputList &ol) ol.endMemberSections(); } -void ClassDef::writeAuthorSection(OutputList &ol) +void ClassDefImpl::writeAuthorSection(OutputList &ol) const { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Man); @@ -1689,7 +2187,7 @@ void ClassDef::writeAuthorSection(OutputList &ol) } -void ClassDef::writeSummaryLinks(OutputList &ol) +void ClassDefImpl::writeSummaryLinks(OutputList &ol) const { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -1748,7 +2246,7 @@ void ClassDef::writeSummaryLinks(OutputList &ol) ol.popGeneratorState(); } -void ClassDef::writeTagFile(FTextStream &tagFile) +void ClassDefImpl::writeTagFile(FTextStream &tagFile) { if (!isLinkableInProject()) return; tagFile << " <compound kind=\""; @@ -1867,12 +2365,12 @@ void ClassDef::writeTagFile(FTextStream &tagFile) } /** Write class documentation inside another container (i.e. a group) */ -void ClassDef::writeInlineDocumentation(OutputList &ol) +void ClassDefImpl::writeInlineDocumentation(OutputList &ol) const { bool isSimple = m_impl->isSimple; ol.addIndexItem(name(),0); - //printf("ClassDef::writeInlineDocumentation(%s)\n",name().data()); + //printf("ClassDefImpl::writeInlineDocumentation(%s)\n",name().data()); QListIterator<LayoutDocEntry> eli( LayoutDocManager::instance().docEntries(LayoutDocManager::Class)); LayoutDocEntry *lde; @@ -1984,7 +2482,7 @@ void ClassDef::writeInlineDocumentation(OutputList &ol) ol.popGeneratorState(); } -void ClassDef::writeMoreLink(OutputList &ol,const QCString &anchor) +void ClassDefImpl::writeMoreLink(OutputList &ol,const QCString &anchor) const { // TODO: clean up this mess by moving it to // the output generators... @@ -2028,7 +2526,7 @@ void ClassDef::writeMoreLink(OutputList &ol,const QCString &anchor) } } -bool ClassDef::visibleInParentsDeclList() const +bool ClassDefImpl::visibleInParentsDeclList() const { static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); static bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES); @@ -2040,7 +2538,7 @@ bool ClassDef::visibleInParentsDeclList() const ); } -void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *header,bool localNames) +void ClassDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const char *header,bool localNames) const { //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); @@ -2149,7 +2647,7 @@ void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *heade } } -void ClassDef::addClassAttributes(OutputList &ol) +void ClassDefImpl::addClassAttributes(OutputList &ol) const { QStrList sl; if (isFinal()) sl.append("final"); @@ -2174,7 +2672,7 @@ void ClassDef::addClassAttributes(OutputList &ol) ol.popGeneratorState(); } -void ClassDef::writeDocumentationContents(OutputList &ol,const QCString & /*pageTitle*/) +void ClassDefImpl::writeDocumentationContents(OutputList &ol,const QCString & /*pageTitle*/) const { ol.startContents(); @@ -2309,7 +2807,7 @@ void ClassDef::writeDocumentationContents(OutputList &ol,const QCString & /*page ol.endContents(); } -QCString ClassDef::title() const +QCString ClassDefImpl::title() const { QCString pageTitle; SrcLangExt lang = getLanguage(); @@ -2359,7 +2857,7 @@ QCString ClassDef::title() const } // write all documentation for this class -void ClassDef::writeDocumentation(OutputList &ol) +void ClassDefImpl::writeDocumentation(OutputList &ol) const { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); @@ -2417,7 +2915,7 @@ void ClassDef::writeDocumentation(OutputList &ol) } } -void ClassDef::writeMemberPages(OutputList &ol) +void ClassDefImpl::writeMemberPages(OutputList &ol) const { /////////////////////////////////////////////////////////////////////////// //// Member definitions on separate pages @@ -2430,8 +2928,7 @@ void ClassDef::writeMemberPages(OutputList &ol) MemberList *ml; for (mli.toFirst();(ml=mli.current());++mli) { - ml->countDocMembers(); - if (ml->numDocMembers()>0 && (ml->listType()&MemberListType_detailedLists)) + if (ml->numDocMembers()>ml->numDocEnumValues() && (ml->listType()&MemberListType_detailedLists)) { ml->writeDocumentationPage(ol,displayName(),this); } @@ -2440,7 +2937,7 @@ void ClassDef::writeMemberPages(OutputList &ol) ol.popGeneratorState(); } -void ClassDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const +void ClassDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const { static bool createSubDirs=Config_getBool(CREATE_SUBDIRS); @@ -2490,7 +2987,7 @@ void ClassDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const -void ClassDef::writeDocumentationForInnerClasses(OutputList &ol) +void ClassDefImpl::writeDocumentationForInnerClasses(OutputList &ol) const { // write inner classes after the parent, so the tag files contain // the definition in proper order! @@ -2515,7 +3012,7 @@ void ClassDef::writeDocumentationForInnerClasses(OutputList &ol) } // write the list of all (inherited) members for this class -void ClassDef::writeMemberList(OutputList &ol) +void ClassDefImpl::writeMemberList(OutputList &ol) const { static bool cOpt = Config_getBool(OPTIMIZE_OUTPUT_FOR_C); //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); @@ -2585,7 +3082,7 @@ void ClassDef::writeMemberList(OutputList &ol) for (;(mi=it.current());++it) { MemberDef *md=mi->memberDef; - ClassDef *cd=md->getClassDef(); + const ClassDef *cd=md->getClassDef(); Protection prot = mi->prot; Specifier virt=md->virtualness(); @@ -2798,9 +3295,8 @@ void ClassDef::writeMemberList(OutputList &ol) ol.popGeneratorState(); } - // add a reference to an example -bool ClassDef::addExample(const char *anchor,const char *nameStr, +bool ClassDefImpl::addExample(const char *anchor,const char *nameStr, const char *file) { if (m_impl->exampleSDict==0) @@ -2821,7 +3317,7 @@ bool ClassDef::addExample(const char *anchor,const char *nameStr, } // returns TRUE if this class is used in an example -bool ClassDef::hasExamples() const +bool ClassDefImpl::hasExamples() const { bool result=FALSE; if (m_impl->exampleSDict) @@ -2829,15 +3325,15 @@ bool ClassDef::hasExamples() const return result; } -void ClassDef::addTypeConstraint(const QCString &typeConstraint,const QCString &type) +void ClassDefImpl::addTypeConstraint(const QCString &typeConstraint,const QCString &type) { //printf("addTypeContraint(%s,%s)\n",type.data(),typeConstraint.data()); static bool hideUndocRelation = Config_getBool(HIDE_UNDOC_RELATIONS); if (typeConstraint.isEmpty() || type.isEmpty()) return; - ClassDef *cd = getResolvedClass(this,getFileDef(),typeConstraint); + ClassDef *cd = const_cast<ClassDef*>(getResolvedClass(this,getFileDef(),typeConstraint)); if (cd==0 && !hideUndocRelation) { - cd = new ClassDef(getDefFileName(),getDefLine(),getDefColumn(),typeConstraint,ClassDef::Class); + cd = new ClassDefImpl(getDefFileName(),getDefLine(),getDefColumn(),typeConstraint,ClassDef::Class); cd->setUsedOnly(TRUE); cd->setLanguage(getLanguage()); Doxygen::hiddenClasses->append(typeConstraint,cd); @@ -2864,7 +3360,7 @@ void ClassDef::addTypeConstraint(const QCString &typeConstraint,const QCString & } // Java Type Constrains: A<T extends C & I> -void ClassDef::addTypeConstraints() +void ClassDefImpl::addTypeConstraints() { if (m_impl->tempArgs) { @@ -2890,7 +3386,7 @@ void ClassDef::addTypeConstraints() } // C# Type Constraints: D<T> where T : C, I -void ClassDef::setTypeConstraints(ArgumentList *al) +void ClassDefImpl::setTypeConstraints(ArgumentList *al) { if (al==0) return; if (!m_impl->typeConstraints) delete m_impl->typeConstraints; @@ -2903,7 +3399,7 @@ void ClassDef::setTypeConstraints(ArgumentList *al) } } -void ClassDef::setTemplateArguments(ArgumentList *al) +void ClassDefImpl::setTemplateArguments(ArgumentList *al) { if (al==0) return; if (m_impl->tempArgs) delete m_impl->tempArgs; // delete old list if needed @@ -2920,7 +3416,7 @@ void ClassDef::setTemplateArguments(ArgumentList *al) /*! Returns \c TRUE iff this class or a class inheriting from this class * is \e not defined in an external tag file. */ -bool ClassDef::hasNonReferenceSuperClass() +bool ClassDefImpl::hasNonReferenceSuperClass() const { bool found=!isReference() && isLinkableInProject() && !isHidden(); if (found) @@ -2957,10 +3453,10 @@ bool ClassDef::hasNonReferenceSuperClass() /*! called from MemberDef::writeDeclaration() to (recursively) write the * definition of an anonymous struct, union or class. */ -void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup, - ClassDef *inheritedFrom,const char *inheritId) +void ClassDefImpl::writeDeclaration(OutputList &ol,const MemberDef *md,bool inGroup, + const ClassDef *inheritedFrom,const char *inheritId) const { - //printf("ClassName=`%s' inGroup=%d\n",name().data(),inGroup); + //printf("ClassName='%s' inGroup=%d\n",name().data(),inGroup); ol.docify(compoundTypeString()); QCString cn = displayName(FALSE); @@ -3007,7 +3503,7 @@ void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup, } /*! a link to this class is possible within this project */ -bool ClassDef::isLinkableInProject() const +bool ClassDefImpl::isLinkableInProject() const { static bool extractLocal = Config_getBool(EXTRACT_LOCAL_CLASSES); static bool extractStatic = Config_getBool(EXTRACT_STATIC); @@ -3029,7 +3525,7 @@ bool ClassDef::isLinkableInProject() const } } -bool ClassDef::isLinkable() const +bool ClassDefImpl::isLinkable() const { if (m_impl->templateMaster) { @@ -3043,7 +3539,7 @@ bool ClassDef::isLinkable() const /*! the class is visible in a class diagram, or class hierarchy */ -bool ClassDef::isVisibleInHierarchy() +bool ClassDefImpl::isVisibleInHierarchy() const { static bool allExternals = Config_getBool(ALLEXTERNALS); static bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES); @@ -3067,17 +3563,17 @@ bool ClassDef::isVisibleInHierarchy() (!m_impl->isStatic || extractStatic); } -bool ClassDef::hasDocumentation() const +bool ClassDefImpl::hasDocumentation() const { - return Definition::hasDocumentation(); + return DefinitionImpl::hasDocumentation(); } //---------------------------------------------------------------------- // recursive function: -// returns TRUE iff class definition `bcd' represents an (in)direct base -// class of class definition `cd'. +// returns TRUE iff class definition 'bcd' represents an (in)direct base +// class of class definition 'cd'. -bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances,int level) +bool ClassDefImpl::isBaseClass(const ClassDef *bcd, bool followInstances,int level) const { bool found=FALSE; //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data()); @@ -3093,7 +3589,7 @@ bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances,int level) BaseClassListIterator bcli(*baseClasses()); for ( ; bcli.current() && !found ; ++bcli) { - ClassDef *ccd=bcli.current()->classDef; + const ClassDef *ccd=bcli.current()->classDef; if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster(); //printf("isBaseClass() baseclass %s\n",ccd->name().data()); if (ccd==bcd) @@ -3107,7 +3603,7 @@ bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances,int level) //---------------------------------------------------------------------- -bool ClassDef::isSubClass(ClassDef *cd,int level) +bool ClassDefImpl::isSubClass(ClassDef *cd,int level) const { bool found=FALSE; if (level>256) @@ -3140,11 +3636,11 @@ static bool isStandardFunc(MemberDef *md) } /*! - * recursively merges the `all members' lists of a class base + * recursively merges the 'all members' lists of a class base * with that of this class. Must only be called for classes without * subclasses! */ -void ClassDef::mergeMembers() +void ClassDefImpl::mergeMembers() { if (m_impl->membersMerged) return; @@ -3156,7 +3652,8 @@ void ClassDef::mergeMembers() m_impl->membersMerged=TRUE; //printf(" mergeMembers for %s\n",name().data()); - bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); + static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB); + static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); if (baseClasses()) { //printf(" => has base classes!\n"); @@ -3196,19 +3693,19 @@ void ClassDef::mergeMembers() bool hidden=FALSE; MemberNameInfoIterator dstMnii(*dstMni); MemberInfo *dstMi; - ClassDef *srcCd = srcMd->getClassDef(); + const ClassDef *srcCd = srcMd->getClassDef(); for ( ; (dstMi=dstMnii.current()) && !found; ++dstMnii ) { MemberDef *dstMd = dstMi->memberDef; if (srcMd!=dstMd) // different members { - ClassDef *dstCd = dstMd->getClassDef(); + 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(); + const ArgumentList *srcAl = srcMd->argumentList(); + const ArgumentList *dstAl = dstMd->argumentList(); found=matchArguments2( srcMd->getOuterScope(),srcMd->getFileDef(),srcAl, dstMd->getOuterScope(),dstMd->getFileDef(),dstAl, @@ -3284,7 +3781,7 @@ void ClassDef::mergeMembers() { if (!isStandardFunc(srcMd)) { - //printf(" insertMember `%s'\n",srcMd->name().data()); + //printf(" insertMember '%s'\n",srcMd->name().data()); internalInsertMember(srcMd,prot,FALSE); } } @@ -3352,7 +3849,7 @@ void ClassDef::mergeMembers() // name().data(),mi->memberDef->name().data(),mi->prot, // bcd->prot,prot); - if (mi->prot!=Private) + if (prot!=Private || extractPrivate) { Specifier virt=mi->virt; if (mi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt; @@ -3361,7 +3858,7 @@ void ClassDef::mergeMembers() { if (!isStandardFunc(mi->memberDef)) { - //printf(" insertMember `%s'\n",mi->memberDef->name().data()); + //printf(" insertMember '%s'\n",mi->memberDef->name().data()); internalInsertMember(mi->memberDef,prot,FALSE); } } @@ -3395,7 +3892,7 @@ void ClassDef::mergeMembers() /*! Merges the members of a Objective-C category into this class. */ -void ClassDef::mergeCategory(ClassDef *category) +void ClassDefImpl::mergeCategory(ClassDef *category) { static bool extractLocalMethods = Config_getBool(EXTRACT_LOCAL_METHODS); bool makePrivate = category->isLocal(); @@ -3533,7 +4030,7 @@ void ClassDef::mergeCategory(ClassDef *category) //---------------------------------------------------------------------------- -void ClassDef::addUsedClass(ClassDef *cd,const char *accessName, +void ClassDefImpl::addUsedClass(ClassDef *cd,const char *accessName, Protection prot) { static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); @@ -3567,7 +4064,7 @@ void ClassDef::addUsedClass(ClassDef *cd,const char *accessName, ucd->addAccessor(acc); } -void ClassDef::addUsedByClass(ClassDef *cd,const char *accessName, +void ClassDefImpl::addUsedByClass(ClassDef *cd,const char *accessName, Protection prot) { static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); @@ -3608,7 +4105,7 @@ void ClassDef::addUsedByClass(ClassDef *cd,const char *accessName, * Must be called before mergeMembers() is called! */ -void ClassDef::determineImplUsageRelation() +void ClassDefImpl::determineImplUsageRelation() { MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict); MemberNameInfo *mni; @@ -3622,7 +4119,7 @@ void ClassDef::determineImplUsageRelation() if (md->isVariable()) // for each member variable in this class { QCString type=removeRedundantWhiteSpace(md->typeString()); - //printf("in class %s found var type=`%s' name=`%s'\n", + //printf("in class %s found var type='%s' name='%s'\n", // name().data(),type.data(),md->name().data()); int pos=0; QCString usedClassName; @@ -3630,7 +4127,7 @@ void ClassDef::determineImplUsageRelation() bool found=FALSE; while (extractClassNameFromType(type,pos,usedClassName,templSpec)!=-1 && !found) { - //printf("usedClassName=`%s' templSpec=%s\n",usedClassName.data(),templSpec.data()); + //printf("usedClassName='%s' templSpec=%s\n",usedClassName.data(),templSpec.data()); // check if usedClassName is a template argument of its class ClassDef *cd=md->getClassDef(); if (cd && cd->templateArguments()) @@ -3722,7 +4219,7 @@ void ClassDef::determineImplUsageRelation() // I have disabled this code because the graphs it renders quickly become // too large to be of practical use. -void ClassDef::addUsedInterfaceClasses(MemberDef *md,const char *typeStr) +void ClassDefImpl::addUsedInterfaceClasses(MemberDef *md,const char *typeStr) { QCString type = typeStr; static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*"); @@ -3742,18 +4239,18 @@ void ClassDef::addUsedInterfaceClasses(MemberDef *md,const char *typeStr) { ucd = new UsesClassDef(cd); m_impl->usesIntfClassDict->insert(cd->name(),ucd); - //printf("in class `%s' adding used intf class `%s'\n", + //printf("in class '%s' adding used intf class '%s'\n", // name().data(),cd->name().data()); } ucd->addAccessor(md->name()); - //printf("in class `%s' adding accessor `%s' to class `%s'\n", + //printf("in class '%s' adding accessor '%s' to class '%s'\n", // name().data(),md->name().data(),ucd->classDef->name().data()); } p=i+l; } } -void ClassDef::determineIntfUsageRelation() +void ClassDefImpl::determineIntfUsageRelation() { MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoList); MemberNameInfo *mni; @@ -3799,7 +4296,7 @@ void ClassDef::determineIntfUsageRelation() } #endif -QCString ClassDef::compoundTypeString() const +QCString ClassDefImpl::compoundTypeString() const { if (getLanguage()==SrcLangExt_Fortran) { @@ -3833,7 +4330,7 @@ QCString ClassDef::compoundTypeString() const } } -QCString ClassDef::getOutputFileBase() const +QCString ClassDefImpl::getOutputFileBase() const { static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS); @@ -3870,12 +4367,12 @@ QCString ClassDef::getOutputFileBase() const return m_impl->fileName; } -QCString ClassDef::getInstanceOutputFileBase() const +QCString ClassDefImpl::getInstanceOutputFileBase() const { return m_impl->fileName; } -QCString ClassDef::getSourceFileBase() const +QCString ClassDefImpl::getSourceFileBase() const { if (m_impl->templateMaster) { @@ -3883,14 +4380,14 @@ QCString ClassDef::getSourceFileBase() const } else { - return Definition::getSourceFileBase(); + return DefinitionImpl::getSourceFileBase(); } } -void ClassDef::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs) +void ClassDefImpl::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs) { gd->addClass(this); - //printf("ClassDef::setGroupDefForAllMembers(%s)\n",gd->name().data()); + //printf("ClassDefImpl::setGroupDefForAllMembers(%s)\n",gd->name().data()); if (m_impl->allMemberNameInfoSDict==0) return; MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict); MemberNameInfo *mni; @@ -3909,7 +4406,7 @@ void ClassDef::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,co } } -void ClassDef::addInnerCompound(Definition *d) +void ClassDefImpl::addInnerCompound(const Definition *d) { //printf("**** %s::addInnerCompound(%s)\n",name().data(),d->name().data()); if (d->definitionType()==Definition::TypeClass) // only classes can be @@ -3919,11 +4416,11 @@ void ClassDef::addInnerCompound(Definition *d) { m_impl->innerClasses = new ClassSDict(17); } - m_impl->innerClasses->inSort(d->localName(),(ClassDef *)d); + m_impl->innerClasses->inSort(d->localName(),dynamic_cast<const ClassDef *>(d)); } } -Definition *ClassDef::findInnerCompound(const char *name) const +Definition *ClassDefImpl::findInnerCompound(const char *name) const { Definition *result=0; if (name==0) return 0; @@ -3934,7 +4431,7 @@ Definition *ClassDef::findInnerCompound(const char *name) const return result; } -//void ClassDef::initTemplateMapping() +//void ClassDefImpl::initTemplateMapping() //{ // m_impl->templateMapping->clear(); // ArgumentList *al = templateArguments(); @@ -3948,9 +4445,9 @@ Definition *ClassDef::findInnerCompound(const char *name) const // } // } //} -//void ClassDef::setTemplateArgumentMapping(const char *formal,const char *actual) +//void ClassDefImpl::setTemplateArgumentMapping(const char *formal,const char *actual) //{ -// //printf("ClassDef::setTemplateArgumentMapping(%s,%s)\n",formal,actual); +// //printf("ClassDefImpl::setTemplateArgumentMapping(%s,%s)\n",formal,actual); // if (m_impl->templateMapping && formal) // { // if (m_impl->templateMapping->find(formal)) @@ -3961,7 +4458,7 @@ Definition *ClassDef::findInnerCompound(const char *name) const // } //} // -//QCString ClassDef::getTemplateArgumentMapping(const char *formal) const +//QCString ClassDefImpl::getTemplateArgumentMapping(const char *formal) const //{ // if (m_impl->templateMapping && formal) // { @@ -3974,8 +4471,8 @@ Definition *ClassDef::findInnerCompound(const char *name) const // return ""; //} -ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName, - int startLine, int startColumn, const QCString &templSpec,bool &freshInstance) +ClassDef *ClassDefImpl::insertTemplateInstance(const QCString &fileName, + int startLine, int startColumn, const QCString &templSpec,bool &freshInstance) const { freshInstance = FALSE; if (m_impl->templateInstances==0) @@ -3985,9 +4482,9 @@ ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName, ClassDef *templateClass=m_impl->templateInstances->find(templSpec); if (templateClass==0) { - Debug::print(Debug::Classes,0," New template instance class `%s'`%s'\n",qPrint(name()),qPrint(templSpec)); + Debug::print(Debug::Classes,0," New template instance class '%s''%s'\n",qPrint(name()),qPrint(templSpec)); QCString tcname = removeRedundantWhiteSpace(localName()+templSpec); - templateClass = new ClassDef( + templateClass = new ClassDefImpl( fileName,startLine,startColumn,tcname,ClassDef::Class); templateClass->setTemplateMaster(this); templateClass->setOuterScope(getOuterScope()); @@ -3998,7 +4495,7 @@ ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName, return templateClass; } -ClassDef *ClassDef::getVariableInstance(const char *templSpec) +ClassDef *ClassDefImpl::getVariableInstance(const char *templSpec) const { if (m_impl->variableInstances==0) { @@ -4008,9 +4505,9 @@ ClassDef *ClassDef::getVariableInstance(const char *templSpec) ClassDef *templateClass=m_impl->variableInstances->find(templSpec); if (templateClass==0) { - Debug::print(Debug::Classes,0," New template variable instance class `%s'`%s'\n",qPrint(name()),qPrint(templSpec)); + Debug::print(Debug::Classes,0," New template variable instance class '%s' '%s'\n",qPrint(name()),qPrint(templSpec)); QCString tcname = removeRedundantWhiteSpace(name()+templSpec); - templateClass = new ClassDef("<code>",1,1,tcname, + templateClass = new ClassDefImpl("<code>",1,1,tcname, ClassDef::Class,0,0,FALSE); templateClass->addMembersToTemplateInstance( this, templSpec ); templateClass->setTemplateMaster(this); @@ -4019,7 +4516,7 @@ ClassDef *ClassDef::getVariableInstance(const char *templSpec) return templateClass; } -void ClassDef::setTemplateBaseClassNames(QDict<int> *templateNames) +void ClassDefImpl::setTemplateBaseClassNames(QDict<int> *templateNames) { if (templateNames==0) return; if (m_impl->templBaseClassNames==0) @@ -4038,12 +4535,12 @@ void ClassDef::setTemplateBaseClassNames(QDict<int> *templateNames) } } -QDict<int> *ClassDef::getTemplateBaseClassNames() const +QDict<int> *ClassDefImpl::getTemplateBaseClassNames() const { return m_impl->templBaseClassNames; } -void ClassDef::addMembersToTemplateInstance(ClassDef *cd,const char *templSpec) +void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const char *templSpec) { //printf("%s::addMembersToTemplateInstance(%s,%s)\n",name().data(),cd->name().data(),templSpec); if (cd->memberNameInfoSDict()==0) return; @@ -4086,7 +4583,7 @@ void ClassDef::addMembersToTemplateInstance(ClassDef *cd,const char *templSpec) } } -QCString ClassDef::getReference() const +QCString ClassDefImpl::getReference() const { if (m_impl->templateMaster) { @@ -4094,11 +4591,11 @@ QCString ClassDef::getReference() const } else { - return Definition::getReference(); + return DefinitionImpl::getReference(); } } -bool ClassDef::isReference() const +bool ClassDefImpl::isReference() const { if (m_impl->templateMaster) { @@ -4106,18 +4603,18 @@ bool ClassDef::isReference() const } else { - return Definition::isReference(); + return DefinitionImpl::isReference(); } } -void ClassDef::getTemplateParameterLists(QList<ArgumentList> &lists) const +void ClassDefImpl::getTemplateParameterLists(QList<ArgumentList> &lists) const { Definition *d=getOuterScope(); if (d) { if (d->definitionType()==Definition::TypeClass) { - ClassDef *cd=(ClassDef *)d; + ClassDef *cd=dynamic_cast<ClassDef *>(d); cd->getTemplateParameterLists(lists); } } @@ -4127,7 +4624,7 @@ void ClassDef::getTemplateParameterLists(QList<ArgumentList> &lists) const } } -QCString ClassDef::qualifiedNameWithTemplateParameters( +QCString ClassDefImpl::qualifiedNameWithTemplateParameters( QList<ArgumentList> *actualParams,int *actualParamIndex) const { //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); @@ -4139,7 +4636,7 @@ QCString ClassDef::qualifiedNameWithTemplateParameters( { if (d->definitionType()==Definition::TypeClass) { - ClassDef *cd=(ClassDef *)d; + ClassDef *cd=dynamic_cast<ClassDef *>(d); scName = cd->qualifiedNameWithTemplateParameters(actualParams,actualParamIndex); } else if (!hideScopeNames) @@ -4186,7 +4683,7 @@ QCString ClassDef::qualifiedNameWithTemplateParameters( return scName; } -QCString ClassDef::className() const +QCString ClassDefImpl::className() const { if (m_impl->className.isEmpty()) { @@ -4198,12 +4695,12 @@ QCString ClassDef::className() const } }; -void ClassDef::setClassName(const char *name) +void ClassDefImpl::setClassName(const char *name) { m_impl->className = name; } -void ClassDef::addListReferences() +void ClassDefImpl::addListReferences() { SrcLangExt lang = getLanguage(); if (!isLinkableInProject()) return; @@ -4240,7 +4737,7 @@ void ClassDef::addListReferences() } } -MemberDef *ClassDef::getMemberByName(const QCString &name) const +MemberDef *ClassDefImpl::getMemberByName(const QCString &name) const { MemberDef *xmd = 0; if (m_impl->allMemberNameInfoSDict) @@ -4254,7 +4751,7 @@ MemberDef *ClassDef::getMemberByName(const QCString &name) const MemberInfo *mi; for (mnii.toFirst();(mi=mnii.current());++mnii) { - ClassDef *mcd=mi->memberDef->getClassDef(); + const ClassDef *mcd=mi->memberDef->getClassDef(); int m=minClassDistance(this,mcd); //printf("found member in %s linkable=%d m=%d\n", // mcd->name().data(),mcd->isLinkable(),m); @@ -4270,12 +4767,12 @@ MemberDef *ClassDef::getMemberByName(const QCString &name) const return xmd; } -bool ClassDef::isAccessibleMember(MemberDef *md) +bool ClassDefImpl::isAccessibleMember(const MemberDef *md) const { return md->getClassDef() && isBaseClass(md->getClassDef(),TRUE); } -MemberList *ClassDef::createMemberList(MemberListType lt) +MemberList *ClassDefImpl::createMemberList(MemberListType lt) { m_impl->memberLists.setAutoDelete(TRUE); QListIterator<MemberList> mli(m_impl->memberLists); @@ -4293,7 +4790,7 @@ MemberList *ClassDef::createMemberList(MemberListType lt) return ml; } -MemberList *ClassDef::getMemberList(MemberListType lt) +MemberList *ClassDefImpl::getMemberList(MemberListType lt) const { QListIterator<MemberList> mli(m_impl->memberLists); MemberList *ml; @@ -4307,7 +4804,7 @@ MemberList *ClassDef::getMemberList(MemberListType lt) return 0; } -void ClassDef::addMemberToList(MemberListType lt,MemberDef *md,bool isBrief) +void ClassDefImpl::addMemberToList(MemberListType lt,MemberDef *md,bool isBrief) { static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); @@ -4319,7 +4816,7 @@ void ClassDef::addMemberToList(MemberListType lt,MemberDef *md,bool isBrief) if ((ml->listType()&MemberListType_detailedLists)==0) md->setSectionList(this,ml); } -void ClassDef::sortMemberLists() +void ClassDefImpl::sortMemberLists() { QListIterator<MemberList> mli(m_impl->memberLists); MemberList *ml; @@ -4333,8 +4830,8 @@ void ClassDef::sortMemberLists() } } -int ClassDef::countMemberDeclarations(MemberListType lt,ClassDef *inheritedFrom, - int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) +int ClassDefImpl::countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom, + int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const { //printf("%s: countMemberDeclarations for %d and %d\n",name().data(),lt,lt2); int count=0; @@ -4344,13 +4841,11 @@ int ClassDef::countMemberDeclarations(MemberListType lt,ClassDef *inheritedFrom, { if (ml) { - ml->countDecMembers(); count+=ml->numDecMembers(); //printf("-> ml=%d\n",ml->numDecMembers()); } if (ml2) { - ml2->countDecMembers(); count+=ml2->numDecMembers(); //printf("-> ml2=%d\n",ml2->numDecMembers()); } @@ -4375,10 +4870,61 @@ int ClassDef::countMemberDeclarations(MemberListType lt,ClassDef *inheritedFrom, return count; } +void ClassDefImpl::setAnonymousEnumType() +{ + QListIterator<LayoutDocEntry> eli( + LayoutDocManager::instance().docEntries(LayoutDocManager::Class)); + LayoutDocEntry *lde; + for (eli.toFirst();(lde=eli.current());++eli) + { + if (lde->kind()==LayoutDocEntry::MemberDecl) + { + LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde; + MemberList * ml = getMemberList(lmd->type); + if (ml) + { + ml->setAnonymousEnumType(); + } + } + else if (lde->kind()==LayoutDocEntry::MemberGroups) + { + if (m_impl->memberGroupSDict) + { + MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + mg->setAnonymousEnumType(); + } + } + } + } +} + +void ClassDefImpl::countMembers() +{ + QListIterator<MemberList> mli(m_impl->memberLists); + MemberList *ml; + for (mli.toFirst();(ml=mli.current());++mli) + { + ml->countDecMembers(); + ml->countDocMembers(); + } + if (m_impl->memberGroupSDict) + { + MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + mg->countDecMembers(); + mg->countDocMembers(); + } + } +} -int ClassDef::countInheritedDecMembers(MemberListType lt, - ClassDef *inheritedFrom,bool invert,bool showAlways, - QPtrDict<void> *visitedClasses) +int ClassDefImpl::countInheritedDecMembers(MemberListType lt, + const ClassDef *inheritedFrom,bool invert,bool showAlways, + QPtrDict<void> *visitedClasses) const { int inhCount = 0; int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE); @@ -4415,8 +4961,8 @@ int ClassDef::countInheritedDecMembers(MemberListType lt, return inhCount; } -void ClassDef::getTitleForMemberListType(MemberListType type, - QCString &title,QCString &subtitle) +void ClassDefImpl::getTitleForMemberListType(MemberListType type, + QCString &title,QCString &subtitle) const { SrcLangExt lang = getLanguage(); QListIterator<LayoutDocEntry> eli( @@ -4439,7 +4985,7 @@ void ClassDef::getTitleForMemberListType(MemberListType type, subtitle=""; } -int ClassDef::countAdditionalInheritedMembers() +int ClassDefImpl::countAdditionalInheritedMembers() const { int totalCount=0; QListIterator<LayoutDocEntry> eli( @@ -4465,7 +5011,7 @@ int ClassDef::countAdditionalInheritedMembers() return totalCount; } -void ClassDef::writeAdditionalInheritedMembers(OutputList &ol) +void ClassDefImpl::writeAdditionalInheritedMembers(OutputList &ol) const { //printf("**** writeAdditionalInheritedMembers()\n"); QListIterator<LayoutDocEntry> eli( @@ -4485,8 +5031,8 @@ void ClassDef::writeAdditionalInheritedMembers(OutputList &ol) } } -int ClassDef::countMembersIncludingGrouped(MemberListType lt, - ClassDef *inheritedFrom,bool additional) +int ClassDefImpl::countMembersIncludingGrouped(MemberListType lt, + const ClassDef *inheritedFrom,bool additional) const { int count=0; MemberList *ml = getMemberList(lt); @@ -4514,10 +5060,11 @@ int ClassDef::countMembersIncludingGrouped(MemberListType lt, return count; } -void ClassDef::writeInheritedMemberDeclarations(OutputList &ol, + +void ClassDefImpl::writeInheritedMemberDeclarations(OutputList &ol, MemberListType lt,int lt2,const QCString &title, - ClassDef *inheritedFrom,bool invert,bool showAlways, - QPtrDict<void> *visitedClasses) + const ClassDef *inheritedFrom,bool invert,bool showAlways, + QPtrDict<void> *visitedClasses) const { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -4563,16 +5110,16 @@ void ClassDef::writeInheritedMemberDeclarations(OutputList &ol, ol.popGeneratorState(); } -void ClassDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title, - const char *subTitle,bool showInline,ClassDef *inheritedFrom,int lt2, - bool invert,bool showAlways,QPtrDict<void> *visitedClasses) +void ClassDefImpl::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title, + const char *subTitle,bool showInline,const ClassDef *inheritedFrom,int lt2, + bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const { - //printf("%s: ClassDef::writeMemberDeclarations lt=%d lt2=%d\n",name().data(),lt,lt2); + //printf("%s: ClassDefImpl::writeMemberDeclarations lt=%d lt2=%d\n",name().data(),lt,lt2); MemberList * ml = getMemberList(lt); MemberList * ml2 = getMemberList((MemberListType)lt2); if (getLanguage()==SrcLangExt_VHDL) // use specific declarations function { - static ClassDef *cdef; + static const ClassDef *cdef; if (cdef!=this) { // only one inline link VhdlDocGen::writeInlineClassLink(this,ol); @@ -4611,8 +5158,8 @@ void ClassDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QC } } -void ClassDef::addGroupedInheritedMembers(OutputList &ol,MemberListType lt, - ClassDef *inheritedFrom,const QCString &inheritId) +void ClassDefImpl::addGroupedInheritedMembers(OutputList &ol,MemberListType lt, + const ClassDef *inheritedFrom,const QCString &inheritId) const { //printf("** %s::addGroupedInheritedMembers(%p) inheritId=%s\n",name().data(),m_impl->memberGroupSDict,inheritId.data()); if (m_impl->memberGroupSDict) @@ -4629,25 +5176,25 @@ void ClassDef::addGroupedInheritedMembers(OutputList &ol,MemberListType lt, } } -void ClassDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title,bool showInline) +void ClassDefImpl::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title,bool showInline) const { - //printf("%s: ClassDef::writeMemberDocumentation()\n",name().data()); + //printf("%s: ClassDefImpl::writeMemberDocumentation()\n",name().data()); MemberList * ml = getMemberList(lt); if (ml) ml->writeDocumentation(ol,displayName(),this,title,FALSE,showInline); } -void ClassDef::writeSimpleMemberDocumentation(OutputList &ol,MemberListType lt) +void ClassDefImpl::writeSimpleMemberDocumentation(OutputList &ol,MemberListType lt) const { - //printf("%s: ClassDef::writeSimpleMemberDocumentation()\n",name().data()); + //printf("%s: ClassDefImpl::writeSimpleMemberDocumentation()\n",name().data()); MemberList * ml = getMemberList(lt); if (ml) ml->writeSimpleDocumentation(ol,this); } -void ClassDef::writePlainMemberDeclaration(OutputList &ol, +void ClassDefImpl::writePlainMemberDeclaration(OutputList &ol, MemberListType lt,bool inGroup, - ClassDef *inheritedFrom,const char *inheritId) + const ClassDef *inheritedFrom,const char *inheritId) const { - //printf("%s: ClassDef::writePlainMemberDeclaration()\n",name().data()); + //printf("%s: ClassDefImpl::writePlainMemberDeclaration()\n",name().data()); MemberList * ml = getMemberList(lt); if (ml) { @@ -4656,222 +5203,227 @@ void ClassDef::writePlainMemberDeclaration(OutputList &ol, } } -bool ClassDef::isLocal() const +bool ClassDefImpl::isLocal() const { return m_impl->isLocal; } -ClassSDict *ClassDef::getClassSDict() const +ClassSDict *ClassDefImpl::getClassSDict() const { return m_impl->innerClasses; } -ClassDef::CompoundType ClassDef::compoundType() const +ClassDefImpl::CompoundType ClassDefImpl::compoundType() const { return m_impl->compType; } -BaseClassList *ClassDef::baseClasses() const +BaseClassList *ClassDefImpl::baseClasses() const { return m_impl->inherits; } -BaseClassList *ClassDef::subClasses() const +BaseClassList *ClassDefImpl::subClasses() const { return m_impl->inheritedBy; } -MemberNameInfoSDict *ClassDef::memberNameInfoSDict() const +MemberNameInfoSDict *ClassDefImpl::memberNameInfoSDict() const { return m_impl->allMemberNameInfoSDict; } -Protection ClassDef::protection() const +Protection ClassDefImpl::protection() const { return m_impl->prot; } -ArgumentList *ClassDef::templateArguments() const +ArgumentList *ClassDefImpl::templateArguments() const { return m_impl->tempArgs; } -NamespaceDef *ClassDef::getNamespaceDef() const +NamespaceDef *ClassDefImpl::getNamespaceDef() const { return m_impl->nspace; } -FileDef *ClassDef::getFileDef() const +FileDef *ClassDefImpl::getFileDef() const { return m_impl->fileDef; } -QDict<ClassDef> *ClassDef::getTemplateInstances() const +QDict<ClassDef> *ClassDefImpl::getTemplateInstances() const { return m_impl->templateInstances; } -ClassDef *ClassDef::templateMaster() const +const ClassDef *ClassDefImpl::templateMaster() const { return m_impl->templateMaster; } -bool ClassDef::isTemplate() const +bool ClassDefImpl::isTemplate() const { return m_impl->tempArgs!=0; } -IncludeInfo *ClassDef::includeInfo() const +IncludeInfo *ClassDefImpl::includeInfo() const { return m_impl->incInfo; } -UsesClassDict *ClassDef::usedImplementationClasses() const +UsesClassDict *ClassDefImpl::usedImplementationClasses() const { return m_impl->usesImplClassDict; } -UsesClassDict *ClassDef::usedByImplementationClasses() const +UsesClassDict *ClassDefImpl::usedByImplementationClasses() const { return m_impl->usedByImplClassDict; } -UsesClassDict *ClassDef::usedInterfaceClasses() const +UsesClassDict *ClassDefImpl::usedInterfaceClasses() const { return m_impl->usesIntfClassDict; } -ConstraintClassDict *ClassDef::templateTypeConstraints() const +ConstraintClassDict *ClassDefImpl::templateTypeConstraints() const { return m_impl->constraintClassDict; } -bool ClassDef::isTemplateArgument() const +bool ClassDefImpl::isTemplateArgument() const { return m_impl->isTemplArg; } -bool ClassDef::isAbstract() const +bool ClassDefImpl::isAbstract() const { return m_impl->isAbstract || (m_impl->spec&Entry::Abstract); } -bool ClassDef::isFinal() const +bool ClassDefImpl::isFinal() const { return m_impl->spec&Entry::Final; } -bool ClassDef::isSealed() const +bool ClassDefImpl::isSealed() const { return m_impl->spec&Entry::Sealed; } -bool ClassDef::isPublished() const +bool ClassDefImpl::isPublished() const { return m_impl->spec&Entry::Published; } -bool ClassDef::isForwardDeclared() const +bool ClassDefImpl::isForwardDeclared() const { return m_impl->spec&Entry::ForwardDecl; } -bool ClassDef::isObjectiveC() const +bool ClassDefImpl::isInterface() const +{ + return m_impl->spec&Entry::Interface; +} + +bool ClassDefImpl::isObjectiveC() const { return getLanguage()==SrcLangExt_ObjC; } -bool ClassDef::isFortran() const +bool ClassDefImpl::isFortran() const { return getLanguage()==SrcLangExt_Fortran; } -bool ClassDef::isCSharp() const +bool ClassDefImpl::isCSharp() const { return getLanguage()==SrcLangExt_CSharp; } -ClassDef *ClassDef::categoryOf() const +ClassDef *ClassDefImpl::categoryOf() const { return m_impl->categoryOf; } -const QList<MemberList> &ClassDef::getMemberLists() const +const QList<MemberList> &ClassDefImpl::getMemberLists() const { return m_impl->memberLists; } -MemberGroupSDict *ClassDef::getMemberGroupSDict() const +MemberGroupSDict *ClassDefImpl::getMemberGroupSDict() const { return m_impl->memberGroupSDict; } -void ClassDef::setNamespace(NamespaceDef *nd) +void ClassDefImpl::setNamespace(NamespaceDef *nd) { m_impl->nspace = nd; } -void ClassDef::setFileDef(FileDef *fd) +void ClassDefImpl::setFileDef(FileDef *fd) { m_impl->fileDef=fd; } -void ClassDef::setSubGrouping(bool enabled) +void ClassDefImpl::setSubGrouping(bool enabled) { m_impl->subGrouping = enabled; } -void ClassDef::setProtection(Protection p) +void ClassDefImpl::setProtection(Protection p) { m_impl->prot=p; } -void ClassDef::setIsStatic(bool b) +void ClassDefImpl::setIsStatic(bool b) { m_impl->isStatic=b; } -void ClassDef::setCompoundType(CompoundType t) +void ClassDefImpl::setCompoundType(CompoundType t) { m_impl->compType = t; } -void ClassDef::setTemplateMaster(ClassDef *tm) +void ClassDefImpl::setTemplateMaster(const ClassDef *tm) { m_impl->templateMaster=tm; } -void ClassDef::makeTemplateArgument(bool b) +void ClassDefImpl::makeTemplateArgument(bool b) { m_impl->isTemplArg = b; } -void ClassDef::setCategoryOf(ClassDef *cd) +void ClassDefImpl::setCategoryOf(ClassDef *cd) { m_impl->categoryOf = cd; } -void ClassDef::setUsedOnly(bool b) +void ClassDefImpl::setUsedOnly(bool b) { m_impl->usedOnly = b; } -bool ClassDef::isUsedOnly() const +bool ClassDefImpl::isUsedOnly() const { return m_impl->usedOnly; } -bool ClassDef::isSimple() const +bool ClassDefImpl::isSimple() const { return m_impl->isSimple; } -MemberDef *ClassDef::isSmartPointer() const +MemberDef *ClassDefImpl::isSmartPointer() const { return m_impl->arrowOperator; } -void ClassDef::reclassifyMember(MemberDef *md,MemberType t) +void ClassDefImpl::reclassifyMember(MemberDef *md,MemberType t) { md->setMemberType(t); QListIterator<MemberList> mli(m_impl->memberLists); @@ -4883,7 +5435,7 @@ void ClassDef::reclassifyMember(MemberDef *md,MemberType t) insertMember(md); } -QCString ClassDef::anchor() const +QCString ClassDefImpl::anchor() const { QCString anc; if (isEmbeddedInOuterScope() && !Doxygen::generatingXmlOutput) @@ -4901,7 +5453,7 @@ QCString ClassDef::anchor() const return anc; } -bool ClassDef::isEmbeddedInOuterScope() const +bool ClassDefImpl::isEmbeddedInOuterScope() const { static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS); @@ -4931,12 +5483,12 @@ bool ClassDef::isEmbeddedInOuterScope() const return b1 || b2; // either reason will do } -const ClassList *ClassDef::taggedInnerClasses() const +const ClassList *ClassDefImpl::taggedInnerClasses() const { return m_impl->taggedInnerClasses; } -void ClassDef::addTaggedInnerClass(ClassDef *cd) +void ClassDefImpl::addTaggedInnerClass(ClassDef *cd) { if (m_impl->taggedInnerClasses==0) { @@ -4945,17 +5497,17 @@ void ClassDef::addTaggedInnerClass(ClassDef *cd) m_impl->taggedInnerClasses->append(cd); } -ClassDef *ClassDef::tagLessReference() const +ClassDef *ClassDefImpl::tagLessReference() const { return m_impl->tagLessRef; } -void ClassDef::setTagLessReference(ClassDef *cd) +void ClassDefImpl::setTagLessReference(ClassDef *cd) { m_impl->tagLessRef = cd; } -void ClassDef::removeMemberFromLists(MemberDef *md) +void ClassDefImpl::removeMemberFromLists(MemberDef *md) { QListIterator<MemberList> mli(m_impl->memberLists); MemberList *ml; @@ -4965,22 +5517,22 @@ void ClassDef::removeMemberFromLists(MemberDef *md) } } -bool ClassDef::isJavaEnum() const +bool ClassDefImpl::isJavaEnum() const { return m_impl->isJavaEnum; } -bool ClassDef::isGeneric() const +bool ClassDefImpl::isGeneric() const { return m_impl->isGeneric; } -void ClassDef::setClassSpecifier(uint64 spec) +void ClassDefImpl::setClassSpecifier(uint64 spec) { m_impl->spec = spec; } -bool ClassDef::isExtension() const +bool ClassDefImpl::isExtension() const { QCString n = name(); int si = n.find('('); @@ -4989,58 +5541,58 @@ bool ClassDef::isExtension() const return b; } -const ClassSDict *ClassDef::innerClasses() const +const ClassSDict *ClassDefImpl::innerClasses() const { return m_impl->innerClasses; } -const FileList &ClassDef::usedFiles() const +const FileList &ClassDefImpl::usedFiles() const { return m_impl->files; } -const ArgumentList *ClassDef::typeConstraints() const +const ArgumentList *ClassDefImpl::typeConstraints() const { return m_impl->typeConstraints; } -const ExampleSDict *ClassDef::exampleList() const +const ExampleSDict *ClassDefImpl::exampleList() const { return m_impl->exampleSDict; } -bool ClassDef::subGrouping() const +bool ClassDefImpl::subGrouping() const { return m_impl->subGrouping; } -bool ClassDef::isSliceLocal() const +bool ClassDefImpl::isSliceLocal() const { return m_impl->spec&Entry::Local; } -void ClassDef::setName(const char *name) +void ClassDefImpl::setName(const char *name) { m_impl->isAnonymous = QCString(name).find('@')!=-1; - Definition::setName(name); + DefinitionImpl::setName(name); } -void ClassDef::setMetaData(const char *md) +void ClassDefImpl::setMetaData(const char *md) { m_impl->metaData = md; } -bool ClassDef::isAnonymous() const +bool ClassDefImpl::isAnonymous() const { return m_impl->isAnonymous; } -QCString ClassDef::collaborationGraphFileName() const +QCString ClassDefImpl::collaborationGraphFileName() const { return m_impl->collabFileName; } -QCString ClassDef::inheritanceGraphFileName() const +QCString ClassDefImpl::inheritanceGraphFileName() const { return m_impl->inheritFileName; } diff --git a/src/classdef.h b/src/classdef.h index 14f9fc8..a442ace 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -50,13 +50,12 @@ class ClassDefImpl; class ArgumentList; class FTextStream; -/** A class representing of a compound symbol. +/** A abstract class representing of a compound symbol. * * A compound can be a class, struct, union, interface, service, singleton, * or exception. - * \note This class should be renamed to CompoundDef */ -class ClassDef : public Definition +class ClassDef : virtual public Definition { public: /** The various compound types */ @@ -71,398 +70,361 @@ class ClassDef : public Definition Singleton, //=Entry::CLASS_SEC }; - /** Creates a new compound definition. - * \param fileName full path and file name in which this compound was - * found. - * \param startLine line number where the definition of this compound - * starts. - * \param startColumn column number where the definition of this compound - * starts. - * \param name the name of this compound (including scope) - * \param ct the kind of Compound - * \param ref the tag file from which this compound is extracted - * or 0 if the compound doesn't come from a tag file - * \param fName the file name as found in the tag file. - * This overwrites the file that doxygen normally - * generates based on the compound type & name. - * \param isSymbol If TRUE this class name is added as a publicly - * visible (and referencable) symbol. - * \param isJavaEnum If TRUE this class is actually a Java enum. - * I didn't add this to CompoundType to avoid having - * to adapt all translators. - */ - ClassDef(const char *fileName,int startLine,int startColumn, - const char *name,CompoundType ct, - const char *ref=0,const char *fName=0, - bool isSymbol=TRUE,bool isJavaEnum=FALSE); - /** Destroys a compound definition. */ - ~ClassDef(); + virtual ~ClassDef() {} + + virtual ClassDef *resolveAlias() = 0; //----------------------------------------------------------------------------------- // --- getters //----------------------------------------------------------------------------------- /** Used for RTTI, this is a class */ - DefType definitionType() const { return TypeClass; } + virtual DefType definitionType() const = 0; /** Returns the unique base name (without extension) of the class's file on disk */ - QCString getOutputFileBase() const; - QCString getInstanceOutputFileBase() const; + virtual QCString getOutputFileBase() const = 0; + virtual QCString getInstanceOutputFileBase() const = 0; /** Returns the base name for the source code file */ - QCString getSourceFileBase() const; + virtual QCString getSourceFileBase() const = 0; /** If this class originated from a tagfile, this will return the tag file reference */ - QCString getReference() const; + virtual QCString getReference() const = 0; /** Returns TRUE if this class is imported via a tag file */ - bool isReference() const; + virtual bool isReference() const = 0; /** Returns TRUE if this is a local class definition, see EXTRACT_LOCAL_CLASSES */ - bool isLocal() const; + virtual bool isLocal() const = 0; /** returns the classes nested into this class */ - ClassSDict *getClassSDict() const; + virtual ClassSDict *getClassSDict() const = 0; /** returns TRUE if this class has documentation */ - bool hasDocumentation() const; + virtual bool hasDocumentation() const = 0; /** returns TRUE if this class has a non-empty detailed description */ - bool hasDetailedDescription() const; - + virtual bool hasDetailedDescription() const = 0; + /** returns the file name to use for the collaboration graph */ - QCString collaborationGraphFileName() const; + virtual QCString collaborationGraphFileName() const = 0; /** returns the file name to use for the inheritance graph */ - QCString inheritanceGraphFileName() const; + virtual QCString inheritanceGraphFileName() const = 0; /** Returns the name as it is appears in the documentation */ - QCString displayName(bool includeScope=TRUE) const; + virtual QCString displayName(bool includeScope=TRUE) const = 0; /** Returns the type of compound this is, i.e. class/struct/union/.. */ - CompoundType compoundType() const; + virtual CompoundType compoundType() const = 0; /** Returns the type of compound as a string */ - QCString compoundTypeString() const; + virtual QCString compoundTypeString() const = 0; /** Returns the list of base classes from which this class directly * inherits. */ - BaseClassList *baseClasses() const; - + virtual BaseClassList *baseClasses() const = 0; + /** Returns the list of sub classes that directly derive from this class */ - BaseClassList *subClasses() const; + virtual BaseClassList *subClasses() const = 0; - /** Returns a dictionary of all members. This includes any inherited + /** Returns a dictionary of all members. This includes any inherited * members. Members are sorted alphabetically. - */ - MemberNameInfoSDict *memberNameInfoSDict() const; + */ + virtual MemberNameInfoSDict *memberNameInfoSDict() const = 0; - /** Return the protection level (Public,Protected,Private) in which + /** Return the protection level (Public,Protected,Private) in which * this compound was found. */ - Protection protection() const; + virtual Protection protection() const = 0; /** returns TRUE iff a link is possible to this item within this project. */ - bool isLinkableInProject() const; + virtual bool isLinkableInProject() const = 0; - /** return TRUE iff a link to this class is possible (either within + /** return TRUE iff a link to this class is possible (either within * this project, or as a cross-reference to another project). */ - bool isLinkable() const; + virtual bool isLinkable() const = 0; /** the class is visible in a class diagram, or class hierarchy */ - bool isVisibleInHierarchy(); - + virtual bool isVisibleInHierarchy() const = 0; + /** show this class in the declaration section of its parent? */ - bool visibleInParentsDeclList() const; + virtual bool visibleInParentsDeclList() const = 0; /** Returns the template arguments of this class * Will return 0 if not applicable. */ - ArgumentList *templateArguments() const; + virtual ArgumentList *templateArguments() const = 0; /** Returns the namespace this compound is in, or 0 if it has a global * scope. */ - NamespaceDef *getNamespaceDef() const; + virtual NamespaceDef *getNamespaceDef() const = 0; /** Returns the file in which this compound's definition can be found. * Should not return 0 (but it might be a good idea to check anyway). */ - FileDef *getFileDef() const; + virtual FileDef *getFileDef() const = 0; - /** Returns the Java package this class is in or 0 if not applicable. - */ + /** Returns the Java package this class is in or 0 if not applicable. + */ + + virtual MemberDef *getMemberByName(const QCString &) const = 0; - MemberDef *getMemberByName(const QCString &) const; - /** Returns TRUE iff \a bcd is a direct or indirect base class of this * class. This function will recursively traverse all branches of the * inheritance tree. */ - bool isBaseClass(ClassDef *bcd,bool followInstances,int level=0); + virtual bool isBaseClass(const ClassDef *bcd,bool followInstances,int level=0) const = 0; /** Returns TRUE iff \a bcd is a direct or indirect sub class of this * class. */ - bool isSubClass(ClassDef *bcd,int level=0); + virtual bool isSubClass(ClassDef *bcd,int level=0) const = 0; /** returns TRUE iff \a md is a member of this class or of the - * the public/protected members of a base class + * the public/protected members of a base class */ - bool isAccessibleMember(MemberDef *md); + virtual bool isAccessibleMember(const MemberDef *md) const = 0; /** Returns a sorted dictionary with all template instances found for * this template class. Returns 0 if not a template or no instances. */ - QDict<ClassDef> *getTemplateInstances() const; + virtual QDict<ClassDef> *getTemplateInstances() const = 0; /** Returns the template master of which this class is an instance. * Returns 0 if not applicable. */ - ClassDef *templateMaster() const; + virtual const ClassDef *templateMaster() const = 0; /** Returns TRUE if this class is a template */ - bool isTemplate() const; + virtual bool isTemplate() const = 0; - IncludeInfo *includeInfo() const; - - UsesClassDict *usedImplementationClasses() const; + virtual IncludeInfo *includeInfo() const = 0; - UsesClassDict *usedByImplementationClasses() const; + virtual UsesClassDict *usedImplementationClasses() const = 0; - UsesClassDict *usedInterfaceClasses() const; + virtual UsesClassDict *usedByImplementationClasses() const = 0; - ConstraintClassDict *templateTypeConstraints() const; + virtual UsesClassDict *usedInterfaceClasses() const = 0; - bool isTemplateArgument() const; + virtual ConstraintClassDict *templateTypeConstraints() const = 0; + + virtual bool isTemplateArgument() const = 0; /** Returns the definition of a nested compound if * available, or 0 otherwise. * @param name The name of the nested compound */ - virtual Definition *findInnerCompound(const char *name) const; + virtual Definition *findInnerCompound(const char *name) const = 0; /** Returns the template parameter lists that form the template * declaration of this class. - * - * Example: <code>template<class T> class TC {};</code> + * + * Example: <code>template<class T> class TC {} = 0;</code> * will return a list with one ArgumentList containing one argument * with type="class" and name="T". */ - void getTemplateParameterLists(QList<ArgumentList> &lists) const; + virtual void getTemplateParameterLists(QList<ArgumentList> &lists) const = 0; - QCString qualifiedNameWithTemplateParameters( - QList<ArgumentList> *actualParams=0,int *actualParamIndex=0) const; + virtual QCString qualifiedNameWithTemplateParameters( + QList<ArgumentList> *actualParams=0,int *actualParamIndex=0) const = 0; /** Returns TRUE if there is at least one pure virtual member in this * class. */ - bool isAbstract() const; + virtual bool isAbstract() const = 0; /** Returns TRUE if this class is implemented in Objective-C */ - bool isObjectiveC() const; + virtual bool isObjectiveC() const = 0; /** Returns TRUE if this class is implemented in Fortran */ - bool isFortran() const; + virtual bool isFortran() const = 0; /** Returns TRUE if this class is implemented in C# */ - bool isCSharp() const; + virtual bool isCSharp() const = 0; /** Returns TRUE if this class is marked as final */ - bool isFinal() const; + virtual bool isFinal() const = 0; /** Returns TRUE if this class is marked as sealed */ - bool isSealed() const; + virtual bool isSealed() const = 0; /** Returns TRUE if this class is marked as published */ - bool isPublished() const; + virtual bool isPublished() const = 0; /** Returns TRUE if this class represents an Objective-C 2.0 extension (nameless category) */ - bool isExtension() const; + virtual bool isExtension() const = 0; /** Returns TRUE if this class represents a forward declaration of a template class */ - bool isForwardDeclared() const; + virtual bool isForwardDeclared() const = 0; + + /** Returns TRUE if this class represents an interface */ + virtual bool isInterface() const = 0; /** Returns the class of which this is a category (Objective-C only) */ - ClassDef *categoryOf() const; + virtual ClassDef *categoryOf() const = 0; /** Returns the name of the class including outer classes, but not * including namespaces. */ - QCString className() const; + virtual QCString className() const = 0; /** Returns the members in the list identified by \a lt */ - MemberList *getMemberList(MemberListType lt); + virtual MemberList *getMemberList(MemberListType lt) const = 0; /** Returns the list containing the list of members sorted per type */ - const QList<MemberList> &getMemberLists() const; + virtual const QList<MemberList> &getMemberLists() const = 0; /** Returns the member groups defined for this class */ - MemberGroupSDict *getMemberGroupSDict() const; + virtual MemberGroupSDict *getMemberGroupSDict() const = 0; - QDict<int> *getTemplateBaseClassNames() const; + virtual QDict<int> *getTemplateBaseClassNames() const = 0; - ClassDef *getVariableInstance(const char *templSpec); + virtual ClassDef *getVariableInstance(const char *templSpec) const = 0; - bool isUsedOnly() const; + virtual bool isUsedOnly() const = 0; - QCString anchor() const; - bool isEmbeddedInOuterScope() const; + virtual QCString anchor() const = 0; + virtual bool isEmbeddedInOuterScope() const = 0; - bool isSimple() const; + virtual bool isSimple() const = 0; - const ClassList *taggedInnerClasses() const; - ClassDef *tagLessReference() const; + virtual const ClassList *taggedInnerClasses() const = 0; + virtual ClassDef *tagLessReference() const = 0; - MemberDef *isSmartPointer() const; + virtual MemberDef *isSmartPointer() const = 0; - bool isJavaEnum() const; + virtual bool isJavaEnum() const = 0; - bool isGeneric() const; - bool isAnonymous() const; - const ClassSDict *innerClasses() const; - QCString title() const; + virtual bool isGeneric() const = 0; + virtual bool isAnonymous() const = 0; + virtual const ClassSDict *innerClasses() const = 0; + virtual QCString title() const = 0; - QCString generatedFromFiles() const; - const FileList &usedFiles() const; + virtual QCString generatedFromFiles() const = 0; + virtual const FileList &usedFiles() const = 0; - const ArgumentList *typeConstraints() const; - const ExampleSDict *exampleList() const; - bool hasExamples() const; - QCString getMemberListFileName() const; - bool subGrouping() const; + virtual const ArgumentList *typeConstraints() const = 0; + virtual const ExampleSDict *exampleList() const = 0; + virtual bool hasExamples() const = 0; + virtual QCString getMemberListFileName() const = 0; + virtual bool subGrouping() const = 0; - bool isSliceLocal() const; + virtual bool isSliceLocal() const = 0; + virtual bool hasNonReferenceSuperClass() const = 0; //----------------------------------------------------------------------------------- // --- setters ---- //----------------------------------------------------------------------------------- - void insertBaseClass(ClassDef *,const char *name,Protection p,Specifier s,const char *t=0); - void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0); - void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force); - void insertMember(MemberDef *); - void insertUsedFile(FileDef *); - bool addExample(const char *anchor,const char *name, const char *file); - void mergeCategory(ClassDef *category); - void setNamespace(NamespaceDef *nd); - void setFileDef(FileDef *fd); - void setSubGrouping(bool enabled); - void setProtection(Protection p); - void setGroupDefForAllMembers(GroupDef *g,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs); - void addInnerCompound(Definition *d); - ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn, - const QCString &templSpec,bool &freshInstance); - void addUsedClass(ClassDef *cd,const char *accessName,Protection prot); - void addUsedByClass(ClassDef *cd,const char *accessName,Protection prot); - void setIsStatic(bool b); - void setCompoundType(CompoundType t); - void setClassName(const char *name); - void setClassSpecifier(uint64 spec); - - void setTemplateArguments(ArgumentList *al); - void setTemplateBaseClassNames(QDict<int> *templateNames); - void setTemplateMaster(ClassDef *tm); - void setTypeConstraints(ArgumentList *al); - void addMembersToTemplateInstance(ClassDef *cd,const char *templSpec); - void makeTemplateArgument(bool b=TRUE); - void setCategoryOf(ClassDef *cd); - void setUsedOnly(bool b); - - void addTaggedInnerClass(ClassDef *cd); - void setTagLessReference(ClassDef *cd); - void setName(const char *name); - - void setMetaData(const char *md); + virtual void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force) = 0; + virtual void setNamespace(NamespaceDef *nd) = 0; + virtual void setFileDef(FileDef *fd) = 0; + virtual void setSubGrouping(bool enabled) = 0; + virtual void setProtection(Protection p) = 0; + virtual void setGroupDefForAllMembers(GroupDef *g,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs) = 0; + virtual void setIsStatic(bool b) = 0; + virtual void setCompoundType(CompoundType t) = 0; + virtual void setClassName(const char *name) = 0; + virtual void setClassSpecifier(uint64 spec) = 0; + virtual void setTemplateArguments(ArgumentList *al) = 0; + virtual void setTemplateBaseClassNames(QDict<int> *templateNames) = 0; + virtual void setTemplateMaster(const ClassDef *tm) = 0; + virtual void setTypeConstraints(ArgumentList *al) = 0; + virtual void setCategoryOf(ClassDef *cd) = 0; + virtual void setUsedOnly(bool b) = 0; + virtual void setTagLessReference(ClassDef *cd) = 0; + virtual void setName(const char *name) = 0; + virtual void setMetaData(const char *md) = 0; //----------------------------------------------------------------------------------- // --- actions ---- //----------------------------------------------------------------------------------- - void findSectionsInDocumentation(); - void addMembersToMemberGroup(); - void addListReferences(); - void addTypeConstraints(); - void computeAnchors(); - void mergeMembers(); - void sortMemberLists(); - void distributeMemberGroupDocumentation(); - void writeDocumentation(OutputList &ol); - void writeDocumentationForInnerClasses(OutputList &ol); - void writeMemberPages(OutputList &ol); - void writeMemberList(OutputList &ol); - void writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup, - ClassDef *inheritedFrom,const char *inheritId); - void writeQuickMemberLinks(OutputList &ol,MemberDef *md) const; - void writeSummaryLinks(OutputList &ol); - void reclassifyMember(MemberDef *md,MemberType t); - void writeInlineDocumentation(OutputList &ol); - void writeDeclarationLink(OutputList &ol,bool &found, - const char *header,bool localNames); - void removeMemberFromLists(MemberDef *md); - void addGroupedInheritedMembers(OutputList &ol,MemberListType lt, - ClassDef *inheritedFrom,const QCString &inheritId); - int countMembersIncludingGrouped(MemberListType lt,ClassDef *inheritedFrom,bool additional); - int countInheritanceNodes(); - void writeTagFile(FTextStream &); - - bool visited; - - protected: - void addUsedInterfaceClasses(MemberDef *md,const char *typeStr); - bool hasNonReferenceSuperClass(); - void showUsedFiles(OutputList &ol); - - private: - void writeDocumentationContents(OutputList &ol,const QCString &pageTitle); - void internalInsertMember(MemberDef *md,Protection prot,bool addToAllList); - void addMemberToList(MemberListType lt,MemberDef *md,bool isBrief); - MemberList *createMemberList(MemberListType lt); - void writeInheritedMemberDeclarations(OutputList &ol,MemberListType lt,int lt2,const QCString &title,ClassDef *inheritedFrom,bool invert,bool showAlways,QPtrDict<void> *visitedClasses); - void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title, - const char *subTitle=0,bool showInline=FALSE,ClassDef *inheritedFrom=0,int lt2=-1,bool invert=FALSE,bool showAlways=FALSE,QPtrDict<void> *visitedClasses=0); - void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title,bool showInline=FALSE); - void writeSimpleMemberDocumentation(OutputList &ol,MemberListType lt); - void writePlainMemberDeclaration(OutputList &ol,MemberListType lt,bool inGroup,ClassDef *inheritedFrom,const char *inheritId); - void writeBriefDescription(OutputList &ol,bool exampleFlag); - void writeDetailedDescription(OutputList &ol,const QCString &pageType,bool exampleFlag, - const QCString &title,const QCString &anchor=QCString()); - void writeIncludeFiles(OutputList &ol); - void writeIncludeFilesForSlice(OutputList &ol); - //void writeAllMembersLink(OutputList &ol); - void writeInheritanceGraph(OutputList &ol); - void writeCollaborationGraph(OutputList &ol); - void writeMemberGroups(OutputList &ol,bool showInline=FALSE); - void writeNestedClasses(OutputList &ol,const QCString &title); - void writeInlineClasses(OutputList &ol); - void startMemberDeclarations(OutputList &ol); - void endMemberDeclarations(OutputList &ol); - void startMemberDocumentation(OutputList &ol); - void endMemberDocumentation(OutputList &ol); - void writeAuthorSection(OutputList &ol); - void writeMoreLink(OutputList &ol,const QCString &anchor); - void writeDetailedDocumentationBody(OutputList &ol); - - int countAdditionalInheritedMembers(); - void writeAdditionalInheritedMembers(OutputList &ol); - void addClassAttributes(OutputList &ol); - int countMemberDeclarations(MemberListType lt,ClassDef *inheritedFrom, - int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses); - int countInheritedDecMembers(MemberListType lt, - ClassDef *inheritedFrom,bool invert,bool showAlways, - QPtrDict<void> *visitedClasses); - void getTitleForMemberListType(MemberListType type, - QCString &title,QCString &subtitle); - QCString includeStatement() const; - void addTypeConstraint(const QCString &typeConstraint,const QCString &type); - - ClassDefImpl *m_impl; + virtual void insertBaseClass(ClassDef *,const char *name,Protection p,Specifier s,const char *t=0) = 0; + virtual void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0) = 0; + virtual void insertMember(MemberDef *) = 0; + virtual void insertUsedFile(FileDef *) = 0; + virtual void addMembersToTemplateInstance(const ClassDef *cd,const char *templSpec) = 0; + virtual void addTaggedInnerClass(ClassDef *cd) = 0; + virtual void addInnerCompound(const Definition *d) = 0; + virtual bool addExample(const char *anchor,const char *name, const char *file) = 0; + virtual ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn, + const QCString &templSpec,bool &freshInstance) const = 0; + virtual void addUsedClass(ClassDef *cd,const char *accessName,Protection prot) = 0; + virtual void addUsedByClass(ClassDef *cd,const char *accessName,Protection prot) = 0; + virtual void makeTemplateArgument(bool b=TRUE) = 0; + virtual void mergeCategory(ClassDef *category) = 0; + virtual void findSectionsInDocumentation() = 0; + virtual void addMembersToMemberGroup() = 0; + virtual void addListReferences() = 0; + virtual void addTypeConstraints() = 0; + virtual void computeAnchors() = 0; + virtual void mergeMembers() = 0; + virtual void sortMemberLists() = 0; + virtual void distributeMemberGroupDocumentation() = 0; + virtual void reclassifyMember(MemberDef *md,MemberType t) = 0; + virtual void removeMemberFromLists(MemberDef *md) = 0; + virtual void setAnonymousEnumType() = 0; + virtual void countMembers() = 0; + + //----------------------------------------------------------------------------------- + // --- write output ---- + //----------------------------------------------------------------------------------- + + virtual void writeDocumentation(OutputList &ol) const = 0; + virtual void writeDocumentationForInnerClasses(OutputList &ol) const = 0; + virtual void writeMemberPages(OutputList &ol) const = 0; + virtual void writeMemberList(OutputList &ol) const = 0; + virtual void writeDeclaration(OutputList &ol,const MemberDef *md,bool inGroup, + const ClassDef *inheritedFrom,const char *inheritId) const = 0; + virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *md) const = 0; + virtual void writeSummaryLinks(OutputList &ol) const = 0; + virtual void writeInlineDocumentation(OutputList &ol) const = 0; + virtual void writeDeclarationLink(OutputList &ol,bool &found, + const char *header,bool localNames) const = 0; + virtual void writeTagFile(FTextStream &) = 0; + virtual void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title, + const char *subTitle=0,bool showInline=FALSE,const ClassDef *inheritedFrom=0, + int lt2=-1,bool invert=FALSE,bool showAlways=FALSE, + QPtrDict<void> *visitedClasses=0) const = 0; + virtual void addGroupedInheritedMembers(OutputList &ol,MemberListType lt, + const ClassDef *inheritedFrom,const QCString &inheritId) const = 0; + + //----------------------------------------------------------------------------------- + // --- count members ---- + //----------------------------------------------------------------------------------- + + virtual int countMembersIncludingGrouped(MemberListType lt, + const ClassDef *inheritedFrom,bool additional) const = 0; + virtual int countInheritanceNodes() const = 0; + virtual int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom, + int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const = 0; + + + //----------------------------------------------------------------------------------- + // --- visiting administration ---- + //----------------------------------------------------------------------------------- + + virtual void setVisited(bool visited) const = 0; + virtual bool isVisited() const = 0; }; +/** Factory method to create a new ClassDef object */ +ClassDef *createClassDef( + const char *fileName,int startLine,int startColumn, + const char *name,ClassDef::CompoundType ct, + const char *ref=0,const char *fName=0, + bool isSymbol=TRUE,bool isJavaEnum=FALSE); + +ClassDef *createClassDefAlias(const Definition *newScope,const ClassDef *cd); + + //------------------------------------------------------------------------ /** Class that contains information about a usage relation. diff --git a/src/classlist.cpp b/src/classlist.cpp index c752fd3..93ae8aa 100644 --- a/src/classlist.cpp +++ b/src/classlist.cpp @@ -92,7 +92,7 @@ bool ClassSDict::declVisible(const ClassDef::CompoundType *filter) const } void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter, - const char *header,bool localNames) + const char *header,bool localNames) const { static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); if (count()>0) @@ -109,6 +109,7 @@ void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *f (filter==0 || *filter==cd->compoundType()) ) { + //printf("writeDeclarationLink()\n"); cd->writeDeclarationLink(ol,found,header,localNames); } } @@ -116,7 +117,7 @@ void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *f } } -void ClassSDict::writeDocumentation(OutputList &ol,Definition * container) +void ClassSDict::writeDocumentation(OutputList &ol,const Definition * container) const { static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); @@ -139,6 +140,7 @@ void ClassSDict::writeDocumentation(OutputList &ol,Definition * container) if (cd->name().find('@')==-1 && cd->isLinkableInProject() && cd->isEmbeddedInOuterScope() && + !cd->isAlias() && (container==0 || cd->partOfGroups()==0) // if container==0 -> show as part of the group docs, otherwise only show if not part of a group ) { diff --git a/src/classlist.h b/src/classlist.h index 2ae7de8..11c8305 100644 --- a/src/classlist.h +++ b/src/classlist.h @@ -59,8 +59,8 @@ class ClassSDict : public SDict<ClassDef> ClassSDict(int size=17) : SDict<ClassDef>(size) {} ~ClassSDict() {} void writeDeclaration(OutputList &ol,const ClassDef::CompoundType *filter=0, - const char *header=0,bool localNames=FALSE); - void writeDocumentation(OutputList &ol,Definition *container=0); + const char *header=0,bool localNames=FALSE) const; + void writeDocumentation(OutputList &ol,const Definition *container=0) const; bool declVisible(const ClassDef::CompoundType *filter=0) const; private: int compareValues(const ClassDef *item1,const ClassDef *item2) const; diff --git a/src/cmdmapper.cpp b/src/cmdmapper.cpp index 55f8214..b4d35d4 100644 --- a/src/cmdmapper.cpp +++ b/src/cmdmapper.cpp @@ -197,6 +197,8 @@ CommandMap htmlTagMap[] = { "blockquote", HTML_BLOCKQUOTE }, { "strike", HTML_STRIKE }, { "u", HTML_UNDERLINE }, + { "ins", HTML_INS }, + { "del", HTML_DEL }, { "c", XML_C }, // { "code", XML_CODE }, <= ambiguous <code> is also a HTML tag diff --git a/src/cmdmapper.h b/src/cmdmapper.h index 8c49b3f..d670cd4 100644 --- a/src/cmdmapper.h +++ b/src/cmdmapper.h @@ -179,6 +179,8 @@ enum HtmlTagType HTML_BLOCKQUOTE= 33, HTML_STRIKE = 34, HTML_UNDERLINE = 35, + HTML_INS = 36, + HTML_DEL = 37, XML_CmdMask = 0x100, @@ -29,7 +29,7 @@ class Definition; void parseCCode(CodeOutputInterface &,const char *,const QCString &, SrcLangExt lang, bool isExample, const char *exName,FileDef *fd, int startLine,int endLine,bool inlineFragment, - MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx, + const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, bool collectXRefs); void resetCCodeParserState(); void codeFreeScanner(); @@ -129,7 +129,7 @@ static bool g_lexInit = FALSE; static QStack<int> g_classScopeLengthStack; static int g_prefixed_with_this_keyword = FALSE; -static Definition *g_searchCtx; +static const Definition *g_searchCtx; static bool g_collectXRefs; // context for an Objective-C method call @@ -139,9 +139,9 @@ struct ObjCCallCtx QCString methodName; QCString objectTypeOrName; QGString comment; - ClassDef *objectType; - MemberDef *objectVar; - MemberDef *method; + const ClassDef *objectType; + const MemberDef *objectVar; + const MemberDef *method; QCString format; int lexState; int braceCount; @@ -252,7 +252,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name) DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' g_currentDefinition=%s\n", ltype.data(),lname.data(),g_currentDefinition?g_currentDefinition->name().data():"<none>")); Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast(); - ClassDef *varType; + const ClassDef *varType; int i=0; if ( (varType=g_codeClassSDict->find(ltype)) || // look for class definitions inside the code block @@ -268,7 +268,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name) QCString typeName(ltype.left(i)); ClassDef* newDef = 0; QCString templateArgs(ltype.right(ltype.length() - i)); - if ( + if ( !typeName.isEmpty() && ( // look for class definitions inside the code block (varType=g_codeClassSDict->find(typeName)) || // otherwise look for global class definitions @@ -338,19 +338,19 @@ class CallContext public: struct Ctx { - Ctx() : name(g_name), type(g_type), d(0) {} + Ctx(QCString _name, QCString _type) : name(_name), type(_type), d(0) {} QCString name; QCString type; - Definition *d; + const Definition *d; }; - CallContext() + CallContext() { - m_defList.append(new Ctx); + m_defList.append(new Ctx("","")); m_defList.setAutoDelete(TRUE); } virtual ~CallContext() {} - void setScope(Definition *d) + void setScope(const Definition *d) { Ctx *ctx = m_defList.getLast(); if (ctx) @@ -359,12 +359,12 @@ class CallContext ctx->d=d; } } - void pushScope() + void pushScope(QCString _name, QCString _type) { - m_defList.append(new Ctx); + m_defList.append(new Ctx(_name,_type)); DBG_CTX((stderr,"** Push call context %d\n",m_defList.count())); } - void popScope() + void popScope(QCString &_name, QCString &_type) { if (m_defList.count()>1) { @@ -372,8 +372,8 @@ class CallContext Ctx *ctx = m_defList.getLast(); if (ctx) { - g_name = ctx->name; - g_type = ctx->type; + _name = ctx->name; + _type = ctx->type; } m_defList.removeLast(); } @@ -386,9 +386,9 @@ class CallContext { DBG_CTX((stderr,"** Clear call context\n")); m_defList.clear(); - m_defList.append(new Ctx); + m_defList.append(new Ctx("","")); } - Definition *getScope() const + const Definition *getScope() const { Ctx *ctx = m_defList.getLast(); if (ctx) return ctx->d; else return 0; @@ -415,7 +415,7 @@ static void pushScope(const char *s) g_classScope += "::"; g_classScope += s; } - //printf("pushScope(%s) result: `%s'\n",s,g_classScope.data()); + //printf("pushScope(%s) result: '%s'\n",s,g_classScope.data()); } /*! remove the top class/namespace name from the scope */ @@ -431,7 +431,7 @@ static void popScope() { //err("Too many end of scopes found!\n"); } - //printf("popScope() result: `%s'\n",g_classScope.data()); + //printf("popScope() result: '%s'\n",g_classScope.data()); } static void setCurrentDoc(const QCString &anchor) @@ -482,7 +482,7 @@ static void setClassScope(const QCString &name) n = n.mid(i+2); } pushScope(n); - //printf("--->New class scope `%s'\n",g_classScope.data()); + //printf("--->New class scope '%s'\n",g_classScope.data()); } /*! start a new line of code, inserting a line number if g_sourceFileDef @@ -513,7 +513,7 @@ static void startCodeLine() g_args.resize(0); g_parmType.resize(0); g_parmName.resize(0); - //printf("Real scope: `%s'\n",g_realScope.data()); + //printf("Real scope: '%s'\n",g_realScope.data()); g_bodyCurlyCount = 0; QCString lineAnchor; lineAnchor.sprintf("l%05d",g_yyLineNr); @@ -567,7 +567,7 @@ static void nextCodeLine() } } -/*! write a code fragment `text' that may span multiple lines, inserting +/*! write a code fragment 'text' that may span multiple lines, inserting * line numbers for each line. */ static void codifyLines(const char *text) @@ -606,7 +606,7 @@ static void codifyLines(const char *text) * split into multiple links with the same destination, one for each line. */ static void writeMultiLineCodeLink(CodeOutputInterface &ol, - Definition *d, + const Definition *d, const char *text) { static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); @@ -674,13 +674,13 @@ static void addUsingDirective(const char *name) } } -static void setParameterList(MemberDef *md) +static void setParameterList(const MemberDef *md) { g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : ""; - ArgumentList *al = md->argumentList(); + const ArgumentList *al = md->argumentList(); if (al==0) return; ArgumentListIterator it(*al); - Argument *a; + const Argument *a; for (;(a=it.current());++it) { g_parmName = a->name.copy(); @@ -695,7 +695,7 @@ static void setParameterList(MemberDef *md) } } -static ClassDef *stripClassName(const char *s,Definition *d=g_currentDefinition) +static const ClassDef *stripClassName(const char *s,Definition *d=g_currentDefinition) { int pos=0; QCString type = s; @@ -704,7 +704,7 @@ static ClassDef *stripClassName(const char *s,Definition *d=g_currentDefinition) while (extractClassNameFromType(type,pos,className,templSpec)!=-1) { QCString clName=className+templSpec; - ClassDef *cd=0; + const ClassDef *cd=0; if (!g_classScope.isEmpty()) { cd=getResolvedClass(d,g_sourceFileDef,g_classScope+"::"+clName); @@ -713,7 +713,7 @@ static ClassDef *stripClassName(const char *s,Definition *d=g_currentDefinition) { cd=getResolvedClass(d,g_sourceFileDef,clName); } - //printf("stripClass trying `%s' = %p\n",clName.data(),cd); + //printf("stripClass trying '%s' = %p\n",clName.data(),cd); if (cd) { return cd; @@ -747,7 +747,7 @@ static MemberDef *setCallContextForVar(const QCString &name) } else // check namespace as well { - NamespaceDef *mnd = getResolvedNamespace(scope); + const NamespaceDef *mnd = getResolvedNamespace(scope); if (mnd && !locName.isEmpty()) { MemberDef *md=mnd->getMemberByName(locName); @@ -768,7 +768,7 @@ static MemberDef *setCallContextForVar(const QCString &name) DBG_CTX((stderr,"local variable?\n")); if (mcd!=VariableContext::dummyContext) { - DBG_CTX((stderr,"local var `%s' mcd=%s\n",name.data(),mcd->name().data())); + DBG_CTX((stderr,"local var '%s' mcd=%s\n",name.data(),mcd->name().data())); g_theCallContext.setScope(mcd); } } @@ -786,7 +786,7 @@ static MemberDef *setCallContextForVar(const QCString &name) DBG_CTX((stderr,"Found member %s\n",md->name().data())); if (g_scopeStack.top()!=CLASSBLOCK) { - DBG_CTX((stderr,"class member `%s' mcd=%s\n",name.data(),mcd->name().data())); + DBG_CTX((stderr,"class member '%s' mcd=%s\n",name.data(),mcd->name().data())); g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope())); } return md; @@ -797,7 +797,7 @@ static MemberDef *setCallContextForVar(const QCString &name) // look for a global member if ((mn=Doxygen::functionNameSDict->find(name))) { - //printf("global var `%s'\n",name.data()); + //printf("global var '%s'\n",name.data()); if (mn->count()==1) // global defined only once { MemberDef *md=mn->getFirst(); @@ -838,12 +838,12 @@ static MemberDef *setCallContextForVar(const QCString &name) static void updateCallContextForSmartPointer() { - Definition *d = g_theCallContext.getScope(); + const Definition *d = g_theCallContext.getScope(); //printf("updateCallContextForSmartPointer() cd=%s\n",cd ? d->name().data() : "<none>"); MemberDef *md; - if (d && d->definitionType()==Definition::TypeClass && (md=((ClassDef*)d)->isSmartPointer())) + if (d && d->definitionType()==Definition::TypeClass && (md=(dynamic_cast<const ClassDef*>(d))->isSmartPointer())) { - ClassDef *ncd = stripClassName(md->typeString(),md->getOuterScope()); + const ClassDef *ncd = stripClassName(md->typeString(),md->getOuterScope()); if (ncd) { g_theCallContext.setScope(ncd); @@ -860,12 +860,12 @@ static bool getLinkInScope(const QCString &c, // scope bool varOnly=FALSE ) { - MemberDef *md; - ClassDef *cd; - FileDef *fd; - NamespaceDef *nd; - GroupDef *gd; - DBG_CTX((stderr,"getLinkInScope: trying `%s'::`%s' varOnly=%d\n",c.data(),m.data(),varOnly)); + const MemberDef *md = 0; + const ClassDef *cd = 0; + const FileDef *fd = 0; + const NamespaceDef *nd = 0; + const GroupDef *gd = 0; + DBG_CTX((stderr,"getLinkInScope: trying '%s'::'%s' varOnly=%d\n",c.data(),m.data(),varOnly)); if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,g_sourceFileDef,FALSE,g_forceTagReference) && (!varOnly || md->isVariable())) { @@ -878,16 +878,16 @@ static bool getLinkInScope(const QCString &c, // scope anchor.sprintf("a%d",g_anchorCount); //printf("addExampleFile(%s,%s,%s)\n",anchor.data(),g_exampleName.data(), // g_exampleFile.data()); - if (md->addExample(anchor,g_exampleName,g_exampleFile)) + if (const_cast<MemberDef*>(md)->addExample(anchor,g_exampleName,g_exampleFile)) { ol.writeCodeAnchor(anchor); g_anchorCount++; } } - Definition *d = md->getOuterScope()==Doxygen::globalScope ? - md->getFileDef() : md->getOuterScope(); - if (md->getGroupDef()) d = md->getGroupDef(); + const Definition *d = md->getOuterScope()==Doxygen::globalScope ? + md->resolveAlias()->getFileDef() : md->getOuterScope(); + if (md->resolveAlias()->getGroupDef()) d = md->resolveAlias()->getGroupDef(); if (d && d->isLinkable()) { g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope())); @@ -897,9 +897,9 @@ static bool getLinkInScope(const QCString &c, // scope if (g_currentDefinition && g_currentMemberDef && md!=g_currentMemberDef && g_insideBody && g_collectXRefs) { - addDocCrossReference(g_currentMemberDef,md); + addDocCrossReference(g_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()); + //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()); writeMultiLineCodeLink(ol,md, text ? text : memberText); addToSearchIndex(text ? text : memberText); @@ -961,8 +961,8 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName { className = substitute(className,".","::"); // for PHP namespaces } - ClassDef *cd=0,*lcd=0; - MemberDef *md=0; + const ClassDef *cd=0,*lcd=0; + const MemberDef *md=0; bool isLocal=FALSE; //printf("generateClassOrGlobalLink(className=%s)\n",className.data()); @@ -983,7 +983,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName cd=getResolvedClass(d,g_sourceFileDef,bareName,&md); // try unspecialized version } } - NamespaceDef *nd = getResolvedNamespace(className); + const NamespaceDef *nd = getResolvedNamespace(className); if (nd && nd->isLinkableInProject()) { g_theCallContext.setScope(nd); @@ -1033,7 +1033,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName anchor.sprintf("_a%d",g_anchorCount); //printf("addExampleClass(%s,%s,%s)\n",anchor.data(),g_exampleName.data(), // g_exampleFile.data()); - if (cd->addExample(anchor,g_exampleName,g_exampleFile)) + if (const_cast<ClassDef*>(cd)->addExample(anchor,g_exampleName,g_exampleFile)) { ol.writeCodeAnchor(anchor); g_anchorCount++; @@ -1044,13 +1044,13 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName g_theCallContext.setScope(cd); if (md) { - Definition *d = md->getOuterScope()==Doxygen::globalScope ? + const Definition *d = md->getOuterScope()==Doxygen::globalScope ? md->getFileDef() : md->getOuterScope(); if (md->getGroupDef()) d = md->getGroupDef(); if (d && d->isLinkable() && md->isLinkable() && g_currentMemberDef && g_collectXRefs) { - addDocCrossReference(g_currentMemberDef,md); + addDocCrossReference(g_currentMemberDef,const_cast<MemberDef*>(md)); } } } @@ -1092,8 +1092,8 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName } text+=getLanguageSpecificSeparator(md->getLanguage()); text+=clName; - md->setName(text); - md->setLocalName(text); + const_cast<MemberDef*>(md)->setName(text); + const_cast<MemberDef*>(md)->setLocalName(text); } else // normal reference { @@ -1103,7 +1103,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName addToSearchIndex(clName); if (g_currentMemberDef && g_collectXRefs) { - addDocCrossReference(g_currentMemberDef,md); + addDocCrossReference(g_currentMemberDef,const_cast<MemberDef*>(md)); } return; } @@ -1122,7 +1122,7 @@ static bool generateClassMemberLink(CodeOutputInterface &ol,MemberDef *xmd,const // extract class definition of the return type in order to resolve // a->b()->c() like call chains - //printf("type=`%s' args=`%s' class=%s\n", + //printf("type='%s' args='%s' class=%s\n", // xmd->typeString(),xmd->argsString(), // xmd->getClassDef()->name().data()); @@ -1139,11 +1139,11 @@ static bool generateClassMemberLink(CodeOutputInterface &ol,MemberDef *xmd,const } } - ClassDef *typeClass = stripClassName(removeAnonymousScopes(xmd->typeString()),xmd->getOuterScope()); + const ClassDef *typeClass = stripClassName(removeAnonymousScopes(xmd->typeString()),xmd->getOuterScope()); DBG_CTX((stderr,"%s -> typeName=%p\n",xmd->typeString(),typeClass)); g_theCallContext.setScope(typeClass); - Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ? + const Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ? xmd->getFileDef() : xmd->getOuterScope(); if (xmd->getGroupDef()) xd = xmd->getGroupDef(); if (xd && xd->isLinkable()) @@ -1172,11 +1172,11 @@ static bool generateClassMemberLink(CodeOutputInterface &ol,MemberDef *xmd,const return FALSE; } -static bool generateClassMemberLink(CodeOutputInterface &ol,Definition *def,const char *memName) +static bool generateClassMemberLink(CodeOutputInterface &ol,const Definition *def,const char *memName) { if (def && def->definitionType()==Definition::TypeClass) { - ClassDef *cd = (ClassDef*)def; + const ClassDef *cd = dynamic_cast<const ClassDef*>(def); MemberDef *xmd = cd->getMemberByName(memName); //printf("generateClassMemberLink(class=%s,member=%s)=%p\n",def->name().data(),memName,xmd); if (xmd) @@ -1197,7 +1197,7 @@ static bool generateClassMemberLink(CodeOutputInterface &ol,Definition *def,cons } else if (def && def->definitionType()==Definition::TypeNamespace) { - NamespaceDef *nd = (NamespaceDef*)def; + const NamespaceDef *nd = dynamic_cast<const NamespaceDef*>(def); //printf("Looking for %s inside namespace %s\n",memName,nd->name().data()); Definition *innerDef = nd->findInnerCompound(memName); if (innerDef) @@ -1220,7 +1220,7 @@ static void generateMemberLink(CodeOutputInterface &ol,const QCString &varName, if (varName.isEmpty()) return; // look for the variable in the current context - ClassDef *vcd = g_theVarContext.findVariable(varName); + const ClassDef *vcd = g_theVarContext.findVariable(varName); if (vcd) { if (vcd!=VariableContext::dummyContext) @@ -1250,7 +1250,7 @@ static void generateMemberLink(CodeOutputInterface &ol,const QCString &varName, vcd = getResolvedClass(g_currentDefinition,g_sourceFileDef,g_classScope); if (vcd && vcd->isLinkable()) { - //printf("Found class %s for variable `%s'\n",g_classScope.data(),varName.data()); + //printf("Found class %s for variable '%s'\n",g_classScope.data(),varName.data()); MemberName *vmn=Doxygen::memberNameSDict->find(varName); if (vmn==0) { @@ -1261,18 +1261,18 @@ static void generateMemberLink(CodeOutputInterface &ol,const QCString &varName, ClassDef *jcd = getClass(vn.left(vi)); vn=vn.right(vn.length()-vi-2); vmn=Doxygen::memberNameSDict->find(vn); - //printf("Trying name `%s' scope=%s\n",vn.data(),scope.data()); + //printf("Trying name '%s' scope=%s\n",vn.data(),scope.data()); if (vmn) { MemberNameIterator vmni(*vmn); - MemberDef *vmd; + const MemberDef *vmd; for (;(vmd=vmni.current());++vmni) { if (/*(vmd->isVariable() || vmd->isFunction()) && */ vmd->getClassDef()==jcd) { //printf("Found variable type=%s\n",vmd->typeString()); - ClassDef *mcd=stripClassName(vmd->typeString(),vmd->getOuterScope()); + const ClassDef *mcd=stripClassName(vmd->typeString(),vmd->getOuterScope()); if (mcd && mcd->isLinkable()) { if (generateClassMemberLink(ol,mcd,memName)) return; @@ -1284,16 +1284,16 @@ static void generateMemberLink(CodeOutputInterface &ol,const QCString &varName, } if (vmn) { - //printf("There is a variable with name `%s'\n",varName); + //printf("There is a variable with name '%s'\n",varName); MemberNameIterator vmni(*vmn); - MemberDef *vmd; + const MemberDef *vmd; for (;(vmd=vmni.current());++vmni) { if (/*(vmd->isVariable() || vmd->isFunction()) && */ vmd->getClassDef()==vcd) { //printf("Found variable type=%s\n",vmd->typeString()); - ClassDef *mcd=stripClassName(vmd->typeString(),vmd->getOuterScope()); + const ClassDef *mcd=stripClassName(vmd->typeString(),vmd->getOuterScope()); if (mcd && mcd->isLinkable()) { if (generateClassMemberLink(ol,mcd,memName)) return; @@ -1335,7 +1335,7 @@ static void generateFunctionLink(CodeOutputInterface &ol,const char *funcName) DBG_CTX((stdout,"*** locScope=%s locFunc=%s\n",locScope.data(),locFunc.data())); int len=2; int i=locFunc.findRev("::"); - if (g_currentMemberDef && g_currentMemberDef->getClassDef() && + if (g_currentMemberDef && g_currentMemberDef->resolveAlias()->getClassDef() && funcName==g_currentMemberDef->localName() && g_currentMemberDef->getDefLine()==g_yyLineNr && generateClassMemberLink(ol,g_currentMemberDef,funcName) @@ -1483,7 +1483,7 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx) if (g_currentDefinition && g_currentDefinition->definitionType()==Definition::TypeClass) { - ctx->objectType = (ClassDef *)g_currentDefinition; + ctx->objectType = dynamic_cast<ClassDef *>(g_currentDefinition); } } else @@ -1507,13 +1507,13 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx) if (g_currentDefinition && g_currentDefinition->definitionType()==Definition::TypeClass) { - ctx->objectVar = ((ClassDef *)g_currentDefinition)->getMemberByName(ctx->objectTypeOrName); + ctx->objectVar = (dynamic_cast<ClassDef *>(g_currentDefinition))->getMemberByName(ctx->objectTypeOrName); //printf(" ctx->objectVar=%p\n",ctx->objectVar); if (ctx->objectVar) { ctx->objectType = stripClassName(ctx->objectVar->typeString()); //printf(" ctx->objectType=%p\n",ctx->objectType); - if (ctx->objectType) + if (ctx->objectType && !ctx->methodName.isEmpty()) { ctx->method = ctx->objectType->getMemberByName(ctx->methodName); //printf(" ctx->method=%p\n",ctx->method); @@ -1525,7 +1525,7 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx) else // local variable { //printf(" object is local variable\n"); - if (cd!=VariableContext::dummyContext) + if (cd!=VariableContext::dummyContext && !ctx->methodName.isEmpty()) { ctx->method = cd->getMemberByName(ctx->methodName); //printf(" class=%p method=%p\n",cd,ctx->method); @@ -1561,7 +1561,7 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx) writeMultiLineCodeLink(*g_code,ctx->method,pName->data()); if (g_currentMemberDef && g_collectXRefs) { - addDocCrossReference(g_currentMemberDef,ctx->method); + addDocCrossReference(g_currentMemberDef,const_cast<MemberDef*>(ctx->method)); } } else @@ -1589,12 +1589,12 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx) if (g_currentDefinition && g_currentDefinition->definitionType()==Definition::TypeClass) { - ctx->objectType = (ClassDef *)g_currentDefinition; + ctx->objectType = dynamic_cast<ClassDef *>(g_currentDefinition); if (ctx->objectType->categoryOf()) { ctx->objectType = ctx->objectType->categoryOf(); } - if (ctx->objectType) + if (ctx->objectType && !ctx->methodName.isEmpty()) { ctx->method = ctx->objectType->getMemberByName(ctx->methodName); } @@ -1608,7 +1608,7 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx) if (g_currentDefinition && g_currentDefinition->definitionType()==Definition::TypeClass) { - ClassDef *cd = (ClassDef *)g_currentDefinition; + ClassDef *cd = dynamic_cast<ClassDef *>(g_currentDefinition); if (cd->categoryOf()) { cd = cd->categoryOf(); @@ -1623,7 +1623,7 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx) if (bclass->classDef->compoundType()!=ClassDef::Protocol) { ctx->objectType = bclass->classDef; - if (ctx->objectType) + if (ctx->objectType && !ctx->methodName.isEmpty()) { ctx->method = ctx->objectType->getMemberByName(ctx->methodName); } @@ -1640,7 +1640,7 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx) writeMultiLineCodeLink(*g_code,ctx->objectVar,pObject->data()); if (g_currentMemberDef && g_collectXRefs) { - addDocCrossReference(g_currentMemberDef,ctx->objectVar); + addDocCrossReference(g_currentMemberDef,const_cast<MemberDef*>(ctx->objectVar)); } } else if (ctx->objectType && @@ -1648,12 +1648,12 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx) ctx->objectType->isLinkable() ) // object is class name { - ClassDef *cd = ctx->objectType; + const ClassDef *cd = ctx->objectType; writeMultiLineCodeLink(*g_code,cd,pObject->data()); } else // object still needs to be resolved { - ClassDef *cd = getResolvedClass(g_currentDefinition, + const ClassDef *cd = getResolvedClass(g_currentDefinition, g_sourceFileDef, *pObject); if (cd && cd->isLinkable()) { @@ -1701,7 +1701,7 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx) else { ctx->objectType = stripClassName(ictx->method->typeString()); - if (ctx->objectType) + if (ctx->objectType && !ctx->methodName.isEmpty()) { ctx->method = ctx->objectType->getMemberByName(ctx->methodName); } @@ -2295,19 +2295,18 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" if (getResolvedClass(g_currentDefinition,g_sourceFileDef,g_curClassName)==0) { DBG_CTX((stderr,"Adding new class %s\n",g_curClassName.data())); - ClassDef *ncd=new ClassDef("<code>",1,1, + ClassDef *ncd=createClassDef("<code>",1,1, g_curClassName,ClassDef::Class,0,0,FALSE); g_codeClassSDict->append(g_curClassName,ncd); // insert base classes. char *s=g_curClassBases.first(); while (s) { - ClassDef *bcd; - bcd=g_codeClassSDict->find(s); + const ClassDef *bcd=g_codeClassSDict->find(s); if (bcd==0) bcd=getResolvedClass(g_currentDefinition,g_sourceFileDef,s); if (bcd && bcd!=ncd) { - ncd->insertBaseClass(bcd,s,Public,Normal); + ncd->insertBaseClass(const_cast<ClassDef*>(bcd),s,Public,Normal); } s=g_curClassBases.next(); } @@ -2475,7 +2474,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <Body>{FLOWCONDITION}/{BN}*"(" { if (g_currentMemberDef && g_currentMemberDef->isFunction()) { - g_currentMemberDef->addFlowKeyWord(); + g_currentMemberDef->incrementFlowKeyWordCount(); } startFontClass("keywordflow"); codifyLines(yytext); @@ -2496,7 +2495,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <Body>{FLOWCONDITION}/([^a-z_A-Z0-9]) { if (g_currentMemberDef && g_currentMemberDef->isFunction()) { - g_currentMemberDef->addFlowKeyWord(); + g_currentMemberDef->incrementFlowKeyWordCount(); } startFontClass("keywordflow"); codifyLines(yytext); @@ -2514,7 +2513,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <Body>{FLOWCONDITION}/{B}* { if (g_currentMemberDef && g_currentMemberDef->isFunction()) { - g_currentMemberDef->addFlowKeyWord(); + g_currentMemberDef->incrementFlowKeyWordCount(); } startFontClass("keywordflow"); codifyLines(yytext); @@ -2522,7 +2521,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } <Body>"*"{B}*")" { // end of cast? g_code->codify(yytext); - g_theCallContext.popScope(); + g_theCallContext.popScope(g_name, g_type); g_bracketCount--; g_parmType = g_name; BEGIN(FuncCall); @@ -2532,7 +2531,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_name.resize(0);g_type.resize(0); if (*yytext==')') { - g_theCallContext.popScope(); + g_theCallContext.popScope(g_name, g_type); g_bracketCount--; BEGIN(FuncCall); } @@ -2864,7 +2863,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } else if (*yytext=='[') { - g_theCallContext.pushScope(); + g_theCallContext.pushScope(g_name, g_type); } g_args.resize(0); g_parmType.resize(0); @@ -2890,7 +2889,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } <ObjCMemberCall>"[" { g_code->codify(yytext); - g_theCallContext.pushScope(); + g_theCallContext.pushScope(g_name, g_type); } <ObjCMemberCall2>{ID}":"? { g_name+=yytext; @@ -2912,7 +2911,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" BEGIN(ObjCMemberCall3); } <ObjCMemberCall2,ObjCMemberCall3>"]" { - g_theCallContext.popScope(); + g_theCallContext.popScope(g_name, g_type); g_code->codify(yytext); BEGIN(Body); } @@ -3002,7 +3001,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <ObjCCall,ObjCMName,ObjCSkipStr>\n { g_currentCtx->format+=*yytext; } <Body>"]" { - g_theCallContext.popScope(); + g_theCallContext.popScope(g_name, g_type); g_code->codify(yytext); // TODO: nested arrays like: a[b[0]->func()]->func() g_name = g_saveName.copy(); @@ -3053,7 +3052,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <MemberCall2,FuncCall>{FLOWCONDITION}/([^a-z_A-Z0-9]) { if (g_currentMemberDef && g_currentMemberDef->isFunction()) { - g_currentMemberDef->addFlowKeyWord(); + g_currentMemberDef->incrementFlowKeyWordCount(); } addParmType(); g_parmName=yytext; @@ -3109,7 +3108,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_parmType.resize(0);g_parmName.resize(0); g_code->codify(yytext); g_bracketCount++; - g_theCallContext.pushScope(); + g_theCallContext.pushScope(g_name, g_type); if (YY_START==FuncCall && !g_insideBody) { g_theVarContext.pushScope(); @@ -3143,7 +3142,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_parmName.resize(0); g_theVarContext.addVariable(g_parmType,g_parmName); } - g_theCallContext.popScope(); + g_theCallContext.popScope(g_name, g_type); g_inForEachExpression = FALSE; //g_theCallContext.setClass(0); // commented out, otherwise a()->b() does not work for b(). g_code->codify(yytext); @@ -3200,7 +3199,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_theVarContext.pushScope(); } g_theVarContext.addVariable(g_parmType,g_parmName); - //g_theCallContext.popScope(); + //g_theCallContext.popScope(g_name, g_type); g_parmType.resize(0);g_parmName.resize(0); int index = g_name.findRev("::"); DBG_CTX((stderr,"g_name=%s\n",g_name.data())); @@ -3208,7 +3207,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" { QCString scope = g_name.left(index); if (!g_classScope.isEmpty()) scope.prepend(g_classScope+"::"); - ClassDef *cd=getResolvedClass(Doxygen::globalScope,g_sourceFileDef,scope); + const ClassDef *cd=getResolvedClass(Doxygen::globalScope,g_sourceFileDef,scope); if (cd) { setClassScope(cd->name()); @@ -3470,14 +3469,14 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <*>\n{B}*"/*@"[{}] { // remove one-line group marker if (Config_getBool(STRIP_CODE_COMMENTS)) { - g_lastSpecialCContext = YY_START; + if (YY_START != RemoveSpecialCComment) g_lastSpecialCContext = YY_START; g_yyLineNr++; BEGIN(RemoveSpecialCComment); } else { // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipCxxComment) + if (YY_START != SkipComment && YY_START != SkipCxxComment) { g_lastCContext = YY_START ; } @@ -3502,13 +3501,13 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <*>^{B}*"/*@"[{}] { // remove multi-line group marker if (Config_getBool(STRIP_CODE_COMMENTS)) { - g_lastSpecialCContext = YY_START; + if (YY_START != RemoveSpecialCComment) g_lastSpecialCContext = YY_START; BEGIN(RemoveSpecialCComment); } else { // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipCxxComment) + if (YY_START != SkipComment && YY_START != SkipCxxComment) { g_lastCContext = YY_START ; } @@ -3553,14 +3552,14 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <*>\n{B}*"/*"[!*]/[^/*] { if (Config_getBool(STRIP_CODE_COMMENTS)) { - g_lastSpecialCContext = YY_START; + if (YY_START != RemoveSpecialCComment) g_lastSpecialCContext = YY_START; g_yyLineNr++; BEGIN(RemoveSpecialCComment); } else { // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipCxxComment) + if (YY_START != SkipComment && YY_START != SkipCxxComment) { g_lastCContext = YY_START ; } @@ -3569,16 +3568,34 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" BEGIN(SkipComment); } } +<*>^{B}*"/**"[*]+/[^/] { // special C "banner" comment block at a new line + if (Config_getBool(JAVADOC_BANNER) && Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) g_lastSpecialCContext = YY_START; + BEGIN(RemoveSpecialCComment); + } + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + g_lastCContext = YY_START ; + } + startFontClass("comment"); + g_code->codify(yytext); + BEGIN(SkipComment); + } + } <*>^{B}*"/*"[!*]/[^/*] { // special C comment block at a new line if (Config_getBool(STRIP_CODE_COMMENTS)) { - g_lastSpecialCContext = YY_START; + if (YY_START != RemoveSpecialCComment) g_lastSpecialCContext = YY_START; BEGIN(RemoveSpecialCComment); } else { // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipCxxComment) + if (YY_START != SkipComment && YY_START != SkipCxxComment) { g_lastCContext = YY_START ; } @@ -3591,13 +3608,13 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" if (YY_START==SkipString) REJECT; if (Config_getBool(STRIP_CODE_COMMENTS)) { - g_lastSpecialCContext = YY_START; + if (YY_START != RemoveSpecialCComment) g_lastSpecialCContext = YY_START; BEGIN(RemoveSpecialCComment); } else { // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipCxxComment) + if (YY_START != SkipComment && YY_START != SkipCxxComment) { g_lastCContext = YY_START ; } @@ -3622,7 +3639,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" startFontClass("comment"); g_code->codify(yytext); // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipCxxComment) + if (YY_START != SkipComment && YY_START != SkipCxxComment) { g_lastCContext = YY_START ; } @@ -3642,11 +3659,11 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } <*>"("|"[" { g_code->codify(yytext); - g_theCallContext.pushScope(); + g_theCallContext.pushScope(g_name, g_type); } <*>")"|"]" { g_code->codify(yytext); - g_theCallContext.popScope(); + g_theCallContext.popScope(g_name, g_type); } <*>\n { g_yyColNr++; @@ -3735,7 +3752,7 @@ void resetCCodeParserState() void parseCCode(CodeOutputInterface &od,const char *className,const QCString &s, SrcLangExt lang,bool exBlock, const char *exName,FileDef *fd, int startLine,int endLine,bool inlineFragment, - MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx, + const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, bool collectXRefs) { //printf("***parseCode() exBlock=%d exName=%s fd=%p className=%s searchCtx=%s\n", @@ -3745,7 +3762,6 @@ void parseCCode(CodeOutputInterface &od,const char *className,const QCString &s, printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL); - TooltipManager::instance()->clearTooltips(); if (g_codeClassSDict==0) { resetCCodeParserState(); @@ -3786,7 +3802,7 @@ void parseCCode(CodeOutputInterface &od,const char *className,const QCString &s, if (fd==0) { // create a dummy filedef for the example - g_sourceFileDef = new FileDef("",(exName?exName:"generated")); + g_sourceFileDef = createFileDef("",(exName?exName:"generated")); cleanupSourceDef = TRUE; } g_insideObjC = lang==SrcLangExt_ObjC; @@ -3828,10 +3844,6 @@ void parseCCode(CodeOutputInterface &od,const char *className,const QCString &s, DBG_CTX((stderr,"endCodeLine(%d)\n",g_yyLineNr)); g_code->endCodeLine(); } - if (fd) - { - TooltipManager::instance()->writeTooltips(*g_code); - } if (cleanupSourceDef) { // delete the temporary file definition used for this example diff --git a/src/commentcnv.l b/src/commentcnv.l index 88236ed..a5dd0af 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -266,7 +266,7 @@ void replaceComment(int offset); else { g_pythonDocString = TRUE; - g_nestingCount=0; + g_nestingCount=1; g_commentStack.clear(); /* to be on the save side */ copyToOutput(yytext,(int)yyleng); BEGIN(CComment); @@ -281,7 +281,7 @@ void replaceComment(int offset); else { copyToOutput(yytext,(int)yyleng); - g_nestingCount=0; + g_nestingCount=0; // Fortran doesn't have an end comment g_commentStack.clear(); /* to be on the save side */ BEGIN(CComment); g_commentStack.push(new CommentCtx(g_lineNr)); @@ -298,7 +298,7 @@ void replaceComment(int offset); if (isFixedForm && (g_col == 0)) { copyToOutput(yytext,(int)yyleng); - g_nestingCount=0; + g_nestingCount=0; // Fortran doesn't have an end comment g_commentStack.clear(); /* to be on the safe side */ BEGIN(CComment); g_commentStack.push(new CommentCtx(g_lineNr)); @@ -399,8 +399,12 @@ void replaceComment(int offset); copyToOutput(yytext,(int)yyleng); } <Scan>"/*"[*!]? { /* start of a C comment */ + if ((g_lang==SrcLangExt_Python) || (g_lang==SrcLangExt_Tcl)) + { + REJECT; + } g_specialComment=(int)yyleng==3; - g_nestingCount=0; + g_nestingCount=1; g_commentStack.clear(); /* to be on the save side */ copyToOutput(yytext,(int)yyleng); BEGIN(CComment); @@ -414,7 +418,7 @@ void replaceComment(int offset); else { copyToOutput(yytext,(int)yyleng); - g_nestingCount=0; + g_nestingCount=0; // Python doesn't have an end comment for # g_commentStack.clear(); /* to be on the save side */ BEGIN(CComment); g_commentStack.push(new CommentCtx(g_lineNr)); @@ -429,7 +433,7 @@ void replaceComment(int offset); { g_vhdl = TRUE; copyToOutput(yytext,(int)yyleng); - g_nestingCount=0; + g_nestingCount=0; // VHDL doesn't have an end comment g_commentStack.clear(); /* to be on the save side */ BEGIN(CComment); g_commentStack.push(new CommentCtx(g_lineNr)); @@ -443,7 +447,7 @@ void replaceComment(int offset); else { copyToOutput(yytext,(int)yyleng); - g_nestingCount=0; + g_nestingCount=0; // Fortran doesn't have an end comment g_commentStack.clear(); /* to be on the save side */ BEGIN(CComment); g_commentStack.push(new CommentCtx(g_lineNr)); @@ -646,6 +650,7 @@ void replaceComment(int offset); } else { + g_nestingCount--; g_pythonDocString = FALSE; copyToOutput(yytext,(int)yyleng); BEGIN(Scan); @@ -660,25 +665,30 @@ void replaceComment(int offset); } } <CComment>"/"+"*" { /* nested C comment */ + if ((g_lang==SrcLangExt_Python) || (g_lang==SrcLangExt_Tcl)) + { + REJECT; + } g_nestingCount++; g_commentStack.push(new CommentCtx(g_lineNr)); copyToOutput(yytext,(int)yyleng); } <CComment>"*"+"/" { /* end of C comment */ - if (g_lang==SrcLangExt_Python) + if ((g_lang==SrcLangExt_Python) || (g_lang==SrcLangExt_Tcl)) { REJECT; } else { copyToOutput(yytext,(int)yyleng); + g_nestingCount--; if (g_nestingCount<=0) { BEGIN(Scan); } else { - g_nestingCount--; + //g_nestingCount--; delete g_commentStack.pop(); } } @@ -829,10 +839,19 @@ void replaceComment(int offset); g_inRoseComment=FALSE; BEGIN(Scan); } -<ReadLine>[^\\@\n]*/\n { - copyToOutput(yytext,(int)yyleng); - BEGIN(g_readLineCtx); - } +<ReadLine>"*/" { + copyToOutput("*‍/",7); + } +<ReadLine>"*" { + copyToOutput(yytext,(int)yyleng); + } +<ReadLine>[^\\@\n\*]* { + copyToOutput(yytext,(int)yyleng); + } +<ReadLine>[^\\@\n\*]*/\n { + copyToOutput(yytext,(int)yyleng); + BEGIN(g_readLineCtx); + } <CComment,ReadLine>[\\@][\\@][~a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command copyToOutput(yytext,(int)yyleng); } @@ -1102,7 +1121,7 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) } tmp += ")"; warn(g_fileName,g_lineNr,"Reached end of file while still inside a (nested) comment. " - "Nesting level %d %s",g_nestingCount+1,tmp.data()); // add one for "normal" expected end of comment + "Nesting level %d %s",g_nestingCount,tmp.data()); } g_commentStack.clear(); g_nestingCount = 0; diff --git a/src/commentscan.h b/src/commentscan.h index d324969..7d2189f 100644 --- a/src/commentscan.h +++ b/src/commentscan.h @@ -24,6 +24,19 @@ class ParserInterface; /** @file * @brief Interface for the comment block parser */ +/** Invokes the comment block parser with the request to preprocess a + * single comment block. + * @param[in] comment A string representing the actual comment block. + * Note that leading *'s are already stripped from the comment block. + * @param[in] fileName The name of the file in which the comment is found. + * Mainly used for producing warnings. + * @param[in] lineNr The line number at which the comment block was found. + * @returns The prepocessed comment block + */ +QCString preprocessCommentBlock(const QCString &comment, + const QCString &fileName, + int lineNr); + /** Invokes the comment block parser with the request to parse a * single comment block. * @param[in] parser The language parse that invoked this function. @@ -72,13 +85,5 @@ bool parseCommentBlock(ParserInterface *parser, bool &newEntryNeeded ); -void groupEnterFile(const char *file,int line); -void groupLeaveFile(const char *file,int line); -void groupLeaveCompound(const char *file,int line,const char *name); -void groupEnterCompound(const char *file,int line,const char *name); -void openGroup(Entry *e,const char *file,int line); -void closeGroup(Entry *,const char *file,int line,bool foundInline=FALSE); -void initGroupInfo(Entry *e); - #endif diff --git a/src/commentscan.l b/src/commentscan.l index 90e7ac3..a495c5e 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -147,30 +147,30 @@ static DocCmdMap docCmdMap[] = // command name handler function ends brief description { "brief", &handleBrief, FALSE }, { "short", &handleBrief, FALSE }, - { "fn", &handleFn, FALSE }, - { "var", &handleFn, FALSE }, - { "typedef", &handleFn, FALSE }, - { "property", &handleFn, FALSE }, - { "def", &handleDef, FALSE }, + { "fn", &handleFn, TRUE }, + { "var", &handleFn, TRUE }, + { "typedef", &handleFn, TRUE }, + { "property", &handleFn, TRUE }, + { "def", &handleDef, TRUE }, { "overload", &handleOverload, FALSE }, - { "enum", &handleEnum, FALSE }, - { "defgroup", &handleDefGroup, FALSE }, - { "addtogroup", &handleAddToGroup, FALSE }, - { "weakgroup", &handleWeakGroup, FALSE }, - { "namespace", &handleNamespace, FALSE }, - { "package", &handlePackage, FALSE }, - { "class", &handleClass, FALSE }, + { "enum", &handleEnum, TRUE }, + { "defgroup", &handleDefGroup, TRUE }, + { "addtogroup", &handleAddToGroup, TRUE }, + { "weakgroup", &handleWeakGroup, TRUE }, + { "namespace", &handleNamespace, TRUE }, + { "package", &handlePackage, TRUE }, + { "class", &handleClass, TRUE }, { "headerfile", &handleHeaderFile, FALSE }, - { "protocol", &handleProtocol, FALSE }, - { "category", &handleCategory, FALSE }, - { "union", &handleUnion, FALSE }, - { "struct", &handleStruct, FALSE }, - { "interface", &handleInterface, FALSE }, - { "idlexcept", &handleIdlException, FALSE }, - { "page", &handlePage, FALSE }, - { "mainpage", &handleMainpage, FALSE }, - { "file", &handleFile, FALSE }, - { "dir", &handleDir, FALSE }, + { "protocol", &handleProtocol, TRUE }, + { "category", &handleCategory, TRUE }, + { "union", &handleUnion, TRUE }, + { "struct", &handleStruct, TRUE }, + { "interface", &handleInterface, TRUE }, + { "idlexcept", &handleIdlException, TRUE }, + { "page", &handlePage, TRUE }, + { "mainpage", &handleMainpage, TRUE }, + { "file", &handleFile, TRUE }, + { "dir", &handleDir, TRUE }, { "example", &handleExample, FALSE }, { "details", &handleDetails, TRUE }, { "name", &handleName, FALSE }, @@ -210,7 +210,7 @@ static DocCmdMap docCmdMap[] = { "elseif", &handleElseIf, FALSE }, { "else", &handleElse, FALSE }, { "endif", &handleEndIf, FALSE }, - { "ingroup", &handleIngroup, FALSE }, + { "ingroup", &handleIngroup, TRUE }, { "nosubgrouping", &handleNoSubGrouping, FALSE }, { "showinitializer", &handleShowInitializer, FALSE }, { "hideinitializer", &handleHideInitializer, FALSE }, @@ -277,6 +277,8 @@ static DocCmdMap docCmdMap[] = { "verbinclude", 0, FALSE }, { "version", 0, TRUE }, { "warning", 0, TRUE }, + { "snippet", 0, TRUE }, + { "snippetlineno", 0, TRUE }, { 0, 0, FALSE } }; @@ -384,11 +386,6 @@ class GuardedSection bool m_parentVisible; }; -void openGroup(Entry *e,const char *file,int line); -void closeGroup(Entry *e,const char *file,int line,bool foundInline=FALSE); -void initGroupInfo(Entry *e); -static void groupAddDocs(Entry *e); - /* ----------------------------------------------------------------- * * statics @@ -449,20 +446,11 @@ static bool g_insideParBlock; //----------------------------------------------------------------------------- -static QStack<Grouping> g_autoGroupStack; -static int g_memberGroupId = DOX_NOGROUP; -static QCString g_memberGroupHeader; -static QCString g_memberGroupDocs; -static QCString g_memberGroupRelates; -static QCString g_compoundName; - -//----------------------------------------------------------------------------- - static void initParser() { g_sectionLabel.resize(0); g_sectionTitle.resize(0); - g_memberGroupHeader.resize(0); + Doxygen::docGroup.clearHeader(); g_insideParBlock = FALSE; } @@ -824,6 +812,10 @@ static inline void setOutput(OutputContext ctx) } else { + if (!current->doc.isEmpty()) // when appending parts add a new line + { + current->doc += "\n"; + } pOutputString = ¤t->doc; inContext = OutputDoc; // need to switch to detailed docs, see bug 631380 } @@ -1121,6 +1113,8 @@ RCSTAG "$"{ID}":"[^\n$]+"$" // the {B}* in the front was added for bug620924 QCString fullMatch = QCString(yytext); int idx = fullMatch.find('{'); + /* handle `\f{` and `@f{` as special cases */ + if ((idx > 1) && (yytext[idx-1] == 'f') && (yytext[idx-2] == '\\' || yytext[idx-2] =='@')) REJECT; int idxEnd = fullMatch.find("}",idx+1); QCString cmdName; QCStringList optList; @@ -1177,7 +1171,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" addOutput(yytext); } } -<Comment>{B}*("\\\\"|"@@")"f"[$\[{] { // escaped formula command +<Comment>{B}*({CMD}{CMD})"f"[$\[{] { // escaped formula command addOutput(yytext); } <Comment>{B}*{CMD}"~"[a-z_A-Z-]* { // language switch command @@ -1189,6 +1183,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" } } <Comment>{B}*{CMD}"f{"[^}\n]+"}"("{"?) { // start of a formula with custom environment + setOutput(OutputDoc); formulaText="\\begin"; formulaEnv=QString(yytext).stripWhiteSpace().data()+2; if (formulaEnv.at(formulaEnv.length()-1)=='{') @@ -1206,18 +1201,19 @@ RCSTAG "$"{ID}":"[^\n$]+"$" BEGIN(ReadFormulaShort); } <Comment>{B}*{CMD}"f[" { // start of a block formula + setOutput(OutputDoc); formulaText="\\["; formulaNewLines=0; BEGIN(ReadFormulaLong); } <Comment>{B}*{CMD}"{" { // begin of a group //langParser->handleGroupStartCommand(g_memberGroupHeader); - openGroup(current,yyFileName,yyLineNr); + Doxygen::docGroup.open(current,yyFileName,yyLineNr); } <Comment>{B}*{CMD}"}" { // end of a group //langParser->handleGroupEndCommand(); - closeGroup(current,yyFileName,yyLineNr,TRUE); - g_memberGroupHeader.resize(0); + Doxygen::docGroup.close(current,yyFileName,yyLineNr,TRUE); + Doxygen::docGroup.clearHeader(); parseMore=TRUE; needNewEntry = TRUE; #if YY_FLEX_MAJOR_VERSION>=2 && (YY_FLEX_MINOR_VERSION>5 || (YY_FLEX_MINOR_VERSION==5 && YY_FLEX_SUBMINOR_VERSION>=33)) @@ -1276,6 +1272,11 @@ RCSTAG "$"{ID}":"[^\n$]+"$" addOutput(insidePre || Doxygen::markdownSupport ? yytext : "–"); } <Comment>"-#"{B}+ { // numbered item + if (inContext!=OutputXRef) + { + briefEndsAtDot=FALSE; + setOutput(OutputDoc); + } addOutput(yytext); } <Comment>("."+)[a-z_A-Z0-9\)] { // . at start or in the middle of a word, or ellipsis @@ -1565,7 +1566,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" yyLineNr++; addOutput('\n'); } -<GroupDocArg2>[^\n\*]+ { // title (stored in type) +<GroupDocArg2>[^\n\\]+ { // title (stored in type) current->type += yytext; current->type = current->type.stripWhiteSpace(); } @@ -1583,11 +1584,16 @@ RCSTAG "$"{ID}":"[^\n$]+"$" addOutput('\n'); BEGIN( Comment ); } +<GroupDocArg2>. { // title (stored in type) + current->type += yytext; + current->type = current->type.stripWhiteSpace(); + } /* --------- handle arguments of page/mainpage command ------------------- */ <PageDocArg1>{FILE} { // first argument; page name current->name = stripQuotes(yytext); + current->args = ""; BEGIN( PageDocArg2 ); } <PageDocArg1>{LC} { yyLineNr++; @@ -1604,17 +1610,21 @@ RCSTAG "$"{ID}":"[^\n$]+"$" } <PageDocArg1>. { // ignore other stuff } -<PageDocArg2>.*"\n" { // second argument; page title - yyLineNr++; +<PageDocArg2>{DOCNL} { // second argument; page title + if (*yytext=='\n') yyLineNr++; + addOutput('\n'); + BEGIN( Comment ); + } +<PageDocArg2>{CMD}[<>] { // bug 748927 QCString tmp = yytext; tmp = substitute(substitute(tmp,"@<","<"),"@>",">"); tmp = substitute(substitute(tmp,"\\<","<"),"\\>",">"); - current->args = tmp; - addOutput('\n'); - BEGIN( Comment ); + current->args += tmp; } - +<PageDocArg2>. { + current->args += yytext; + } /* --------- handle arguments of the param command ------------ */ <ParamArg1>{ID}/{B}*"," { addOutput(yytext); @@ -1794,7 +1804,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" g_sectionTitle+=yytext; addOutput(yytext); } -<SectionTitle>("\\\\"|"@@"){ID} { // unescape escaped command +<SectionTitle>({CMD}{CMD}){ID} { // unescape escaped command g_sectionTitle+=&yytext[1]; addOutput(yytext); } @@ -1884,17 +1894,20 @@ RCSTAG "$"{ID}":"[^\n$]+"$" addOutput('\n'); } <FormatBlock>"/*" { // start of a C-comment - g_commentCount++; + if (!(blockName=="code" || blockName=="verbatim")) g_commentCount++; addOutput(yytext); } <FormatBlock>"*/" { // end of a C-comment addOutput(yytext); - g_commentCount--; - if (g_commentCount<0 && blockName!="verbatim") - { - warn(yyFileName,yyLineNr, + if (!(blockName=="code" || blockName=="verbatim")) + { + g_commentCount--; + if (g_commentCount<0) + { + warn(yyFileName,yyLineNr, "found */ without matching /* while inside a \\%s block! Perhaps a missing \\end%s?\n",blockName.data(),blockName.data()); - } + } + } } <FormatBlock>. { addOutput(*yytext); @@ -1954,6 +1967,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" addOutput(*yytext); } <GuardParamEnd>{B}*{DOCNL} { + lineCount(); g_spaceBeforeIf.resize(0); BEGIN(Comment); } @@ -2108,10 +2122,10 @@ RCSTAG "$"{ID}":"[^\n$]+"$" <NameParam>{LC} { // line continuation yyLineNr++; addOutput('\n'); - g_memberGroupHeader+=' '; + Doxygen::docGroup.appendHeader(' '); } <NameParam>. { // ignore other stuff - g_memberGroupHeader+=*yytext; + Doxygen::docGroup.appendHeader(*yytext); current->name+=*yytext; } @@ -2287,7 +2301,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$" if (*yytext=='\n') yyLineNr++; addOutput('\n'); setOutput(OutputDoc); - addOutput("\\copydetails "); + addOutput(" \\copydetails "); addOutput(g_copyDocArg); addOutput("\n"); BEGIN(Comment); @@ -2348,6 +2362,7 @@ static bool handleDefGroup(const QCString &, const QCStringList &) { bool stop=makeStructuralIndicator(Entry::GROUPDOC_SEC); current->groupDocType = Entry::GROUPDOC_NORMAL; + setOutput(OutputBrief); BEGIN( GroupDocArg1 ); return stop; } @@ -2451,6 +2466,7 @@ static bool handleMainpage(const QCString &, const QCStringList &) { current->name = "mainpage"; } + current->name = ""; BEGIN( PageDocArg2 ); return stop; } @@ -2529,11 +2545,11 @@ static bool handleName(const QCString &, const QCStringList &) bool stop=makeStructuralIndicator(Entry::MEMBERGRP_SEC); if (!stop) { - g_memberGroupHeader.resize(0); + Doxygen::docGroup.clearHeader(); BEGIN( NameParam ); - if (g_memberGroupId!=DOX_NOGROUP) // end of previous member group + if (!Doxygen::docGroup.isEmpty()) // end of previous member group { - closeGroup(current,yyFileName,yyLineNr,TRUE); + Doxygen::docGroup.close(current,yyFileName,yyLineNr,TRUE,true); } } return stop; @@ -2961,7 +2977,7 @@ static bool handleToc(const QCString &, const QCStringList &optList) { if (sscanf(opt.right(opt.length() - i - 1).data(),"%d%c",&level,&dum) != 1) { - warn(yyFileName,yyLineNr,"Unknown option:level specified with \\tableofcontents: `%s'", (*it).stripWhiteSpace().data()); + warn(yyFileName,yyLineNr,"Unknown option:level specified with \\tableofcontents: '%s'", (*it).stripWhiteSpace().data()); opt = ""; } else @@ -2991,7 +3007,7 @@ static bool handleToc(const QCString &, const QCStringList &optList) } else { - warn(yyFileName,yyLineNr,"Unknown option specified with \\tableofcontents: `%s'", (*it).stripWhiteSpace().data()); + warn(yyFileName,yyLineNr,"Unknown option specified with \\tableofcontents: '%s'", (*it).stripWhiteSpace().data()); } } } @@ -3072,6 +3088,33 @@ static void checkFormula() //---------------------------------------------------------------------------- +QCString preprocessCommentBlock(const QCString &comment, + const QCString &fileName, + int lineNr) +{ + if (!comment.isEmpty() && Doxygen::markdownSupport) + { + QCString result = processMarkdown(fileName,lineNr,0,comment); + const char *p = result.data(); + if (p) + { + while (*p==' ') p++; // skip over spaces + while (*p=='\n') p++; // skip over newlines + if (qstrncmp(p,"<br>",4)==0) p+=4; // skip over <br> + } + if (p>result.data()) + { + // strip part of the input + result = result.mid(p-result.data()); + } + return result; + } + else + { + return comment; + } +} + bool parseCommentBlock(/* in */ ParserInterface *parser, /* in */ Entry *curEntry, /* in */ const QCString &comment, @@ -3094,26 +3137,7 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, langParser = parser; current = curEntry; if (comment.isEmpty()) return FALSE; // avoid empty strings - if (Doxygen::markdownSupport) - { - inputString = processMarkdown(fileName,lineNr,NULL,comment); - const char *p = inputString.data(); - if (p) - { - while (*p==' ') p++; // skip over spaces - while (*p=='\n') p++; // skip over newlines - if (qstrncmp(p,"<br>",4)==0) p+=4; // skip over <br> - } - if (p>inputString.data()) - { - // strip part of the input - inputString = inputString.mid(p-inputString.data()); - } - } - else - { - inputString = comment; - } + inputString = comment; inputString.append(" "); inputPosition = position; yyLineNr = lineNr; @@ -3126,6 +3150,10 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, parseMore = FALSE; inBody = isInbody; outputXRef.resize(0); + if (!isBrief && !isAutoBriefOn && !current->doc.isEmpty()) + { // add newline separator between detailed comment blocks + current->doc += '\n'; + } setOutput( isBrief || isAutoBriefOn ? OutputBrief : OutputDoc ); briefEndsAtDot = isAutoBriefOn; g_condCount = 0; @@ -3173,9 +3201,9 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, } if (current->section==Entry::MEMBERGRP_SEC && - g_memberGroupId==DOX_NOGROUP) // @name section but no group started yet + Doxygen::docGroup.isEmpty()) // @name section but no group started yet { - openGroup(current,yyFileName,yyLineNr); + Doxygen::docGroup.open(current,yyFileName,yyLineNr,true); } Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: %s:%d\noutput=[\n" @@ -3189,7 +3217,7 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, checkFormula(); prot = protection; - groupAddDocs(curEntry); + Doxygen::docGroup.addDocs(curEntry); newEntryNeeded = needNewEntry; @@ -3208,185 +3236,6 @@ bool parseCommentBlock(/* in */ ParserInterface *parser, return parseMore; } -//--------------------------------------------------------------------------- - -void groupEnterFile(const char *fileName,int) -{ - g_autoGroupStack.setAutoDelete(TRUE); - g_autoGroupStack.clear(); - g_memberGroupId = DOX_NOGROUP; - g_memberGroupDocs.resize(0); - g_memberGroupRelates.resize(0); - g_compoundName=fileName; -} - -void groupLeaveFile(const char *fileName,int line) -{ - //if (g_memberGroupId!=DOX_NOGROUP) - //{ - // warn(fileName,line,"end of file while inside a member group\n"); - //} - g_memberGroupId=DOX_NOGROUP; - g_memberGroupRelates.resize(0); - g_memberGroupDocs.resize(0); - if (!g_autoGroupStack.isEmpty()) - { - warn(fileName,line,"end of file while inside a group\n"); - } -} - -void groupEnterCompound(const char *fileName,int line,const char *name) -{ - if (g_memberGroupId!=DOX_NOGROUP) - { - warn(fileName,line,"try to put compound %s inside a member group\n",name); - } - g_memberGroupId=DOX_NOGROUP; - g_memberGroupRelates.resize(0); - g_memberGroupDocs.resize(0); - g_compoundName = name; - int i = g_compoundName.find('('); - if (i!=-1) - { - g_compoundName=g_compoundName.left(i); // strip category (Obj-C) - } - if (g_compoundName.isEmpty()) - { - g_compoundName=fileName; - } - //printf("groupEnterCompound(%s)\n",name); -} - -void groupLeaveCompound(const char *,int,const char * /*name*/) -{ - //printf("groupLeaveCompound(%s)\n",name); - //if (g_memberGroupId!=DOX_NOGROUP) - //{ - // warn(fileName,line,"end of compound %s while inside a member group\n",name); - //} - g_memberGroupId=DOX_NOGROUP; - g_memberGroupRelates.resize(0); - g_memberGroupDocs.resize(0); - g_compoundName.resize(0); -} - -static int findExistingGroup(int &groupId,const MemberGroupInfo *info) -{ - //printf("findExistingGroup %s:%s\n",info->header.data(),info->compoundName.data()); - QIntDictIterator<MemberGroupInfo> di(Doxygen::memGrpInfoDict); - MemberGroupInfo *mi; - for (di.toFirst();(mi=di.current());++di) - { - if (g_compoundName==mi->compoundName && // same file or scope - !mi->header.isEmpty() && // not a nameless group - qstricmp(mi->header,info->header)==0 // same header name - ) - { - //printf("Found it!\n"); - return (int)di.currentKey(); // put the item in this group - } - } - groupId++; // start new group - return groupId; -} - -void openGroup(Entry *e,const char *,int) -{ - //printf("==> openGroup(name=%s,sec=%x) g_autoGroupStack=%d\n", - // e->name.data(),e->section,g_autoGroupStack.count()); - if (e->section==Entry::GROUPDOC_SEC) // auto group - { - g_autoGroupStack.push(new Grouping(e->name,e->groupingPri())); - } - else // start of a member group - { - //printf(" membergroup id=%d %s\n",g_memberGroupId,g_memberGroupHeader.data()); - if (g_memberGroupId==DOX_NOGROUP) // no group started yet - { - static int curGroupId=0; - - MemberGroupInfo *info = new MemberGroupInfo; - info->header = g_memberGroupHeader.stripWhiteSpace(); - info->compoundName = g_compoundName; - g_memberGroupId = findExistingGroup(curGroupId,info); - //printf(" use membergroup %d\n",g_memberGroupId); - Doxygen::memGrpInfoDict.insert(g_memberGroupId,info); - - g_memberGroupRelates = e->relates; - e->mGrpId = g_memberGroupId; - } - } -} - -void closeGroup(Entry *e,const char *fileName,int line,bool foundInline) -{ - //printf("==> closeGroup(name=%s,sec=%x,file=%s,line=%d) g_autoGroupStack=%d\n", - // e->name.data(),e->section,fileName,line,g_autoGroupStack.count()); - if (g_memberGroupId!=DOX_NOGROUP) // end of member group - { - MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(g_memberGroupId); - if (info) // known group - { - info->doc = g_memberGroupDocs; - info->docFile = fileName; - info->docLine = line; - } - g_memberGroupId=DOX_NOGROUP; - g_memberGroupRelates.resize(0); - g_memberGroupDocs.resize(0); - if (!foundInline) e->mGrpId=DOX_NOGROUP; - //printf("new group id=%d\n",g_memberGroupId); - } - else if (!g_autoGroupStack.isEmpty()) // end of auto group - { - Grouping *grp = g_autoGroupStack.pop(); - // see bug577005: we should not remove the last group for e - if (!foundInline) e->groups->removeLast(); - //printf("Removing %s e=%p\n",grp->groupname.data(),e); - delete grp; - if (!foundInline) initGroupInfo(e); - } -} - -void initGroupInfo(Entry *e) -{ - //printf("==> initGroup(id=%d,related=%s,e=%p)\n",g_memberGroupId, - // g_memberGroupRelates.data(),e); - e->mGrpId = g_memberGroupId; - e->relates = g_memberGroupRelates; - if (!g_autoGroupStack.isEmpty()) - { - //printf("Appending group %s to %s: count=%d entry=%p\n", - // g_autoGroupStack.top()->groupname.data(), - // e->name.data(),e->groups->count(),e); - e->groups->append(new Grouping(*g_autoGroupStack.top())); - } -} - -static void groupAddDocs(Entry *e) -{ - if (e->section==Entry::MEMBERGRP_SEC) - { - g_memberGroupDocs=e->brief.stripWhiteSpace(); - e->doc = stripLeadingAndTrailingEmptyLines(e->doc,e->docLine); - if (!g_memberGroupDocs.isEmpty() && !e->doc.isEmpty()) - { - g_memberGroupDocs+="\n\n"; - } - g_memberGroupDocs+=e->doc; - MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(g_memberGroupId); - if (info) - { - info->doc = g_memberGroupDocs; - info->docFile = e->docFile; - info->docLine = e->docLine; - info->setRefItems(e->sli); - } - e->doc.resize(0); - e->brief.resize(0); - } -} - static void handleGuard(const QCString &expr) { CondParser prs; diff --git a/src/config.h b/src/config.h index 102774e..1b79b1e 100644 --- a/src/config.h +++ b/src/config.h @@ -65,6 +65,8 @@ namespace Config /*! Post processed the parsed data. Replaces raw string values by the actual values. * and replaces environment variables. * \param clearHeaderAndFooter set to TRUE when writing header and footer templates. + * \param compare signals if we in Doxyfile compare (`-x`) mode are or not. Influences + * setting of the default value. */ void postProcess(bool clearHeaderAndFooter, bool compare = FALSE); diff --git a/src/config.xml b/src/config.xml index fdc562d..e68b3d7 100644 --- a/src/config.xml +++ b/src/config.xml @@ -105,7 +105,6 @@ PROJECT_NAME = Example INPUT = example.cc example.h WARNINGS = YES TAGFILES = qt.tag -PERL_PATH = /usr/local/bin/perl SEARCHENGINE = NO \endverbatim @@ -120,7 +119,6 @@ INPUT = examples/examples.doc src FILE_PATTERNS = *.cc *.h INCLUDE_PATH = examples TAGFILES = qt.tag -PERL_PATH = /usr/bin/perl SEARCHENGINE = YES \endverbatim @@ -480,6 +478,17 @@ Go to the <a href="commands.html">next</a> section or return to the ]]> </docs> </option> + <option type='bool' id='JAVADOC_BANNER' defval='0'> + <docs> +<![CDATA[ + If the \c JAVADOC_BANNER tag is set to \c YES then doxygen + will interpret a line such as \verbatim /***************\endverbatim as being the + beginning of a Javadoc-style comment "banner". If set to \c NO, the + Javadoc-style will behave just like regular comments and it will + not be interpreted by doxygen. +]]> + </docs> + </option> <option type='bool' id='QT_AUTOBRIEF' defval='0'> <docs> <![CDATA[ @@ -667,7 +676,7 @@ Go to the <a href="commands.html">next</a> section or return to the ]]> </docs> </option> - <option type='int' id='TOC_INCLUDE_HEADINGS' minval='0' maxval='99' defval='0' depends='MARKDOWN_SUPPORT'> + <option type='int' id='TOC_INCLUDE_HEADINGS' minval='0' maxval='99' defval='5' depends='MARKDOWN_SUPPORT'> <docs> <![CDATA[ When the \c TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings @@ -838,6 +847,14 @@ Go to the <a href="commands.html">next</a> section or return to the ]]> </docs> </option> + <option type='bool' id='EXTRACT_PRIV_VIRTUAL' defval='0'> + <docs> +<![CDATA[ + If the \c EXTRACT_PRIV_VIRTUAL tag is set to \c YES, documented private + virtual methods of a class will be included in the documentation. +]]> + </docs> + </option> <option type='bool' id='EXTRACT_PACKAGE' defval='0'> <docs> <![CDATA[ @@ -943,8 +960,8 @@ Go to the <a href="commands.html">next</a> section or return to the will only generate file names in lower-case letters. If set to \c YES, upper-case letters are also allowed. This is useful if you have classes or files whose names only differ in case and if your file system - supports case sensitive file names. Windows and Mac users are advised to set this - option to \c NO. + supports case sensitive file names. Windows (including Cygwin) ands + Mac users are advised to set this option to \c NO. ]]> </docs> </option> @@ -2202,7 +2219,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <![CDATA[ The \c QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help Project output. For more information please see - <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace">Qt Help Project / Namespace</a>. + <a href="https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace">Qt Help Project / Namespace</a>. ]]> </docs> </option> @@ -2211,7 +2228,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <![CDATA[ The \c QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt Help Project output. For more information please see - <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>. + <a href="https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>. ]]> </docs> </option> @@ -2219,7 +2236,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <docs> <![CDATA[ If the \c QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom filter to add. For more information please see - <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. + <a href="https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. ]]> </docs> </option> @@ -2228,7 +2245,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <![CDATA[ The \c QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the custom filter to add. For more information please see - <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. + <a href="https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. ]]> </docs> </option> @@ -2236,7 +2253,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. <docs> <![CDATA[ The \c QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's filter section matches. - <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>. + <a href="https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>. ]]> </docs> </option> @@ -2594,11 +2611,12 @@ EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... ]]> </docs> </option> - <option type='string' id='LATEX_MAKEINDEX_CMD' defval='\makeindex' depends='GENERATE_LATEX'> + <option type='string' id='LATEX_MAKEINDEX_CMD' defval='makeindex' depends='GENERATE_LATEX'> <docs> <![CDATA[ The \c LATEX_MAKEINDEX_CMD tag can be used to specify the command name to - generate index for \f$\mbox{\LaTeX}\f$. + generate index for \f$\mbox{\LaTeX}\f$. In case there is no backslash (`\`) as first character it + will be automatically added in the \f$\mbox{\LaTeX}\f$ code. @note This tag is used in the generated output file (`.tex`). \sa \ref cfg_makeindex_cmd_name "MAKEINDEX_CMD_NAME" for the part in the `Makefile` / `make.bat`. @@ -3220,14 +3238,6 @@ where `loc1` and `loc2` can be relative or absolute paths or URLs. ]]> </docs> </option> - <option type='string' id='PERL_PATH' format='file' defval='/usr/bin/perl' abspath='1'> - <docs> -<![CDATA[ - The \c PERL_PATH should be the absolute path and name of the perl script - interpreter (i.e. the result of `'which perl'`). -]]> - </docs> - </option> </group> <group name='Dot' docs='Configuration options related to the dot tool'> <option type='bool' id='CLASS_DIAGRAMS' defval='1'> @@ -3241,17 +3251,6 @@ where `loc1` and `loc2` can be relative or absolute paths or URLs. ]]> </docs> </option> - <option type='string' id='MSCGEN_PATH' format='dir' defval=''> - <docs> -<![CDATA[ - You can define message sequence charts within doxygen comments using the \ref cmdmsc "\\msc" - command. Doxygen will then run the <a href="http://www.mcternan.me.uk/mscgen/">mscgen tool</a>) to - produce the chart and insert it in the documentation. The <code>MSCGEN_PATH</code> tag allows you to - specify the directory where the \c mscgen tool resides. If left empty the tool is assumed to - be found in the default search path. -]]> - </docs> - </option> <option type='string' id='DIA_PATH' format='dir' defval=''> <docs> <![CDATA[ @@ -3630,5 +3629,7 @@ remove the intermediate dot files that are used to generate the various graphs. <option type='obsolete' id='SYMBOL_CACHE_SIZE'/> <option type='obsolete' id='XML_SCHEMA'/> <option type='obsolete' id='XML_DTD'/> + <option type='obsolete' id='PERL_PATH'/> + <option type='obsolete' id='MSCGEN_PATH'/> </group> </doxygenconfig> diff --git a/src/configgen.py b/src/configgen.py index ca2a5d1..dbba264 100755 --- a/src/configgen.py +++ b/src/configgen.py @@ -717,6 +717,10 @@ def main(): print("") print("void ConfigValues::init()") print("{") + print(" static bool first = TRUE;") + print(" if (!first) return;") + print(" first = FALSE;") + print("") for n in elem.childNodes: if n.nodeType == Node.ELEMENT_NODE: if (n.nodeName == "group"): diff --git a/src/configimpl.l b/src/configimpl.l index 644250f..bcb5a8c 100644 --- a/src/configimpl.l +++ b/src/configimpl.l @@ -174,7 +174,7 @@ void ConfigInt::convertStrToVal() int val = m_valueString.toInt(&ok); if (!ok || val<m_minVal || val>m_maxVal) { - config_warn("argument `%s' for option %s is not a valid number in the range [%d..%d]!\n" + config_warn("argument '%s' for option %s is not a valid number in the range [%d..%d]!\n" "Using the default: %d!\n",m_valueString.data(),m_name.data(),m_minVal,m_maxVal,m_value); } else @@ -199,7 +199,7 @@ void ConfigBool::convertStrToVal() } else { - config_warn("argument `%s' for option %s is not a valid boolean value\n" + config_warn("argument '%s' for option %s is not a valid boolean value\n" "Using the default: %s!\n",m_valueString.data(),m_name.data(),m_value?"YES":"NO"); } } @@ -699,19 +699,19 @@ static void readIncludeFile(const char *incName) %% <*>\0x0d -<PreStart>"##".*"\n" { config->appendStartComment(yytext);} +<PreStart>"##".*"\n" { config->appendStartComment(yytext);yyLineNr++;} <PreStart>. { BEGIN(Start); unput(*yytext); } -<Start,GetString,GetStrList,GetBool,SkipInvalid>"##".*"\n" { config->appendUserComment(yytext);} +<Start,GetString,GetStrList,GetBool,SkipInvalid>"##".*"\n" { config->appendUserComment(yytext);yyLineNr++;} <Start,GetString,GetStrList,GetBool,SkipInvalid>"#" { BEGIN(SkipComment); } <Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"=" { QCString cmd=yytext; cmd=cmd.left(cmd.length()-1).stripWhiteSpace(); ConfigOption *option = config->get(cmd); if (option==0) // oops not known { - config_warn("ignoring unsupported tag `%s' at line %d, file %s\n", + config_warn("ignoring unsupported tag '%s' at line %d, file %s\n", cmd.data(),yyLineNr,yyFileName.data()); BEGIN(SkipInvalid); } @@ -754,12 +754,12 @@ static void readIncludeFile(const char *incName) case ConfigOption::O_Obsolete: if (config_upd) { - config_warn("Tag `%s' at line %d of file `%s' has become obsolete.\n" + config_warn("Tag '%s' at line %d of file '%s' has become obsolete.\n" " This tag has been removed.\n", cmd.data(),yyLineNr,yyFileName.data()); } else { - config_warn("Tag `%s' at line %d of file `%s' has become obsolete.\n" + config_warn("Tag '%s' at line %d of file '%s' has become obsolete.\n" " To avoid this warning please remove this line from your configuration " "file or upgrade it using \"doxygen -u\"\n", cmd.data(),yyLineNr,yyFileName.data()); } @@ -768,12 +768,12 @@ static void readIncludeFile(const char *incName) case ConfigOption::O_Disabled: if (config_upd) { - config_warn("Tag `%s' at line %d of file `%s' belongs to an option that was not enabled at compile time.\n" + config_warn("Tag '%s' at line %d of file '%s' belongs to an option that was not enabled at compile time.\n" " This tag has been removed.\n", cmd.data(),yyLineNr,yyFileName.data()); } else { - config_warn("Tag `%s' at line %d of file `%s' belongs to an option that was not enabled at compile time.\n" + config_warn("Tag '%s' at line %d of file '%s' belongs to an option that was not enabled at compile time.\n" " To avoid this warning please remove this line from your configuration " "file or upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),yyLineNr,yyFileName.data()); } @@ -787,7 +787,7 @@ static void readIncludeFile(const char *incName) ConfigOption *option = config->get(cmd); if (option==0) // oops not known { - config_warn("ignoring unsupported tag `%s' at line %d, file %s\n", + config_warn("ignoring unsupported tag '%s' at line %d, file %s\n", cmd.data(),yyLineNr,yyFileName.data()); BEGIN(SkipInvalid); } @@ -809,18 +809,18 @@ static void readIncludeFile(const char *incName) case ConfigOption::O_String: case ConfigOption::O_Int: case ConfigOption::O_Bool: - config_warn("operator += not supported for `%s'. Ignoring line at line %d, file %s\n", + config_warn("operator += not supported for '%s'. Ignoring line at line %d, file %s\n", yytext,yyLineNr,yyFileName.data()); BEGIN(SkipInvalid); break; case ConfigOption::O_Obsolete: - config_warn("Tag `%s' at line %d of file %s has become obsolete.\n" + config_warn("Tag '%s' at line %d of file %s has become obsolete.\n" "To avoid this warning please update your configuration " "file using \"doxygen -u\"\n", cmd.data(),yyLineNr,yyFileName.data()); BEGIN(SkipInvalid); break; case ConfigOption::O_Disabled: - config_warn("Tag `%s' at line %d of file %s belongs to an option that was not enabled at compile time.\n" + config_warn("Tag '%s' at line %d of file %s belongs to an option that was not enabled at compile time.\n" "To avoid this warning please remove this line from your configuration " "file, upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),yyLineNr,yyFileName.data()); BEGIN(SkipInvalid); @@ -857,13 +857,13 @@ static void readIncludeFile(const char *incName) } } -<Start>[a-z_A-Z0-9]+ { config_warn("ignoring unknown tag `%s' at line %d, file %s\n",yytext,yyLineNr,yyFileName.data()); } +<Start>[a-z_A-Z0-9]+ { config_warn("ignoring unknown tag '%s' at line %d, file %s\n",yytext,yyLineNr,yyFileName.data()); } <GetString,GetBool,SkipInvalid>\n { yyLineNr++; BEGIN(Start); } <GetStrList>\n { yyLineNr++; if (!elemStr.isEmpty()) { - //printf("elemStr1=`%s'\n",elemStr.data()); + //printf("elemStr1='%s'\n",elemStr.data()); l->append(elemStr); } BEGIN(Start); @@ -871,7 +871,7 @@ static void readIncludeFile(const char *incName) <GetStrList>[ \t,]+ { if (!elemStr.isEmpty()) { - //printf("elemStr2=`%s'\n",elemStr.data()); + //printf("elemStr2='%s'\n",elemStr.data()); l->append(elemStr); } elemStr.resize(0); @@ -886,7 +886,7 @@ static void readIncludeFile(const char *incName) <GetQuotedString>"\""|"\n" { // we add a bogus space to signal that the string was quoted. This space will be stripped later on. tmpString+=" "; - //printf("Quoted String = `%s'\n",tmpString.data()); + //printf("Quoted String = '%s'\n",tmpString.data()); if (lastState==GetString) { (*s)+=configStringRecode(tmpString,encoding,"UTF-8"); @@ -917,7 +917,7 @@ static void readIncludeFile(const char *incName) else { *b=FALSE; - config_warn("Invalid value `%s' for " + config_warn("Invalid value '%s' for " "boolean tag in line %d, file %s; use YES or NO\n", bs.data(),yyLineNr,yyFileName.data()); } @@ -943,7 +943,7 @@ void ConfigImpl::writeTemplate(FTextStream &t,bool sl,bool upd) { t << takeStartComment() << endl; } - t << "# Doxyfile " << versionString << endl << endl; + t << "# Doxyfile " << getVersion() << endl << endl; if (!sl) { t << convertToComment(m_header,""); @@ -964,7 +964,12 @@ void ConfigImpl::writeTemplate(FTextStream &t,bool sl,bool upd) void ConfigImpl::compareDoxyfile(FTextStream &t) { - t << "# Difference with default Doxyfile " << versionString << endl; + t << "# Difference with default Doxyfile " << getVersion(); + if (strlen(getGitVersion())) + { + t << " (" << getGitVersion() << ")"; + } + t << endl; QListIterator<ConfigOption> it = iterator(); ConfigOption *option; for (;(option=it.current());++it) @@ -1003,7 +1008,7 @@ static void substEnvVarsInString(QCString &s) //printf("substEnvVarInString(%s) start\n",s.data()); while ((i=re.match(s,p,&l))!=-1 || (i=re2.match(s,p,&l))!=-1) { - //printf("Found environment var s.mid(%d,%d)=`%s'\n",i+2,l-3,s.mid(i+2,l-3).data()); + //printf("Found environment var s.mid(%d,%d)='%s'\n",i+2,l-3,s.mid(i+2,l-3).data()); QCString env=portable_getenv(s.mid(i+2,l-3)); substEnvVarsInString(env); // recursively expand variables if needed. s = s.left(i)+env+s.right(s.length()-i-l); @@ -1200,7 +1205,7 @@ static QCString configFileToString(const char *name) QFileInfo fi(name); if (!fi.exists() || !fi.isFile()) { - config_err("file `%s' not found\n",name); + config_err("file '%s' not found\n",name); return ""; } f.setName(name); @@ -1221,7 +1226,7 @@ static QCString configFileToString(const char *name) } if (!fileOpened) { - config_err("cannot open file `%s' for reading\n",name); + config_err("cannot open file '%s' for reading\n",name); exit(1); } return ""; @@ -1316,7 +1321,9 @@ void Config::init() void Config::checkAndCorrect() { - QCString &warnFormat = ConfigImpl_getString("WARN_FORMAT"); + ConfigValues::instance().init(); + + QCString &warnFormat = Config_getString(WARN_FORMAT); if (warnFormat.stripWhiteSpace().isEmpty()) { warnFormat="$file:$line $text"; @@ -1338,7 +1345,7 @@ void Config::checkAndCorrect() } } - QCString &manExtension = ConfigImpl_getString("MAN_EXTENSION"); + QCString &manExtension = Config_getString(MAN_EXTENSION); // set default man page extension if non is given by the user if (manExtension.isEmpty()) @@ -1346,7 +1353,7 @@ void Config::checkAndCorrect() manExtension=".3"; } - QCString &paperType = ConfigImpl_getEnum("PAPER_TYPE"); + QCString &paperType = Config_getEnum(PAPER_TYPE); paperType=paperType.lower().stripWhiteSpace(); if (paperType.isEmpty() || paperType=="a4wide") { @@ -1359,14 +1366,14 @@ void Config::checkAndCorrect() paperType="a4"; } - QCString &outputLanguage=ConfigImpl_getEnum("OUTPUT_LANGUAGE"); + QCString &outputLanguage=Config_getEnum(OUTPUT_LANGUAGE); outputLanguage=outputLanguage.stripWhiteSpace(); if (outputLanguage.isEmpty()) { outputLanguage = "English"; } - QCString &htmlFileExtension=ConfigImpl_getString("HTML_FILE_EXTENSION"); + QCString &htmlFileExtension=Config_getString(HTML_FILE_EXTENSION); htmlFileExtension=htmlFileExtension.stripWhiteSpace(); if (htmlFileExtension.isEmpty()) { @@ -1374,7 +1381,7 @@ void Config::checkAndCorrect() } // expand the relative stripFromPath values - QStrList &stripFromPath = ConfigImpl_getList("STRIP_FROM_PATH"); + QStrList &stripFromPath = Config_getList(STRIP_FROM_PATH); char *sfp = stripFromPath.first(); if (sfp==0) // by default use the current path { @@ -1389,49 +1396,49 @@ void Config::checkAndCorrect() } // expand the relative stripFromPath values - QStrList &stripFromIncPath = ConfigImpl_getList("STRIP_FROM_INC_PATH"); + QStrList &stripFromIncPath = Config_getList(STRIP_FROM_INC_PATH); cleanUpPaths(stripFromIncPath); // Test to see if HTML header is valid - QCString &headerFile = ConfigImpl_getString("HTML_HEADER"); + QCString &headerFile = Config_getString(HTML_HEADER); if (!headerFile.isEmpty()) { QFileInfo fi(headerFile); if (!fi.exists()) { - err("tag HTML_HEADER: header file `%s' " + err("tag HTML_HEADER: header file '%s' " "does not exist\n",headerFile.data()); exit(1); } } // Test to see if HTML footer is valid - QCString &footerFile = ConfigImpl_getString("HTML_FOOTER"); + QCString &footerFile = Config_getString(HTML_FOOTER); if (!footerFile.isEmpty()) { QFileInfo fi(footerFile); if (!fi.exists()) { - err("tag HTML_FOOTER: footer file `%s' " + err("tag HTML_FOOTER: footer file '%s' " "does not exist\n",footerFile.data()); exit(1); } } // Test to see if MathJax code file is valid - if (ConfigImpl_getBool("USE_MATHJAX")) + if (Config_getBool(USE_MATHJAX)) { - QCString &MathJaxCodefile = ConfigImpl_getString("MATHJAX_CODEFILE"); + QCString &MathJaxCodefile = Config_getString(MATHJAX_CODEFILE); if (!MathJaxCodefile.isEmpty()) { QFileInfo fi(MathJaxCodefile); if (!fi.exists()) { - err("tag MATHJAX_CODEFILE file `%s' " + err("tag MATHJAX_CODEFILE file '%s' " "does not exist\n",MathJaxCodefile.data()); exit(1); } } - QCString &path = ConfigImpl_getString("MATHJAX_RELPATH"); + QCString &path = Config_getString(MATHJAX_RELPATH); if (!path.isEmpty() && path.at(path.length()-1)!='/') { path+="/"; @@ -1440,43 +1447,43 @@ void Config::checkAndCorrect() } // Test to see if LaTeX header is valid - QCString &latexHeaderFile = ConfigImpl_getString("LATEX_HEADER"); + QCString &latexHeaderFile = Config_getString(LATEX_HEADER); if (!latexHeaderFile.isEmpty()) { QFileInfo fi(latexHeaderFile); if (!fi.exists()) { - err("tag LATEX_HEADER: header file `%s' " + err("tag LATEX_HEADER: header file '%s' " "does not exist\n",latexHeaderFile.data()); exit(1); } } // Test to see if LaTeX footer is valid - QCString &latexFooterFile = ConfigImpl_getString("LATEX_FOOTER"); + QCString &latexFooterFile = Config_getString(LATEX_FOOTER); if (!latexFooterFile.isEmpty()) { QFileInfo fi(latexFooterFile); if (!fi.exists()) { - err("tag LATEX_FOOTER: footer file `%s' " + err("tag LATEX_FOOTER: footer file '%s' " "does not exist\n",latexFooterFile.data()); exit(1); } } // check include path - QStrList &includePath = ConfigImpl_getList("INCLUDE_PATH"); + QStrList &includePath = Config_getList(INCLUDE_PATH); char *s=includePath.first(); while (s) { QFileInfo fi(s); - if (!fi.exists()) warn_uncond("tag INCLUDE_PATH: include path `%s' " + if (!fi.exists()) warn_uncond("tag INCLUDE_PATH: include path '%s' " "does not exist\n",s); s=includePath.next(); } // check aliases - QStrList &aliasList = ConfigImpl_getList("ALIASES"); + QStrList &aliasList = Config_getList(ALIASES); s=aliasList.first(); while (s) { @@ -1486,33 +1493,33 @@ void Config::checkAndCorrect() alias=alias.stripWhiteSpace(); if (alias.find(re1)!=0 && alias.find(re2)!=0) { - err("Illegal alias format `%s'. Use \"name=value\" or \"name(n)=value\", where n is the number of arguments\n", + err("Illegal alias format '%s'. Use \"name=value\" or \"name(n)=value\", where n is the number of arguments\n", alias.data()); } s=aliasList.next(); } // check if GENERATE_TREEVIEW and GENERATE_HTMLHELP are both enabled - if (ConfigImpl_getBool("GENERATE_TREEVIEW") && ConfigImpl_getBool("GENERATE_HTMLHELP")) + if (Config_getBool(GENERATE_TREEVIEW) && Config_getBool(GENERATE_HTMLHELP)) { err("When enabling GENERATE_HTMLHELP the tree view (GENERATE_TREEVIEW) should be disabled. I'll do it for you.\n"); - ConfigImpl_getBool("GENERATE_TREEVIEW")=FALSE; + Config_getBool(GENERATE_TREEVIEW)=FALSE; } - if (ConfigImpl_getBool("SEARCHENGINE") && ConfigImpl_getBool("GENERATE_HTMLHELP")) + if (Config_getBool(SEARCHENGINE) && Config_getBool(GENERATE_HTMLHELP)) { err("When enabling GENERATE_HTMLHELP the search engine (SEARCHENGINE) should be disabled. I'll do it for you.\n"); - ConfigImpl_getBool("SEARCHENGINE")=FALSE; + Config_getBool(SEARCHENGINE)=FALSE; } // check if SEPARATE_MEMBER_PAGES and INLINE_GROUPED_CLASSES are both enabled - if (ConfigImpl_getBool("SEPARATE_MEMBER_PAGES") && ConfigImpl_getBool("INLINE_GROUPED_CLASSES")) + if (Config_getBool(SEPARATE_MEMBER_PAGES) && Config_getBool(INLINE_GROUPED_CLASSES)) { err("When enabling INLINE_GROUPED_CLASSES the SEPARATE_MEMBER_PAGES option should be disabled. I'll do it for you.\n"); - ConfigImpl_getBool("SEPARATE_MEMBER_PAGES")=FALSE; + Config_getBool(SEPARATE_MEMBER_PAGES)=FALSE; } // check dot image format - QCString &dotImageFormat=ConfigImpl_getEnum("DOT_IMAGE_FORMAT"); + QCString &dotImageFormat=Config_getEnum(DOT_IMAGE_FORMAT); dotImageFormat=dotImageFormat.stripWhiteSpace(); if (dotImageFormat.isEmpty()) { @@ -1520,11 +1527,11 @@ void Config::checkAndCorrect() } //else if (dotImageFormat!="gif" && dotImageFormat!="png" && dotImageFormat!="jpg") //{ - // err("Invalid value for DOT_IMAGE_FORMAT: `%s'. Using the default.\n",dotImageFormat.data()); + // err("Invalid value for DOT_IMAGE_FORMAT: '%s'. Using the default.\n",dotImageFormat.data()); // dotImageFormat = "png"; //} - QCString &dotFontName=ConfigImpl_getString("DOT_FONTNAME"); + QCString &dotFontName=Config_getString(DOT_FONTNAME); if (dotFontName=="FreeSans" || dotFontName=="FreeSans.ttf") { warn_uncond("doxygen no longer ships with the FreeSans font.\n" @@ -1534,7 +1541,7 @@ void Config::checkAndCorrect() // check dot path - QCString &dotPath = ConfigImpl_getString("DOT_PATH"); + QCString &dotPath = Config_getString(DOT_PATH); if (!dotPath.isEmpty()) { QFileInfo fi(dotPath); @@ -1565,32 +1572,8 @@ void Config::checkAndCorrect() dotPath=""; } - // check mscgen path - QCString &mscgenPath = ConfigImpl_getString("MSCGEN_PATH"); - if (!mscgenPath.isEmpty()) - { - QFileInfo dp(mscgenPath+"/mscgen"+portable_commandExtension()); - if (!dp.exists() || !dp.isFile()) - { - warn_uncond("the mscgen tool could not be found at %s\n",mscgenPath.data()); - mscgenPath=""; - } - else - { - mscgenPath=dp.dirPath(TRUE).utf8()+"/"; -#if defined(_WIN32) // convert slashes - uint i=0,l=mscgenPath.length(); - for (i=0;i<l;i++) if (mscgenPath.at(i)=='/') mscgenPath.at(i)='\\'; -#endif - } - } - else // make sure the string is empty but not null! - { - mscgenPath=""; - } - // check plantuml path - QCString &plantumlJarPath = ConfigImpl_getString("PLANTUML_JAR_PATH"); + QCString &plantumlJarPath = Config_getString(PLANTUML_JAR_PATH); if (!plantumlJarPath.isEmpty()) { QFileInfo pu(plantumlJarPath); @@ -1621,7 +1604,7 @@ void Config::checkAndCorrect() } // check dia path - QCString &diaPath = ConfigImpl_getString("DIA_PATH"); + QCString &diaPath = Config_getString(DIA_PATH); if (!diaPath.isEmpty()) { QFileInfo dp(diaPath+"/dia"+portable_commandExtension()); @@ -1645,7 +1628,7 @@ void Config::checkAndCorrect() } // check input - QStrList &inputSources=ConfigImpl_getList("INPUT"); + QStrList &inputSources=Config_getList(INPUT); if (inputSources.count()==0) { // use current dir as the default @@ -1659,14 +1642,14 @@ void Config::checkAndCorrect() QFileInfo fi(s); if (!fi.exists()) { - warn_uncond("tag INPUT: input source `%s' does not exist\n",s); + warn_uncond("tag INPUT: input source '%s' does not exist\n",s); } s=inputSources.next(); } } // add default file patterns if needed - QStrList &filePatternList = ConfigImpl_getList("FILE_PATTERNS"); + QStrList &filePatternList = Config_getList(FILE_PATTERNS); if (filePatternList.isEmpty()) { ConfigOption * opt = ConfigImpl::instance()->get("FILE_PATTERNS"); @@ -1677,65 +1660,65 @@ void Config::checkAndCorrect() } // add default pattern if needed - QStrList &examplePatternList = ConfigImpl_getList("EXAMPLE_PATTERNS"); + QStrList &examplePatternList = Config_getList(EXAMPLE_PATTERNS); if (examplePatternList.isEmpty()) { examplePatternList.append("*"); } // if no output format is enabled, warn the user - if (!ConfigImpl_getBool("GENERATE_HTML") && - !ConfigImpl_getBool("GENERATE_LATEX") && - !ConfigImpl_getBool("GENERATE_MAN") && - !ConfigImpl_getBool("GENERATE_RTF") && - !ConfigImpl_getBool("GENERATE_XML") && - !ConfigImpl_getBool("GENERATE_PERLMOD") && - !ConfigImpl_getBool("GENERATE_RTF") && - !ConfigImpl_getBool("GENERATE_DOCBOOK") && - !ConfigImpl_getBool("GENERATE_AUTOGEN_DEF") && - ConfigImpl_getString("GENERATE_TAGFILE").isEmpty() + if (!Config_getBool(GENERATE_HTML) && + !Config_getBool(GENERATE_LATEX) && + !Config_getBool(GENERATE_MAN) && + !Config_getBool(GENERATE_RTF) && + !Config_getBool(GENERATE_XML) && + !Config_getBool(GENERATE_PERLMOD) && + !Config_getBool(GENERATE_RTF) && + !Config_getBool(GENERATE_DOCBOOK) && + !Config_getBool(GENERATE_AUTOGEN_DEF) && + Config_getString(GENERATE_TAGFILE).isEmpty() ) { warn_uncond("No output formats selected! Set at least one of the main GENERATE_* options to YES.\n"); } // check HTMLHELP creation requirements - if (!ConfigImpl_getBool("GENERATE_HTML") && - ConfigImpl_getBool("GENERATE_HTMLHELP")) + if (!Config_getBool(GENERATE_HTML) && + Config_getBool(GENERATE_HTMLHELP)) { warn_uncond("GENERATE_HTMLHELP=YES requires GENERATE_HTML=YES.\n"); } // check QHP creation requirements - if (ConfigImpl_getBool("GENERATE_QHP")) + if (Config_getBool(GENERATE_QHP)) { - if (ConfigImpl_getString("QHP_NAMESPACE").isEmpty()) + if (Config_getString(QHP_NAMESPACE).isEmpty()) { err("GENERATE_QHP=YES requires QHP_NAMESPACE to be set. Using 'org.doxygen.doc' as default!.\n"); - ConfigImpl_getString("QHP_NAMESPACE")="org.doxygen.doc"; + Config_getString(QHP_NAMESPACE)="org.doxygen.doc"; } - if (ConfigImpl_getString("QHP_VIRTUAL_FOLDER").isEmpty()) + if (Config_getString(QHP_VIRTUAL_FOLDER).isEmpty()) { err("GENERATE_QHP=YES requires QHP_VIRTUAL_FOLDER to be set. Using 'doc' as default!\n"); - ConfigImpl_getString("QHP_VIRTUAL_FOLDER")="doc"; + Config_getString(QHP_VIRTUAL_FOLDER)="doc"; } } - if (ConfigImpl_getBool("OPTIMIZE_OUTPUT_JAVA") && ConfigImpl_getBool("INLINE_INFO")) + if (Config_getBool(OPTIMIZE_OUTPUT_JAVA) && Config_getBool(INLINE_INFO)) { // don't show inline info for Java output, since Java has no inline // concept. - ConfigImpl_getBool("INLINE_INFO")=FALSE; + Config_getBool(INLINE_INFO)=FALSE; } - int &depth = ConfigImpl_getInt("MAX_DOT_GRAPH_DEPTH"); + int &depth = Config_getInt(MAX_DOT_GRAPH_DEPTH); if (depth==0) { depth=1000; } - int &hue = ConfigImpl_getInt("HTML_COLORSTYLE_HUE"); + int &hue = Config_getInt(HTML_COLORSTYLE_HUE); if (hue<0) { hue=0; @@ -1745,7 +1728,7 @@ void Config::checkAndCorrect() hue=hue%360; } - int &sat = ConfigImpl_getInt("HTML_COLORSTYLE_SAT"); + int &sat = Config_getInt(HTML_COLORSTYLE_SAT); if (sat<0) { sat=0; @@ -1754,7 +1737,7 @@ void Config::checkAndCorrect() { sat=255; } - int &gamma = ConfigImpl_getInt("HTML_COLORSTYLE_GAMMA"); + int &gamma = Config_getInt(HTML_COLORSTYLE_GAMMA); if (gamma<40) { gamma=40; @@ -1764,16 +1747,16 @@ void Config::checkAndCorrect() gamma=240; } - QCString mathJaxFormat = ConfigImpl_getEnum("MATHJAX_FORMAT"); + QCString mathJaxFormat = Config_getEnum(MATHJAX_FORMAT); if (!mathJaxFormat.isEmpty() && mathJaxFormat!="HTML-CSS" && mathJaxFormat!="NativeMML" && mathJaxFormat!="SVG") { err("Unsupported value for MATHJAX_FORMAT: Should be one of HTML-CSS, NativeMML, or SVG\n"); - ConfigImpl_getEnum("MATHJAX_FORMAT")="HTML-CSS"; + Config_getEnum(MATHJAX_FORMAT)="HTML-CSS"; } // add default words if needed - QStrList &annotationFromBrief = ConfigImpl_getList("ABBREVIATE_BRIEF"); + QStrList &annotationFromBrief = Config_getList(ABBREVIATE_BRIEF); if (annotationFromBrief.isEmpty()) { annotationFromBrief.append("The $name class"); @@ -1790,21 +1773,21 @@ void Config::checkAndCorrect() } // some default settings for vhdl - if (ConfigImpl_getBool("OPTIMIZE_OUTPUT_VHDL") && - (ConfigImpl_getBool("INLINE_INHERITED_MEMB") || - ConfigImpl_getBool("INHERIT_DOCS") || - !ConfigImpl_getBool("HIDE_SCOPE_NAMES") || - !ConfigImpl_getBool("EXTRACT_PRIVATE") || - !ConfigImpl_getBool("EXTRACT_PACKAGE") + if (Config_getBool(OPTIMIZE_OUTPUT_VHDL) && + (Config_getBool(INLINE_INHERITED_MEMB) || + Config_getBool(INHERIT_DOCS) || + !Config_getBool(HIDE_SCOPE_NAMES) || + !Config_getBool(EXTRACT_PRIVATE) || + !Config_getBool(EXTRACT_PACKAGE) ) ) { - bool b1 = ConfigImpl_getBool("INLINE_INHERITED_MEMB"); - bool b2 = ConfigImpl_getBool("INHERIT_DOCS"); - bool b3 = ConfigImpl_getBool("HIDE_SCOPE_NAMES"); - bool b4 = ConfigImpl_getBool("EXTRACT_PRIVATE"); - bool b5 = ConfigImpl_getBool("SKIP_FUNCTION_MACROS"); - bool b6 = ConfigImpl_getBool("EXTRACT_PACKAGE"); + bool b1 = Config_getBool(INLINE_INHERITED_MEMB); + bool b2 = Config_getBool(INHERIT_DOCS); + bool b3 = Config_getBool(HIDE_SCOPE_NAMES); + bool b4 = Config_getBool(EXTRACT_PRIVATE); + bool b5 = Config_getBool(SKIP_FUNCTION_MACROS); + bool b6 = Config_getBool(EXTRACT_PACKAGE); const char *s1,*s2,*s3,*s4,*s5,*s6; if (b1) s1=" INLINE_INHERITED_MEMB = NO (was YES)\n"; else s1=""; if (b2) s2=" INHERIT_DOCS = NO (was YES)\n"; else s2=""; @@ -1818,15 +1801,15 @@ void Config::checkAndCorrect() "%s%s%s%s%s%s",s1,s2,s3,s4,s5,s6 ); - ConfigImpl_getBool("INLINE_INHERITED_MEMB") = FALSE; - ConfigImpl_getBool("INHERIT_DOCS") = FALSE; - ConfigImpl_getBool("HIDE_SCOPE_NAMES") = TRUE; - ConfigImpl_getBool("EXTRACT_PRIVATE") = TRUE; - ConfigImpl_getBool("ENABLE_PREPROCESSING") = FALSE; - ConfigImpl_getBool("EXTRACT_PACKAGE") = TRUE; + Config_getBool(INLINE_INHERITED_MEMB) = FALSE; + Config_getBool(INHERIT_DOCS) = FALSE; + Config_getBool(HIDE_SCOPE_NAMES) = TRUE; + Config_getBool(EXTRACT_PRIVATE) = TRUE; + Config_getBool(ENABLE_PREPROCESSING) = FALSE; + Config_getBool(EXTRACT_PACKAGE) = TRUE; } - checkFileName(ConfigImpl_getString("GENERATE_TAGFILE"),"GENERATE_TAGFILE"); + checkFileName(Config_getString(GENERATE_TAGFILE),"GENERATE_TAGFILE"); #if 0 // TODO: this breaks test 25; SOURCEBROWSER = NO and SOURCE_TOOLTIPS = YES. // So this and other regressions should be analysed and fixed before this can be enabled @@ -1852,7 +1835,6 @@ void Config::checkAndCorrect() } #endif - ConfigValues::instance().init(); } @@ -1882,10 +1864,10 @@ void Config::postProcess(bool clearHeaderAndFooter, bool compare) // refers to the files that we are supposed to parse. if (clearHeaderAndFooter) { - ConfigImpl_getString("HTML_HEADER")=""; - ConfigImpl_getString("HTML_FOOTER")=""; - ConfigImpl_getString("LATEX_HEADER")=""; - ConfigImpl_getString("LATEX_FOOTER")=""; + Config_getString(HTML_HEADER)=""; + Config_getString(HTML_FOOTER)=""; + Config_getString(LATEX_HEADER)=""; + Config_getString(LATEX_FOOTER)=""; } } diff --git a/src/constexp.h b/src/constexp.h index d84e94e..8bf582e 100644 --- a/src/constexp.h +++ b/src/constexp.h @@ -22,12 +22,21 @@ #include "cppvalue.h" #include <qcstring.h> -extern bool parseconstexp(const char *fileName,int line,const QCString &s); -extern int constexpYYparse(); -extern int constexpYYdebug; -extern QCString g_strToken; -extern CPPValue g_resultValue; -extern QCString g_constExpFileName; -extern int g_constExpLineNr; +#define YYSTYPE CPPValue +typedef void* yyscan_t; +struct constexpYY_state +{ + QCString g_strToken; + CPPValue g_resultValue; + int g_constExpLineNr; + QCString g_constExpFileName; + + const char *g_inputString; + int g_inputPosition; +}; +extern bool parseconstexp(const char *fileName,int line,const QCString &s); +extern int constexpYYparse(yyscan_t); +extern int constexpYYlex(YYSTYPE *lvalp, yyscan_t); +struct constexpYY_state* constexpYYget_extra (yyscan_t yyscanner ); #endif diff --git a/src/constexp.l b/src/constexp.l index 8a7db04..c9b984a 100644 --- a/src/constexp.l +++ b/src/constexp.l @@ -17,44 +17,30 @@ */ %option never-interactive %option prefix="constexpYY" +%option nounput +%option reentrant bison-bridge +%option extra-type="struct constexpYY_state *" %{ #include "constexp.h" #include "cppvalue.h" -#include "ce_parse.h" // generated header file +#include "ce_parse.hpp" // generated header file #include "message.h" #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 - -QCString g_strToken; -CPPValue g_resultValue; -int g_constExpLineNr; -QCString g_constExpFileName; -static const char *g_inputString; -static int g_inputPosition; -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); +static int yyread(char *buf,int max_size,yyscan_t yyscanner); -static int yyread(char *buf,int max_size) -{ - int c=0; - while( c < max_size && g_inputString[g_inputPosition] ) - { - *buf = g_inputString[g_inputPosition++] ; - c++; buf++; - } - return c; -} +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size,yyscanner); %} CONSTSUFFIX ([uU][lL]?[lL]?)|([lL][lL]?[uU]?) -%option nounput %% @@ -83,44 +69,73 @@ CONSTSUFFIX ([uU][lL]?[lL]?)|([lL][lL]?[uU]?) "(" { return TOK_LPAREN; } ")" { return TOK_RPAREN; } "'"(([^\'\n\r\\]+)|(\\(([ntvbrfa\\?'\"])|([0-9]+)|([xX][0-9a-fA-F]+))))"'" { - g_strToken=yytext; + yyextra->g_strToken=yytext; return TOK_CHARACTER; } -0[0-7]*{CONSTSUFFIX}? { g_strToken=yytext; +0[0-7]*{CONSTSUFFIX}? { yyextra->g_strToken=yytext; return TOK_OCTALINT; } -[1-9][0-9]*{CONSTSUFFIX}? { g_strToken=yytext; +[1-9][0-9]*{CONSTSUFFIX}? { yyextra->g_strToken=yytext; return TOK_DECIMALINT; } -(0x|0X)[0-9a-fA-F]+{CONSTSUFFIX}? { g_strToken=yytext+2; +(0x|0X)[0-9a-fA-F]+{CONSTSUFFIX}? { yyextra->g_strToken=yytext+2; return TOK_HEXADECIMALINT; } (([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+))([eE]([\-\+])?[0-9]+)?([fFlL])? { - g_strToken=yytext; return TOK_FLOAT; + yyextra->g_strToken=yytext; return TOK_FLOAT; } ([0-9]+[eE])([\-\+])?[0-9]+([fFlL])? { - g_strToken=yytext; return TOK_FLOAT; + yyextra->g_strToken=yytext; return TOK_FLOAT; } . \n %% +static int yyread(char *buf,int max_size,yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + int c=0; + while( c < max_size && yyextra->g_inputString[yyextra->g_inputPosition] ) + { + *buf = yyextra->g_inputString[yyextra->g_inputPosition++] ; + c++; buf++; + } + return c; +} + + +static yyscan_t yyscanner; +static struct constexpYY_state constexpYY_extra; + bool parseconstexp(const char *fileName,int lineNr,const QCString &s) { + constexpYYlex_init_extra(&constexpYY_extra, &yyscanner); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + +#ifdef FLEX_DEBUG + yyset_debug(1,yyscanner); +#endif + + yyextra->g_constExpFileName = fileName; + yyextra->g_constExpLineNr = lineNr; + yyextra->g_inputString = s; + yyextra->g_inputPosition = 0; + constexpYYrestart( yyin, yyscanner ); + printlex(yy_flex_debug, TRUE, __FILE__, fileName); - //printf("Expression: `%s'\n",s.data()); - g_constExpFileName = fileName; - g_constExpLineNr = lineNr; - g_inputString = s; - g_inputPosition = 0; - constexpYYrestart( constexpYYin ); - constexpYYparse(); + //printf("Expression: '%s'\n",s.data()); + + constexpYYparse(yyscanner); + //printf("Result: %ld\n",(long)g_resultValue); printlex(yy_flex_debug, FALSE, __FILE__, fileName); - return (long)g_resultValue!=0; + bool result = (long)yyextra->g_resultValue!=0; + + constexpYYlex_destroy(yyscanner); + return result; } extern "C" { - int constexpYYwrap() { return 1; } + int constexpYYwrap(yyscan_t yyscanner) { return 1; } } diff --git a/src/constexp.y b/src/constexp.y index f87ebf3..62a51f3 100644 --- a/src/constexp.y +++ b/src/constexp.y @@ -26,24 +26,24 @@ #define MSDOS #endif -#define YYSTYPE CPPValue #include <stdio.h> #include <stdlib.h> -int constexpYYerror(const char *s) +int constexpYYerror(yyscan_t yyscanner, const char *s) { - warn(g_constExpFileName,g_constExpLineNr, + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + warn(yyextra->g_constExpFileName, yyextra->g_constExpLineNr, "preprocessing issue while doing constant expression evaluation: %s",s); return 0; } -int constexpYYlex(); - %} -%no-lines -%name-prefix="constexpYY" +%name-prefix "constexpYY" +%define api.pure full +%lex-param {yyscan_t yyscanner} +%parse-param {yyscan_t yyscanner} %token TOK_QUESTIONMARK %token TOK_COLON @@ -78,7 +78,10 @@ int constexpYYlex(); %% start: constant_expression - { g_resultValue = $1; return 0; } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + yyextra->g_resultValue = $1; return 0; + } ; constant_expression: logical_or_expression @@ -267,15 +270,30 @@ primary_expression: constant ; constant: TOK_OCTALINT - { $$ = parseOctal(); } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + $$ = parseOctal(yyextra->g_strToken); + } | TOK_DECIMALINT - { $$ = parseDecimal(); } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + $$ = parseDecimal(yyextra->g_strToken); + } | TOK_HEXADECIMALINT - { $$ = parseHexadecimal(); } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + $$ = parseHexadecimal(yyextra->g_strToken); + } | TOK_CHARACTER - { $$ = parseCharacter(); } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + $$ = parseCharacter(yyextra->g_strToken); + } | TOK_FLOAT - { $$ = parseFloat(); } + { + struct constexpYY_state* yyextra = constexpYYget_extra(yyscanner); + $$ = parseFloat(yyextra->g_strToken); + } ; %% diff --git a/src/context.cpp b/src/context.cpp index 6b5d2ac..49c9afa 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -39,6 +39,12 @@ #include "latexgen.h" #include "latexdocvisitor.h" #include "dot.h" +#include "dotcallgraph.h" +#include "dotclassgraph.h" +#include "dotdirdeps.h" +#include "dotgfxhierarchytable.h" +#include "dotgroupcollaboration.h" +#include "dotincldepgraph.h" #include "diagram.h" #include "example.h" #include "membername.h" @@ -374,7 +380,7 @@ class DoxygenContext::Private public: TemplateVariant version() const { - return versionString; + return getVersion(); } TemplateVariant date() const { @@ -1254,7 +1260,7 @@ TemplateVariant TranslateContext::get(const char *n) const return p->get(n); } -static TemplateVariant parseDoc(Definition *def,const QCString &file,int line, +static TemplateVariant parseDoc(const Definition *def,const QCString &file,int line, const QCString &relPath,const QCString &docStr,bool isBrief) { TemplateVariant result; @@ -1324,7 +1330,7 @@ static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const Q return TemplateVariant(s.data(),TRUE); } -static TemplateVariant parseCode(FileDef *fd,const QCString &relPath) +static TemplateVariant parseCode(const FileDef *fd,const QCString &relPath) { static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); ParserInterface *pIntf = Doxygen::parserManager->getParser(fd->getDefFileExtension()); @@ -1341,7 +1347,7 @@ static TemplateVariant parseCode(FileDef *fd,const QCString &relPath) fd->getLanguage(), // lang FALSE, // isExampleBlock 0, // exampleName - fd, // fileDef + const_cast<FileDef*>(fd), // fileDef, TODO: should be const -1, // startLine -1, // endLine FALSE, // inlineFragment @@ -1360,7 +1366,7 @@ static TemplateVariant parseCode(FileDef *fd,const QCString &relPath) fd->getLanguage(), // lang FALSE, // isExampleBlock 0, // exampleName - fd, // fileDef + const_cast<FileDef*>(fd), // fileDef, TODO: should be const -1, // startLine -1, // endLine FALSE, // inlineFragment @@ -1387,7 +1393,7 @@ template<typename T> class DefinitionContext { public: - DefinitionContext(Definition *d) : m_def(d) + DefinitionContext(const Definition *d) : m_def(d) { assert(d!=0); } @@ -1574,17 +1580,17 @@ class DefinitionContext return FALSE; } } - void fillPath(Definition *def,TemplateList *list) const + void fillPath(const Definition *def,TemplateList *list) const { - Definition *outerScope = def->getOuterScope(); + const Definition *outerScope = def->getOuterScope(); Definition::DefType type = def->definitionType(); if (outerScope && outerScope!=Doxygen::globalScope) { fillPath(outerScope,list); } - else if (type==Definition::TypeFile && ((const FileDef*)def)->getDirDef()) + else if (type==Definition::TypeFile && (dynamic_cast<const FileDef*>(def))->getDirDef()) { - fillPath(((const FileDef*)def)->getDirDef(),list); + fillPath((dynamic_cast<const FileDef*>(def))->getDirDef(),list); } list->append(NavPathElemContext::alloc(def)); } @@ -1598,9 +1604,9 @@ class DefinitionContext { fillPath(m_def->getOuterScope(),list); } - else if (m_def->definitionType()==Definition::TypeFile && ((const FileDef *)m_def)->getDirDef()) + else if (m_def->definitionType()==Definition::TypeFile && (dynamic_cast<const FileDef *>(m_def))->getDirDef()) { - fillPath(((const FileDef *)m_def)->getDirDef(),list); + fillPath((dynamic_cast<const FileDef *>(m_def))->getDirDef(),list); } cache.navPath.reset(list); } @@ -1618,7 +1624,7 @@ class DefinitionContext protected: struct Cachable : public Definition::Cookie { - Cachable(Definition *def) : detailsOutputFormat(ContextOutputFormat_Unspecified), + Cachable(const Definition *def) : detailsOutputFormat(ContextOutputFormat_Unspecified), briefOutputFormat(ContextOutputFormat_Unspecified), inbodyDocsOutputFormat(ContextOutputFormat_Unspecified) { @@ -1675,7 +1681,7 @@ class DefinitionContext assert(c!=0); return *c; } - Definition *m_def; + const Definition *m_def; }; //%% } @@ -1810,7 +1816,7 @@ TemplateListIntf::ConstIterator *IncludeInfoListContext::createIterator() const class ClassContext::Private : public DefinitionContext<ClassContext::Private> { public: - Private(ClassDef *cd) : DefinitionContext<ClassContext::Private>(cd), + Private(const ClassDef *cd) : DefinitionContext<ClassContext::Private>(cd), m_classDef(cd) { static bool init=FALSE; @@ -1926,7 +1932,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> Cachable &cache = getCache(); if (!cache.classGraph) { - cache.classGraph.reset(new DotClassGraph(m_classDef,DotNode::Inheritance)); + cache.classGraph.reset(new DotClassGraph(m_classDef,Inheritance)); } return cache.classGraph.get(); } @@ -2048,7 +2054,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> Cachable &cache = getCache(); if (!cache.collaborationGraph) { - cache.collaborationGraph.reset(new DotClassGraph(m_classDef,DotNode::Collaboration)); + cache.collaborationGraph.reset(new DotClassGraph(m_classDef,Collaboration)); } return cache.collaborationGraph.get(); } @@ -2322,7 +2328,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> if (m_classDef->getClassSDict()) { ClassSDict::Iterator sdi(*m_classDef->getClassSDict()); - ClassDef *cd; + const ClassDef *cd; for (sdi.toFirst();(cd=sdi.current());++sdi) { if (cd->visibleInParentsDeclList()) @@ -2344,7 +2350,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> if (m_classDef->getClassSDict()) { ClassSDict::Iterator sdi(*m_classDef->getClassSDict()); - ClassDef *cd; + const ClassDef *cd; for (sdi.toFirst();(cd=sdi.current());++sdi) { if (cd->name().find('@')==-1 && @@ -2365,16 +2371,16 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> { return m_classDef->compoundTypeString(); } - void addTemplateDecls(Definition *d,TemplateList *tl) const + void addTemplateDecls(const Definition *d,TemplateList *tl) const { if (d->definitionType()==Definition::TypeClass) { - Definition *parent = d->getOuterScope(); + const Definition *parent = d->getOuterScope(); if (parent) { addTemplateDecls(parent,tl); } - ClassDef *cd=(ClassDef *)d; + const ClassDef *cd=dynamic_cast<const ClassDef *>(d); if (cd->templateArguments()) { ArgumentListContext *al = ArgumentListContext::alloc(cd->templateArguments(),cd,relPathAsString()); @@ -2438,7 +2444,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> } return cache.examples.get(); } - void addMembers(ClassDef *cd,MemberListType lt) const + void addMembers(const ClassDef *cd,MemberListType lt) const { MemberList *ml = cd->getMemberList(lt); if (ml) @@ -2595,10 +2601,10 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> } private: - ClassDef *m_classDef; + const ClassDef *m_classDef; struct Cachable : public DefinitionContext<ClassContext::Private>::Cachable { - Cachable(ClassDef *cd) : DefinitionContext<ClassContext::Private>::Cachable(cd), + Cachable(const ClassDef *cd) : DefinitionContext<ClassContext::Private>::Cachable(cd), inheritanceNodes(-1) { } SharedPtr<IncludeInfoContext> includeInfo; SharedPtr<InheritanceListContext> inheritsList; @@ -2672,7 +2678,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> PropertyMapper<ClassContext::Private> ClassContext::Private::s_inst; -ClassContext::ClassContext(ClassDef *cd) : RefCountedContext("ClassContext") +ClassContext::ClassContext(const ClassDef *cd) : RefCountedContext("ClassContext") { //printf("ClassContext::ClassContext(%s)\n",cd?cd->name().data():"<none>"); p = new Private(cd); @@ -2695,7 +2701,7 @@ TemplateVariant ClassContext::get(const char *n) const class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Private> { public: - Private(NamespaceDef *nd) : DefinitionContext<NamespaceContext::Private>(nd), + Private(const NamespaceDef *nd) : DefinitionContext<NamespaceContext::Private>(nd), m_namespaceDef(nd) { static bool init=FALSE; @@ -2764,7 +2770,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri if (m_namespaceDef->getClassSDict()) { ClassSDict::Iterator sdi(*m_namespaceDef->getClassSDict()); - ClassDef *cd; + const ClassDef *cd; for (sdi.toFirst();(cd=sdi.current());++sdi) { if (sliceOpt && (cd->compoundType()==ClassDef::Struct || @@ -2792,7 +2798,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri if (m_namespaceDef->getNamespaceSDict()) { NamespaceSDict::Iterator sdi(*m_namespaceDef->getNamespaceSDict()); - NamespaceDef *nd; + const NamespaceDef *nd; for (sdi.toFirst();(nd=sdi.current());++sdi) { if (nd->isLinkable() && !nd->isConstantGroup()) @@ -2814,7 +2820,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri if (m_namespaceDef->getNamespaceSDict()) { NamespaceSDict::Iterator sdi(*m_namespaceDef->getNamespaceSDict()); - NamespaceDef *nd; + const NamespaceDef *nd; for (sdi.toFirst();(nd=sdi.current());++sdi) { if (nd->isLinkable() && nd->isConstantGroup()) @@ -2932,7 +2938,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri if (m_namespaceDef->getClassSDict()) { ClassSDict::Iterator sdi(*m_namespaceDef->getClassSDict()); - ClassDef *cd; + const ClassDef *cd; for (sdi.toFirst();(cd=sdi.current());++sdi) { if (cd->name().find('@')==-1 && @@ -2949,10 +2955,10 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri return cache.inlineClasses.get(); } private: - NamespaceDef *m_namespaceDef; + const NamespaceDef *m_namespaceDef; struct Cachable : public DefinitionContext<NamespaceContext::Private>::Cachable { - Cachable(NamespaceDef *nd) : DefinitionContext<NamespaceContext::Private>::Cachable(nd) {} + Cachable(const NamespaceDef *nd) : DefinitionContext<NamespaceContext::Private>::Cachable(nd) {} SharedPtr<TemplateList> classes; SharedPtr<TemplateList> interfaces; SharedPtr<TemplateList> namespaces; @@ -2984,7 +2990,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri PropertyMapper<NamespaceContext::Private> NamespaceContext::Private::s_inst; -NamespaceContext::NamespaceContext(NamespaceDef *nd) : RefCountedContext("NamespaceContext") +NamespaceContext::NamespaceContext(const NamespaceDef *nd) : RefCountedContext("NamespaceContext") { p = new Private(nd); } @@ -3006,7 +3012,7 @@ TemplateVariant NamespaceContext::get(const char *n) const class FileContext::Private : public DefinitionContext<FileContext::Private> { public: - Private(FileDef *fd) : DefinitionContext<FileContext::Private>(fd) , m_fileDef(fd) + Private(const FileDef *fd) : DefinitionContext<FileContext::Private>(fd) , m_fileDef(fd) { if (fd==0) abort(); static bool init=FALSE; @@ -3229,7 +3235,7 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> if (m_fileDef->getClassSDict()) { ClassSDict::Iterator sdi(*m_fileDef->getClassSDict()); - ClassDef *cd; + const ClassDef *cd; for (sdi.toFirst();(cd=sdi.current());++sdi) { if (cd->visibleInParentsDeclList()) @@ -3251,7 +3257,7 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> if (m_fileDef->getNamespaceSDict()) { NamespaceSDict::Iterator sdi(*m_fileDef->getNamespaceSDict()); - NamespaceDef *nd; + const NamespaceDef *nd; for (sdi.toFirst();(nd=sdi.current());++sdi) { if (nd->isLinkable() && !nd->isConstantGroup()) @@ -3396,7 +3402,7 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> if (m_fileDef->getClassSDict()) { ClassSDict::Iterator sdi(*m_fileDef->getClassSDict()); - ClassDef *cd; + const ClassDef *cd; for (sdi.toFirst();(cd=sdi.current());++sdi) { if (cd->name().find('@')==-1 && @@ -3418,10 +3424,10 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> } private: - FileDef *m_fileDef; + const FileDef *m_fileDef; struct Cachable : public DefinitionContext<FileContext::Private>::Cachable { - Cachable(FileDef *fd) : DefinitionContext<FileContext::Private>::Cachable(fd) {} + Cachable(const FileDef *fd) : DefinitionContext<FileContext::Private>::Cachable(fd) {} SharedPtr<IncludeInfoListContext> includeInfoList; ScopedPtr<DotInclDepGraph> includeGraph; ScopedPtr<DotInclDepGraph> includedByGraph; @@ -3458,7 +3464,7 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> PropertyMapper<FileContext::Private> FileContext::Private::s_inst; -FileContext::FileContext(FileDef *fd) : RefCountedContext("FileContext") +FileContext::FileContext(const FileDef *fd) : RefCountedContext("FileContext") { p = new Private(fd); } @@ -3480,7 +3486,7 @@ TemplateVariant FileContext::get(const char *n) const class DirContext::Private : public DefinitionContext<DirContext::Private> { public: - Private(DirDef *dd) : DefinitionContext<DirContext::Private>(dd) , m_dirDef(dd) + Private(const DirDef *dd) : DefinitionContext<DirContext::Private>(dd) , m_dirDef(dd) { static bool init=FALSE; if (!init) @@ -3529,7 +3535,7 @@ class DirContext::Private : public DefinitionContext<DirContext::Private> cache.dirs.reset(TemplateList::alloc()); const DirList &subDirs = m_dirDef->subDirs(); QListIterator<DirDef> it(subDirs); - DirDef *dd; + const DirDef *dd; for (it.toFirst();(dd=it.current());++it) { DirContext *dc = new DirContext(dd); @@ -3548,7 +3554,7 @@ class DirContext::Private : public DefinitionContext<DirContext::Private> if (files) { QListIterator<FileDef> it(*files); - FileDef *fd; + const FileDef *fd; for (it.toFirst();(fd=it.current());++it) { FileContext *fc = FileContext::alloc(fd); @@ -3637,10 +3643,10 @@ class DirContext::Private : public DefinitionContext<DirContext::Private> } private: - DirDef *m_dirDef; + const DirDef *m_dirDef; struct Cachable : public DefinitionContext<DirContext::Private>::Cachable { - Cachable(DirDef *dd) : DefinitionContext<DirContext::Private>::Cachable(dd) {} + Cachable(const DirDef *dd) : DefinitionContext<DirContext::Private>::Cachable(dd) {} SharedPtr<TemplateList> dirs; SharedPtr<TemplateList> files; ScopedPtr<DotDirDeps> dirDepsGraph; @@ -3657,7 +3663,7 @@ class DirContext::Private : public DefinitionContext<DirContext::Private> PropertyMapper<DirContext::Private> DirContext::Private::s_inst; -DirContext::DirContext(DirDef *fd) : RefCountedContext("DirContext") +DirContext::DirContext(const DirDef *fd) : RefCountedContext("DirContext") { p = new Private(fd); } @@ -3679,7 +3685,7 @@ TemplateVariant DirContext::get(const char *n) const class PageContext::Private : public DefinitionContext<PageContext::Private> { public: - Private(PageDef *pd,bool isMainPage,bool isExample) + Private(const PageDef *pd,bool isMainPage,bool isExample) : DefinitionContext<PageContext::Private>(pd) , m_pageDef(pd), m_isMainPage(isMainPage), m_isExample(isExample) { @@ -3768,10 +3774,10 @@ class PageContext::Private : public DefinitionContext<PageContext::Private> } } private: - PageDef *m_pageDef; + const PageDef *m_pageDef; struct Cachable : public DefinitionContext<PageContext::Private>::Cachable { - Cachable(PageDef *pd) : DefinitionContext<PageContext::Private>::Cachable(pd), + Cachable(const PageDef *pd) : DefinitionContext<PageContext::Private>::Cachable(pd), exampleOutputFormat(ContextOutputFormat_Unspecified) { } ScopedPtr<TemplateVariant> example; ContextOutputFormat exampleOutputFormat; @@ -3790,7 +3796,7 @@ class PageContext::Private : public DefinitionContext<PageContext::Private> PropertyMapper<PageContext::Private> PageContext::Private::s_inst; -PageContext::PageContext(PageDef *pd,bool isMainPage,bool isExample) : RefCountedContext("PageContext") +PageContext::PageContext(const PageDef *pd,bool isMainPage,bool isExample) : RefCountedContext("PageContext") { p = new Private(pd,isMainPage,isExample); } @@ -3854,7 +3860,7 @@ class TextGeneratorHtml : public TextGeneratorIntf if (ref) { m_ts << "<a class=\"elRef\" "; - m_ts << externalLinkTarget() << externalRef(m_relPath,ref,FALSE); + m_ts << externalLinkTarget(); } else { @@ -3949,7 +3955,7 @@ class TextGeneratorFactory virtual ~TextGeneratorFactory() {} }; -TemplateVariant createLinkedText(Definition *def,const QCString &relPath,const QCString &text) +TemplateVariant createLinkedText(const Definition *def,const QCString &relPath,const QCString &text) { QGString s; FTextStream ts(&s); @@ -4023,7 +4029,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> s_inst.addProperty("isSealed", &Private::isSealed); s_inst.addProperty("isImplementation", &Private::isImplementation); s_inst.addProperty("isExternal", &Private::isExternal); - s_inst.addProperty("isAlias", &Private::isAlias); + s_inst.addProperty("isTypeAlias", &Private::isTypeAlias); s_inst.addProperty("isDefault", &Private::isDefault); s_inst.addProperty("isDelete", &Private::isDelete); s_inst.addProperty("isNoExcept", &Private::isNoExcept); @@ -4334,9 +4340,9 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> { return m_memberDef->isExternal(); } - TemplateVariant isAlias() const + TemplateVariant isTypeAlias() const { - return m_memberDef->isAlias(); + return m_memberDef->isTypeAlias(); } TemplateVariant isDefault() const { @@ -4452,7 +4458,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> Cachable &cache = getCache(); if (!cache.anonymousType) { - ClassDef *cd = m_memberDef->getClassDefOfAnonymousType(); + const ClassDef *cd = m_memberDef->getClassDefOfAnonymousType(); if (cd) { cache.anonymousType.reset(ClassContext::alloc(cd)); @@ -4508,7 +4514,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> Cachable &cache = getCache(); if (!cache.enumValues) { - MemberList *ml = m_memberDef->enumFieldList(); + const MemberList *ml = m_memberDef->enumFieldList(); if (ml) { cache.enumValues.reset(MemberListContext::alloc(ml)); @@ -4538,7 +4544,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> } TemplateVariant templateAlias() const { - if (m_memberDef->isAlias()) + if (m_memberDef->isTypeAlias()) { return createLinkedText(m_memberDef,relPathAsString(), QCString(" = ")+m_memberDef->typeString()); @@ -4638,7 +4644,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> return createLinkedText(m_memberDef,relPathAsString(), m_memberDef->displayDefinition()); } - ArgumentList *getDefArgList() const + const ArgumentList *getDefArgList() const { return (m_memberDef->isDocsForDefinition()) ? m_memberDef->argumentList() : m_memberDef->declArgumentList(); @@ -4648,7 +4654,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> Cachable &cache = getCache(); if (!cache.arguments) { - ArgumentList *defArgList = getDefArgList(); + const ArgumentList *defArgList = getDefArgList(); if (defArgList && !m_memberDef->isProperty()) { cache.arguments.reset(ArgumentListContext::alloc(defArgList,m_memberDef,relPathAsString())); @@ -4666,27 +4672,27 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> } TemplateVariant hasConstQualifier() const { - ArgumentList *al = getDefArgList(); + const ArgumentList *al = getDefArgList(); return al ? al->constSpecifier : FALSE; } TemplateVariant hasVolatileQualifier() const { - ArgumentList *al = getDefArgList(); + const ArgumentList *al = getDefArgList(); return al ? al->volatileSpecifier : FALSE; } TemplateVariant hasRefQualifierLValue() const { - ArgumentList *al = getDefArgList(); + const ArgumentList *al = getDefArgList(); return al ? al->refQualifier==RefQualifierLValue : FALSE; } TemplateVariant hasRefQualifierRValue() const { - ArgumentList *al = getDefArgList(); + const ArgumentList *al = getDefArgList(); return al ? al->refQualifier==RefQualifierRValue : FALSE; } TemplateVariant trailingReturnType() const { - ArgumentList *al = getDefArgList(); + const ArgumentList *al = getDefArgList(); if (al && !al->trailingReturnType.isEmpty()) { return createLinkedText(m_memberDef,relPathAsString(), @@ -4703,7 +4709,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> } void addTemplateDecls(TemplateList *tl) const { - ClassDef *cd=m_memberDef->getClassDef(); + const ClassDef *cd=m_memberDef->getClassDef(); if (m_memberDef->definitionTemplateParameterLists()) { QListIterator<ArgumentList> ali(*m_memberDef->definitionTemplateParameterLists()); @@ -4813,7 +4819,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> cache.implements.reset(TemplateList::alloc()); if (md) { - ClassDef *cd = md->getClassDef(); + const ClassDef *cd = md->getClassDef(); if (cd && (md->virtualness()==Pure || cd->compoundType()==ClassDef::Interface)) { MemberContext *mc = MemberContext::alloc(md); @@ -4832,7 +4838,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> cache.reimplements.reset(TemplateList::alloc()); if (md) { - ClassDef *cd = md->getClassDef(); + const ClassDef *cd = md->getClassDef(); if (cd && md->virtualness()!=Pure && cd->compoundType()!=ClassDef::Interface) { MemberContext *mc = MemberContext::alloc(md); @@ -4855,7 +4861,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> MemberDef *md=0; for (mli.toFirst();(md=mli.current());++mli) { - ClassDef *cd = md->getClassDef(); + const ClassDef *cd = md->getClassDef(); if (cd && (md->virtualness()==Pure || cd->compoundType()==ClassDef::Interface)) { MemberContext *mc = new MemberContext(md); @@ -4879,7 +4885,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> MemberDef *md=0; for (mli.toFirst();(md=mli.current());++mli) { - ClassDef *cd = md->getClassDef(); + const ClassDef *cd = md->getClassDef(); if (cd && md->virtualness()!=Pure && cd->compoundType()!=ClassDef::Interface) { MemberContext *mc = new MemberContext(md); @@ -4976,7 +4982,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> if (!cache.sourceCodeParsed) { QCString codeFragment; - FileDef *fd = m_memberDef->getBodyDef(); + const FileDef *fd = m_memberDef->getBodyDef(); int startLine = m_memberDef->getStartBodyLine(); int endLine = m_memberDef->getEndBodyLine(); if (fd && readCodeFragment(fd->absFilePath(), @@ -5271,7 +5277,7 @@ TemplateVariant MemberContext::get(const char *n) const class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> { public: - Private(GroupDef *gd) : DefinitionContext<ModuleContext::Private>(gd) , m_groupDef(gd) + Private(const GroupDef *gd) : DefinitionContext<ModuleContext::Private>(gd) , m_groupDef(gd) { static bool init=FALSE; if (!init) @@ -5416,7 +5422,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> if (m_groupDef->getSubGroups()) { GroupListIterator gli(*m_groupDef->getSubGroups()); - GroupDef *gd; + const GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { if (gd->isVisible()) @@ -5438,7 +5444,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> if (m_groupDef->getExamples()) { PageSDict::Iterator eli(*m_groupDef->getExamples()); - PageDef *ex; + const PageDef *ex; for (eli.toFirst();(ex=eli.current());++eli) { exampleList->append(PageContext::alloc(ex,FALSE,TRUE)); @@ -5457,7 +5463,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> if (m_groupDef->getExamples()) { PageSDict::Iterator eli(*m_groupDef->getPages()); - PageDef *ex; + const PageDef *ex; for (eli.toFirst();(ex=eli.current());++eli) { pageList->append(PageContext::alloc(ex,FALSE,TRUE)); @@ -5476,7 +5482,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> if (m_groupDef->getDirs()) { QListIterator<DirDef> it(*m_groupDef->getDirs()); - DirDef *dd; + const DirDef *dd; for (it.toFirst();(dd=it.current());++it) { dirList->append(DirContext::alloc(dd)); @@ -5495,7 +5501,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> if (m_groupDef->getFiles()) { QListIterator<FileDef> it(*m_groupDef->getFiles()); - FileDef *fd; + const FileDef *fd; for (it.toFirst();(fd=it.current());++it) { fileList->append(FileContext::alloc(fd)); @@ -5514,7 +5520,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> if (m_groupDef->getClasses()) { ClassSDict::Iterator sdi(*m_groupDef->getClasses()); - ClassDef *cd; + const ClassDef *cd; for (sdi.toFirst();(cd=sdi.current());++sdi) { if (cd->visibleInParentsDeclList()) @@ -5536,7 +5542,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> if (m_groupDef->getNamespaces()) { NamespaceSDict::Iterator sdi(*m_groupDef->getNamespaces()); - NamespaceDef *nd; + const NamespaceDef *nd; for (sdi.toFirst();(nd=sdi.current());++sdi) { if (nd->isLinkable() && !nd->isConstantGroup()) @@ -5730,7 +5736,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> if (m_groupDef->getClasses()) { ClassSDict::Iterator sdi(*m_groupDef->getClasses()); - ClassDef *cd; + const ClassDef *cd; for (sdi.toFirst();(cd=sdi.current());++sdi) { if (cd->name().find('@')==-1 && @@ -5751,10 +5757,10 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> return "module"; //theTranslator->trGroup(FALSE,TRUE); } private: - GroupDef *m_groupDef; + const GroupDef *m_groupDef; struct Cachable : public DefinitionContext<ModuleContext::Private>::Cachable { - Cachable(GroupDef *gd) : DefinitionContext<ModuleContext::Private>::Cachable(gd) {} + Cachable(const GroupDef *gd) : DefinitionContext<ModuleContext::Private>::Cachable(gd) {} SharedPtr<TemplateList> modules; SharedPtr<TemplateList> dirs; SharedPtr<TemplateList> files; @@ -5805,7 +5811,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> PropertyMapper<ModuleContext::Private> ModuleContext::Private::s_inst; -ModuleContext::ModuleContext(GroupDef *gd) : RefCountedContext("ModuleContext") +ModuleContext::ModuleContext(const GroupDef *gd) : RefCountedContext("ModuleContext") { p = new Private(gd); } @@ -5829,7 +5835,7 @@ class ClassListContext::Private : public GenericNodeListContext void addClasses(const ClassSDict &classSDict) { ClassSDict::Iterator cli(classSDict); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst() ; (cd=cli.current()) ; ++cli ) { if (cd->getLanguage()==SrcLangExt_VHDL && @@ -5908,7 +5914,7 @@ class ClassIndexContext::Private if (Doxygen::classSDict) { ClassSDict::Iterator cli(*Doxygen::classSDict); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst() ; (cd=cli.current()) ; ++cli ) { if (cd->getLanguage()==SrcLangExt_VHDL && @@ -6216,7 +6222,7 @@ class NestingNodeContext::Private { public: Private(const NestingNodeContext *parent,const NestingNodeContext *thisNode, - Definition *d,int index,int level,bool addCls,bool inherit, bool hideSuper) + const Definition *d,int index,int level,bool addCls,bool inherit, bool hideSuper) : m_parent(parent), m_def(d), m_level(level), m_index(index) { m_children.reset(NestingContext::alloc(thisNode,level+1)); @@ -6278,7 +6284,7 @@ class NestingNodeContext::Private { if (!m_cache.classContext && m_def->definitionType()==Definition::TypeClass) { - m_cache.classContext.reset(ClassContext::alloc((ClassDef*)m_def)); + m_cache.classContext.reset(ClassContext::alloc(dynamic_cast<const ClassDef*>(m_def))); } if (m_cache.classContext) { @@ -6293,7 +6299,7 @@ class NestingNodeContext::Private { if (!m_cache.namespaceContext && m_def->definitionType()==Definition::TypeNamespace) { - m_cache.namespaceContext.reset(NamespaceContext::alloc((NamespaceDef*)m_def)); + m_cache.namespaceContext.reset(NamespaceContext::alloc(dynamic_cast<const NamespaceDef*>(m_def))); } if (m_cache.namespaceContext) { @@ -6308,7 +6314,7 @@ class NestingNodeContext::Private { if (!m_cache.dirContext && m_def->definitionType()==Definition::TypeDir) { - m_cache.dirContext.reset(DirContext::alloc((DirDef*)m_def)); + m_cache.dirContext.reset(DirContext::alloc(dynamic_cast<const DirDef*>(m_def))); } if (m_cache.dirContext) { @@ -6323,7 +6329,7 @@ class NestingNodeContext::Private { if (!m_cache.fileContext && m_def->definitionType()==Definition::TypeFile) { - m_cache.fileContext.reset(FileContext::alloc((FileDef*)m_def)); + m_cache.fileContext.reset(FileContext::alloc(dynamic_cast<const FileDef*>(m_def))); } if (m_cache.fileContext) { @@ -6338,7 +6344,7 @@ class NestingNodeContext::Private { if (!m_cache.pageContext && m_def->definitionType()==Definition::TypePage) { - m_cache.pageContext.reset(PageContext::alloc((PageDef*)m_def,FALSE,FALSE)); + m_cache.pageContext.reset(PageContext::alloc(dynamic_cast<const PageDef*>(m_def),FALSE,FALSE)); } if (m_cache.pageContext) { @@ -6353,7 +6359,7 @@ class NestingNodeContext::Private { if (!m_cache.moduleContext && m_def->definitionType()==Definition::TypeGroup) { - m_cache.moduleContext.reset(ModuleContext::alloc((GroupDef*)m_def)); + m_cache.moduleContext.reset(ModuleContext::alloc(dynamic_cast<const GroupDef*>(m_def))); } if (m_cache.moduleContext) { @@ -6425,14 +6431,14 @@ class NestingNodeContext::Private void addClasses(bool inherit, bool hideSuper) { - ClassDef *cd = m_def->definitionType()==Definition::TypeClass ? (ClassDef*)m_def : 0; + const ClassDef *cd = dynamic_cast<const ClassDef*>(m_def); if (cd && inherit) { - bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd); + bool hasChildren = !cd->isVisited() && !hideSuper && classHasVisibleChildren(cd); if (hasChildren) { - bool wasVisited=cd->visited; - cd->visited=TRUE; + bool wasVisited=cd->isVisited(); + cd->setVisited(TRUE); if (cd->getLanguage()==SrcLangExt_VHDL) { m_children->addDerivedClasses(cd->baseClasses(),wasVisited); @@ -6453,7 +6459,7 @@ class NestingNodeContext::Private } void addNamespaces(bool addClasses) { - NamespaceDef *nd = m_def->definitionType()==Definition::TypeNamespace ? (NamespaceDef*)m_def : 0; + const NamespaceDef *nd = dynamic_cast<const NamespaceDef*>(m_def); if (nd && nd->getNamespaceSDict()) { m_children->addNamespaces(*nd->getNamespaceSDict(),FALSE,addClasses); @@ -6465,7 +6471,7 @@ class NestingNodeContext::Private } void addDirFiles() { - DirDef *dd = m_def->definitionType()==Definition::TypeDir ? (DirDef*)m_def : 0; + const DirDef *dd = dynamic_cast<const DirDef*>(m_def); if (dd) { m_children->addDirs(dd->subDirs()); @@ -6477,7 +6483,7 @@ class NestingNodeContext::Private } void addPages() { - PageDef *pd = m_def->definitionType()==Definition::TypePage ? (PageDef*)m_def : 0; + const PageDef *pd = dynamic_cast<const PageDef*>(m_def); if (pd && pd->getSubPages()) { m_children->addPages(*pd->getSubPages(),FALSE); @@ -6485,7 +6491,7 @@ class NestingNodeContext::Private } void addModules() { - GroupDef *gd = m_def->definitionType()==Definition::TypeGroup ? (GroupDef*)m_def : 0; + const GroupDef *gd = dynamic_cast<const GroupDef*>(m_def); if (gd && gd->getSubGroups()) { m_children->addModules(*gd->getSubGroups()); @@ -6493,7 +6499,7 @@ class NestingNodeContext::Private } private: const NestingNodeContext *m_parent; - Definition *m_def; + const Definition *m_def; SharedPtr<NestingContext> m_children; int m_level; int m_index; @@ -6515,7 +6521,7 @@ class NestingNodeContext::Private PropertyMapper<NestingNodeContext::Private> NestingNodeContext::Private::s_inst; NestingNodeContext::NestingNodeContext(const NestingNodeContext *parent, - Definition *d,int index,int level,bool addClass,bool inherit,bool hideSuper) + const Definition *d,int index,int level,bool addClass,bool inherit,bool hideSuper) : RefCountedContext("NestingNodeContext") { p = new Private(parent,this,d,index,level,addClass,inherit,hideSuper); @@ -6548,7 +6554,7 @@ class NestingContext::Private : public GenericNodeListContext void addNamespaces(const NamespaceSDict &nsDict,bool rootOnly,bool addClasses) { NamespaceSDict::Iterator nli(nsDict); - NamespaceDef *nd; + const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { if (nd->localName().find('@')==-1 && @@ -6568,7 +6574,7 @@ class NestingContext::Private : public GenericNodeListContext void addClasses(const ClassSDict &clDict,bool rootOnly) { ClassSDict::Iterator cli(clDict); - ClassDef *cd; + const ClassDef *cd; for (;(cd=cli.current());++cli) { if (cd->getLanguage()==SrcLangExt_VHDL) @@ -6597,7 +6603,7 @@ class NestingContext::Private : public GenericNodeListContext void addDirs(const DirSDict &dirDict) { SDict<DirDef>::Iterator dli(dirDict); - DirDef *dd; + const DirDef *dd; for (dli.toFirst();(dd=dli.current());++dli) { if (dd->getOuterScope()==Doxygen::globalScope) @@ -6610,7 +6616,7 @@ class NestingContext::Private : public GenericNodeListContext void addDirs(const DirList &dirList) { QListIterator<DirDef> li(dirList); - DirDef *dd; + const DirDef *dd; for (li.toFirst();(dd=li.current());++li) { append(NestingNodeContext::alloc(m_parent,dd,m_index,m_level,FALSE,FALSE,FALSE)); @@ -6624,7 +6630,7 @@ class NestingContext::Private : public GenericNodeListContext for (fnli.toFirst();(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); - FileDef *fd; + const FileDef *fd; for (;(fd=fni.current());++fni) { if (fd->getDirDef()==0) // top level file @@ -6638,7 +6644,7 @@ class NestingContext::Private : public GenericNodeListContext void addFiles(const FileList &fList) { QListIterator<FileDef> li(fList); - FileDef *fd; + const FileDef *fd; for (li.toFirst();(fd=li.current());++li) { append(NestingNodeContext::alloc(m_parent,fd,m_index,m_level,FALSE,FALSE,FALSE)); @@ -6648,7 +6654,7 @@ class NestingContext::Private : public GenericNodeListContext void addPages(const PageSDict &pages,bool rootOnly) { SDict<PageDef>::Iterator pli(pages); - PageDef *pd; + const PageDef *pd; for (pli.toFirst();(pd=pli.current());++pli) { if (!rootOnly || @@ -6663,7 +6669,7 @@ class NestingContext::Private : public GenericNodeListContext void addModules(const GroupSDict &groups) { GroupSDict::Iterator gli(groups); - GroupDef *gd; + const GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { static bool externalGroups = Config_getBool(EXTERNAL_GROUPS); @@ -6679,7 +6685,7 @@ class NestingContext::Private : public GenericNodeListContext void addModules(const GroupList &list) { GroupListIterator gli(list); - GroupDef *gd; + const GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { if (gd->isVisible()) @@ -6696,7 +6702,7 @@ class NestingContext::Private : public GenericNodeListContext BaseClassDef *bcd; for (bcli.toFirst() ; (bcd=bcli.current()) ; ++bcli) { - ClassDef *cd=bcd->classDef; + const ClassDef *cd=bcd->classDef; if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) { continue; @@ -6723,7 +6729,7 @@ class NestingContext::Private : public GenericNodeListContext void addClassHierarchy(const ClassSDict &classSDict,bool) { ClassSDict::Iterator cli(classSDict); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) { bool b; @@ -6744,7 +6750,7 @@ class NestingContext::Private : public GenericNodeListContext if (cd->isVisibleInHierarchy()) // should it be visible { // new root level class - NestingNodeContext *nnc = NestingNodeContext::alloc(m_parent,cd,m_index,m_level,TRUE,TRUE,cd->visited); + NestingNodeContext *nnc = NestingNodeContext::alloc(m_parent,cd,m_index,m_level,TRUE,TRUE,cd->isVisited()); append(nnc); m_index++; } @@ -6973,7 +6979,7 @@ class NamespaceListContext::Private : public GenericNodeListContext void addNamespaces(const NamespaceSDict &nsDict) { NamespaceSDict::Iterator nli(nsDict); - NamespaceDef *nd; + const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { if (nd->isLinkableInProject()) @@ -7148,7 +7154,7 @@ class FileListContext::Private : public GenericNodeListContext for (fnli.toFirst();(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); - FileDef *fd; + const FileDef *fd; for (fni.toFirst();(fd=fni.current());++fni) { bool doc = fd->isLinkableInProject(); @@ -7198,7 +7204,7 @@ class DirListContext::Private : public GenericNodeListContext public: Private() { - DirDef *dir; + const DirDef *dir; DirSDict::Iterator sdi(*Doxygen::directories); for (sdi.toFirst();(dir=sdi.current());++sdi) { @@ -7240,19 +7246,19 @@ TemplateListIntf::ConstIterator *DirListContext::createIterator() const class UsedFilesContext::Private : public GenericNodeListContext { public: - void addFile(FileDef *fd) + void addFile(const FileDef *fd) { append(FileContext::alloc(fd)); } }; -UsedFilesContext::UsedFilesContext(ClassDef *cd) : RefCountedContext("UsedFilesContext") +UsedFilesContext::UsedFilesContext(const ClassDef *cd) : RefCountedContext("UsedFilesContext") { p = new Private; if (cd) { QListIterator<FileDef> li(cd->usedFiles()); - FileDef *fd; + const FileDef *fd; for (li.toFirst();(fd=li.current());++li) { p->addFile(fd); @@ -7281,7 +7287,7 @@ TemplateListIntf::ConstIterator *UsedFilesContext::createIterator() const return p->createIterator(); } -void UsedFilesContext::addFile(FileDef *fd) +void UsedFilesContext::addFile(const FileDef *fd) { p->addFile(fd); } @@ -7518,7 +7524,7 @@ class PageListContext::Private : public GenericNodeListContext void addPages(const PageSDict &pages) { PageSDict::Iterator pdi(pages); - PageDef *pd=0; + const PageDef *pd=0; for (pdi.toFirst();(pd=pdi.current());++pdi) { if (!pd->getGroupDef() && !pd->isReference()) @@ -7567,7 +7573,7 @@ class ExampleListContext::Private : public GenericNodeListContext if (Doxygen::exampleSDict) { PageSDict::Iterator pdi(*Doxygen::exampleSDict); - PageDef *pd=0; + const PageDef *pd=0; for (pdi.toFirst();(pd=pdi.current());++pdi) { if (!pd->getGroupDef() && !pd->isReference()) @@ -7614,7 +7620,7 @@ class ModuleListContext::Private : public GenericNodeListContext void addModules() { GroupSDict::Iterator gli(*Doxygen::groupSDict); - GroupDef *gd; + const GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { if (!gd->isReference()) @@ -7769,7 +7775,7 @@ TemplateVariant ModuleTreeContext::get(const char *name) const class NavPathElemContext::Private { public: - Private(Definition *def) : m_def(def) + Private(const Definition *def) : m_def(def) { static bool init=FALSE; if (!init) @@ -7805,11 +7811,11 @@ class NavPathElemContext::Private QCString text = m_def->localName(); if (type==Definition::TypeGroup) { - text = ((const GroupDef*)m_def)->groupTitle(); + text = (dynamic_cast<const GroupDef*>(m_def))->groupTitle(); } - else if (type==Definition::TypePage && !(((const PageDef*)m_def)->title().isEmpty())) + else if (type==Definition::TypePage && ((dynamic_cast<const PageDef*>(m_def))->hasTitle())) { - text = ((const PageDef*)m_def)->title(); + text = (dynamic_cast<const PageDef*>(m_def))->title(); } else if (type==Definition::TypeClass) { @@ -7834,14 +7840,14 @@ class NavPathElemContext::Private return m_def->externalReference(relPathAsString()); } private: - Definition *m_def; + const Definition *m_def; static PropertyMapper<NavPathElemContext::Private> s_inst; }; //%% } PropertyMapper<NavPathElemContext::Private> NavPathElemContext::Private::s_inst; -NavPathElemContext::NavPathElemContext(Definition *def) : RefCountedContext("NavPathElemContext") +NavPathElemContext::NavPathElemContext(const Definition *def) : RefCountedContext("NavPathElemContext") { p = new Private(def); } @@ -8014,7 +8020,7 @@ class GlobalsIndexContext::Private MemberNameIterator mni(*mn); for (mni.toFirst();(md=mni.current());++mni) { - FileDef *fd=md->getFileDef(); + const FileDef *fd=md->getFileDef(); if (fd && fd->isLinkableInProject() && !md->name().isEmpty() && !md->getNamespaceDef() && md->isLinkableInProject()) { @@ -8171,7 +8177,7 @@ class ClassMembersIndexContext::Private MemberNameIterator mni(*mn); for (mni.toFirst();(md=mni.current());++mni) { - ClassDef *cd = md->getClassDef(); + const ClassDef *cd = md->getClassDef(); if (cd && cd->isLinkableInProject() && cd->templateMaster()==0 && md->isLinkableInProject() && !md->name().isEmpty()) { @@ -8330,7 +8336,7 @@ class NamespaceMembersIndexContext::Private MemberNameIterator mni(*mn); for (mni.toFirst();(md=mni.current());++mni) { - NamespaceDef *nd=md->getNamespaceDef(); + const NamespaceDef *nd=md->getNamespaceDef(); if (nd && nd->isLinkableInProject() && !md->name().isEmpty() && md->isLinkableInProject()) { @@ -8508,7 +8514,7 @@ TemplateVariant InheritanceGraphContext::get(const char *name) const class InheritanceNodeContext::Private { public: - Private(ClassDef *cd,const QCString &name) : m_classDef(cd), m_name(name) + Private(const ClassDef *cd,const QCString &name) : m_classDef(cd), m_name(name) { static bool init=FALSE; if (!init) @@ -8535,7 +8541,7 @@ class InheritanceNodeContext::Private return m_name; } private: - ClassDef *m_classDef; + const ClassDef *m_classDef; mutable SharedPtr<ClassContext> m_classContext; QCString m_name; static PropertyMapper<InheritanceNodeContext::Private> s_inst; @@ -8544,7 +8550,7 @@ class InheritanceNodeContext::Private PropertyMapper<InheritanceNodeContext::Private> InheritanceNodeContext::Private::s_inst; -InheritanceNodeContext::InheritanceNodeContext(ClassDef *cd,const QCString &name) : RefCountedContext("InheritanceNodeContext") +InheritanceNodeContext::InheritanceNodeContext(const ClassDef *cd,const QCString &name) : RefCountedContext("InheritanceNodeContext") { p = new Private(cd,name); } @@ -8565,7 +8571,7 @@ TemplateVariant InheritanceNodeContext::get(const char *name) const class InheritanceListContext::Private : public GenericNodeListContext { public: - void addClass(ClassDef *cd,const QCString &name) + void addClass(const ClassDef *cd,const QCString &name) { append(InheritanceNodeContext::alloc(cd,name)); } @@ -8580,7 +8586,7 @@ InheritanceListContext::InheritanceListContext(const BaseClassList *list, bool b BaseClassDef *bcd; for (li.toFirst();(bcd=li.current());++li) { - ClassDef *cd=bcd->classDef; + const ClassDef *cd=bcd->classDef; QCString name; if (baseClasses) { @@ -8806,7 +8812,7 @@ class AllMembersListContext::Private : public GenericNodeListContext for (mnii2.toFirst();(mi=mnii2.current());++mnii2) { MemberDef *md=mi->memberDef; - ClassDef *cd=md->getClassDef(); + const ClassDef *cd=md->getClassDef(); if (cd && !md->name().isEmpty() && md->name()[0]!='@') { if ((cd->isLinkable() && md->isLinkable()) || @@ -8862,7 +8868,7 @@ TemplateListIntf::ConstIterator *AllMembersListContext::createIterator() const class MemberGroupInfoContext::Private { public: - Private(Definition *def,const QCString &relPath,const MemberGroup *mg) : + Private(const Definition *def,const QCString &relPath,const MemberGroup *mg) : m_def(def), m_relPath(relPath), m_memberGroup(mg) @@ -8936,7 +8942,7 @@ class MemberGroupInfoContext::Private return FALSE; } private: - Definition *m_def; + const Definition *m_def; QCString m_relPath; const MemberGroup *m_memberGroup; struct Cachable @@ -8952,7 +8958,7 @@ class MemberGroupInfoContext::Private PropertyMapper<MemberGroupInfoContext::Private> MemberGroupInfoContext::Private::s_inst; -MemberGroupInfoContext::MemberGroupInfoContext(Definition *def, +MemberGroupInfoContext::MemberGroupInfoContext(const Definition *def, const QCString &relPath,const MemberGroup *mg) : RefCountedContext("MemberGroupInfoContext") { p = new Private(def,relPath,mg); @@ -8974,7 +8980,7 @@ TemplateVariant MemberGroupInfoContext::get(const char *name) const class MemberGroupListContext::Private : public GenericNodeListContext { public: - void addMemberGroup(Definition *def,const QCString &relPath,const MemberGroup *mg) + void addMemberGroup(const Definition *def,const QCString &relPath,const MemberGroup *mg) { append(MemberGroupInfoContext::alloc(def,relPath,mg)); } @@ -8985,7 +8991,7 @@ MemberGroupListContext::MemberGroupListContext() : RefCountedContext("MemberGrou p = new Private; } -MemberGroupListContext::MemberGroupListContext(Definition *def,const QCString &relPath,const MemberGroupList *list) : RefCountedContext("MemberGroupListContext") +MemberGroupListContext::MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupList *list) : RefCountedContext("MemberGroupListContext") { p = new Private; if (list) @@ -8999,7 +9005,7 @@ MemberGroupListContext::MemberGroupListContext(Definition *def,const QCString &r } } -MemberGroupListContext::MemberGroupListContext(Definition *def,const QCString &relPath,const MemberGroupSDict *dict,bool subGrouping) : RefCountedContext("MemberGroupListContext") +MemberGroupListContext::MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupSDict *dict,bool subGrouping) : RefCountedContext("MemberGroupListContext") { p = new Private; if (dict) @@ -9045,7 +9051,7 @@ TemplateListIntf::ConstIterator *MemberGroupListContext::createIterator() const class MemberListInfoContext::Private { public: - Private(Definition *def,const QCString &relPath,const MemberList *ml,const QCString &title,const QCString &subtitle) : + Private(const Definition *def,const QCString &relPath,const MemberList *ml,const QCString &title,const QCString &subtitle) : m_def(def), m_memberList(ml), m_relPath(relPath), @@ -9102,7 +9108,7 @@ class MemberListInfoContext::Private m_def->definitionType()==Definition::TypeClass) { InheritedMemberInfoListContext *ctx = InheritedMemberInfoListContext::alloc(); - ctx->addMemberList((ClassDef*)m_def,m_memberList->listType(),m_title,FALSE); + ctx->addMemberList(dynamic_cast<const ClassDef*>(m_def),m_memberList->listType(),m_title,FALSE); m_cache.inherited.reset(ctx); } if (m_cache.inherited) @@ -9115,7 +9121,7 @@ class MemberListInfoContext::Private } } private: - Definition *m_def; + const Definition *m_def; const MemberList *m_memberList; QCString m_relPath; QCString m_title; @@ -9134,7 +9140,7 @@ class MemberListInfoContext::Private PropertyMapper<MemberListInfoContext::Private> MemberListInfoContext::Private::s_inst; MemberListInfoContext::MemberListInfoContext( - Definition *def,const QCString &relPath,const MemberList *ml, + const Definition *def,const QCString &relPath,const MemberList *ml, const QCString &title,const QCString &subtitle) : RefCountedContext("MemberListInfoContext") { p = new Private(def,relPath,ml,title,subtitle); @@ -9157,7 +9163,7 @@ TemplateVariant MemberListInfoContext::get(const char *name) const class InheritedMemberInfoContext::Private { public: - Private(ClassDef *cd,MemberList *ml,const QCString &title) + Private(const ClassDef *cd,MemberList *ml,const QCString &title) : m_class(cd), m_memberList(ml), m_title(title) { static bool init=FALSE; @@ -9216,7 +9222,7 @@ class InheritedMemberInfoContext::Private } private: - ClassDef * m_class; + const ClassDef * m_class; MemberList *m_memberList; QCString m_title; mutable SharedPtr<ClassContext> m_classCtx; @@ -9228,7 +9234,7 @@ class InheritedMemberInfoContext::Private PropertyMapper<InheritedMemberInfoContext::Private> InheritedMemberInfoContext::Private::s_inst; -InheritedMemberInfoContext::InheritedMemberInfoContext(ClassDef *cd,MemberList *ml, +InheritedMemberInfoContext::InheritedMemberInfoContext(const ClassDef *cd,MemberList *ml, const QCString &title) : RefCountedContext("InheritedMemberInfoContext") { p = new Private(cd,ml,title); @@ -9250,7 +9256,7 @@ TemplateVariant InheritedMemberInfoContext::get(const char *name) const class InheritedMemberInfoListContext::Private : public GenericNodeListContext { public: - void addMemberList(ClassDef *inheritedFrom,MemberList *ml,MemberList *combinedList) + void addMemberList(const ClassDef *inheritedFrom,MemberList *ml,MemberList *combinedList) { if (ml) { @@ -9265,7 +9271,7 @@ class InheritedMemberInfoListContext::Private : public GenericNodeListContext } } } - void addMemberListIncludingGrouped(ClassDef *inheritedFrom,MemberList *ml,MemberList *combinedList) + void addMemberListIncludingGrouped(const ClassDef *inheritedFrom,MemberList *ml,MemberList *combinedList) { if (ml) { @@ -9281,8 +9287,8 @@ class InheritedMemberInfoListContext::Private : public GenericNodeListContext } } } - void addMemberGroupsOfClass(ClassDef *inheritedFrom, - ClassDef *cd,MemberListType lt,MemberList *combinedList) + void addMemberGroupsOfClass(const ClassDef *inheritedFrom, + const ClassDef *cd,MemberListType lt,MemberList *combinedList) { if (cd->getMemberGroupSDict()) { @@ -9307,7 +9313,7 @@ class InheritedMemberInfoListContext::Private : public GenericNodeListContext } } } - void addInheritedMembers(ClassDef *inheritedFrom,ClassDef *cd,MemberListType lt, + void addInheritedMembers(const ClassDef *inheritedFrom,const ClassDef *cd,MemberListType lt, MemberListType lt1,int lt2,const QCString &title,bool additionalList) { int count = cd->countMembersIncludingGrouped(lt1,inheritedFrom,additionalList); @@ -9324,7 +9330,7 @@ class InheritedMemberInfoListContext::Private : public GenericNodeListContext append(InheritedMemberInfoContext::alloc(cd,combinedList,title)); } } - void findInheritedMembers(ClassDef *inheritedFrom,ClassDef *cd,MemberListType lt, + void findInheritedMembers(const ClassDef *inheritedFrom,const ClassDef *cd,MemberListType lt, int lt2, const QCString &title,bool additionalList, QPtrDict<void> *visitedClasses) { @@ -9366,7 +9372,7 @@ InheritedMemberInfoListContext::InheritedMemberInfoListContext() : RefCountedCon } void InheritedMemberInfoListContext::addMemberList( - ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList) + const ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList) { QPtrDict<void> visited(17); bool memberInSection = cd->countMembersIncludingGrouped(lt,cd,FALSE)>0; @@ -9407,7 +9413,7 @@ TemplateListIntf::ConstIterator *InheritedMemberInfoListContext::createIterator( class ArgumentContext::Private { public: - Private(const Argument *arg,Definition *def,const QCString &relPath) : + Private(const Argument *arg,const Definition *def,const QCString &relPath) : m_argument(arg), m_def(def), m_relPath(relPath) { static bool init=FALSE; @@ -9477,7 +9483,7 @@ class ArgumentContext::Private } private: const Argument *m_argument; - Definition *m_def; + const Definition *m_def; QCString m_relPath; struct Cachable { @@ -9490,7 +9496,7 @@ class ArgumentContext::Private PropertyMapper<ArgumentContext::Private> ArgumentContext::Private::s_inst; -ArgumentContext::ArgumentContext(const Argument *al,Definition *def,const QCString &relPath) : RefCountedContext("ArgumentContext") +ArgumentContext::ArgumentContext(const Argument *al,const Definition *def,const QCString &relPath) : RefCountedContext("ArgumentContext") { p = new Private(al,def,relPath); } @@ -9511,7 +9517,7 @@ TemplateVariant ArgumentContext::get(const char *name) const class ArgumentListContext::Private : public GenericNodeListContext { public: - void addArgument(const Argument *arg,Definition *def,const QCString &relPath) + void addArgument(const Argument *arg,const Definition *def,const QCString &relPath) { append(ArgumentContext::alloc(arg,def,relPath)); } @@ -9523,7 +9529,7 @@ ArgumentListContext::ArgumentListContext() : RefCountedContext("ArgumentListCont } ArgumentListContext::ArgumentListContext(const ArgumentList *list, - Definition *def,const QCString &relPath) : RefCountedContext("ArgumentListContext") + const Definition *def,const QCString &relPath) : RefCountedContext("ArgumentListContext") { p = new Private; if (list) @@ -9614,8 +9620,7 @@ class SymbolContext::Private const Definition *prev = m_prevDef; const Definition *nextScope = next ? next->getOuterScope() : 0; const Definition *prevScope = prev ? prev->getOuterScope() : 0; - bool isMemberDef = m_def->definitionType()==Definition::TypeMember; - const MemberDef *md = isMemberDef ? (const MemberDef*)m_def : 0; + const MemberDef *md = dynamic_cast<const MemberDef*>(m_def); bool isFunctionLike = md && (md->isFunction() || md->isSlot() || md->isSignal()); bool overloadedFunction = isFunctionLike && ((prevScope!=0 && scope==prevScope) || (scope && scope==nextScope)); @@ -9646,7 +9651,7 @@ class SymbolContext::Private { if (md) { - FileDef *fd = md->getBodyDef(); + const FileDef *fd = md->getBodyDef(); if (fd==0) fd = md->getFileDef(); if (fd) { @@ -9714,8 +9719,8 @@ class SymbolListContext::Private : public GenericNodeListContext Private(const SearchDefinitionList *sdl) { QListIterator<Definition> li(*sdl); - Definition *def; - Definition *prev = 0; + const Definition *def; + const Definition *prev = 0; for (li.toFirst();(def=li.current());) { ++li; @@ -10300,7 +10305,7 @@ void generateOutputViaTemplate() else { // TODO: for LaTeX output index should be main... => solve in template - Doxygen::mainPage = new PageDef("[generated]",1,"index","",theTranslator->trMainPage()); + Doxygen::mainPage = createPageDef("[generated]",1,"index","",theTranslator->trMainPage()); Doxygen::mainPage->setFileName("index"); SharedPtr<PageContext> mainPage(PageContext::alloc(Doxygen::mainPage,TRUE,FALSE)); ctx->set("mainPage",mainPage.get()); @@ -10365,13 +10370,13 @@ void generateOutputViaTemplate() // clear all cached data in Definition objects. QDictIterator<DefinitionIntf> di(*Doxygen::symbolMap); - DefinitionIntf *intf; + const DefinitionIntf *intf; for (;(intf=di.current());++di) { if (intf->definitionType()==DefinitionIntf::TypeSymbolList) // list of symbols { - DefinitionListIterator dli(*(DefinitionList*)intf); - Definition *d; + DefinitionListIterator dli(*dynamic_cast<const DefinitionList*>(intf)); + const Definition *d; // for each symbol for (dli.toFirst();(d=dli.current());++dli) { @@ -10380,7 +10385,7 @@ void generateOutputViaTemplate() } else // single symbol { - Definition *d = (Definition *)intf; + const Definition *d = dynamic_cast<const Definition *>(intf); d->setCookie(0); } } diff --git a/src/context.h b/src/context.h index e082c4b..ecd1227 100644 --- a/src/context.h +++ b/src/context.h @@ -186,7 +186,7 @@ class TranslateContext : public RefCountedContext, public TemplateStructIntf class UsedFilesContext : public RefCountedContext, public TemplateListIntf { public: - static UsedFilesContext *alloc(ClassDef *cd) { return new UsedFilesContext(cd); } + static UsedFilesContext *alloc(const ClassDef *cd) { return new UsedFilesContext(cd); } // TemplateListIntf virtual int count() const; @@ -195,10 +195,10 @@ class UsedFilesContext : public RefCountedContext, public TemplateListIntf virtual int addRef() { return RefCountedContext::addRef(); } virtual int release() { return RefCountedContext::release(); } - void addFile(FileDef *fd); + void addFile(const FileDef *fd); private: - UsedFilesContext(ClassDef *cd); + UsedFilesContext(const ClassDef *cd); ~UsedFilesContext(); class Private; @@ -253,7 +253,7 @@ class IncludeInfoListContext : public RefCountedContext, public TemplateListIntf class ClassContext : public RefCountedContext, public TemplateStructIntf { public: - static ClassContext *alloc(ClassDef *cd) { return new ClassContext(cd); } + static ClassContext *alloc(const ClassDef *cd) { return new ClassContext(cd); } // TemplateStructIntf methods virtual TemplateVariant get(const char *name) const; @@ -261,7 +261,7 @@ class ClassContext : public RefCountedContext, public TemplateStructIntf virtual int release() { return RefCountedContext::release(); } private: - ClassContext(ClassDef *); + ClassContext(const ClassDef *); ~ClassContext(); class Private; Private *p; @@ -272,7 +272,7 @@ class ClassContext : public RefCountedContext, public TemplateStructIntf class NamespaceContext : public RefCountedContext, public TemplateStructIntf { public: - static NamespaceContext *alloc(NamespaceDef *nd) { return new NamespaceContext(nd); } + static NamespaceContext *alloc(const NamespaceDef *nd) { return new NamespaceContext(nd); } // TemplateStructIntf methods virtual TemplateVariant get(const char *name) const; @@ -280,7 +280,7 @@ class NamespaceContext : public RefCountedContext, public TemplateStructIntf virtual int release() { return RefCountedContext::release(); } private: - NamespaceContext(NamespaceDef *); + NamespaceContext(const NamespaceDef *); ~NamespaceContext(); class Private; Private *p; @@ -291,7 +291,7 @@ class NamespaceContext : public RefCountedContext, public TemplateStructIntf class FileContext : public RefCountedContext, public TemplateStructIntf { public: - static FileContext *alloc(FileDef *fd) { return new FileContext(fd); } + static FileContext *alloc(const FileDef *fd) { return new FileContext(fd); } // TemplateStructIntf methods virtual TemplateVariant get(const char *name) const; @@ -299,7 +299,7 @@ class FileContext : public RefCountedContext, public TemplateStructIntf virtual int release() { return RefCountedContext::release(); } private: - FileContext(FileDef *); + FileContext(const FileDef *); ~FileContext(); class Private; Private *p; @@ -309,7 +309,7 @@ class FileContext : public RefCountedContext, public TemplateStructIntf class DirContext : public RefCountedContext, public TemplateStructIntf { public: - static DirContext *alloc(DirDef *dd) { return new DirContext(dd); } + static DirContext *alloc(const DirDef *dd) { return new DirContext(dd); } // TemplateStructIntf methods virtual TemplateVariant get(const char *name) const; @@ -317,7 +317,7 @@ class DirContext : public RefCountedContext, public TemplateStructIntf virtual int release() { return RefCountedContext::release(); } private: - DirContext(DirDef *); + DirContext(const DirDef *); ~DirContext(); class Private; Private *p; @@ -329,7 +329,7 @@ class DirContext : public RefCountedContext, public TemplateStructIntf class PageContext : public RefCountedContext, public TemplateStructIntf { public: - static PageContext *alloc(PageDef *pd,bool isMainPage,bool isExample) { return new PageContext(pd,isMainPage,isExample); } + static PageContext *alloc(const PageDef *pd,bool isMainPage,bool isExample) { return new PageContext(pd,isMainPage,isExample); } // TemplateStructIntf methods virtual TemplateVariant get(const char *name) const; @@ -337,7 +337,7 @@ class PageContext : public RefCountedContext, public TemplateStructIntf virtual int release() { return RefCountedContext::release(); } private: - PageContext(PageDef *,bool isMainPage,bool isExample); + PageContext(const PageDef *,bool isMainPage,bool isExample); ~PageContext(); class Private; Private *p; @@ -368,7 +368,7 @@ class MemberContext : public RefCountedContext, public TemplateStructIntf class ModuleContext : public RefCountedContext, public TemplateStructIntf { public: - static ModuleContext *alloc(GroupDef *gd) { return new ModuleContext(gd); } + static ModuleContext *alloc(const GroupDef *gd) { return new ModuleContext(gd); } // TemplateStructIntf methods virtual TemplateVariant get(const char *name) const; @@ -376,7 +376,7 @@ class ModuleContext : public RefCountedContext, public TemplateStructIntf virtual int release() { return RefCountedContext::release(); } private: - ModuleContext(GroupDef *); + ModuleContext(const GroupDef *); ~ModuleContext(); class Private; Private *p; @@ -447,7 +447,7 @@ class InheritanceGraphContext : public RefCountedContext, public TemplateStructI class ClassInheritanceNodeContext : public RefCountedContext, public TemplateStructIntf { public: - static ClassInheritanceNodeContext *alloc(ClassDef *cd) + static ClassInheritanceNodeContext *alloc(const ClassDef *cd) { return new ClassInheritanceNodeContext(cd); } // TemplateStructIntf methods @@ -458,7 +458,7 @@ class ClassInheritanceNodeContext : public RefCountedContext, public TemplateStr void addChildren(const BaseClassList *bcl,bool hideSuper); private: - ClassInheritanceNodeContext(ClassDef *); + ClassInheritanceNodeContext(const ClassDef *); ~ClassInheritanceNodeContext(); class Private; Private *p; @@ -509,7 +509,7 @@ class ClassHierarchyContext : public RefCountedContext, public TemplateStructInt class NestingNodeContext : public RefCountedContext, public TemplateStructIntf { public: - static NestingNodeContext *alloc(const NestingNodeContext *parent,Definition *def, + static NestingNodeContext *alloc(const NestingNodeContext *parent,const Definition *def, int index,int level,bool addClasses,bool inherit,bool hideSuper) { return new NestingNodeContext(parent,def,index,level,addClasses,inherit,hideSuper); } @@ -522,7 +522,7 @@ class NestingNodeContext : public RefCountedContext, public TemplateStructIntf private: NestingNodeContext(const NestingNodeContext *parent, - Definition *,int index,int level,bool addClasses,bool inherit,bool hideSuper); + const Definition *,int index,int level,bool addClasses,bool inherit,bool hideSuper); ~NestingNodeContext(); class Private; Private *p; @@ -729,7 +729,7 @@ class PageTreeContext : public RefCountedContext, public TemplateStructIntf class ModuleNodeContext : public RefCountedContext, public TemplateStructIntf { public: - static ModuleNodeContext *alloc(GroupDef *gd) { return new ModuleNodeContext(gd); } + static ModuleNodeContext *alloc(const GroupDef *gd) { return new ModuleNodeContext(gd); } // TemplateStructIntf methods virtual TemplateVariant get(const char *name) const; @@ -737,7 +737,7 @@ class ModuleNodeContext : public RefCountedContext, public TemplateStructIntf virtual int release() { return RefCountedContext::release(); } private: - ModuleNodeContext(GroupDef *); + ModuleNodeContext(const GroupDef *); ~ModuleNodeContext(); class Private; Private *p; @@ -889,7 +889,7 @@ class NamespaceMembersIndexContext : public RefCountedContext, public TemplateSt class NavPathElemContext : public RefCountedContext, public TemplateStructIntf { public: - static NavPathElemContext *alloc(Definition *def) { return new NavPathElemContext(def); } + static NavPathElemContext *alloc(const Definition *def) { return new NavPathElemContext(def); } // TemplateStructIntf methods virtual TemplateVariant get(const char *name) const; @@ -897,7 +897,7 @@ class NavPathElemContext : public RefCountedContext, public TemplateStructIntf virtual int release() { return RefCountedContext::release(); } private: - NavPathElemContext(Definition *def); + NavPathElemContext(const Definition *def); ~NavPathElemContext(); class Private; Private *p; @@ -909,7 +909,7 @@ class NavPathElemContext : public RefCountedContext, public TemplateStructIntf class InheritanceNodeContext : public RefCountedContext, public TemplateStructIntf { public: - static InheritanceNodeContext *alloc(ClassDef *cd,const QCString &name) + static InheritanceNodeContext *alloc(const ClassDef *cd,const QCString &name) { return new InheritanceNodeContext(cd,name); } // TemplateStructIntf methods @@ -918,7 +918,7 @@ class InheritanceNodeContext : public RefCountedContext, public TemplateStructIn virtual int release() { return RefCountedContext::release(); } private: - InheritanceNodeContext(ClassDef *cd,const QCString &name); + InheritanceNodeContext(const ClassDef *cd,const QCString &name); ~InheritanceNodeContext(); class Private; Private *p; @@ -979,7 +979,7 @@ class MemberListContext : public RefCountedContext, public TemplateListIntf class MemberGroupInfoContext : public RefCountedContext, public TemplateStructIntf { public: - static MemberGroupInfoContext *alloc(Definition *def,const QCString &relPath,const MemberGroup *mg) + static MemberGroupInfoContext *alloc(const Definition *def,const QCString &relPath,const MemberGroup *mg) { return new MemberGroupInfoContext(def,relPath,mg); } // TemplateStructIntf methods @@ -988,7 +988,7 @@ class MemberGroupInfoContext : public RefCountedContext, public TemplateStructIn virtual int release() { return RefCountedContext::release(); } private: - MemberGroupInfoContext(Definition *def,const QCString &relPath,const MemberGroup *mg); + MemberGroupInfoContext(const Definition *def,const QCString &relPath,const MemberGroup *mg); ~MemberGroupInfoContext(); class Private; Private *p; @@ -1001,9 +1001,9 @@ class MemberGroupListContext : public RefCountedContext, public TemplateListIntf public: static MemberGroupListContext *alloc() { return new MemberGroupListContext; } - static MemberGroupListContext *alloc(Definition *def,const QCString &relPath,const MemberGroupList *list) + static MemberGroupListContext *alloc(const Definition *def,const QCString &relPath,const MemberGroupList *list) { return new MemberGroupListContext(def,relPath,list); } - static MemberGroupListContext *alloc(Definition *def,const QCString &relPath,const MemberGroupSDict *dict,bool subGrouping) + static MemberGroupListContext *alloc(const Definition *def,const QCString &relPath,const MemberGroupSDict *dict,bool subGrouping) { return new MemberGroupListContext(def,relPath,dict,subGrouping); } // TemplateListIntf @@ -1015,8 +1015,8 @@ class MemberGroupListContext : public RefCountedContext, public TemplateListIntf private: MemberGroupListContext(); - MemberGroupListContext(Definition *def,const QCString &relPath,const MemberGroupList *list); - MemberGroupListContext(Definition *def,const QCString &relPath,const MemberGroupSDict *mgDict,bool subGrouping); + MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupList *list); + MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupSDict *mgDict,bool subGrouping); ~MemberGroupListContext(); class Private; Private *p; @@ -1028,7 +1028,7 @@ class MemberGroupListContext : public RefCountedContext, public TemplateListIntf class MemberListInfoContext : public RefCountedContext, public TemplateStructIntf { public: - static MemberListInfoContext *alloc(Definition *def,const QCString &relPath, + static MemberListInfoContext *alloc(const Definition *def,const QCString &relPath, const MemberList *ml,const QCString &title, const QCString &subtitle=QCString()) { return new MemberListInfoContext(def,relPath,ml,title,subtitle); } @@ -1039,7 +1039,7 @@ class MemberListInfoContext : public RefCountedContext, public TemplateStructInt virtual int release() { return RefCountedContext::release(); } private: - MemberListInfoContext(Definition *def,const QCString &relPath, + MemberListInfoContext(const Definition *def,const QCString &relPath, const MemberList *ml,const QCString &title, const QCString &subtitle=QCString()); ~MemberListInfoContext(); @@ -1071,7 +1071,7 @@ class MemberInfoContext : public RefCountedContext, public TemplateStructIntf class InheritedMemberInfoContext : public RefCountedContext, public TemplateStructIntf { public: - static InheritedMemberInfoContext *alloc(ClassDef *cd,MemberList *ml,const QCString &title) + static InheritedMemberInfoContext *alloc(const ClassDef *cd,MemberList *ml,const QCString &title) { return new InheritedMemberInfoContext(cd,ml,title); } // TemplateStructIntf methods @@ -1080,7 +1080,7 @@ class InheritedMemberInfoContext : public RefCountedContext, public TemplateStru virtual int release() { return RefCountedContext::release(); } private: - InheritedMemberInfoContext(ClassDef *cd,MemberList *ml,const QCString &title); + InheritedMemberInfoContext(const ClassDef *cd,MemberList *ml,const QCString &title); ~InheritedMemberInfoContext(); class Private; Private *p; @@ -1092,7 +1092,7 @@ class InheritedMemberInfoListContext : public RefCountedContext, public Template { public: static InheritedMemberInfoListContext *alloc() { return new InheritedMemberInfoListContext; } - void addMemberList(ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList=TRUE); + void addMemberList(const ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList=TRUE); // TemplateListIntf virtual int count() const; @@ -1138,7 +1138,7 @@ class AllMembersListContext : public RefCountedContext, public TemplateListIntf class ArgumentContext : public RefCountedContext, public TemplateStructIntf { public: - static ArgumentContext *alloc(const Argument *arg,Definition *def,const QCString &relPath) + static ArgumentContext *alloc(const Argument *arg,const Definition *def,const QCString &relPath) { return new ArgumentContext(arg,def,relPath); } // TemplateStructIntf methods @@ -1147,7 +1147,7 @@ class ArgumentContext : public RefCountedContext, public TemplateStructIntf virtual int release() { return RefCountedContext::release(); } private: - ArgumentContext(const Argument *arg,Definition *def,const QCString &relPath); + ArgumentContext(const Argument *arg,const Definition *def,const QCString &relPath); ~ArgumentContext(); class Private; Private *p; @@ -1159,7 +1159,7 @@ class ArgumentListContext : public RefCountedContext, public TemplateListIntf { public: static ArgumentListContext *alloc() { return new ArgumentListContext; } - static ArgumentListContext *alloc(const ArgumentList *al,Definition *def,const QCString &relPath) + static ArgumentListContext *alloc(const ArgumentList *al,const Definition *def,const QCString &relPath) { return new ArgumentListContext(al,def,relPath); } // TemplateListIntf @@ -1171,7 +1171,7 @@ class ArgumentListContext : public RefCountedContext, public TemplateListIntf private: ArgumentListContext(); - ArgumentListContext(const ArgumentList *al,Definition *def,const QCString &relPath); + ArgumentListContext(const ArgumentList *al,const Definition *def,const QCString &relPath); ~ArgumentListContext(); class Private; Private *p; diff --git a/src/cppvalue.cpp b/src/cppvalue.cpp index 176931d..1543498 100644 --- a/src/cppvalue.cpp +++ b/src/cppvalue.cpp @@ -21,44 +21,44 @@ #include "cppvalue.h" #include "constexp.h" -CPPValue parseOctal() +CPPValue parseOctal(const QCString& token) { long val = 0; - for (const char *p = g_strToken.data(); *p != 0; p++) + for (const char *p = token.data(); *p != 0; p++) { if (*p >= '0' && *p <= '7') val = val * 8 + *p - '0'; } return CPPValue(val); } -CPPValue parseDecimal() +CPPValue parseDecimal(const QCString& token) { long val = 0; - for (const char *p = g_strToken.data(); *p != 0; p++) + for (const char *p = token.data(); *p != 0; p++) { if (*p >= '0' && *p <= '9') val = val * 10 + *p - '0'; } return CPPValue(val); } -CPPValue parseHexadecimal() +CPPValue parseHexadecimal(const QCString& token) { long val = 0; - for (const char *p = g_strToken.data(); *p != 0; p++) + for (const char *p = token.data(); *p != 0; p++) { if (*p >= '0' && *p <= '9') val = val * 16 + *p - '0'; else if (*p >= 'a' && *p <= 'f') val = val * 16 + *p - 'a' + 10; else if (*p >= 'A' && *p <= 'F') val = val * 16 + *p - 'A' + 10; } - //printf("parseHexadecimal %s->%x\n",g_strToken.data(),val); + //printf("parseHexadecimal %s->%x\n",token.data(),val); return CPPValue(val); } -CPPValue parseCharacter() // does not work for '\n' and the alike +CPPValue parseCharacter(const QCString& token) // does not work for '\n' and the alike { - if (g_strToken[1]=='\\') + if (token[1]=='\\') { - switch(g_strToken[2]) + switch(token[2]) { case 'n': return CPPValue((long)'\n'); case 't': return CPPValue((long)'\t'); @@ -79,17 +79,17 @@ CPPValue parseCharacter() // does not work for '\n' and the alike case '5': // fall through case '6': // fall through case '7': // fall through - return parseOctal(); + return parseOctal(token); case 'x': - case 'X': return parseHexadecimal(); - default: printf("Invalid escape sequence %s found!\n",g_strToken.data()); + case 'X': return parseHexadecimal(token); + default: printf("Invalid escape sequence %s found!\n",token.data()); return CPPValue(0L); } } - return CPPValue((long)g_strToken[1]); + return CPPValue((long)token[1]); } -CPPValue parseFloat() +CPPValue parseFloat(const QCString& token) { - return CPPValue(atof(g_strToken)); + return CPPValue(atof(token)); } diff --git a/src/cppvalue.h b/src/cppvalue.h index 59dd594..cde033d 100644 --- a/src/cppvalue.h +++ b/src/cppvalue.h @@ -21,6 +21,7 @@ #include <stdio.h> #include <qglobal.h> +#include <qcstring.h> /** A class representing a C-preprocessor value. */ class CPPValue @@ -52,10 +53,10 @@ class CPPValue } v; }; -extern CPPValue parseOctal(); -extern CPPValue parseDecimal(); -extern CPPValue parseHexadecimal(); -extern CPPValue parseCharacter(); -extern CPPValue parseFloat(); +extern CPPValue parseOctal(const QCString& token); +extern CPPValue parseDecimal(const QCString& token); +extern CPPValue parseHexadecimal(const QCString& token); +extern CPPValue parseCharacter(const QCString& token); +extern CPPValue parseFloat(const QCString& token); #endif diff --git a/src/debug.cpp b/src/debug.cpp index c81a1af..4c7afb3 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -48,6 +48,8 @@ static LabelMap s_labels[] = { "markdown", Debug::Markdown }, { "filteroutput", Debug::FilterOutput }, { "lex", Debug::Lex }, + { "plantuml", Debug::Plantuml }, + { "fortranfixed2free", Debug::FortranFixed2Free }, { 0, (Debug::DebugMask)0 } }; diff --git a/src/debug.h b/src/debug.h index 8a28c7a..79bc3d8 100644 --- a/src/debug.h +++ b/src/debug.h @@ -37,7 +37,9 @@ class Debug ExtCmd = 0x00000400, Markdown = 0x00000800, FilterOutput = 0x00001000, - Lex = 0x00002000 + Lex = 0x00002000, + Plantuml = 0x00004000, + FortranFixed2Free = 0x00008000 }; static void print(DebugMask mask,int prio,const char *fmt,...); static int setFlag(const char *label); diff --git a/src/declinfo.h b/src/declinfo.h index d226c7d..2039dca 100644 --- a/src/declinfo.h +++ b/src/declinfo.h @@ -20,9 +20,10 @@ #include <stdio.h> #include <qcstring.h> +#include "types.h" extern void parseFuncDecl(const QCString &decl, - bool objC, + const SrcLangExt lang, QCString &clName, QCString &type, QCString &name, diff --git a/src/declinfo.l b/src/declinfo.l index a91f832..36ef94a 100644 --- a/src/declinfo.l +++ b/src/declinfo.l @@ -16,6 +16,10 @@ */ %option never-interactive %option prefix="declinfoYY" +%option nounput +%option noyywrap +%option reentrant +%option extra-type="struct declinfoYY_state *" %{ @@ -30,82 +34,48 @@ #include "declinfo.h" #include "util.h" #include "message.h" +#include "types.h" #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 +#define YY_NEVER_INTERACTIVE 1 /* ----------------------------------------------------------------- * * statics */ - -static const char * inputString; -static int inputPosition; -static QCString scope; -static QCString className; -static QCString classTempList; -static QCString funcTempList; -static QCString type; -static QCString name; -static QCString args; -static int sharpCount; -static bool classTempListFound; -static bool funcTempListFound; -static QCString exceptionString; -static bool insideObjC; - -static void addType() -{ - //printf("addType() type=`%s' scope=`%s' name=`%s'\n", - // type.data(),scope.data(),name.data()); - if (name.isEmpty() && scope.isEmpty()) return; - if (!type.isEmpty()) type+=" "; - if (!scope.isEmpty()) type+=scope+"::"; - type+=name; - scope.resize(0); - name.resize(0); -} - -static void addTypeName() +struct declinfoYY_state { - //printf("addTypeName() type=`%s' scope=`%s' name=`%s'\n", - // type.data(),scope.data(),name.data()); - if (name.isEmpty() || - name.at(name.length()-1)==':') // end of Objective-C keyword => append to name not type - { - return; - } - if (!type.isEmpty()) type+=' '; - type+=name; - name.resize(0); -} - -#define YY_NEVER_INTERACTIVE 1 - + const char *inputString; + int inputPosition; + QCString scope; + QCString className; + QCString classTempList; + QCString funcTempList; + QCString type; + QCString name; + QCString args; + int sharpCount; + bool classTempListFound; + bool funcTempListFound; + QCString exceptionString; + bool insideObjC; + bool insidePHP; +}; + +static void addType(yyscan_t yyscanner); +static void addTypeName(yyscan_t yyscanner); +static int yyread(char *buf,int max_size, yyscan_t yyscanner); + /* ----------------------------------------------------------------- */ #undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); - -static int yyread(char *buf,int max_size) -{ - int c=0; - while( c < max_size && inputString[inputPosition] ) - { - *buf = inputString[inputPosition++] ; - c++; buf++; - } - return c; -} - +#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size,yyscanner); %} B [ \t] ID "$"?([a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*)|(@[0-9]+) -%option nounput -%option noyywrap - %x Start %x Template %x ReadArgs @@ -119,161 +89,222 @@ ID "$"?([a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*)|(@[0-9]+) %% <Start>"operator"/({B}*"["{B}*"]")* { // operator rule must be before {ID} rule - name += yytext; + yyextra->name += yytext; BEGIN(Operator); } <Start>{ID}{B}*"("{B}*{ID}{B}*")" { // Objective-C class categories - if (!insideObjC) + if (!yyextra->insideObjC) { REJECT; } else { - name += yytext; + yyextra->name += yytext; } } +<Start>([~!]{B}*)?{ID}{B}*"["{B}*"]" { // PHP + if (!yyextra->insidePHP) + { + REJECT; + } + addTypeName(yyscanner); + yyextra->name += removeRedundantWhiteSpace(yytext); + } <Start>([~!]{B}*)?{ID}/({B}*"["{B}*"]")* { // the []'s are for Java, // the / was add to deal with multi- // dimensional C++ arrays like A[][15] // the leading ~ is for a destructor // the leading ! is for a C++/CLI finalizer (see bug 456475 and 635198) - addTypeName(); - name += yytext; + addTypeName(yyscanner); + yyextra->name += removeRedundantWhiteSpace(yytext); } -<Start>{B}*"::"{B}* { // found a scope specifier - if (!scope.isEmpty()) +<Start>{B}*"::"{B}* { // found a yyextra->scope specifier + if (!yyextra->scope.isEmpty()) { - scope+="::"+name; // add name to scope + yyextra->scope+="::"+yyextra->name; // add yyextra->name to yyextra->scope } else { - scope = name.copy(); // scope becomes name + yyextra->scope = yyextra->name.copy(); // yyextra->scope becomes yyextra->name } - name.resize(0); + yyextra->name.resize(0); } <Start>{B}*":" { // Objective-C argument separator - name+=yytext; + yyextra->name+=yytext; } <Start>[*&]+ { - addType(); - type+=yytext; + addType(yyscanner); + yyextra->type+=yytext; } <Start>{B}+ { - addType(); + addType(yyscanner); } <Start>{B}*"("({ID}"::")*{B}*[&*]({B}*("const"|"volatile"){B}+)? { - addType(); + addType(yyscanner); QCString text=yytext; - type+=text.stripWhiteSpace(); + yyextra->type+=text.stripWhiteSpace(); } <Start>{B}*")" { - type+=")"; + yyextra->type+=")"; } <Start>{B}*"(" { // TODO: function pointers - args+="("; + yyextra->args+="("; BEGIN(ReadArgs); } <Start>{B}*"[" { - args+="["; + yyextra->args+="["; BEGIN(ReadArgs); } <Start>{B}*"<" { - name+="<"; - sharpCount=0; + yyextra->name+="<"; + yyextra->sharpCount=0; BEGIN(Template); } -<Template>"<<" { name+="<<"; } -<Template>">>" { name+=">>"; } +<Template>"<<" { yyextra->name+="<<"; } +<Template>">>" { yyextra->name+=">>"; } <Template>"<" { - name+="<"; - sharpCount++; + yyextra->name+="<"; + yyextra->sharpCount++; } <Template>">" { - name+=">"; - if (sharpCount) - --sharpCount; + yyextra->name+=">"; + if (yyextra->sharpCount) + --yyextra->sharpCount; else { BEGIN(Start); } } <Template>. { - name+=*yytext; + yyextra->name+=*yytext; } <Operator>{B}*"("{B}*")"{B}*"<>"{B}*/"(" { - name+="() <>"; + yyextra->name+="() <>"; BEGIN(ReadArgs); } <Operator>{B}*"("{B}*")"{B}*/"(" { - name+="()"; + yyextra->name+="()"; BEGIN(ReadArgs); } <Operator>[^(]*{B}*("<>"{B}*)?/"(" { - name+=yytext; + yyextra->name+=yytext; BEGIN(ReadArgs); } <ReadArgs>"throw"{B}*"(" { - exceptionString="throw("; + yyextra->exceptionString="throw("; BEGIN(ReadExceptions); } <ReadArgs>. { - args+=*yytext; + yyextra->args+=*yytext; } <ReadExceptions>. { - exceptionString+=*yytext; + yyextra->exceptionString+=*yytext; } <*>. <*>\n %% -/*@ ---------------------------------------------------------------------------- +static void addType(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + //printf("addType() yyextra->type='%s' yyextra->scope='%s' yyextra->name='%s'\n", + // yyextra->type.data(),yyextra->scope.data(),yyextra->name.data()); + if (yyextra->name.isEmpty() && yyextra->scope.isEmpty()) return; + if (!yyextra->type.isEmpty()) yyextra->type+=" "; + if (!yyextra->scope.isEmpty()) yyextra->type+=yyextra->scope+"::"; + yyextra->type+=yyextra->name; + yyextra->scope.resize(0); + yyextra->name.resize(0); +} + +static void addTypeName(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + //printf("addTypeName() yyextra->type='%s' yyextra->scope='%s' yyextra->name='%s'\n", + // yyextra->type.data(),yyextra->scope.data(),yyextra->name.data()); + if (yyextra->name.isEmpty() || + yyextra->name.at(yyextra->name.length()-1)==':') // end of Objective-C keyword => append to yyextra->name not yyextra->type + { + return; + } + if (!yyextra->type.isEmpty()) yyextra->type+=' '; + yyextra->type+=yyextra->name; + yyextra->name.resize(0); +} + +static int yyread(char *buf,int max_size, yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + int c=0; + while( c < max_size && yyextra->inputString[yyextra->inputPosition] ) + { + *buf = yyextra->inputString[yyextra->inputPosition++] ; + c++; buf++; + } + return c; +} + +/*@ public interface------------------------------------------------------------ */ +static yyscan_t g_yyscanner; +static struct declinfoYY_state g_declinfo_extra; -void parseFuncDecl(const QCString &decl,bool objC,QCString &cl,QCString &t, +void parseFuncDecl(const QCString &decl,const SrcLangExt lang,QCString &cl,QCString &t, QCString &n,QCString &a,QCString &ftl,QCString &exc) { + if (decl.isEmpty()) + { + return; + } + declinfoYYlex_init_extra(&g_declinfo_extra, &g_yyscanner); + struct yyguts_t *yyg = (struct yyguts_t*)g_yyscanner; + +#ifdef FLEX_DEBUG + yyset_debug(1,g_yyscanner); +#endif + printlex(yy_flex_debug, TRUE, __FILE__, NULL); - inputString = decl; - //printf("Input=`%s'\n",inputString); - if (inputString==0) return; - inputPosition = 0; - classTempListFound = FALSE; - funcTempListFound = FALSE; - insideObjC = objC; - scope.resize(0); - className.resize(0); - classTempList.resize(0); - funcTempList.resize(0); - name.resize(0); - type.resize(0); - args.resize(0); - exceptionString.resize(0); - // first we try to find the type, scope, name and arguments - declinfoYYrestart( declinfoYYin ); + yyextra->inputString = decl; + //printf("Input='%s'\n",yyextra->inputString); + yyextra->inputPosition = 0; + yyextra->classTempListFound = FALSE; + yyextra->funcTempListFound = FALSE; + yyextra->insideObjC = lang==SrcLangExt_ObjC; + yyextra->insidePHP = lang==SrcLangExt_PHP; + yyextra->scope.resize(0); + yyextra->className.resize(0); + yyextra->classTempList.resize(0); + yyextra->funcTempList.resize(0); + yyextra->name.resize(0); + yyextra->type.resize(0); + yyextra->args.resize(0); + yyextra->exceptionString.resize(0); + // first we try to find the yyextra->type, yyextra->scope, yyextra->name and arguments + declinfoYYrestart( yyin, g_yyscanner ); BEGIN( Start ); - declinfoYYlex(); + declinfoYYlex(g_yyscanner); - //printf("type=`%s' class=`%s' name=`%s' args=`%s'\n", - // type.data(),scope.data(),name.data(),args.data()); + //printf("yyextra->type='%s' class='%s' yyextra->name='%s' yyextra->args='%s'\n", + // yyextra->type.data(),yyextra->scope.data(),yyextra->name.data(),yyextra->args.data()); - int nb = name.findRev('['); - if (nb!=-1 && args.isEmpty()) // correct for [] in name ambigity (due to Java return type allowing []) + int nb = yyextra->name.findRev('['); + if (nb!=-1 && yyextra->args.isEmpty()) // correct for [] in yyextra->name ambigity (due to Java return yyextra->type allowing []) { - args.prepend(name.right(name.length()-nb)); - name=name.left(nb); + yyextra->args.prepend(yyextra->name.right(yyextra->name.length()-nb)); + yyextra->name=yyextra->name.left(nb); } #if 0 { - int l=scope.length(); + int l=yyextra->scope.length(); int i=0; int skipCount=0; cl.resize(0); ctl.resize(0); for (i=0;i<l;i++) { - char c=scope.at(i); + char c=yyextra->scope.at(i); if (c=='<') skipCount++; else if (c=='>') @@ -282,12 +313,12 @@ void parseFuncDecl(const QCString &decl,bool objC,QCString &cl,QCString &t, cl+=c; } } - cl=stripTemplateSpecifiersFromScope(removeRedundantWhiteSpace(scope),FALSE); + cl=stripTemplateSpecifiersFromScope(removeRedundantWhiteSpace(yyextra->scope),FALSE); ctl.resize(0); #endif - cl=scope; - n=removeRedundantWhiteSpace(name); + cl=yyextra->scope; + n=removeRedundantWhiteSpace(yyextra->name); int il,ir; if ((il=n.find('<'))!=-1 && (ir=n.findRev('>'))!=-1) // TODO: handle cases like where n="operator<< <T>" @@ -296,24 +327,23 @@ void parseFuncDecl(const QCString &decl,bool objC,QCString &cl,QCString &t, n=n.left(il); } - //ctl=classTempList.copy(); - //ftl=funcTempList.copy(); - t=removeRedundantWhiteSpace(type); - a=removeRedundantWhiteSpace(args); - exc=removeRedundantWhiteSpace(exceptionString); + //ctl=yyextra->classTempList.copy(); + //ftl=yyextra->funcTempList.copy(); + t=removeRedundantWhiteSpace(yyextra->type); + a=removeRedundantWhiteSpace(yyextra->args); + exc=removeRedundantWhiteSpace(yyextra->exceptionString); if (!t.isEmpty() && t.at(t.length()-1)==')') // for function pointers { a.prepend(")"); t=t.left(t.length()-1); } - //printf("type=`%s' class=`%s' name=`%s' args=`%s'\n", + //printf("yyextra->type='%s' class='%s' yyextra->name='%s' yyextra->args='%s'\n", // t.data(),cl.data(),n.data(),a.data()); printlex(yy_flex_debug, FALSE, __FILE__, NULL); + declinfoYYlex_destroy(g_yyscanner); return; - - } //extern "C" { // some bogus code to keep the compiler happy @@ -324,18 +354,18 @@ void parseFuncDecl(const QCString &decl,bool objC,QCString &cl,QCString &t, #if 0 void dumpDecl(const char *s) { - QCString className; + QCString yyextra->className; QCString classTNames; - QCString type; - QCString name; - QCString args; + QCString yyextra->type; + QCString yyextra->name; + QCString yyextra->args; QCString funcTNames; msg("-----------------------------------------\n"); - parseFuncDecl(s,className,classTNames,type,name,args,funcTNames); - msg("type=`%s' class=`%s' classTempl=`%s' name=`%s' " - "funcTemplateNames=`%s' args=`%s'\n", - type.data(),className.data(),classTNames.data(), - name.data(),funcTNames.data(),args.data() + parseFuncDecl(s,yyextra->className,classTNames,yyextra->type,yyextra->name,yyextra->args,funcTNames); + msg("yyextra->type='%s' class='%s' classTempl='%s' yyextra->name='%s' " + "funcTemplateNames='%s' yyextra->args='%s'\n", + yyextra->type.data(),yyextra->className.data(),classTNames.data(), + yyextra->name.data(),funcTNames.data(),yyextra->args.data() ); } @@ -346,11 +376,11 @@ int main() dumpDecl("const A<T>::Value* A<T>::getValue<S>(const A<T>&a)"); dumpDecl("func()"); dumpDecl("friend void bla<>()"); - dumpDecl("name< T > :: operator () (int bla)"); - dumpDecl("name< T > :: operator << (int bla)"); - dumpDecl("name< T > :: operator << <> (int bla)"); - dumpDecl("className::func()"); - dumpDecl("void ( * Name < T > :: bla ) ( int, char * )"); + dumpDecl("yyextra->name< T > :: operator () (int bla)"); + dumpDecl("yyextra->name< T > :: operator << (int bla)"); + dumpDecl("yyextra->name< T > :: operator << <> (int bla)"); + dumpDecl("yyextra->className::func()"); + dumpDecl("void ( * yyextra->Name < T > :: bla ) ( int, char * )"); } #endif diff --git a/src/defargs.l b/src/defargs.l index 7e9ccca..85878c1 100644 --- a/src/defargs.l +++ b/src/defargs.l @@ -282,6 +282,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" <CopyArgSharp>"<<" { if (g_argRoundCount>0) { + // for e.g. < typename A = (i<<3) > *g_copyArgValue += yytext; } else @@ -289,17 +290,10 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" REJECT; } } -<CopyArgSharp>">>)" { // combined token (see bug 790320) - *g_copyArgValue += yytext; - if (g_argSharpCount>0) g_argSharpCount--; - else BEGIN( g_readArgContext ); - if (g_argSharpCount>0) g_argSharpCount--; - else BEGIN( g_readArgContext ); - g_argRoundCount--; - } <CopyArgSharp>">>" { if (g_argRoundCount>0) { + // for e.g. < typename A = (i>>3) > *g_copyArgValue += yytext; } else @@ -308,12 +302,14 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" } } <CopyArgSharp>"<" { - g_argSharpCount++; + // don't count < inside (, e.g. for things like: < typename A=(i<6) > + if (g_argRoundCount==0) g_argSharpCount++; *g_copyArgValue += *yytext; } <CopyArgSharp>">" { *g_copyArgValue += *yytext; - if (g_argSharpCount>0) g_argSharpCount--; + // don't count > inside ) + if (g_argSharpCount>0 && g_argRoundCount==0) g_argSharpCount--; else BEGIN( g_readArgContext ); } <CopyArgSharp>"(" { @@ -371,7 +367,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" { g_curArgTypeName=removeRedundantWhiteSpace(g_curArgTypeName); g_curArgDefValue=g_curArgDefValue.stripWhiteSpace(); - //printf("curArgType=`%s' curArgDefVal=`%s'\n",g_curArgTypeName.data(),g_curArgDefValue.data()); + //printf("curArgType='%s' curArgDefVal='%s'\n",g_curArgTypeName.data(),g_curArgDefValue.data()); int l=g_curArgTypeName.length(); if (l>0) { @@ -451,7 +447,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" a->defval = g_curArgDefValue.copy(); //printf("a->type=%s a->name=%s a->defval=\"%s\"\n",a->type.data(),a->name.data(),a->defval.data()); a->docs = g_curArgDocs.stripWhiteSpace(); - //printf("Argument `%s' `%s' adding docs=`%s'\n",a->type.data(),a->name.data(),a->docs.data()); + //printf("Argument '%s' '%s' adding docs='%s'\n",a->type.data(),a->name.data(),a->docs.data()); g_argList->append(a); } g_curArgAttrib.resize(0); @@ -483,7 +479,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_curArgTypeName+=" []"; g_curArgArray.resize(0); } - //printf("resolveName `%s'->`%s'\n",yytext,name.data()); + //printf("resolveName '%s'->'%s'\n",yytext,name.data()); g_curArgTypeName+=name; } <ReadFuncArgType,ReadFuncArgPtr>. { diff --git a/src/defgen.cpp b/src/defgen.cpp index a8f89c5..aa9a1da 100644 --- a/src/defgen.cpp +++ b/src/defgen.cpp @@ -27,6 +27,7 @@ #include "defargs.h" #include "outputgen.h" #include "dot.h" +#include "dotclassgraph.h" #include "arguments.h" #include "memberlist.h" #include "namespacedef.h" @@ -144,7 +145,7 @@ void generateDEFForMember(MemberDef *md, if (isFunc) //function { ArgumentList *declAl = new ArgumentList; - ArgumentList *defAl = md->argumentList(); + const ArgumentList *defAl = md->argumentList(); stringToArgumentList(md->argsString(),declAl); QCString fcnPrefix = " " + memPrefix + "param-"; @@ -220,7 +221,7 @@ void generateDEFForMember(MemberDef *md, // TODO: exceptions, const volatile if (md->memberType()==MemberType_Enumeration) // enum { - MemberList *enumList = md->enumFieldList(); + const MemberList *enumList = md->enumFieldList(); if (enumList!=0) { MemberListIterator emli(*enumList); @@ -262,7 +263,7 @@ void generateDEFForMember(MemberDef *md, t << memPrefix << "referenceto = {" << endl; t << refPrefix << "id = '" << rmd->getBodyDef()->getOutputFileBase() - << "_1" // encoded `:' character (see util.cpp:convertNameToFile) + << "_1" // encoded ':' character (see util.cpp:convertNameToFile) << rmd->anchor() << "';" << endl; t << refPrefix << "line = '" @@ -295,7 +296,7 @@ void generateDEFForMember(MemberDef *md, t << memPrefix << "referenceby = {" << endl; t << refPrefix << "id = '" << rmd->getBodyDef()->getOutputFileBase() - << "_1" // encoded `:' character (see util.cpp:convertNameToFile) + << "_1" // encoded ':' character (see util.cpp:convertNameToFile) << rmd->anchor() << "';" << endl; t << refPrefix << "line = '" @@ -466,14 +467,14 @@ void generateDEFForClass(ClassDef *cd,FTextStream &t) t << " cp-documentation = <<_EnD_oF_dEf_TeXt_" << endl << cd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl; - DotClassGraph inheritanceGraph(cd,DotNode::Inheritance); + DotClassGraph inheritanceGraph(cd,Inheritance); if (!inheritanceGraph.isTrivial()) { t << " cp-inheritancegraph = <<_EnD_oF_dEf_TeXt_" << endl; inheritanceGraph.writeDEF(t); t << endl << "_EnD_oF_dEf_TeXt_;" << endl; } - DotClassGraph collaborationGraph(cd,DotNode::Collaboration); + DotClassGraph collaborationGraph(cd,Collaboration); if (!collaborationGraph.isTrivial()) { t << " cp-collaborationgraph = <<_EnD_oF_dEf_TeXt_" << endl; @@ -576,13 +577,13 @@ void generateDEF() dir.setPath(QDir::currentDirPath()); if (!dir.mkdir(outputDirectory)) { - err("tag OUTPUT_DIRECTORY: Output directory `%s' does not " + err("tag OUTPUT_DIRECTORY: Output directory '%s' does not " "exist and cannot be created\n",outputDirectory.data()); exit(1); } else { - msg("Notice: Output directory `%s' does not exist. " + msg("Notice: Output directory '%s' does not exist. " "I have created it for you.\n", outputDirectory.data()); } dir.cd(outputDirectory); diff --git a/src/definition.cpp b/src/definition.cpp index fbf5be8..3b5fea1 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -22,10 +22,11 @@ #include <stdlib.h> #include <assert.h> #include "config.h" -#include "definition.h" +#include "definitionimpl.h" #include "doxygen.h" #include "language.h" #include "message.h" +#include "portable.h" #include "outputlist.h" #include "code.h" #include "util.h" @@ -34,7 +35,6 @@ #include "section.h" #include "htags.h" #include "parserintf.h" -#include "marshal.h" #include "debug.h" #include "vhdldocgen.h" #include "memberlist.h" @@ -44,19 +44,16 @@ #include "pagedef.h" #include "bufstr.h" -#define START_MARKER 0x4445465B // DEF[ -#define END_MARKER 0x4445465D // DEF] - //----------------------------------------------------------------------------------------- - -/** Private data associated with a Symbol Definition object. */ -class DefinitionImpl +/** Private data associated with a Symbol DefinitionImpl object. */ +class DefinitionImpl::IMPL { public: - DefinitionImpl(); - ~DefinitionImpl(); + IMPL(); + ~IMPL(); void init(const char *df, const char *n); + void setDefFileName(const QCString &df); SectionDict *sectionDict; // dictionary of all sections, not accessible @@ -82,16 +79,23 @@ class DefinitionImpl Definition *outerScope; // not owner - // where the item was found + // where the item was defined QCString defFileName; QCString defFileExt; SrcLangExt lang; QCString id; // clang unique id + + QCString name; + bool isSymbol; + QCString symbolName; + int defLine; + int defColumn; + Cookie *cookie; }; -DefinitionImpl::DefinitionImpl() +DefinitionImpl::IMPL::IMPL() : sectionDict(0), sourceRefByDict(0), sourceRefsDict(0), xrefListItems(0), partOfGroups(0), details(0), inbodyDocs(0), brief(0), body(0), hidden(FALSE), isArtificial(FALSE), @@ -99,7 +103,7 @@ DefinitionImpl::DefinitionImpl() { } -DefinitionImpl::~DefinitionImpl() +DefinitionImpl::IMPL::~IMPL() { delete sectionDict; delete sourceRefByDict; @@ -112,7 +116,7 @@ DefinitionImpl::~DefinitionImpl() delete inbodyDocs; } -void DefinitionImpl::init(const char *df, const char *n) +void DefinitionImpl::IMPL::setDefFileName(const QCString &df) { defFileName = df; int lastDot = defFileName.findRev('.'); @@ -120,6 +124,11 @@ void DefinitionImpl::init(const char *df, const char *n) { defFileExt = defFileName.mid(lastDot); } +} + +void DefinitionImpl::IMPL::init(const char *df, const char *n) +{ + setDefFileName(df); QCString name = n; if (name!="<globalScope>") { @@ -145,6 +154,14 @@ void DefinitionImpl::init(const char *df, const char *n) hidden = FALSE; isArtificial = FALSE; lang = SrcLangExt_Unknown; + cookie = 0; +} + +void DefinitionImpl::setDefFile(const QCString &df,int defLine,int defCol) +{ + m_impl->setDefFileName(df); + m_impl->defLine = defLine; + m_impl->defColumn = defCol; } //----------------------------------------------------------------------------------------- @@ -206,7 +223,7 @@ static bool matchExcludedSymbols(const char *name) return FALSE; } -void Definition::addToMap(const char *name,Definition *d) +static void addToMap(const char *name,Definition *d) { bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); QCString symbolName = name; @@ -214,7 +231,7 @@ void Definition::addToMap(const char *name,Definition *d) if (!vhdlOpt && index!=-1) symbolName=symbolName.mid(index+2); if (!symbolName.isEmpty()) { - //printf("******* adding symbol `%s' (%p)\n",symbolName.data(),d); + //printf("******* adding symbol '%s' (%p)\n",symbolName.data(),d); DefinitionIntf *di=Doxygen::symbolMap->find(symbolName); //printf(" addToMap(%p): looking for symbol %s: %p\n",d,symbolName.data(),di); if (di==0) // new Symbol @@ -253,12 +270,12 @@ void Definition::addToMap(const char *name,Definition *d) } } -void Definition::removeFromMap(Definition *d) +static void removeFromMap(Definition *d) { - QCString symbolName = d->m_symbolName; + QCString symbolName = d->_symbolName(); if (!symbolName.isEmpty()) { - //printf("******* removing symbol `%s' (%p)\n",symbolName.data(),d); + //printf("******* removing symbol '%s' (%p)\n",symbolName.data(),d); DefinitionIntf *di=Doxygen::symbolMap->find(symbolName); if (di) { @@ -283,16 +300,16 @@ void Definition::removeFromMap(Definition *d) } } -Definition::Definition(const char *df,int dl,int dc, +DefinitionImpl::DefinitionImpl(const char *df,int dl,int dc, const char *name,const char *b, - const char *d,bool isSymbol) : m_cookie(0) + const char *d,bool isSymbol) { - m_name = name; - m_defLine = dl; - m_defColumn = dc; - m_impl = new DefinitionImpl; + m_impl = new DefinitionImpl::IMPL; + m_impl->name = name; + m_impl->defLine = dl; + m_impl->defColumn = dc; m_impl->init(df,name); - m_isSymbol = isSymbol; + m_impl->isSymbol = isSymbol; if (isSymbol) addToMap(name,this); _setBriefDescription(b,df,dl); _setDocumentation(d,df,dl,TRUE,FALSE); @@ -302,12 +319,9 @@ Definition::Definition(const char *df,int dl,int dc, } } -Definition::Definition(const Definition &d) : DefinitionIntf(), m_cookie(0) +DefinitionImpl::DefinitionImpl(const DefinitionImpl &d) { - m_name = d.m_name; - m_defLine = d.m_defLine; - m_defColumn = d.m_defColumn; - m_impl = new DefinitionImpl; + m_impl = new DefinitionImpl::IMPL; *m_impl = *d.m_impl; m_impl->sectionDict = 0; m_impl->sourceRefByDict = 0; @@ -378,13 +392,12 @@ Definition::Definition(const Definition &d) : DefinitionIntf(), m_cookie(0) m_impl->inbodyDocs = new DocInfo(*d.m_impl->inbodyDocs); } - m_isSymbol = d.m_isSymbol; - if (m_isSymbol) addToMap(m_name,this); + if (m_impl->isSymbol) addToMap(m_impl->name,this); } -Definition::~Definition() +DefinitionImpl::~DefinitionImpl() { - if (m_isSymbol) + if (m_impl->isSymbol) { removeFromMap(this); } @@ -393,33 +406,31 @@ Definition::~Definition() delete m_impl; m_impl=0; } - delete m_cookie; - m_cookie=0; } -void Definition::setName(const char *name) +void DefinitionImpl::setName(const char *name) { if (name==0) return; - m_name = name; + m_impl->name = name; } -void Definition::setId(const char *id) +void DefinitionImpl::setId(const char *id) { if (id==0) return; m_impl->id = id; if (Doxygen::clangUsrMap) { - //printf("Definition::setId '%s'->'%s'\n",id,m_name.data()); + //printf("DefinitionImpl::setId '%s'->'%s'\n",id,m_name.data()); Doxygen::clangUsrMap->insert(id,this); } } -QCString Definition::id() const +QCString DefinitionImpl::id() const { return m_impl->id; } -void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList) +void DefinitionImpl::addSectionsToDefinition(QList<SectionInfo> *anchorList) { if (!anchorList) return; //printf("%s: addSectionsToDefinition(%d)\n",name().data(),anchorList->count()); @@ -427,7 +438,7 @@ void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList) SectionInfo *si; for (;(si=it.current());++it) { - //printf("Add section `%s' to definition `%s'\n", + //printf("Add section '%s' to definition '%s'\n", // si->label.data(),name().data()); SectionInfo *gsi=Doxygen::sectionDict->find(si->label); //printf("===== label=%s gsi=%p\n",si->label.data(),gsi); @@ -448,9 +459,9 @@ void Definition::addSectionsToDefinition(QList<SectionInfo> *anchorList) } } -bool Definition::hasSections() const +bool DefinitionImpl::hasSections() const { - //printf("Definition::hasSections(%s) #sections=%d\n",name().data(), + //printf("DefinitionImpl::hasSections(%s) #sections=%d\n",name().data(), // m_impl->sectionDict ? m_impl->sectionDict->count() : 0); if (m_impl->sectionDict==0) return FALSE; SDict<SectionInfo>::Iterator li(*m_impl->sectionDict); @@ -468,10 +479,10 @@ bool Definition::hasSections() const return FALSE; } -void Definition::addSectionsToIndex() +void DefinitionImpl::addSectionsToIndex() { if (m_impl->sectionDict==0) return; - //printf("Definition::addSectionsToIndex()\n"); + //printf("DefinitionImpl::addSectionsToIndex()\n"); SDict<SectionInfo>::Iterator li(*m_impl->sectionDict); SectionInfo *si; int level=1; @@ -521,7 +532,7 @@ void Definition::addSectionsToIndex() } } -void Definition::writeDocAnchorsToTagFile(FTextStream &tagFile) +void DefinitionImpl::writeDocAnchorsToTagFile(FTextStream &tagFile) const { if (m_impl->sectionDict) { @@ -545,7 +556,7 @@ void Definition::writeDocAnchorsToTagFile(FTextStream &tagFile) } } -bool Definition::_docsAlreadyAdded(const QCString &doc,QCString &sigList) +bool DefinitionImpl::_docsAlreadyAdded(const QCString &doc,QCString &sigList) { uchar md5_sig[16]; QCString sigStr(33); @@ -567,7 +578,7 @@ bool Definition::_docsAlreadyAdded(const QCString &doc,QCString &sigList) } } -void Definition::_setDocumentation(const char *d,const char *docFile,int docLine, +void DefinitionImpl::_setDocumentation(const char *d,const char *docFile,int docLine, bool stripWhiteSpace,bool atTop) { //printf("%s::setDocumentation(%s,%s,%d,%d)\n",name().data(),d,docFile,docLine,stripWhiteSpace); @@ -583,7 +594,7 @@ void Definition::_setDocumentation(const char *d,const char *docFile,int docLine } if (!_docsAlreadyAdded(doc,m_impl->docSignatures)) { - //printf("setting docs for %s: `%s'\n",name().data(),m_doc.data()); + //printf("setting docs for %s: '%s'\n",name().data(),m_doc.data()); if (m_impl->details==0) { m_impl->details = new DocInfo; @@ -613,7 +624,7 @@ void Definition::_setDocumentation(const char *d,const char *docFile,int docLine } } -void Definition::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) +void DefinitionImpl::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) { if (d==0) return; _setDocumentation(d,docFile,docLine,stripWhiteSpace,FALSE); @@ -633,7 +644,7 @@ static bool lastCharIsMultibyte(const QCString &s) return TRUE; } -void Definition::_setBriefDescription(const char *b,const char *briefFile,int briefLine) +void DefinitionImpl::_setBriefDescription(const char *b,const char *briefFile,int briefLine) { static QCString outputLanguage = Config_getEnum(OUTPUT_LANGUAGE); static bool needsDot = outputLanguage!="Japanese" && @@ -664,7 +675,7 @@ void Definition::_setBriefDescription(const char *b,const char *briefFile,int br } else { - //fprintf(stderr,"Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine); + //fprintf(stderr,"DefinitionImpl::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine); if (m_impl->brief==0) { m_impl->brief = new BriefInfo; @@ -688,13 +699,13 @@ void Definition::_setBriefDescription(const char *b,const char *briefFile,int br } } -void Definition::setBriefDescription(const char *b,const char *briefFile,int briefLine) +void DefinitionImpl::setBriefDescription(const char *b,const char *briefFile,int briefLine) { if (b==0) return; _setBriefDescription(b,briefFile,briefLine); } -void Definition::_setInbodyDocumentation(const char *doc,const char *inbodyFile,int inbodyLine) +void DefinitionImpl::_setInbodyDocumentation(const char *doc,const char *inbodyFile,int inbodyLine) { if (m_impl->inbodyDocs==0) { @@ -712,7 +723,7 @@ void Definition::_setInbodyDocumentation(const char *doc,const char *inbodyFile, } } -void Definition::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine) +void DefinitionImpl::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine) { if (d==0) return; _setInbodyDocumentation(d,inbodyFile,inbodyLine); @@ -902,7 +913,7 @@ bool readCodeFragment(const char *fileName, int pc=0; while ((c=*p++)!='{' && c!=':' && c!=0) { - //printf("parsing char `%c'\n",c); + //printf("parsing char '%c'\n",c); if (c=='\n') { lineNr++,col=0; @@ -1003,7 +1014,7 @@ bool readCodeFragment(const char *fileName, return found; } -QCString Definition::getSourceFileBase() const +QCString DefinitionImpl::getSourceFileBase() const { ASSERT(definitionType()!=Definition::TypeFile); // file overloads this method QCString fn; @@ -1016,7 +1027,7 @@ QCString Definition::getSourceFileBase() const return fn; } -QCString Definition::getSourceAnchor() const +QCString DefinitionImpl::getSourceAnchor() const { const int maxAnchorStrLen = 20; char anchorStr[maxAnchorStrLen]; @@ -1036,13 +1047,13 @@ QCString Definition::getSourceAnchor() const } /*! Write a reference to the source code defining this definition */ -void Definition::writeSourceDef(OutputList &ol,const char *) +void DefinitionImpl::writeSourceDef(OutputList &ol,const char *) const { static bool latexSourceCode = Config_getBool(LATEX_SOURCE_CODE); static bool rtfSourceCode = Config_getBool(RTF_SOURCE_CODE); static bool docbookSourceCode = Config_getBool(DOCBOOK_PROGRAMLISTING); ol.pushGeneratorState(); - //printf("Definition::writeSourceRef %d %p\n",bodyLine,bodyDef); + //printf("DefinitionImpl::writeSourceRef %d %p\n",bodyLine,bodyDef); QCString fn = getSourceFileBase(); if (!fn.isEmpty()) { @@ -1226,7 +1237,7 @@ void Definition::writeSourceDef(OutputList &ol,const char *) ol.popGeneratorState(); } -void Definition::setBodySegment(int bls,int ble) +void DefinitionImpl::setBodySegment(int bls,int ble) { //printf("setBodySegment(%d,%d) for %s\n",bls,ble,name().data()); if (m_impl->body==0) m_impl->body = new BodyInfo; @@ -1234,13 +1245,13 @@ void Definition::setBodySegment(int bls,int ble) m_impl->body->endLine=ble; } -void Definition::setBodyDef(FileDef *fd) +void DefinitionImpl::setBodyDef(FileDef *fd) { if (m_impl->body==0) m_impl->body = new BodyInfo; m_impl->body->fileDef=fd; } -bool Definition::hasSources() const +bool DefinitionImpl::hasSources() const { return m_impl->body && m_impl->body->startLine!=-1 && m_impl->body->endLine>=m_impl->body->startLine && @@ -1248,7 +1259,7 @@ bool Definition::hasSources() const } /*! Write code of this definition into the documentation */ -void Definition::writeInlineCode(OutputList &ol,const char *scopeName) +void DefinitionImpl::writeInlineCode(OutputList &ol,const char *scopeName) const { static bool inlineSources = Config_getBool(INLINE_SOURCES); ol.pushGeneratorState(); @@ -1266,9 +1277,9 @@ void Definition::writeInlineCode(OutputList &ol,const char *scopeName) // codeFragment.data(),m_impl->defFileExt.data()); ParserInterface *pIntf = Doxygen::parserManager->getParser(m_impl->defFileExt); pIntf->resetCodeParserState(); - //printf("Read:\n`%s'\n\n",codeFragment.data()); - MemberDef *thisMd = 0; - if (definitionType()==TypeMember) thisMd = (MemberDef *)this; + //printf("Read:\n'%s'\n\n",codeFragment.data()); + const MemberDef *thisMd = 0; + if (definitionType()==TypeMember) thisMd = dynamic_cast <const MemberDef*>(this); ol.startCodeFragment(); pIntf->parseCode(ol, // codeOutIntf @@ -1293,8 +1304,8 @@ void Definition::writeInlineCode(OutputList &ol,const char *scopeName) /*! Write a reference to the source code fragments in which this * definition is used. */ -void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, - const QCString &text,MemberSDict *members,bool /*funcOnly*/) +void DefinitionImpl::_writeSourceRefList(OutputList &ol,const char *scopeName, + const QCString &text,MemberSDict *members,bool /*funcOnly*/) const { static bool latexSourceCode = Config_getBool(LATEX_SOURCE_CODE); static bool docbookSourceCode = Config_getBool(DOCBOOK_PROGRAMLISTING); @@ -1338,7 +1349,7 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, { name+="()"; } - //Definition *d = md->getOutputFileBase(); + //DefinitionImpl *d = md->getOutputFileBase(); //if (d==Doxygen::globalScope) d=md->getBodyDef(); if (sourceBrowser && !(md->isLinkable() && !refLinkSource) && @@ -1445,17 +1456,17 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName, ol.popGeneratorState(); } -void Definition::writeSourceReffedBy(OutputList &ol,const char *scopeName) +void DefinitionImpl::writeSourceReffedBy(OutputList &ol,const char *scopeName) const { _writeSourceRefList(ol,scopeName,theTranslator->trReferencedBy(),m_impl->sourceRefByDict,FALSE); } -void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) +void DefinitionImpl::writeSourceRefs(OutputList &ol,const char *scopeName) const { _writeSourceRefList(ol,scopeName,theTranslator->trReferences(),m_impl->sourceRefsDict,TRUE); } -bool Definition::hasDocumentation() const +bool DefinitionImpl::hasDocumentation() const { static bool extractAll = Config_getBool(EXTRACT_ALL); //static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); @@ -1470,7 +1481,7 @@ bool Definition::hasDocumentation() const return hasDocs; } -bool Definition::hasUserDocumentation() const +bool DefinitionImpl::hasUserDocumentation() const { bool hasDocs = (m_impl->details && !m_impl->details->doc.isEmpty()) || @@ -1480,7 +1491,7 @@ bool Definition::hasUserDocumentation() const } -void Definition::addSourceReferencedBy(MemberDef *md) +void DefinitionImpl::addSourceReferencedBy(const MemberDef *md) { if (md) { @@ -1503,7 +1514,7 @@ void Definition::addSourceReferencedBy(MemberDef *md) } } -void Definition::addSourceReferences(MemberDef *md) +void DefinitionImpl::addSourceReferences(const MemberDef *md) { if (md) { @@ -1526,17 +1537,17 @@ void Definition::addSourceReferences(MemberDef *md) } } -Definition *Definition::findInnerCompound(const char *) const +Definition *DefinitionImpl::findInnerCompound(const char *) const { return 0; } -void Definition::addInnerCompound(Definition *) +void DefinitionImpl::addInnerCompound(const Definition *) { - err("Definition::addInnerCompound() called\n"); + err("DefinitionImpl::addInnerCompound() called\n"); } -QCString Definition::qualifiedName() const +QCString DefinitionImpl::qualifiedName() const { //static int count=0; //count++; @@ -1576,7 +1587,7 @@ QCString Definition::qualifiedName() const return m_impl->qualifiedName; } -void Definition::setOuterScope(Definition *d) +void DefinitionImpl::setOuterScope(Definition *d) { //printf("%s::setOuterScope(%s)\n",name().data(),d?d->name().data():"<none>"); Definition *p = m_impl->outerScope; @@ -1585,7 +1596,7 @@ void Definition::setOuterScope(Definition *d) while (p && !found) { found = (p==d); - p = p->m_impl->outerScope; + p = p->getOuterScope(); } if (!found) { @@ -1595,18 +1606,18 @@ void Definition::setOuterScope(Definition *d) m_impl->hidden = m_impl->hidden || d->isHidden(); } -QCString Definition::localName() const +QCString DefinitionImpl::localName() const { return m_impl->localName; } -void Definition::makePartOfGroup(GroupDef *gd) +void DefinitionImpl::makePartOfGroup(GroupDef *gd) { if (m_impl->partOfGroups==0) m_impl->partOfGroups = new GroupList; m_impl->partOfGroups->append(gd); } -void Definition::setRefItems(const QList<ListItemInfo> *sli) +void DefinitionImpl::setRefItems(const QList<ListItemInfo> *sli) { //printf("%s::setRefItems()\n",name().data()); if (sli) @@ -1626,7 +1637,7 @@ void Definition::setRefItems(const QList<ListItemInfo> *sli) } } -void Definition::mergeRefItems(Definition *d) +void DefinitionImpl::mergeRefItems(Definition *d) { //printf("%s::mergeRefItems()\n",name().data()); QList<ListItemInfo> *xrefList = d->xrefListItems(); @@ -1658,7 +1669,7 @@ void Definition::mergeRefItems(Definition *d) } } -int Definition::_getXRefListId(const char *listName) const +int DefinitionImpl::_getXRefListId(const char *listName) const { if (m_impl->xrefListItems) { @@ -1675,12 +1686,12 @@ int Definition::_getXRefListId(const char *listName) const return -1; } -QList<ListItemInfo> *Definition::xrefListItems() const +QList<ListItemInfo> *DefinitionImpl::xrefListItems() const { return m_impl->xrefListItems; } -QCString Definition::pathFragment() const +QCString DefinitionImpl::pathFragment() const { QCString result; if (m_impl->outerScope && m_impl->outerScope!=Doxygen::globalScope) @@ -1690,13 +1701,13 @@ QCString Definition::pathFragment() const if (isLinkable()) { if (!result.isEmpty()) result+="/"; - if (definitionType()==Definition::TypeGroup && ((const GroupDef*)this)->groupTitle()) + if (definitionType()==Definition::TypeGroup && (dynamic_cast <const GroupDef*>(this))->groupTitle()) { - result+=((const GroupDef*)this)->groupTitle(); + result+=(dynamic_cast <const GroupDef*>(this))->groupTitle(); } - else if (definitionType()==Definition::TypePage && !((const PageDef*)this)->title().isEmpty()) + else if (definitionType()==Definition::TypePage && (dynamic_cast <const PageDef*>(this))->hasTitle()) { - result+=((const PageDef*)this)->title(); + result+=(dynamic_cast <const PageDef*>(this))->title(); } else { @@ -1716,7 +1727,7 @@ QCString Definition::pathFragment() const /*! Returns the string used in the footer for $navpath when * GENERATE_TREEVIEW is enabled */ -QCString Definition::navigationPathAsString() const +QCString DefinitionImpl::navigationPathAsString() const { QCString result; Definition *outerScope = getOuterScope(); @@ -1725,22 +1736,22 @@ QCString Definition::navigationPathAsString() const { result+=outerScope->navigationPathAsString(); } - else if (definitionType()==Definition::TypeFile && ((const FileDef*)this)->getDirDef()) + else if (definitionType()==Definition::TypeFile && (dynamic_cast<const FileDef*>(this))->getDirDef()) { - result+=((const FileDef*)this)->getDirDef()->navigationPathAsString(); + result+=(dynamic_cast<const FileDef*>(this))->getDirDef()->navigationPathAsString(); } result+="<li class=\"navelem\">"; if (isLinkable()) { - if (definitionType()==Definition::TypeGroup && ((const GroupDef*)this)->groupTitle()) + if (definitionType()==Definition::TypeGroup && (dynamic_cast<const GroupDef*>(this))->groupTitle()) { result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+ - convertToHtml(((const GroupDef*)this)->groupTitle())+"</a>"; + convertToHtml((dynamic_cast<const GroupDef*>(this))->groupTitle())+"</a>"; } - else if (definitionType()==Definition::TypePage && !((const PageDef*)this)->title().isEmpty()) + else if (definitionType()==Definition::TypePage && (dynamic_cast<const PageDef*>(this))->hasTitle()) { result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+ - convertToHtml(((const PageDef*)this)->title())+"</a>"; + convertToHtml((dynamic_cast<const PageDef*>(this))->title())+"</a>"; } else if (definitionType()==Definition::TypeClass) { @@ -1768,7 +1779,7 @@ QCString Definition::navigationPathAsString() const } // TODO: move to htmlgen -void Definition::writeNavigationPath(OutputList &ol) const +void DefinitionImpl::writeNavigationPath(OutputList &ol) const { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -1785,7 +1796,7 @@ void Definition::writeNavigationPath(OutputList &ol) const } // TODO: move to htmlgen -void Definition::writeToc(OutputList &ol, const LocalToc &localToc) +void DefinitionImpl::writeToc(OutputList &ol, const LocalToc &localToc) const { SectionDict *sectionDict = m_impl->sectionDict; if (sectionDict==0) return; @@ -1925,31 +1936,31 @@ void Definition::writeToc(OutputList &ol, const LocalToc &localToc) //---------------------------------------------------------------------------------------- -SectionDict * Definition::getSectionDict(void) +SectionDict * DefinitionImpl::getSectionDict() const { return m_impl->sectionDict; } -QCString Definition::symbolName() const +QCString DefinitionImpl::symbolName() const { - return m_symbolName; + return m_impl->symbolName; } //---------------------- -QCString Definition::documentation() const +QCString DefinitionImpl::documentation() const { return m_impl->details ? m_impl->details->doc : QCString(""); } -int Definition::docLine() const +int DefinitionImpl::docLine() const { return m_impl->details ? m_impl->details->line : 1; } -QCString Definition::docFile() const +QCString DefinitionImpl::docFile() const { - return m_impl->details ? m_impl->details->file : QCString("<"+m_name+">"); + return m_impl->details ? m_impl->details->file : QCString("<"+m_impl->name+">"); } //---------------------------------------------------------------------------- @@ -2003,7 +2014,7 @@ QCString abbreviate(const char *s,const char *name) //---------------------- -QCString Definition::briefDescription(bool abbr) const +QCString DefinitionImpl::briefDescription(bool abbr) const { //printf("%s::briefDescription(%d)='%s'\n",name().data(),abbr,m_impl->brief?m_impl->brief->doc.data():"<none>"); return m_impl->brief ? @@ -2011,7 +2022,7 @@ QCString Definition::briefDescription(bool abbr) const QCString(""); } -QCString Definition::briefDescriptionAsTooltip() const +QCString DefinitionImpl::briefDescriptionAsTooltip() const { if (m_impl->brief) { @@ -2020,7 +2031,7 @@ QCString Definition::briefDescriptionAsTooltip() const static bool reentering=FALSE; if (!reentering) { - MemberDef *md = definitionType()==TypeMember ? (MemberDef*)this : 0; + 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( @@ -2036,97 +2047,97 @@ QCString Definition::briefDescriptionAsTooltip() const return QCString(""); } -int Definition::briefLine() const +int DefinitionImpl::briefLine() const { return m_impl->brief ? m_impl->brief->line : 1; } -QCString Definition::briefFile() const +QCString DefinitionImpl::briefFile() const { - return m_impl->brief ? m_impl->brief->file : QCString("<"+m_name+">"); + return m_impl->brief ? m_impl->brief->file : QCString("<"+m_impl->name+">"); } //---------------------- -QCString Definition::inbodyDocumentation() const +QCString DefinitionImpl::inbodyDocumentation() const { return m_impl->inbodyDocs ? m_impl->inbodyDocs->doc : QCString(""); } -int Definition::inbodyLine() const +int DefinitionImpl::inbodyLine() const { return m_impl->inbodyDocs ? m_impl->inbodyDocs->line : 1; } -QCString Definition::inbodyFile() const +QCString DefinitionImpl::inbodyFile() const { - return m_impl->inbodyDocs ? m_impl->inbodyDocs->file : QCString("<"+m_name+">"); + return m_impl->inbodyDocs ? m_impl->inbodyDocs->file : QCString("<"+m_impl->name+">"); } //---------------------- -QCString Definition::getDefFileName() const +QCString DefinitionImpl::getDefFileName() const { return m_impl->defFileName; } -QCString Definition::getDefFileExtension() const +QCString DefinitionImpl::getDefFileExtension() const { return m_impl->defFileExt; } -bool Definition::isHidden() const +bool DefinitionImpl::isHidden() const { return m_impl->hidden; } -bool Definition::isVisibleInProject() const +bool DefinitionImpl::isVisibleInProject() const { return isLinkableInProject() && !m_impl->hidden; } -bool Definition::isVisible() const +bool DefinitionImpl::isVisible() const { return isLinkable() && !m_impl->hidden; } -bool Definition::isArtificial() const +bool DefinitionImpl::isArtificial() const { return m_impl->isArtificial; } -QCString Definition::getReference() const +QCString DefinitionImpl::getReference() const { return m_impl->ref; } -bool Definition::isReference() const +bool DefinitionImpl::isReference() const { return !m_impl->ref.isEmpty(); } -int Definition::getStartBodyLine() const +int DefinitionImpl::getStartBodyLine() const { return m_impl->body ? m_impl->body->startLine : -1; } -int Definition::getEndBodyLine() const +int DefinitionImpl::getEndBodyLine() const { return m_impl->body ? m_impl->body->endLine : -1; } -FileDef *Definition::getBodyDef() const +FileDef *DefinitionImpl::getBodyDef() const { return m_impl->body ? m_impl->body->fileDef : 0; } -GroupList *Definition::partOfGroups() const +GroupList *DefinitionImpl::partOfGroups() const { return m_impl->partOfGroups; } -bool Definition::isLinkableViaGroup() const +bool DefinitionImpl::isLinkableViaGroup() const { GroupList *gl = partOfGroups(); if (gl) @@ -2141,64 +2152,69 @@ bool Definition::isLinkableViaGroup() const return FALSE; } -Definition *Definition::getOuterScope() const +Definition *DefinitionImpl::getOuterScope() const { return m_impl->outerScope; } -MemberSDict *Definition::getReferencesMembers() const +MemberSDict *DefinitionImpl::getReferencesMembers() const { return m_impl->sourceRefsDict; } -MemberSDict *Definition::getReferencedByMembers() const +MemberSDict *DefinitionImpl::getReferencedByMembers() const { return m_impl->sourceRefByDict; } -void Definition::setReference(const char *r) +void DefinitionImpl::setReference(const char *r) { m_impl->ref=r; } -SrcLangExt Definition::getLanguage() const +SrcLangExt DefinitionImpl::getLanguage() const { return m_impl->lang; } -void Definition::setHidden(bool b) +void DefinitionImpl::setHidden(bool b) { m_impl->hidden = m_impl->hidden || b; } -void Definition::setArtificial(bool b) +void DefinitionImpl::setArtificial(bool b) { m_impl->isArtificial = b; } -void Definition::setLocalName(const QCString name) +void DefinitionImpl::setLocalName(const QCString name) { m_impl->localName=name; } -void Definition::setLanguage(SrcLangExt lang) +void DefinitionImpl::setLanguage(SrcLangExt lang) { m_impl->lang=lang; } -void Definition::_setSymbolName(const QCString &name) +void DefinitionImpl::_setSymbolName(const QCString &name) { - m_symbolName=name; + m_impl->symbolName=name; } -bool Definition::hasBriefDescription() const +QCString DefinitionImpl::_symbolName() const +{ + return m_impl->symbolName; +} + +bool DefinitionImpl::hasBriefDescription() const { static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC); return !briefDescription().isEmpty() && briefMemberDesc; } -QCString Definition::externalReference(const QCString &relPath) const +QCString DefinitionImpl::externalReference(const QCString &relPath) const { QCString ref = getReference(); if (!ref.isEmpty()) @@ -2220,5 +2236,52 @@ QCString Definition::externalReference(const QCString &relPath) const return relPath; } +QCString DefinitionImpl::name() const +{ + return m_impl->name; +} + +int DefinitionImpl::getDefLine() const +{ + return m_impl->defLine; +} + +int DefinitionImpl::getDefColumn() const +{ + return m_impl->defColumn; +} + +void DefinitionImpl::setCookie(Cookie *cookie) const +{ + delete m_impl->cookie; + m_impl->cookie = cookie; +} + +Definition::Cookie *DefinitionImpl::cookie() const +{ + return m_impl->cookie; +} + +void DefinitionImpl::writeQuickMemberLinks(OutputList &,const MemberDef *) const +{ +} + +void DefinitionImpl::writeSummaryLinks(OutputList &) const +{ +} + +//--------------------------------------------------------------------------------- +DefinitionAliasImpl::DefinitionAliasImpl(const Definition *scope,const Definition *alias) + : m_scope(scope), m_def(alias), m_cookie(0) +{ + //printf("%s::addToMap(%s)\n",qPrint(name()),qPrint(alias->name())); + addToMap(alias->name(),this); +} + +DefinitionAliasImpl::~DefinitionAliasImpl() +{ + //printf("~DefinitionAliasImpl()\n"); + removeFromMap(this); +} diff --git a/src/definition.h b/src/definition.h index c0428a0..db9bbbc 100644 --- a/src/definition.h +++ b/src/definition.h @@ -23,6 +23,12 @@ #include "types.h" +#if defined(_WIN32) && !defined(__CYGWIN__) +// To disable 'inherits via dominance' warnings. +// See also https://stackoverflow.com/a/14487243/784672 +#pragma warning( disable: 4250 ) +#endif + class FileDef; class OutputList; class SectionDict; @@ -33,7 +39,6 @@ class GroupList; struct ListItemInfo; struct SectionInfo; class Definition; -class DefinitionImpl; class FTextStream; /** Data associated with a detailed description. */ @@ -97,35 +102,28 @@ class Definition : public DefinitionIntf virtual ~Cookie() {} }; - /*! Create a new definition */ - Definition( - const char *defFileName,int defLine,int defColumn, - const char *name,const char *b=0,const char *d=0, - bool isSymbol=TRUE); - - /*! Destroys the definition */ - virtual ~Definition(); - //----------------------------------------------------------------------------------- // ---- getters ----- //----------------------------------------------------------------------------------- + /*! Returns TRUE if this is an alias of another definition */ + virtual bool isAlias() const = 0; /*! Returns the name of the definition */ - const QCString& name() const { return m_name; } + virtual QCString name() const = 0; /*! Returns the name of the definition as it appears in the output */ virtual QCString displayName(bool includeScope=TRUE) const = 0; /*! Returns the local name without any scope qualifiers. */ - QCString localName() const; + virtual QCString localName() const = 0; /*! Returns the fully qualified name of this definition */ - virtual QCString qualifiedName() const; + virtual QCString qualifiedName() const = 0; /*! Returns the name of this definition as it appears in the symbol map. */ - QCString symbolName() const; + virtual QCString symbolName() const = 0; /*! Returns the base file name (without extension) of this definition. * as it is referenced to/written to disk. @@ -136,68 +134,68 @@ class Definition : public DefinitionIntf virtual QCString anchor() const = 0; /*! Returns the name of the source listing of this definition. */ - virtual QCString getSourceFileBase() const; + virtual QCString getSourceFileBase() const = 0; /*! Returns the anchor of the source listing of this definition. */ - virtual QCString getSourceAnchor() const; + virtual QCString getSourceAnchor() const = 0; /*! Returns the detailed description of this definition */ - virtual QCString documentation() const; + virtual QCString documentation() const = 0; /*! Returns the line number at which the detailed documentation was found. */ - int docLine() const; + virtual int docLine() const = 0; /*! Returns the file in which the detailed documentation block was found. * This can differ from getDefFileName(). */ - QCString docFile() const; + virtual QCString docFile() const = 0; /*! Returns the brief description of this definition. This can include commands. */ - virtual QCString briefDescription(bool abbreviate=FALSE) const; + virtual QCString briefDescription(bool abbreviate=FALSE) const = 0; /*! Returns a plain text version of the brief description suitable for use * as a tool tip. */ - QCString briefDescriptionAsTooltip() const; + virtual QCString briefDescriptionAsTooltip() const = 0; /*! Returns the line number at which the brief description was found. */ - int briefLine() const; + virtual int briefLine() const = 0; /*! Returns the documentation found inside the body of a member */ - QCString inbodyDocumentation() const; + virtual QCString inbodyDocumentation() const = 0; /*! Returns the file in which the in body documentation was found */ - QCString inbodyFile() const; + virtual QCString inbodyFile() const = 0; /*! Returns the line at which the first in body documentation part was found */ - int inbodyLine() const; + virtual int inbodyLine() const = 0; /*! Returns the file in which the brief description was found. * This can differ from getDefFileName(). */ - QCString briefFile() const; + virtual QCString briefFile() const = 0; /*! returns the file in which this definition was found */ - QCString getDefFileName() const; + virtual QCString getDefFileName() const = 0; /*! returns the extension of the file in which this definition was found */ - QCString getDefFileExtension() const; + virtual QCString getDefFileExtension() const = 0; /*! returns the line number at which the definition was found */ - int getDefLine() const { return m_defLine; } + virtual int getDefLine() const = 0; /*! returns the column number at which the definition was found */ - int getDefColumn() const { return m_defColumn; } + virtual int getDefColumn() const = 0; /*! Returns TRUE iff the definition is documented * (which could be generated documentation) * @see hasUserDocumentation() */ - virtual bool hasDocumentation() const; + virtual bool hasDocumentation() const = 0; /*! Returns TRUE iff the definition is documented by the user. */ - virtual bool hasUserDocumentation() const; + virtual bool hasUserDocumentation() const = 0; /*! Returns TRUE iff it is possible to link to this item within this * project. @@ -212,172 +210,158 @@ class Definition : public DefinitionIntf /*! Returns TRUE iff the name is part of this project and * may appear in the output */ - virtual bool isVisibleInProject() const; + virtual bool isVisibleInProject() const = 0; /*! Returns TRUE iff the name may appear in the output */ - virtual bool isVisible() const; + virtual bool isVisible() const = 0; /*! Returns TRUE iff this item is supposed to be hidden from the output. */ - bool isHidden() const; + virtual bool isHidden() const = 0; /*! returns TRUE if this entity was artificially introduced, for * instance because it is used to show a template instantiation relation. */ - bool isArtificial() const; + virtual bool isArtificial() const = 0; /*! If this definition was imported via a tag file, this function * returns the tagfile for the external project. This can be * translated into an external link target via * Doxygen::tagDestinationDict */ - virtual QCString getReference() const; + virtual QCString getReference() const = 0; /*! Returns TRUE if this definition is imported via a tag file. */ - virtual bool isReference() const; + virtual bool isReference() const = 0; /*! Convenience method to return a resolved external link */ - QCString externalReference(const QCString &relPath) const; + virtual QCString externalReference(const QCString &relPath) const = 0; /*! Returns the first line of the body of this item (applicable to classes and * functions). */ - int getStartBodyLine() const; + virtual int getStartBodyLine() const = 0; /*! Returns the last line of the body of this item (applicable to classes and * functions). */ - int getEndBodyLine() const; + virtual int getEndBodyLine() const = 0; /*! Returns the file in which the body of this item is located or 0 if no * body is available. */ - FileDef *getBodyDef() const; + virtual FileDef *getBodyDef() const = 0; /** Returns the programming language this definition was written in. */ - SrcLangExt getLanguage() const; + virtual SrcLangExt getLanguage() const = 0; - GroupList *partOfGroups() const; - bool isLinkableViaGroup() const; + virtual GroupList *partOfGroups() const = 0; + virtual bool isLinkableViaGroup() const = 0; - QList<ListItemInfo> *xrefListItems() const; + virtual QList<ListItemInfo> *xrefListItems() const = 0; - virtual Definition *findInnerCompound(const char *name) const ; - virtual Definition *getOuterScope() const; + virtual Definition *findInnerCompound(const char *name) const = 0; + virtual Definition *getOuterScope() const = 0; - MemberSDict *getReferencesMembers() const; - MemberSDict *getReferencedByMembers() const; + virtual MemberSDict *getReferencesMembers() const = 0; + virtual MemberSDict *getReferencedByMembers() const = 0; - bool hasSections() const; - bool hasSources() const; + virtual bool hasSections() const = 0; + virtual bool hasSources() const = 0; /** returns TRUE if this class has a brief description */ - bool hasBriefDescription() const; + virtual bool hasBriefDescription() const = 0; - QCString id() const; + virtual QCString id() const = 0; /** returns the section dictionary, only of importance for pagedef */ - SectionDict * getSectionDict(void); + virtual SectionDict * getSectionDict() const = 0; + + virtual QCString navigationPathAsString() const = 0; + virtual QCString pathFragment() const = 0; //----------------------------------------------------------------------------------- // ---- setters ----- //----------------------------------------------------------------------------------- /*! Sets a new \a name for the definition */ - virtual void setName(const char *name); + virtual void setName(const char *name) = 0; /*! Sets a unique id for the symbol. Used for libclang integration. */ - void setId(const char *name); + virtual void setId(const char *name) = 0; + + /*! Set a new file name and position */ + virtual void setDefFile(const QCString& df,int defLine,int defColumn) = 0; /*! Sets the documentation of this definition to \a d. */ - virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE); + virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE) = 0; /*! Sets the brief description of this definition to \a b. * A dot is added to the sentence if not available. */ - virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine); + virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine) = 0; /*! Set the documentation that was found inside the body of an item. * If there was already some documentation set, the new documentation * will be appended. */ - virtual void setInbodyDocumentation(const char *d,const char *docFile,int docLine); + virtual void setInbodyDocumentation(const char *d,const char *docFile,int docLine) = 0; /*! Sets the tag file id via which this definition was imported. */ - void setReference(const char *r); - - /*! Add the list of anchors that mark the sections that are found in the - * documentation. - */ - void addSectionsToDefinition(QList<SectionInfo> *anchorList); + virtual void setReference(const char *r) = 0; // source references - void setBodySegment(int bls,int ble); - void setBodyDef(FileDef *fd); - void addSourceReferencedBy(MemberDef *d); - void addSourceReferences(MemberDef *d); + virtual void setBodySegment(int bls,int ble) = 0; + virtual void setBodyDef(FileDef *fd) = 0; - void setRefItems(const QList<ListItemInfo> *sli); - void mergeRefItems(Definition *d); - virtual void addInnerCompound(Definition *d); - virtual void setOuterScope(Definition *d); + virtual void setRefItems(const QList<ListItemInfo> *sli) = 0; + virtual void setOuterScope(Definition *d) = 0; - virtual void setHidden(bool b); + virtual void setHidden(bool b) = 0; - void setArtificial(bool b); - void setLanguage(SrcLangExt lang); + virtual void setArtificial(bool b) = 0; + virtual void setLanguage(SrcLangExt lang) = 0; + virtual void setLocalName(const QCString name) = 0; //----------------------------------------------------------------------------------- // --- actions ---- //----------------------------------------------------------------------------------- - void writeSourceDef(OutputList &ol,const char *scopeName); - void writeInlineCode(OutputList &ol,const char *scopeName); - void writeSourceRefs(OutputList &ol,const char *scopeName); - void writeSourceReffedBy(OutputList &ol,const char *scopeName); - void makePartOfGroup(GroupDef *gd); - //void writePathFragment(OutputList &ol) const; - void writeNavigationPath(OutputList &ol) const; - QCString navigationPathAsString() const; - virtual void writeQuickMemberLinks(OutputList &,MemberDef *) const {} - virtual void writeSummaryLinks(OutputList &) {} - QCString pathFragment() const; - - /*! Writes the documentation anchors of the definition to - * the Doxygen::tagFile stream. + virtual void makePartOfGroup(GroupDef *gd) = 0; + + /*! Add the list of anchors that mark the sections that are found in the + * documentation. */ - void writeDocAnchorsToTagFile(FTextStream &); - void setLocalName(const QCString name); - - void addSectionsToIndex(); - void writeToc(OutputList &ol, const LocalToc <); - - void setCookie(Cookie *cookie) { delete m_cookie; m_cookie = cookie; } - Cookie *cookie() const { return m_cookie; } - - protected: - - Definition(const Definition &d); - - private: - static void addToMap(const char *name,Definition *d); - static void removeFromMap(Definition *d); - - void _setSymbolName(const QCString &name); - - int _getXRefListId(const char *listName) const; - void _writeSourceRefList(OutputList &ol,const char *scopeName, - const QCString &text,MemberSDict *members,bool); - 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); - bool _docsAlreadyAdded(const QCString &doc,QCString &sigList); - DefinitionImpl *m_impl; // internal structure holding all private data - QCString m_name; - bool m_isSymbol; - QCString m_symbolName; - int m_defLine; - int m_defColumn; - Cookie *m_cookie; + virtual void addSectionsToDefinition(QList<SectionInfo> *anchorList) = 0; + virtual void addSourceReferencedBy(const MemberDef *d) = 0; + virtual void addSourceReferences(const MemberDef *d) = 0; + virtual void mergeRefItems(Definition *d) = 0; + virtual void addInnerCompound(const Definition *d) = 0; + virtual void addSectionsToIndex() = 0; + + //----------------------------------------------------------------------------------- + // --- writing output ---- + //----------------------------------------------------------------------------------- + virtual void writeSourceDef(OutputList &ol,const char *scopeName) const = 0; + virtual void writeInlineCode(OutputList &ol,const char *scopeName) const = 0; + virtual void writeSourceRefs(OutputList &ol,const char *scopeName) const = 0; + virtual void writeSourceReffedBy(OutputList &ol,const char *scopeName) const = 0; + virtual void writeNavigationPath(OutputList &ol) const = 0; + virtual void writeQuickMemberLinks(OutputList &,const MemberDef *) const = 0; + virtual void writeSummaryLinks(OutputList &) const = 0; + virtual void writeDocAnchorsToTagFile(FTextStream &) const = 0; + virtual void writeToc(OutputList &ol, const LocalToc <) const = 0; + + //----------------------------------------------------------------------------------- + // --- cookie storage ---- + //----------------------------------------------------------------------------------- + virtual void setCookie(Cookie *cookie) const = 0; + virtual Cookie *cookie() const = 0; + + //----------------------------------------------------------------------------------- + // --- symbol name ---- + //----------------------------------------------------------------------------------- + virtual void _setSymbolName(const QCString &name) = 0; + virtual QCString _symbolName() const = 0; }; /** A list of Definition objects. */ diff --git a/src/definitionimpl.h b/src/definitionimpl.h new file mode 100644 index 0000000..4dd324b --- /dev/null +++ b/src/definitionimpl.h @@ -0,0 +1,284 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2019 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef DEFINITIONIMPL_H +#define DEFINITIONIMPL_H + +#include "definition.h" + +class DefinitionImpl : virtual public Definition +{ + public: + /*! Create a new definition */ + DefinitionImpl( + const char *defFileName,int defLine,int defColumn, + const char *name,const char *b=0,const char *d=0, + bool isSymbol=TRUE); + virtual ~DefinitionImpl(); + + virtual bool isAlias() const { return FALSE; } + virtual QCString name() const; + virtual QCString localName() const; + virtual QCString qualifiedName() const; + virtual QCString symbolName() const; + virtual QCString getSourceFileBase() const; + virtual QCString getSourceAnchor() const; + virtual QCString documentation() const; + virtual int docLine() const; + virtual QCString docFile() const; + virtual QCString briefDescription(bool abbreviate=FALSE) const; + virtual QCString briefDescriptionAsTooltip() const; + virtual int briefLine() const; + virtual QCString inbodyDocumentation() const; + virtual QCString inbodyFile() const; + virtual int inbodyLine() const; + virtual QCString briefFile() const; + virtual QCString getDefFileName() const; + virtual QCString getDefFileExtension() const; + virtual int getDefLine() const; + virtual int getDefColumn() const; + virtual bool hasDocumentation() const; + virtual bool hasUserDocumentation() const; + virtual bool isVisibleInProject() const; + virtual bool isVisible() const; + virtual bool isHidden() const; + virtual bool isArtificial() const; + virtual QCString getReference() const; + virtual bool isReference() const; + virtual QCString externalReference(const QCString &relPath) const; + virtual int getStartBodyLine() const; + virtual int getEndBodyLine() const; + virtual FileDef *getBodyDef() const; + virtual SrcLangExt getLanguage() const; + virtual GroupList *partOfGroups() const; + virtual bool isLinkableViaGroup() const; + virtual QList<ListItemInfo> *xrefListItems() const; + virtual Definition *findInnerCompound(const char *name) const; + virtual Definition *getOuterScope() const; + virtual MemberSDict *getReferencesMembers() const; + virtual MemberSDict *getReferencedByMembers() const; + virtual bool hasSections() const; + virtual bool hasSources() const; + virtual bool hasBriefDescription() const; + virtual QCString id() const; + virtual SectionDict * getSectionDict() const; + virtual void setName(const char *name); + virtual void setId(const char *name); + virtual void setDefFile(const QCString& df,int defLine,int defColumn); + virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE); + virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine); + virtual void setInbodyDocumentation(const char *d,const char *docFile,int docLine); + virtual void setReference(const char *r); + virtual void addSectionsToDefinition(QList<SectionInfo> *anchorList); + virtual void setBodySegment(int bls,int ble); + virtual void setBodyDef(FileDef *fd); + virtual void addSourceReferencedBy(const MemberDef *d); + virtual void addSourceReferences(const MemberDef *d); + virtual void setRefItems(const QList<ListItemInfo> *sli); + virtual void mergeRefItems(Definition *d); + virtual void addInnerCompound(const Definition *d); + virtual void setOuterScope(Definition *d); + virtual void setHidden(bool b); + virtual void setArtificial(bool b); + virtual void setLanguage(SrcLangExt lang); + virtual void writeSourceDef(OutputList &ol,const char *scopeName) const; + virtual void writeInlineCode(OutputList &ol,const char *scopeName) const; + virtual void writeSourceRefs(OutputList &ol,const char *scopeName) const; + virtual void writeSourceReffedBy(OutputList &ol,const char *scopeName) const; + virtual void makePartOfGroup(GroupDef *gd); + virtual void writeNavigationPath(OutputList &ol) const; + virtual QCString navigationPathAsString() const; + virtual void writeQuickMemberLinks(OutputList &,const MemberDef *) const; + virtual void writeSummaryLinks(OutputList &) const; + virtual QCString pathFragment() const; + virtual void writeDocAnchorsToTagFile(FTextStream &) const; + virtual void setLocalName(const QCString name); + virtual void addSectionsToIndex(); + virtual void writeToc(OutputList &ol, const LocalToc <) const; + virtual void setCookie(Cookie *cookie) const; + virtual Cookie *cookie() const; + + protected: + + DefinitionImpl(const DefinitionImpl &d); + + private: + virtual void _setSymbolName(const QCString &name); + 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 _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); + bool _docsAlreadyAdded(const QCString &doc,QCString &sigList); + + // PIMPL idiom + class IMPL; + IMPL *m_impl; // internal structure holding all private data +}; + +class DefinitionAliasImpl : virtual public Definition +{ + public: + DefinitionAliasImpl(const Definition *scope,const Definition *alias); + virtual ~DefinitionAliasImpl(); + + virtual bool isAlias() const { return TRUE; } + virtual QCString name() const + { return m_def->name(); } + virtual QCString localName() const + { return m_def->localName(); } + virtual QCString qualifiedName() const + { return m_def->qualifiedName(); } + virtual QCString symbolName() const + { return m_def->symbolName(); } + virtual QCString getSourceFileBase() const + { return m_def->getSourceFileBase(); } + virtual QCString getSourceAnchor() const + { return m_def->getSourceAnchor(); } + virtual QCString documentation() const + { return m_def->documentation(); } + virtual int docLine() const + { return m_def->docLine(); } + virtual QCString docFile() const + { return m_def->docFile(); } + virtual QCString briefDescription(bool abbreviate=FALSE) const + { return m_def->briefDescription(abbreviate); } + virtual QCString briefDescriptionAsTooltip() const + { return m_def->briefDescriptionAsTooltip(); } + virtual int briefLine() const + { return m_def->briefLine(); } + virtual QCString inbodyDocumentation() const + { return m_def->inbodyDocumentation(); } + virtual QCString inbodyFile() const + { return m_def->inbodyFile(); } + virtual int inbodyLine() const + { return m_def->inbodyLine(); } + virtual QCString briefFile() const + { return m_def->briefFile(); } + virtual QCString getDefFileName() const + { return m_def->getDefFileName(); } + virtual QCString getDefFileExtension() const + { return m_def->getDefFileExtension(); } + virtual int getDefLine() const + { return m_def->getDefLine(); } + virtual int getDefColumn() const + { return m_def->getDefColumn(); } + virtual bool hasDocumentation() const + { return m_def->hasDocumentation(); } + virtual bool hasUserDocumentation() const + { return m_def->hasUserDocumentation(); } + virtual bool isVisibleInProject() const + { return m_def->isVisibleInProject(); } + virtual bool isVisible() const + { return m_def->isVisible(); } + virtual bool isHidden() const + { return m_def->isHidden(); } + virtual bool isArtificial() const + { return m_def->isArtificial(); } + virtual QCString getReference() const + { return m_def->getReference(); } + virtual bool isReference() const + { return m_def->isReference(); } + virtual QCString externalReference(const QCString &relPath) const + { return m_def->externalReference(relPath); } + virtual int getStartBodyLine() const + { return m_def->getStartBodyLine(); } + virtual int getEndBodyLine() const + { return m_def->getEndBodyLine(); } + virtual FileDef *getBodyDef() const + { return m_def->getBodyDef(); } + virtual SrcLangExt getLanguage() const + { return m_def->getLanguage(); } + virtual GroupList *partOfGroups() const + { return m_def->partOfGroups(); } + virtual bool isLinkableViaGroup() const + { return m_def->isLinkableViaGroup(); } + virtual QList<ListItemInfo> *xrefListItems() const + { return m_def->xrefListItems(); } + virtual Definition *findInnerCompound(const char *name) const + { return m_def->findInnerCompound(name); } + virtual Definition *getOuterScope() const + { return const_cast<Definition*>(m_scope); } + virtual MemberSDict *getReferencesMembers() const + { return m_def->getReferencesMembers(); } + virtual MemberSDict *getReferencedByMembers() const + { return m_def->getReferencedByMembers(); } + virtual bool hasSections() const + { return m_def->hasSections(); } + virtual bool hasSources() const + { return m_def->hasSources(); } + virtual bool hasBriefDescription() const + { return m_def->hasBriefDescription(); } + virtual QCString id() const + { return m_def->id(); } + virtual SectionDict * getSectionDict() const + { return m_def->getSectionDict(); } + virtual QCString navigationPathAsString() const + { return m_def->navigationPathAsString(); } + virtual QCString pathFragment() const + { return m_def->pathFragment(); } + virtual void setName(const char *name) { } + virtual void setId(const char *name) { } + virtual void setDefFile(const QCString& df,int defLine,int defColumn) {} + virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE) {} + virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine) {} + virtual void setInbodyDocumentation(const char *d,const char *docFile,int docLine) {} + virtual void setReference(const char *r) {} + virtual void addSectionsToDefinition(QList<SectionInfo> *anchorList) {} + virtual void setBodySegment(int bls,int ble) {} + virtual void setBodyDef(FileDef *fd) {} + virtual void addSourceReferencedBy(const MemberDef *d) {} + virtual void addSourceReferences(const MemberDef *d) {} + virtual void setRefItems(const QList<ListItemInfo> *sli) {} + virtual void mergeRefItems(Definition *d) {} + virtual void addInnerCompound(const Definition *d) {} + virtual void setOuterScope(Definition *d) {} + virtual void setHidden(bool b) {} + virtual void setArtificial(bool b) {} + virtual void setLanguage(SrcLangExt lang) {} + virtual void writeSourceDef(OutputList &ol,const char *scopeName) const {} + virtual void writeInlineCode(OutputList &ol,const char *scopeName) const {} + virtual void writeSourceRefs(OutputList &ol,const char *scopeName) const {} + virtual void writeSourceReffedBy(OutputList &ol,const char *scopeName) const {} + virtual void makePartOfGroup(GroupDef *gd) {} + virtual void writeNavigationPath(OutputList &ol) const {} + virtual void writeQuickMemberLinks(OutputList &,const MemberDef *) const {} + virtual void writeSummaryLinks(OutputList &) const {} + virtual void writeDocAnchorsToTagFile(FTextStream &) const {} + virtual void setLocalName(const QCString name) {} + virtual void addSectionsToIndex() {} + virtual void writeToc(OutputList &ol, const LocalToc <) const {} + virtual void setCookie(Cookie *cookie) const { delete m_cookie; m_cookie = cookie; } + virtual Cookie *cookie() const { return m_cookie; } + protected: + const Definition *getAlias() const { return m_def; } + const Definition *getScope() const { return m_scope; } + + private: + virtual void _setSymbolName(const QCString &name) { m_symbolName = name; } + virtual QCString _symbolName() const { return m_symbolName; } + const Definition *m_scope; + const Definition *m_def; + mutable Cookie *m_cookie; + QCString m_symbolName; +}; + + +#endif diff --git a/src/dia.cpp b/src/dia.cpp index 5adbc7c..8dab5b0 100644 --- a/src/dia.cpp +++ b/src/dia.cpp @@ -65,6 +65,8 @@ void writeDiaGraphFromFile(const char *inFile,const char *outDir, portable_sysTimerStart(); if ((exitCode=portable_system(diaExe,diaArgs,FALSE))!=0) { + err("Problems running %s. Check your installation or look typos in you dia file %s\n", + diaExe.data(),inFile); portable_sysTimerStop(); goto error; } diff --git a/src/diagram.cpp b/src/diagram.cpp index 83e42b3..08b49ca 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -42,7 +42,7 @@ class DiagramItemList; class DiagramItem { public: - DiagramItem(DiagramItem *p,int number,ClassDef *cd, + DiagramItem(DiagramItem *p,int number,const ClassDef *cd, Protection prot,Specifier virt,const char *ts); ~DiagramItem(); QCString label() const; @@ -60,7 +60,7 @@ class DiagramItem Specifier virtualness() const { return virt; } void putInList() { inList=TRUE; } bool isInList() const { return inList; } - ClassDef *getClassDef() const { return classDef; } + const ClassDef *getClassDef() const { return classDef; } private: DiagramItemList *children; DiagramItem *parent; @@ -70,7 +70,7 @@ class DiagramItem Specifier virt; QCString templSpec; bool inList; - ClassDef *classDef; + const ClassDef *classDef; }; /** Class representing a list of DiagramItem object. */ @@ -91,7 +91,7 @@ class DiagramRow : public QList<DiagramItem> level=l; setAutoDelete(TRUE); } - void insertClass(DiagramItem *parent,ClassDef *cd,bool doBases, + void insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases, Protection prot,Specifier virt,const char *ts); uint number() { return level; } private: @@ -111,7 +111,7 @@ class DiagramRowIterator : public QListIterator<DiagramRow> class TreeDiagram : public QList<DiagramRow> { public: - TreeDiagram(ClassDef *root,bool doBases); + TreeDiagram(const ClassDef *root,bool doBases); ~TreeDiagram(); void computeLayout(); uint computeRows(); @@ -252,7 +252,7 @@ static void writeVectorBox(FTextStream &t,DiagramItem *di, if (di->virtualness()==Virtual) t << "solid\n"; } -static void writeMapArea(FTextStream &t,ClassDef *cd,QCString relPath, +static void writeMapArea(FTextStream &t,const ClassDef *cd,QCString relPath, int x,int y,int w,int h) { if (cd->isLinkable()) @@ -261,7 +261,7 @@ static void writeMapArea(FTextStream &t,ClassDef *cd,QCString relPath, t << "<area "; if (!ref.isEmpty()) { - t << externalLinkTarget() << externalRef(relPath,ref,FALSE); + t << externalLinkTarget(); } t << "href=\""; t << externalRef(relPath,ref,TRUE); @@ -283,7 +283,7 @@ static void writeMapArea(FTextStream &t,ClassDef *cd,QCString relPath, } //----------------------------------------------------------------------------- -DiagramItem::DiagramItem(DiagramItem *p,int number,ClassDef *cd, +DiagramItem::DiagramItem(DiagramItem *p,int number,const ClassDef *cd, Protection pr,Specifier vi,const char *ts) { parent=p; @@ -354,7 +354,7 @@ void DiagramItem::addChild(DiagramItem *di) children->append(di); } -void DiagramRow::insertClass(DiagramItem *parent,ClassDef *cd,bool doBases, +void DiagramRow::insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases, Protection prot,Specifier virt,const char *ts) { //if (cd->visited) return; // the visit check does not work in case of @@ -406,7 +406,7 @@ void DiagramRow::insertClass(DiagramItem *parent,ClassDef *cd,bool doBases, } } -TreeDiagram::TreeDiagram(ClassDef *root,bool doBases) +TreeDiagram::TreeDiagram(const ClassDef *root,bool doBases) { setAutoDelete(TRUE); DiagramRow *row=new DiagramRow(this,0); @@ -1020,11 +1020,11 @@ void clearVisitFlags() ClassDef *cd; for (;(cd=cli.current());++cli) { - cd->visited=FALSE; + cd->setVisited(FALSE); } } -ClassDiagram::ClassDiagram(ClassDef *root) +ClassDiagram::ClassDiagram(const ClassDef *root) { clearVisitFlags(); base = new TreeDiagram(root,TRUE); @@ -1165,7 +1165,7 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path, t << " /boxwidth boxwidth str stringwidth pop max def\n"; t << "} def\n"; t << "\n"; - t << "/box % draws a box with text `arg1' at grid pos (arg2,arg3)\n"; + t << "/box % draws a box with text 'arg1' at grid pos (arg2,arg3)\n"; t << "{ gsave\n"; t << " 2 setlinewidth\n"; t << " newpath\n"; @@ -1267,7 +1267,7 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path, t << " stroke\n"; t << "} def\n"; t << "\n"; - t << "/conn % connections the blocks from col `arg1' to `arg2' of row `arg3'\n"; + t << "/conn % connections the blocks from col 'arg1' to 'arg2' of row 'arg3'\n"; t << "{\n"; t << " /ys exch def\n"; t << " /xe exch def\n"; @@ -1337,7 +1337,7 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path, QCString epstopdfArgs(4096); epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"", epsBaseName.data(),epsBaseName.data()); - //printf("Converting eps using `%s'\n",epstopdfArgs.data()); + //printf("Converting eps using '%s'\n",epstopdfArgs.data()); portable_sysTimerStart(); if (portable_system("epstopdf",epstopdfArgs)!=0) { diff --git a/src/diagram.h b/src/diagram.h index 2922657..05af28e 100644 --- a/src/diagram.h +++ b/src/diagram.h @@ -29,7 +29,7 @@ class FTextStream; class ClassDiagram { public: - ClassDiagram(ClassDef *root); + ClassDiagram(const ClassDef *root); ~ClassDiagram(); void writeFigure(FTextStream &t,const char *path, const char *file) const; diff --git a/src/dirdef.cpp b/src/dirdef.cpp index 7294e4f..5db8b99 100644 --- a/src/dirdef.cpp +++ b/src/dirdef.cpp @@ -8,17 +8,90 @@ #include "language.h" #include "message.h" #include "dot.h" +#include "dotdirdeps.h" #include "layout.h" #include "ftextstream.h" #include "config.h" #include "docparser.h" +#include "definitionimpl.h" + +//---------------------------------------------------------------------- + +class DirDefImpl : public DefinitionImpl, public DirDef +{ + public: + DirDefImpl(const char *path); + virtual ~DirDefImpl(); + + virtual DefType definitionType() const { return TypeDir; } + virtual QCString getOutputFileBase() const; + virtual QCString anchor() const { return QCString(); } + virtual bool isLinkableInProject() const; + virtual bool isLinkable() const; + virtual QCString displayName(bool=TRUE) const { return m_dispName; } + virtual const QCString &shortName() const { return m_shortName; } + virtual void addSubDir(DirDef *subdir); + virtual FileList * getFiles() const { return m_fileList; } + virtual void addFile(FileDef *fd); + virtual const DirList &subDirs() const { return m_subdirs; } + virtual bool isCluster() const { return m_subdirs.count()>0; } + virtual int level() const { return m_level; } + virtual DirDef *parent() const { return m_parent; } + virtual int dirCount() const { return m_dirCount; } + virtual const QDict<UsedDir> *usedDirs() const { return m_usedDirs; } + virtual bool isParentOf(const DirDef *dir) const; + virtual bool depGraphIsTrivial() const; + virtual QCString shortTitle() const; + virtual bool hasDetailedDescription() const; + virtual void writeDocumentation(OutputList &ol); + virtual void writeTagFile(FTextStream &t); + virtual void setDiskName(const QCString &name) { m_diskName = name; } + virtual void sort(); + virtual void setParent(DirDef *parent); + virtual void setLevel(); + virtual void addUsesDependency(DirDef *usedDir,FileDef *srcFd, + FileDef *dstFd,bool inherited); + virtual void computeDependencies(); + + public: + static DirDef *mergeDirectoryInTree(const QCString &path); + + private: + + void writeDetailedDescription(OutputList &ol,const QCString &title); + void writeBriefDescription(OutputList &ol); + void writeDirectoryGraph(OutputList &ol); + void writeSubDirList(OutputList &ol); + void writeFileList(OutputList &ol); + void startMemberDeclarations(OutputList &ol); + void endMemberDeclarations(OutputList &ol); + + static DirDef *createNewDir(const char *path); + static bool matchPath(const QCString &path,QStrList &l); + + DirList m_subdirs; + QCString m_dispName; + QCString m_shortName; + QCString m_diskName; + FileList *m_fileList; // list of files in the group + int m_dirCount; + int m_level; + DirDef *m_parent; + QDict<UsedDir> *m_usedDirs; +}; + +DirDef *createDirDef(const char *path) +{ + return new DirDefImpl(path); +} + //---------------------------------------------------------------------- // method implementation static int g_dirCount=0; -DirDef::DirDef(const char *path) : Definition(path,1,1,path), visited(FALSE) +DirDefImpl::DirDefImpl(const char *path) : DefinitionImpl(path,1,1,path) { bool fullPathNames = Config_getBool(FULL_PATH_NAMES); // get display name (stipping the paths mentioned in STRIP_FROM_PATH) @@ -49,36 +122,41 @@ DirDef::DirDef(const char *path) : Definition(path,1,1,path), visited(FALSE) m_parent=0; } -DirDef::~DirDef() +DirDefImpl::~DirDefImpl() { delete m_fileList; delete m_usedDirs; } -bool DirDef::isLinkableInProject() const +bool DirDefImpl::isLinkableInProject() const { return !isReference(); } -bool DirDef::isLinkable() const +bool DirDefImpl::isLinkable() const { return isReference() || isLinkableInProject(); } -void DirDef::addSubDir(DirDef *subdir) +void DirDefImpl::addSubDir(DirDef *subdir) { m_subdirs.append(subdir); subdir->setOuterScope(this); - subdir->m_parent=this; + subdir->setParent(this); +} + +void DirDefImpl::setParent(DirDef *p) +{ + m_parent=p; } -void DirDef::addFile(FileDef *fd) +void DirDefImpl::addFile(FileDef *fd) { m_fileList->append(fd); fd->setDirDef(this); } -void DirDef::sort() +void DirDefImpl::sort() { m_subdirs.sort(); m_fileList->sort(); @@ -116,14 +194,14 @@ static QCString encodeDirName(const QCString &anchor) // return result; } -QCString DirDef::getOutputFileBase() const +QCString DirDefImpl::getOutputFileBase() const { - //printf("DirDef::getOutputFileBase() %s->dir_%s\n", + //printf("DirDefImpl::getOutputFileBase() %s->dir_%s\n", // m_diskName.data(),encodeDirName(m_diskName).data()); return "dir_"+encodeDirName(m_diskName); } -void DirDef::writeDetailedDescription(OutputList &ol,const QCString &title) +void DirDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title) { if ((!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF)) || !documentation().isEmpty()) @@ -168,7 +246,7 @@ void DirDef::writeDetailedDescription(OutputList &ol,const QCString &title) } } -void DirDef::writeBriefDescription(OutputList &ol) +void DirDefImpl::writeBriefDescription(OutputList &ol) { if (hasBriefDescription()) { @@ -205,7 +283,7 @@ void DirDef::writeBriefDescription(OutputList &ol) ol.writeSynopsis(); } -void DirDef::writeDirectoryGraph(OutputList &ol) +void DirDefImpl::writeDirectoryGraph(OutputList &ol) { // write graph dependency graph if (Config_getBool(DIRECTORY_GRAPH) && Config_getBool(HAVE_DOT)) @@ -225,7 +303,7 @@ void DirDef::writeDirectoryGraph(OutputList &ol) } } -void DirDef::writeSubDirList(OutputList &ol) +void DirDefImpl::writeSubDirList(OutputList &ol) { int numSubdirs = 0; QListIterator<DirDef> it(m_subdirs); @@ -275,7 +353,7 @@ void DirDef::writeSubDirList(OutputList &ol) } } -void DirDef::writeFileList(OutputList &ol) +void DirDefImpl::writeFileList(OutputList &ol) { int numFiles = 0; QListIterator<FileDef> it(*m_fileList); @@ -347,28 +425,28 @@ void DirDef::writeFileList(OutputList &ol) } } -void DirDef::startMemberDeclarations(OutputList &ol) +void DirDefImpl::startMemberDeclarations(OutputList &ol) { ol.startMemberSections(); } -void DirDef::endMemberDeclarations(OutputList &ol) +void DirDefImpl::endMemberDeclarations(OutputList &ol) { ol.endMemberSections(); } -QCString DirDef::shortTitle() const +QCString DirDefImpl::shortTitle() const { return theTranslator->trDirReference(m_shortName); } -bool DirDef::hasDetailedDescription() const +bool DirDefImpl::hasDetailedDescription() const { static bool repeatBrief = Config_getBool(REPEAT_BRIEF); return (!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty(); } -void DirDef::writeTagFile(FTextStream &tagFile) +void DirDefImpl::writeTagFile(FTextStream &tagFile) { tagFile << " <compound kind=\"dir\">" << endl; tagFile << " <name>" << convertToXML(displayName()) << "</name>" << endl; @@ -415,7 +493,7 @@ void DirDef::writeTagFile(FTextStream &tagFile) tagFile << " </compound>" << endl; } -void DirDef::writeDocumentation(OutputList &ol) +void DirDefImpl::writeDocumentation(OutputList &ol) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); ol.pushGeneratorState(); @@ -529,7 +607,7 @@ void DirDef::writeDocumentation(OutputList &ol) ol.popGeneratorState(); } -void DirDef::setLevel() +void DirDefImpl::setLevel() { if (m_level==-1) // level not set before { @@ -549,7 +627,7 @@ void DirDef::setLevel() /** Add as "uses" dependency between \a this dir and \a dir, * that was caused by a dependency on file \a fd. */ -void DirDef::addUsesDependency(DirDef *dir,FileDef *srcFd, +void DirDefImpl::addUsesDependency(DirDef *dir,FileDef *srcFd, FileDef *dstFd,bool inherited) { if (this==dir) return; // do not add self-dependencies @@ -603,7 +681,7 @@ void DirDef::addUsesDependency(DirDef *dir,FileDef *srcFd, /** Computes the dependencies between directories */ -void DirDef::computeDependencies() +void DirDefImpl::computeDependencies() { FileList *fl = m_fileList; if (fl) @@ -649,7 +727,7 @@ void DirDef::computeDependencies() } } -bool DirDef::isParentOf(DirDef *dir) const +bool DirDefImpl::isParentOf(const DirDef *dir) const { if (dir->parent()==this) // this is a parent of dir return TRUE; @@ -659,7 +737,7 @@ bool DirDef::isParentOf(DirDef *dir) const return FALSE; } -bool DirDef::depGraphIsTrivial() const +bool DirDefImpl::depGraphIsTrivial() const { return m_usedDirs->count()==0; } @@ -704,21 +782,21 @@ FilePair *UsedDir::findFilePair(const char *name) return n.isEmpty() ? 0 : m_filePairs.find(n); } -DirDef *DirDef::createNewDir(const char *path) +DirDef *DirDefImpl::createNewDir(const char *path) { ASSERT(path!=0); DirDef *dir = Doxygen::directories->find(path); if (dir==0) // new dir { //printf("Adding new dir %s\n",path); - dir = new DirDef(path); + dir = createDirDef(path); //printf("createNewDir %s short=%s\n",path,dir->shortName().data()); Doxygen::directories->append(path,dir); } return dir; } -bool DirDef::matchPath(const QCString &path,QStrList &l) +bool DirDefImpl::matchPath(const QCString &path,QStrList &l) { const char *s=l.first(); while (s) @@ -736,9 +814,9 @@ bool DirDef::matchPath(const QCString &path,QStrList &l) /*! strip part of \a path if it matches * one of the paths in the Config_getList(STRIP_FROM_PATH) list */ -DirDef *DirDef::mergeDirectoryInTree(const QCString &path) +DirDef *DirDefImpl::mergeDirectoryInTree(const QCString &path) { - //printf("DirDef::mergeDirectoryInTree(%s)\n",path.data()); + //printf("DirDefImpl::mergeDirectoryInTree(%s)\n",path.data()); int p=0,i=0; DirDef *dir=0; while ((i=path.find('/',p))!=-1) @@ -941,7 +1019,7 @@ void buildDirectories() DirDef *dir; if ((dir=Doxygen::directories->find(fd->getPath()))==0) // new directory { - dir = DirDef::mergeDirectoryInTree(fd->getPath()); + dir = DirDefImpl::mergeDirectoryInTree(fd->getPath()); } if (dir && !fd->isDocumentationFile()) dir->addFile(fd); } @@ -967,7 +1045,7 @@ void buildDirectories() if (parent) { parent->addSubDir(dir); - //printf("DirDef::addSubdir(): Adding subdir\n%s to\n%s\n", + //printf("DirDefImpl::addSubdir(): Adding subdir\n%s to\n%s\n", // dir->displayName().data(), parent->displayName().data()); } } diff --git a/src/dirdef.h b/src/dirdef.h index 2fb04f5..2ea54af 100644 --- a/src/dirdef.h +++ b/src/dirdef.h @@ -41,70 +41,44 @@ class DirList : public QList<DirDef> }; /** A model of a directory symbol. */ -class DirDef : public Definition +class DirDef : virtual public Definition { public: - DirDef(const char *path); - virtual ~DirDef(); + virtual ~DirDef() {} // accessors - DefType definitionType() const { return TypeDir; } - QCString getOutputFileBase() const; - QCString anchor() const { return QCString(); } - bool isLinkableInProject() const; - bool isLinkable() const; - QCString displayName(bool=TRUE) const { return m_dispName; } - const QCString &shortName() const { return m_shortName; } - void addSubDir(DirDef *subdir); - FileList * getFiles() const { return m_fileList; } - void addFile(FileDef *fd); - const DirList &subDirs() const { return m_subdirs; } - bool isCluster() const { return m_subdirs.count()>0; } - int level() const { return m_level; } - DirDef *parent() const { return m_parent; } - int dirCount() const { return m_dirCount; } - const QDict<UsedDir> *usedDirs() const { return m_usedDirs; } - bool isParentOf(DirDef *dir) const; - bool depGraphIsTrivial() const; - QCString shortTitle() const; - bool hasDetailedDescription() const; + virtual DefType definitionType() const = 0; + virtual QCString getOutputFileBase() const = 0; + virtual QCString anchor() const = 0; + virtual bool isLinkableInProject() const = 0; + virtual bool isLinkable() const = 0; + virtual QCString displayName(bool=TRUE) const = 0; + virtual const QCString &shortName() const = 0; + virtual void addSubDir(DirDef *subdir) = 0; + virtual FileList * getFiles() const = 0; + virtual void addFile(FileDef *fd) = 0; + virtual const DirList &subDirs() const = 0; + virtual bool isCluster() const = 0; + virtual int level() const = 0; + virtual DirDef *parent() const = 0; + virtual int dirCount() const = 0; + virtual const QDict<UsedDir> *usedDirs() const = 0; + virtual bool isParentOf(const DirDef *dir) const = 0; + virtual bool depGraphIsTrivial() const = 0; + virtual QCString shortTitle() const = 0; + virtual bool hasDetailedDescription() const = 0; // generate output - void writeDocumentation(OutputList &ol); - void writeTagFile(FTextStream &t); - - static DirDef *mergeDirectoryInTree(const QCString &path); - bool visited; - void setDiskName(const QCString &name) { m_diskName = name; } - void sort(); - - private: - friend void computeDirDependencies(); - - void writeDetailedDescription(OutputList &ol,const QCString &title); - void writeBriefDescription(OutputList &ol); - void writeDirectoryGraph(OutputList &ol); - void writeSubDirList(OutputList &ol); - void writeFileList(OutputList &ol); - void startMemberDeclarations(OutputList &ol); - void endMemberDeclarations(OutputList &ol); - - void setLevel(); - static DirDef *createNewDir(const char *path); - static bool matchPath(const QCString &path,QStrList &l); - void addUsesDependency(DirDef *usedDir,FileDef *srcFd, - FileDef *dstFd,bool inherited); - void computeDependencies(); - - DirList m_subdirs; - QCString m_dispName; - QCString m_shortName; - QCString m_diskName; - FileList *m_fileList; // list of files in the group - int m_dirCount; - int m_level; - DirDef *m_parent; - QDict<UsedDir> *m_usedDirs; + virtual void writeDocumentation(OutputList &ol) = 0; + virtual void writeTagFile(FTextStream &t) = 0; + + virtual void setDiskName(const QCString &name) = 0; + virtual void sort() = 0; + virtual void setParent(DirDef *parent) = 0; + virtual void setLevel() = 0; + virtual void addUsesDependency(DirDef *usedDir,FileDef *srcFd, + FileDef *dstFd,bool inherited) = 0; + virtual void computeDependencies() = 0; }; /** Class representing a pair of FileDef objects */ @@ -151,16 +125,16 @@ class UsedDir class DirRelation { public: - DirRelation(const QCString &name,DirDef *src,UsedDir *dst) + DirRelation(const QCString &name,const DirDef *src,UsedDir *dst) : m_name(name), m_src(src), m_dst(dst) {} - DirDef *source() const { return m_src; } + const DirDef *source() const { return m_src; } UsedDir *destination() const { return m_dst; } void writeDocumentation(OutputList &ol); QCString getOutputFileBase() const { return m_name; } private: QCString m_name; - DirDef *m_src; + const DirDef *m_src; UsedDir *m_dst; }; diff --git a/src/docbookgen.cpp b/src/docbookgen.cpp index 97c602d..7fe849a 100644 --- a/src/docbookgen.cpp +++ b/src/docbookgen.cpp @@ -33,6 +33,11 @@ #include "defargs.h" #include "outputgen.h" #include "dot.h" +#include "dotcallgraph.h" +#include "dotclassgraph.h" +#include "dotdirdeps.h" +#include "dotgroupcollaboration.h" +#include "dotincldepgraph.h" #include "pagedef.h" #include "filename.h" #include "version.h" @@ -153,7 +158,7 @@ void DocbookCodeGenerator::writeCodeLink(const char *ref,const char *file, { Docbook_DB(("(writeCodeLink)\n")); writeDocbookLink(m_t,ref,file,anchor,name,tooltip); - m_col+=strlen(name); + m_col+=(int)strlen(name); } void DocbookCodeGenerator::writeCodeLinkLine(const char *ref,const char *file, const char *anchor,const char *name, @@ -164,7 +169,7 @@ void DocbookCodeGenerator::writeCodeLinkLine(const char *ref,const char *file, m_t << "_1l"; writeDocbookString(m_t,name); m_t << "\"/>"; - m_col+=strlen(name); + m_col+=(int)strlen(name); } void DocbookCodeGenerator::writeTooltip(const char *, const DocLinkInfo &, const char *, const char *, const SourceLinkInfo &, const SourceLinkInfo & @@ -180,7 +185,7 @@ void DocbookCodeGenerator::startCodeLine(bool) } void DocbookCodeGenerator::endCodeLine() { - m_t << endl; + if (m_insideCodeLine) m_t << endl; Docbook_DB(("(endCodeLine)\n")); m_lineNumber = -1; m_refId.resize(0); @@ -230,7 +235,7 @@ void DocbookCodeGenerator::writeLineNumber(const char *ref,const char *fileName, } } -void DocbookCodeGenerator::setCurrentDoc(Definition *,const char *,bool) +void DocbookCodeGenerator::setCurrentDoc(const Definition *,const char *,bool) { } void DocbookCodeGenerator::addWord(const char *,bool) @@ -238,7 +243,7 @@ void DocbookCodeGenerator::addWord(const char *,bool) } void DocbookCodeGenerator::finish() { - if (m_insideCodeLine) endCodeLine(); + endCodeLine(); } void DocbookCodeGenerator::startCodeFragment() { @@ -246,6 +251,9 @@ void DocbookCodeGenerator::startCodeFragment() } void DocbookCodeGenerator::endCodeFragment() { + //endCodeLine checks is there is still an open code line, if so closes it. + endCodeLine(); + m_t << "</computeroutput></literallayout>" << endl; } @@ -537,7 +545,7 @@ DB_GEN_C2("IndexSections " << is) { t << "</title>" << endl; ClassSDict::Iterator cli(*Doxygen::classSDict); - ClassDef *cd=0; + const ClassDef *cd=0; bool found=FALSE; for (cli.toFirst();(cd=cli.current()) && !found;++cli) { @@ -572,7 +580,7 @@ DB_GEN_C2("IndexSections " << is) for (fnli.toFirst();(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); - FileDef *fd; + const FileDef *fd; for (;(fd=fni.current());++fni) { if (fd->isLinkableInProject()) @@ -635,7 +643,7 @@ DB_GEN_C if (!pd->getGroupDef() && !pd->isReference() && pd->name() == stripPath(name)) { t << "<chapter>\n"; - if (!pd->title().isEmpty()) + if (pd->hasTitle()) { t << " <title>" << convertToDocBook(pd->title()) << "</title>" << endl; } @@ -648,7 +656,7 @@ DB_GEN_C } } } -void DocbookGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *) +void DocbookGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *) { DB_GEN_C DocbookDocVisitor *visitor = @@ -1002,6 +1010,9 @@ DB_GEN_C void DocbookGenerator::endCodeFragment() { DB_GEN_C + //endCodeLine checks is there is still an open code line, if so closes it. + endCodeLine(); + t << "</programlisting>"; } void DocbookGenerator::startMemberTemplateParams() @@ -1095,7 +1106,7 @@ void DocbookGenerator::startGroupCollaboration() { DB_GEN_C } -void DocbookGenerator::endGroupCollaboration(const DotGroupCollaboration &g) +void DocbookGenerator::endGroupCollaboration(DotGroupCollaboration &g) { DB_GEN_C g.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,FALSE); @@ -1104,7 +1115,7 @@ void DocbookGenerator::startDotGraph() { DB_GEN_C } -void DocbookGenerator::endDotGraph(const DotClassGraph &g) +void DocbookGenerator::endDotGraph(DotClassGraph &g) { DB_GEN_C g.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,TRUE,FALSE); @@ -1113,7 +1124,7 @@ void DocbookGenerator::startInclDepGraph() { DB_GEN_C } -void DocbookGenerator::endInclDepGraph(const DotInclDepGraph &g) +void DocbookGenerator::endInclDepGraph(DotInclDepGraph &g) { DB_GEN_C QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT), fileName,relPath,FALSE); @@ -1122,7 +1133,7 @@ void DocbookGenerator::startCallGraph() { DB_GEN_C } -void DocbookGenerator::endCallGraph(const DotCallGraph &g) +void DocbookGenerator::endCallGraph(DotCallGraph &g) { DB_GEN_C QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT), fileName,relPath,FALSE); @@ -1131,7 +1142,7 @@ void DocbookGenerator::startDirDepGraph() { DB_GEN_C } -void DocbookGenerator::endDirDepGraph(const DotDirDeps &g) +void DocbookGenerator::endDirDepGraph(DotDirDeps &g) { DB_GEN_C QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT), fileName,relPath,FALSE); diff --git a/src/docbookgen.h b/src/docbookgen.h index 08255a1..8f71722 100644 --- a/src/docbookgen.h +++ b/src/docbookgen.h @@ -49,7 +49,7 @@ class DocbookCodeGenerator : public CodeOutputInterface void writeCodeAnchor(const char *); void writeLineNumber(const char *extRef,const char *compId, const char *anchorId,int l); - void setCurrentDoc(Definition *,const char *,bool); + void setCurrentDoc(const Definition *,const char *,bool); void addWord(const char *,bool); void finish(); void startCodeFragment(); @@ -137,7 +137,7 @@ class DocbookGenerator : public OutputGenerator { m_codeGen.writeCodeAnchor(anchor); } // --------------------------- - void writeDoc(DocNode *,Definition *ctx,MemberDef *md); + void writeDoc(DocNode *,const Definition *ctx,const MemberDef *md); /////////////////////////////////////////////////////////////// // structural output interface @@ -281,16 +281,16 @@ class DocbookGenerator : public OutputGenerator void startClassDiagram(); void endClassDiagram(const ClassDiagram &,const char *,const char *); void startDotGraph(); - void endDotGraph(const DotClassGraph &g); + void endDotGraph(DotClassGraph &g); void startInclDepGraph(); - void endInclDepGraph(const DotInclDepGraph &g); + void endInclDepGraph(DotInclDepGraph &g); void startGroupCollaboration(); - void endGroupCollaboration(const DotGroupCollaboration &g); + void endGroupCollaboration(DotGroupCollaboration &g); void startCallGraph(); - void endCallGraph(const DotCallGraph &g); + void endCallGraph(DotCallGraph &g); void startDirDepGraph(); - void endDirDepGraph(const DotDirDeps &g); - void writeGraphicalHierarchy(const DotGfxHierarchyTable &g){DB_GEN_NEW}; + void endDirDepGraph(DotDirDeps &g); + void writeGraphicalHierarchy(DotGfxHierarchyTable &g){DB_GEN_NEW}; void startQuickIndices(){DB_GEN_EMPTY}; void endQuickIndices(){DB_GEN_EMPTY}; void writeSplitBar(const char *){DB_GEN_EMPTY}; @@ -339,7 +339,7 @@ class DocbookGenerator : public OutputGenerator void writeLabel(const char *,bool); void endLabels(); - void setCurrentDoc(Definition *,const char *,bool) {DB_GEN_EMPTY} + void setCurrentDoc(const Definition *,const char *,bool) {DB_GEN_EMPTY} void addWord(const char *,bool) {DB_GEN_EMPTY} private: diff --git a/src/docbookvisitor.cpp b/src/docbookvisitor.cpp index 99df99c..a42a895 100644 --- a/src/docbookvisitor.cpp +++ b/src/docbookvisitor.cpp @@ -263,7 +263,9 @@ DB_VIS_C case DocStyleChange::Small: /* XSLT Stylesheets can be used */ break; /* HTML only */ case DocStyleChange::Strike: break; + case DocStyleChange::Del: break; case DocStyleChange::Underline: break; + case DocStyleChange::Ins: break; case DocStyleChange::Div: /* HTML only */ break; case DocStyleChange::Span: /* HTML only */ break; } @@ -353,7 +355,7 @@ DB_VIS_C case DocVerbatim::PlantUML: { static QCString docbookOutput = Config_getString(DOCBOOK_OUTPUT); - QCString baseName = writePlantUMLSource(docbookOutput,s->exampleFile(),s->text()); + QCString baseName = PlantumlManager::instance()->writePlantUMLSource(docbookOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_BITMAP); QCString shortName = baseName; int i; if ((i=shortName.findRev('/'))!=-1) @@ -386,13 +388,14 @@ DB_VIS_C { m_t << "<literallayout><computeroutput>"; QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), - inc->exampleFile(), &fd); + inc->exampleFile(), fd); + delete fd; m_t << "</computeroutput></literallayout>"; } break; @@ -407,9 +410,8 @@ DB_VIS_C m_t << "</computeroutput></literallayout>"; break; case DocInclude::DontInclude: - break; + case DocInclude::DontIncWithLines: case DocInclude::HtmlInclude: - break; case DocInclude::LatexInclude: break; case DocInclude::VerbInclude: @@ -432,7 +434,7 @@ DB_VIS_C case DocInclude::SnipWithLines: { QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); m_t << "<literallayout><computeroutput>"; Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci, @@ -441,13 +443,14 @@ DB_VIS_C langExt, inc->isExample(), inc->exampleFile(), - &fd, + fd, lineBlock(inc->text(),inc->blockId()), -1, // endLine FALSE, // inlineFragment 0, // memberDef TRUE // show line number ); + delete fd; m_t << "</computeroutput></literallayout>"; } break; @@ -471,16 +474,33 @@ DB_VIS_C pushEnabled(); m_hide = TRUE; } - SrcLangExt langExt = getLanguageFromFileName(m_langExt); + QCString locLangExt = getFileNameExtension(op->includeFileName()); + if (locLangExt.isEmpty()) locLangExt = m_langExt; + SrcLangExt langExt = getLanguageFromFileName(locLangExt); if (op->type()!=DocIncOperator::Skip) { popEnabled(); if (!m_hide) { - Doxygen::parserManager->getParser(m_langExt) + FileDef *fd = 0; + if (!op->includeFileName().isEmpty()) + { + QFileInfo cfi( op->includeFileName() ); + fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + } + + Doxygen::parserManager->getParser(locLangExt) ->parseCode(m_ci,op->context(), op->text(),langExt,op->isExample(), - op->exampleFile()); + op->exampleFile(), + fd, // fileDef + op->line(), // startLine + -1, // endLine + FALSE, // inline fragment + 0, // memberDef + op->showLineNo() // show line numbers + ); + if (fd) delete fd; } pushEnabled(); m_hide=TRUE; @@ -618,164 +638,162 @@ DB_VIS_C case DocSimpleSect::See: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trSeeAlso() << ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trSeeAlso() << "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trSeeAlso()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trSeeAlso()) << "</title>" << endl; } break; case DocSimpleSect::Return: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trReturns()<< ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trReturns()<< "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trReturns()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trReturns()) << "</title>" << endl; } break; case DocSimpleSect::Author: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trAuthor(TRUE, TRUE) << ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trAuthor(TRUE, TRUE) << "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trAuthor(TRUE, TRUE)) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trAuthor(TRUE, TRUE)) << "</title>" << endl; } break; case DocSimpleSect::Authors: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trAuthor(TRUE, FALSE) << ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trAuthor(TRUE, FALSE) << "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trAuthor(TRUE, FALSE)) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trAuthor(TRUE, FALSE)) << "</title>" << endl; } break; case DocSimpleSect::Version: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trVersion() << ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trVersion() << "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trVersion()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trVersion()) << "</title>" << endl; } break; case DocSimpleSect::Since: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trSince() << ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trSince() << "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trSince()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trSince()) << "</title>" << endl; } break; case DocSimpleSect::Date: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trDate() << ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trDate() << "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trDate()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trDate()) << "</title>" << endl; } break; case DocSimpleSect::Note: if (m_insidePre) { - m_t << "<note><title>" << theTranslator->trNote() << ": </title>" << endl; + m_t << "<note><title>" << theTranslator->trNote() << "</title>" << endl; } else { - m_t << "<note><title>" << convertToDocBook(theTranslator->trNote()) << ": </title>" << endl; + m_t << "<note><title>" << convertToDocBook(theTranslator->trNote()) << "</title>" << endl; } break; case DocSimpleSect::Warning: if (m_insidePre) { - m_t << "<warning><title>" << theTranslator->trWarning() << ": </title>" << endl; + m_t << "<warning><title>" << theTranslator->trWarning() << "</title>" << endl; } else { - m_t << "<warning><title>" << convertToDocBook(theTranslator->trWarning()) << ": </title>" << endl; + m_t << "<warning><title>" << convertToDocBook(theTranslator->trWarning()) << "</title>" << endl; } break; case DocSimpleSect::Pre: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trPrecondition() << ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trPrecondition() << "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trPrecondition()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trPrecondition()) << "</title>" << endl; } break; case DocSimpleSect::Post: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trPostcondition() << ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trPostcondition() << "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trPostcondition()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trPostcondition()) << "</title>" << endl; } break; case DocSimpleSect::Copyright: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trCopyright() << ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trCopyright() << "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trCopyright()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trCopyright()) << "</title>" << endl; } break; case DocSimpleSect::Invar: if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trInvariant() << ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trInvariant() << "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trInvariant()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trInvariant()) << "</title>" << endl; } break; case DocSimpleSect::Remark: // <remark> is miising the <title> possibility if (m_insidePre) { - m_t << "<formalpara><title>" << theTranslator->trRemarks() << ": </title>" << endl; + m_t << "<formalpara><title>" << theTranslator->trRemarks() << "</title>" << endl; } else { - m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trRemarks()) << ": </title>" << endl; + m_t << "<formalpara><title>" << convertToDocBook(theTranslator->trRemarks()) << "</title>" << endl; } break; case DocSimpleSect::Attention: if (m_insidePre) { - m_t << "<caution><title>" << theTranslator->trAttention() << ": </title>" << endl; + m_t << "<caution><title>" << theTranslator->trAttention() << "</title>" << endl; } else { - m_t << "<caution><title>" << convertToDocBook(theTranslator->trAttention()) << ": </title>" << endl; + m_t << "<caution><title>" << convertToDocBook(theTranslator->trAttention()) << "</title>" << endl; } break; case DocSimpleSect::User: + case DocSimpleSect::Rcs: + case DocSimpleSect::Unknown: if (s->hasTitle()) m_t << "<formalpara>" << endl; else m_t << "<para>" << endl; break; - case DocSimpleSect::Rcs: - case DocSimpleSect::Unknown: - m_t << "<para>" << endl; - break; } } @@ -785,11 +803,9 @@ DB_VIS_C if (m_hide) return; switch(s->type()) { + case DocSimpleSect::User: case DocSimpleSect::Rcs: case DocSimpleSect::Unknown: - m_t << "</para>" << endl; - break; - case DocSimpleSect::User: if (s->hasTitle()) m_t << "</formalpara>" << endl; else @@ -955,7 +971,7 @@ DB_VIS_C if (m_hide) return; m_t << "<informaltable frame=\"all\">" << endl; m_t << " <tgroup cols=\"" << t->numColumns() << "\" align=\"left\" colsep=\"1\" rowsep=\"1\">" << endl; - for (int i = 0; i <t->numColumns(); i++) + for (uint i = 0; i <t->numColumns(); i++) { // do something with colwidth based of cell width specification (be aware of possible colspan in the header)? m_t << " <colspec colname='c" << i+1 << "'/>\n"; @@ -1417,11 +1433,9 @@ DB_VIS_C { QListIterator<DocNode> li(pl->paramTypes()); DocNode *type; - bool first=TRUE; m_t << " <entry>"; for (li.toFirst();(type=li.current());++li) { - if (!first) m_t << " | "; else first=FALSE; if (type->kind()==DocNode::Kind_Word) { visit((DocWord*)type); @@ -1430,6 +1444,11 @@ DB_VIS_C { visit((DocLinkedWord*)type); } + else if (type->kind()==DocNode::Kind_Sep) + { + m_t << " " << ((DocSeparator *)type)->chars() << " "; + } + } m_t << " </entry>"; } @@ -1509,22 +1528,6 @@ DB_VIS_C m_t << " "; } -void DocbookDocVisitor::visitPre(DocCopy *) -{ -DB_VIS_C - if (m_hide) return; - // TODO: to be implemented -} - - -void DocbookDocVisitor::visitPost(DocCopy *) -{ -DB_VIS_C - if (m_hide) return; - // TODO: to be implemented -} - - void DocbookDocVisitor::visitPre(DocText *) { DB_VIS_C @@ -1642,7 +1645,7 @@ DB_VIS_C shortName=shortName.right(shortName.length()-i-1); } QCString outDir = Config_getString(DOCBOOK_OUTPUT); - generatePlantUMLOutput(baseName,outDir,PUML_BITMAP); + PlantumlManager::instance()->generatePlantUMLOutput(baseName,outDir,PlantumlManager::PUML_BITMAP); visitPreStart(m_t, s->children(), s->hasCaption(), s->relPath() + shortName + ".png", s->width(),s->height()); visitCaption(s->children()); visitPostEnd(m_t, s->hasCaption()); diff --git a/src/docbookvisitor.h b/src/docbookvisitor.h index 24b1fbb..47275f7 100644 --- a/src/docbookvisitor.h +++ b/src/docbookvisitor.h @@ -127,8 +127,6 @@ class DocbookDocVisitor : public DocVisitor void visitPost(DocXRefItem *); void visitPre(DocInternalRef *); void visitPost(DocInternalRef *); - void visitPre(DocCopy *); - void visitPost(DocCopy *); void visitPre(DocText *); void visitPost(DocText *); void visitPre(DocHtmlBlockQuote *); diff --git a/src/docgroup.cpp b/src/docgroup.cpp new file mode 100644 index 0000000..1f4fb6d --- /dev/null +++ b/src/docgroup.cpp @@ -0,0 +1,215 @@ +#include "doxygen.h" +#include "util.h" +#include "entry.h" +#include "message.h" +#include "docgroup.h" + + +void DocGroup::enterFile(const char *fileName,int) +{ + m_openCount = 0; + m_autoGroupStack.setAutoDelete(TRUE); + m_autoGroupStack.clear(); + m_memberGroupId = DOX_NOGROUP; + m_memberGroupDocs.resize(0); + m_memberGroupRelates.resize(0); + m_compoundName=fileName; +} + +void DocGroup::leaveFile(const char *fileName,int line) +{ + //if (m_memberGroupId!=DOX_NOGROUP) + //{ + // warn(fileName,line,"end of file while inside a member group\n"); + //} + m_memberGroupId=DOX_NOGROUP; + m_memberGroupRelates.resize(0); + m_memberGroupDocs.resize(0); + if (!m_autoGroupStack.isEmpty()) + { + warn(fileName,line,"end of file while inside a group"); + } + else if (m_openCount > 0) // < 0 is already handled on close call + { + warn(fileName,line,"end of file with unbalanced grouping commands"); + } +} + +void DocGroup::enterCompound(const char *fileName,int line,const char *name) +{ + if (m_memberGroupId!=DOX_NOGROUP) + { + warn(fileName,line,"try to put compound %s inside a member group\n",name); + } + m_memberGroupId=DOX_NOGROUP; + m_memberGroupRelates.resize(0); + m_memberGroupDocs.resize(0); + m_compoundName = name; + int i = m_compoundName.find('('); + if (i!=-1) + { + m_compoundName=m_compoundName.left(i); // strip category (Obj-C) + } + if (m_compoundName.isEmpty()) + { + m_compoundName=fileName; + } + //printf("groupEnterCompound(%s)\n",name); +} + +void DocGroup::leaveCompound(const char *,int,const char * /*name*/) +{ + //printf("groupLeaveCompound(%s)\n",name); + //if (m_memberGroupId!=DOX_NOGROUP) + //{ + // warn(fileName,line,"end of compound %s while inside a member group\n",name); + //} + m_memberGroupId=DOX_NOGROUP; + m_memberGroupRelates.resize(0); + m_memberGroupDocs.resize(0); + m_compoundName.resize(0); +} + +int DocGroup::findExistingGroup(int &groupId,const MemberGroupInfo *info) +{ + //printf("findExistingGroup %s:%s\n",info->header.data(),info->compoundName.data()); + QIntDictIterator<MemberGroupInfo> di(Doxygen::memGrpInfoDict); + MemberGroupInfo *mi; + for (di.toFirst();(mi=di.current());++di) + { + if (m_compoundName==mi->compoundName && // same file or scope + !mi->header.isEmpty() && // not a nameless group + qstricmp(mi->header,info->header)==0 // same header name + ) + { + //printf("Found it!\n"); + return (int)di.currentKey(); // put the item in this group + } + } + groupId++; // start new group + return groupId; +} + +void DocGroup::open(Entry *e,const char *,int, bool implicit) +{ + if (!implicit) m_openCount++; + //printf("==> openGroup(name=%s,sec=%x) m_autoGroupStack=%d\n", + // e->name.data(),e->section,m_autoGroupStack.count()); + if (e->section==Entry::GROUPDOC_SEC) // auto group + { + m_autoGroupStack.push(new Grouping(e->name,e->groupingPri())); + } + else // start of a member group + { + //printf(" membergroup id=%d %s\n",m_memberGroupId,m_memberGroupHeader.data()); + if (m_memberGroupId==DOX_NOGROUP) // no group started yet + { + static int curGroupId=0; + + MemberGroupInfo *info = new MemberGroupInfo; + info->header = m_memberGroupHeader.stripWhiteSpace(); + info->compoundName = m_compoundName; + m_memberGroupId = findExistingGroup(curGroupId,info); + //printf(" use membergroup %d\n",m_memberGroupId); + Doxygen::memGrpInfoDict.insert(m_memberGroupId,info); + + m_memberGroupRelates = e->relates; + e->mGrpId = m_memberGroupId; + } + } +} + +void DocGroup::close(Entry *e,const char *fileName,int line,bool foundInline,bool implicit) +{ + if (!implicit) + { + if (m_openCount < 1) + { + warn(fileName,line,"unbalanced grouping commands"); + } + else + { + m_openCount--; + } + } + //printf("==> closeGroup(name=%s,sec=%x,file=%s,line=%d) m_autoGroupStack=%d\n", + // e->name.data(),e->section,fileName,line,m_autoGroupStack.count()); + if (m_memberGroupId!=DOX_NOGROUP) // end of member group + { + MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(m_memberGroupId); + if (info) // known group + { + info->doc = m_memberGroupDocs; + info->docFile = fileName; + info->docLine = line; + } + m_memberGroupId=DOX_NOGROUP; + m_memberGroupRelates.resize(0); + m_memberGroupDocs.resize(0); + if (!foundInline) e->mGrpId=DOX_NOGROUP; + //printf("new group id=%d\n",m_memberGroupId); + } + else if (!m_autoGroupStack.isEmpty()) // end of auto group + { + Grouping *grp = m_autoGroupStack.pop(); + // see bug577005: we should not remove the last group for e + if (!foundInline) e->groups->removeLast(); + //printf("Removing %s e=%p\n",grp->groupname.data(),e); + delete grp; + if (!foundInline) initGroupInfo(e); + } +} + +void DocGroup::initGroupInfo(Entry *e) +{ + //printf("==> initGroup(id=%d,related=%s,e=%p)\n",m_memberGroupId, + // m_memberGroupRelates.data(),e); + e->mGrpId = m_memberGroupId; + e->relates = m_memberGroupRelates; + if (!m_autoGroupStack.isEmpty()) + { + //printf("Appending group %s to %s: count=%d entry=%p\n", + // m_autoGroupStack.top()->groupname.data(), + // e->name.data(),e->groups->count(),e); + e->groups->append(new Grouping(*m_autoGroupStack.top())); + } +} + +void DocGroup::addDocs(Entry *e) +{ + if (e->section==Entry::MEMBERGRP_SEC) + { + m_memberGroupDocs=e->brief.stripWhiteSpace(); + e->doc = stripLeadingAndTrailingEmptyLines(e->doc,e->docLine); + if (!m_memberGroupDocs.isEmpty() && !e->doc.isEmpty()) + { + m_memberGroupDocs+="\n\n"; + } + m_memberGroupDocs+=e->doc; + MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(m_memberGroupId); + if (info) + { + info->doc = m_memberGroupDocs; + info->docFile = e->docFile; + info->docLine = e->docLine; + info->setRefItems(e->sli); + } + e->doc.resize(0); + e->brief.resize(0); + } +} + +bool DocGroup::isEmpty() const +{ + return (m_memberGroupId==DOX_NOGROUP); +} + +void DocGroup::clearHeader() +{ + m_memberGroupHeader.resize(0); +} + +void DocGroup::appendHeader(const char text) +{ + m_memberGroupHeader += text; +} diff --git a/src/docgroup.h b/src/docgroup.h new file mode 100644 index 0000000..4775d90 --- /dev/null +++ b/src/docgroup.h @@ -0,0 +1,54 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2019 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef DOCGROUP_H +#define DOCGROUP_H + +#include <qstack.h> +#include <qstring.h> +#include "membergroup.h" + +class Entry; + +class DocGroup +{ + public: + DocGroup() {}; + + public: + void enterFile(const char *fileName,int); + void leaveFile(const char *fileName,int line); + void enterCompound(const char *fileName,int line,const char *name); + void leaveCompound(const char *,int,const char * /*name*/); + void open(Entry *e,const char *,int,bool implicit=false); + void close(Entry *e,const char *fileName,int line,bool foundInline,bool implicit=false); + void initGroupInfo(Entry *e); + bool isEmpty() const; + void clearHeader(); + void appendHeader(const char); + void addDocs(Entry *e); + + private: + int findExistingGroup(int &groupId,const MemberGroupInfo *info); + int m_openCount; + QCString m_memberGroupHeader; + int m_memberGroupId; + QCString m_memberGroupRelates; + QCString m_memberGroupDocs; + QStack<Grouping> m_autoGroupStack; + QCString m_compoundName; +}; + +#endif diff --git a/src/docparser.cpp b/src/docparser.cpp index a5c0cc7..9dd1c71 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -87,7 +87,7 @@ static const char *sectionLevelToName[] = //--------------------------------------------------------------------------- // Parser state: global variables during a call to validatingParseDoc -static Definition * g_scope; +static const Definition * g_scope; static QCString g_context; static bool g_inSeeBlock; static bool g_xmlComment; @@ -101,8 +101,9 @@ static QCString g_relPath; static bool g_hasParamCommand; static bool g_hasReturnCommand; +static QDict<void> g_retvalsFound; static QDict<void> g_paramsFound; -static MemberDef * g_memberDef; +static const MemberDef * g_memberDef; static bool g_isExample; static QCString g_exampleName; static SectionDict * g_sectionDict; @@ -112,13 +113,15 @@ static QCString g_includeFileName; static QCString g_includeFileText; static uint g_includeFileOffset; static uint g_includeFileLength; +static uint g_includeFileLine; +static bool g_includeFileShowLineNo; /** Parser's context to store all global variables. */ struct DocParserContext { - Definition *scope; + const Definition *scope; QCString context; bool inSeeBlock; bool xmlComment; @@ -133,7 +136,8 @@ struct DocParserContext bool hasParamCommand; bool hasReturnCommand; - MemberDef * memberDef; + const MemberDef * memberDef; + QDict<void> retvalsFound; QDict<void> paramsFound; bool isExample; QCString exampleName; @@ -143,6 +147,8 @@ struct DocParserContext QCString includeFileText; uint includeFileOffset; uint includeFileLength; + uint includeFileLine; + bool includeFileLineNo; TokenInfo *token; }; @@ -179,6 +185,7 @@ static void docParserPushContext(bool saveParamInfo=TRUE) ctx->hasParamCommand = g_hasParamCommand; ctx->hasReturnCommand = g_hasReturnCommand; ctx->paramsFound = g_paramsFound; + ctx->retvalsFound = g_retvalsFound; } ctx->memberDef = g_memberDef; @@ -190,6 +197,8 @@ static void docParserPushContext(bool saveParamInfo=TRUE) ctx->includeFileText = g_includeFileText; ctx->includeFileOffset = g_includeFileOffset; ctx->includeFileLength = g_includeFileLength; + ctx->includeFileLine = g_includeFileLine; + ctx->includeFileLineNo = g_includeFileShowLineNo; ctx->token = g_token; g_token = new TokenInfo; @@ -217,6 +226,7 @@ static void docParserPopContext(bool keepParamInfo=FALSE) { g_hasParamCommand = ctx->hasParamCommand; g_hasReturnCommand = ctx->hasReturnCommand; + g_retvalsFound = ctx->retvalsFound; g_paramsFound = ctx->paramsFound; } g_memberDef = ctx->memberDef; @@ -228,6 +238,8 @@ static void docParserPopContext(bool keepParamInfo=FALSE) g_includeFileText = ctx->includeFileText; g_includeFileOffset = ctx->includeFileOffset; g_includeFileLength = ctx->includeFileLength; + g_includeFileLine = ctx->includeFileLine; + g_includeFileShowLineNo = ctx->includeFileLineNo; delete g_token; g_token = ctx->token; @@ -275,7 +287,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool bool ambig; FileDef *fd; //printf("Search for %s\n",fileName); - if ((fd=findFileDef(Doxygen::imageNameDict,fileName,ambig))) + if ((fd=findFileDef(Doxygen::imageNameDict,fileName,ambig)) && !ambig) { QCString inputFile = fd->absFilePath(); QFile inImage(inputFile); @@ -335,11 +347,11 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool "could not write output image %s",qPrint(outputFile)); } } - else - { - warn(g_fileName,doctokenizerYYlineno, - "Prevented to copy file %s onto itself!\n",qPrint(inputFile)); - } + //else + //{ + // warn(g_fileName,doctokenizerYYlineno, + // "Prevented to copy file %s onto itself!\n",qPrint(inputFile)); + //} } else { @@ -366,13 +378,16 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool return baseName; } } - else if (ambig && dowarn) + else if (ambig) { - QCString text; - text.sprintf("image file name %s is ambiguous.\n",qPrint(fileName)); - text+="Possible candidates:\n"; - text+=showFileDefMatches(Doxygen::imageNameDict,fileName); - warn_doc_error(g_fileName,doctokenizerYYlineno,text); + if (dowarn) + { + QCString text; + text.sprintf("image file name %s is ambiguous.\n",qPrint(fileName)); + text+="Possible candidates:\n"; + text+=showFileDefMatches(Doxygen::imageNameDict,fileName); + warn_doc_error(g_fileName,doctokenizerYYlineno,text); + } } else { @@ -388,19 +403,19 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool return result; } -/*! Collects the parameters found with \@param or \@retval commands - * in a global list g_paramsFound. If \a isParam is set to TRUE - * and the parameter is not an actual parameter of the current +/*! Collects the parameters found with \@param command + * in a global list g_paramsFound. If + * the parameter is not an actual parameter of the current * member g_memberDef, then a warning is raised (unless warnings * are disabled altogether). */ -static void checkArgumentName(const QCString &name,bool isParam) +static void checkArgumentName(const QCString &name) { if (!Config_getBool(WARN_IF_DOC_ERROR)) return; if (g_memberDef==0) return; // not a member - ArgumentList *al=g_memberDef->isDocsForDefinition() ? - g_memberDef->argumentList() : - g_memberDef->declArgumentList(); + const ArgumentList *al=g_memberDef->isDocsForDefinition() ? + g_memberDef->argumentList() : + g_memberDef->declArgumentList(); SrcLangExt lang = g_memberDef->getLanguage(); //printf("isDocsForDefinition()=%d\n",g_memberDef->isDocsForDefinition()); if (al==0) return; // no argument list @@ -411,25 +426,25 @@ static void checkArgumentName(const QCString &name,bool isParam) { QCString aName=name.mid(i,l); if (lang==SrcLangExt_Fortran) aName=aName.lower(); - //printf("aName=`%s'\n",aName.data()); + //printf("aName='%s'\n",aName.data()); ArgumentListIterator ali(*al); - Argument *a; + const Argument *a; bool found=FALSE; for (ali.toFirst();(a=ali.current());++ali) { QCString argName = g_memberDef->isDefine() ? a->type : a->name; if (lang==SrcLangExt_Fortran) argName=argName.lower(); argName=argName.stripWhiteSpace(); - //printf("argName=`%s' aName=%s\n",argName.data(),aName.data()); + //printf("argName='%s' aName=%s\n",argName.data(),aName.data()); if (argName.right(3)=="...") argName=argName.left(argName.length()-3); - if (aName==argName) + if (aName==argName) { g_paramsFound.insert(aName,(void *)(0x8)); found=TRUE; break; } } - if (!found && isParam) + if (!found) { //printf("member type=%d\n",g_memberDef->memberType()); QCString scope=g_memberDef->getScopeString(); @@ -457,6 +472,23 @@ static void checkArgumentName(const QCString &name,bool isParam) p=i+l; } } +/*! Collects the return values found with \@retval command + * in a global list g_retvalsFound. + */ +static void checkRetvalName(const QCString &name) +{ + if (!Config_getBool(WARN_IF_DOC_ERROR)) return; + if (g_memberDef==0 || name.isEmpty()) return; // not a member or no valid name + if (g_retvalsFound.find(name)) + { + warn_doc_error(g_memberDef->getDefFileName(), + g_memberDef->getDefLine(), + "return value '" + name + "' of " + + QCString(g_memberDef->qualifiedName()) + + " has multiple documentation sections"); + } + g_retvalsFound.insert(name,(void *)(0x8)); +} /*! Checks if the parameters that have been specified using \@param are * indeed all parameters and that a parameter does not have multiple @@ -468,14 +500,14 @@ static void checkUnOrMultipleDocumentedParams() { if (g_memberDef && g_hasParamCommand && Config_getBool(WARN_IF_DOC_ERROR)) { - ArgumentList *al=g_memberDef->isDocsForDefinition() ? + const ArgumentList *al=g_memberDef->isDocsForDefinition() ? g_memberDef->argumentList() : g_memberDef->declArgumentList(); SrcLangExt lang = g_memberDef->getLanguage(); if (al!=0) { ArgumentListIterator ali(*al); - Argument *a; + const Argument *a; bool found=FALSE; for (ali.toFirst();(a=ali.current());++ali) { @@ -509,7 +541,7 @@ static void checkUnOrMultipleDocumentedParams() "argument '" + aName + "' from the argument list of " + QCString(g_memberDef->qualifiedName()) + - " has muliple @param documentation sections"); + " has multiple @param documentation sections"); } } if (found) @@ -550,106 +582,6 @@ static void checkUnOrMultipleDocumentedParams() } } -/*! Check if a member has documentation for its parameter and or return - * type, if applicable. If found this will be stored in the member, this - * is needed as a member can have brief and detailed documentation, while - * only one of these needs to document the parameters. - */ -static void detectNoDocumentedParams() -{ - if (g_memberDef && Config_getBool(WARN_NO_PARAMDOC)) - { - ArgumentList *al = g_memberDef->argumentList(); - ArgumentList *declAl = g_memberDef->declArgumentList(); - QCString returnType = g_memberDef->typeString(); - bool isPython = g_memberDef->getLanguage()==SrcLangExt_Python; - - if (!g_memberDef->hasDocumentedParams() && - g_hasParamCommand) - { - //printf("%s->setHasDocumentedParams(TRUE);\n",g_memberDef->name().data()); - g_memberDef->setHasDocumentedParams(TRUE); - } - else if (!g_memberDef->hasDocumentedParams()) - { - bool allDoc=TRUE; // no parameter => all parameters are documented - if ( // member has parameters - al!=0 && // but the member has a parameter list - al->count()>0 // with at least one parameter (that is not void) - ) - { - ArgumentListIterator ali(*al); - Argument *a; - - // see if all parameters have documentation - for (ali.toFirst();(a=ali.current()) && allDoc;++ali) - { - if (!a->name.isEmpty() && a->type!="void" && - !(isPython && (a->name=="self" || a->name=="cls")) - ) - { - allDoc = !a->docs.isEmpty(); - } - //printf("a->type=%s a->name=%s doc=%s\n", - // a->type.data(),a->name.data(),a->docs.data()); - } - if (!allDoc && declAl!=0) // try declaration arguments as well - { - allDoc=TRUE; - ArgumentListIterator ali(*declAl); - Argument *a; - for (ali.toFirst();(a=ali.current()) && allDoc;++ali) - { - if (!a->name.isEmpty() && a->type!="void" && - !(isPython && (a->name=="self" || a->name=="cls")) - ) - { - allDoc = !a->docs.isEmpty(); - } - //printf("a->name=%s doc=%s\n",a->name.data(),a->docs.data()); - } - } - } - if (allDoc) - { - //printf("%s->setHasDocumentedParams(TRUE);\n",g_memberDef->name().data()); - g_memberDef->setHasDocumentedParams(TRUE); - } - } - //printf("Member %s hadDocumentedReturnType()=%d hasReturnCommand=%d\n", - // g_memberDef->name().data(),g_memberDef->hasDocumentedReturnType(),g_hasReturnCommand); - if (!g_memberDef->hasDocumentedReturnType() && // docs not yet found - g_hasReturnCommand) - { - g_memberDef->setHasDocumentedReturnType(TRUE); - } - else if ( // see if return needs to documented - g_memberDef->hasDocumentedReturnType() || - returnType.isEmpty() || // empty return type - returnType.find("void")!=-1 || // void return type - returnType.find("subroutine")!=-1 || // fortran subroutine - g_memberDef->isConstructor() || // a constructor - g_memberDef->isDestructor() // or destructor - ) - { - g_memberDef->setHasDocumentedReturnType(TRUE); - } - else if ( // see if return type is documented in a function w/o return type - g_memberDef->hasDocumentedReturnType() && - (returnType.isEmpty() || // empty return type - returnType.find("void")!=-1 || // void return type - returnType.find("subroutine")!=-1 || // fortran subroutine - g_memberDef->isConstructor() || // a constructor - g_memberDef->isDestructor() // or destructor - ) - ) - { - warn_doc_error(g_fileName,doctokenizerYYlineno,"documented empty return type"); - } - } -} - - //--------------------------------------------------------------------------- /*! Strips known html and tex extensions from \a text. */ @@ -747,13 +679,15 @@ static bool insideTable(DocNode *n) static bool findDocsForMemberOrCompound(const char *commandName, QCString *pDoc, QCString *pBrief, - Definition **pDef) + const Definition **pDef) { //printf("findDocsForMemberOrCompound(%s)\n",commandName); *pDoc=""; *pBrief=""; *pDef=0; QCString cmdArg=substitute(commandName,"#","::"); + cmdArg = replaceScopeSeparator(cmdArg); + int l=cmdArg.length(); if (l==0) return FALSE; @@ -779,16 +713,15 @@ static bool findDocsForMemberOrCompound(const char *commandName, QCString name=removeRedundantWhiteSpace(cmdArg.left(funcStart)); QCString args=cmdArg.right(l-funcStart); - // try if the link is to a member - MemberDef *md=0; - ClassDef *cd=0; - FileDef *fd=0; - NamespaceDef *nd=0; - GroupDef *gd=0; - PageDef *pd=0; + const MemberDef *md=0; + const ClassDef *cd=0; + const FileDef *fd=0; + const NamespaceDef *nd=0; + const GroupDef *gd=0; + const PageDef *pd=0; bool found = getDefs( - g_context.find('.')==-1?g_context.data():"", // `find('.') is a hack to detect files + g_context.find('.')==-1?g_context.data():"", // find('.') is a hack to detect files name, args.isEmpty()?0:args.data(), md,cd,fd,nd,gd,FALSE,0,TRUE); @@ -810,7 +743,7 @@ static bool findDocsForMemberOrCompound(const char *commandName, { fullName.prepend(g_context.left(scopeOffset)+"::"); } - //printf("Trying fullName=`%s'\n",fullName.data()); + //printf("Trying fullName='%s'\n",fullName.data()); // try class, namespace, group, page, file reference cd = Doxygen::classSDict->find(fullName); @@ -908,8 +841,8 @@ 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", - qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + qPrint(saveCmdName)); return tok; } while ((tok=doctokenizerYYlex()) && @@ -944,7 +877,7 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, break; } } - DBG(("handleStyleArgument(%s) end tok=%x\n",qPrint(cmdName),tok)); + DBG(("handleStyleArgument(%s) end tok=%x\n",qPrint(saveCmdName),tok)); return (tok==TK_NEWPARA || tok==TK_LISTITEM || tok==TK_ENDLIST ) ? tok : RetVal_OK; } @@ -1037,6 +970,11 @@ static int handleAHref(DocNode *parent,QList<DocNode> &children,const HtmlAttrib { if (!opt->value.isEmpty()) { + // copy attributes + HtmlAttribList attrList = tagHtmlAttribs; + // and remove the href attribute + bool result = attrList.remove(index); + ASSERT(result); DocAnchor *anc = new DocAnchor(parent,opt->value,TRUE); children.append(anc); break; // stop looking for other tag attribs @@ -1082,7 +1020,9 @@ const char *DocStyleChange::styleString() const case DocStyleChange::Div: return "div"; case DocStyleChange::Span: return "span"; case DocStyleChange::Strike: return "strike"; + case DocStyleChange::Del: return "del"; case DocStyleChange::Underline: return "u"; + case DocStyleChange::Ins: return "ins"; } return "<invalid>"; } @@ -1112,8 +1052,8 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor // ------- try to turn the word 'name' into a link - Definition *compound=0; - MemberDef *member=0; + const Definition *compound=0; + const MemberDef *member=0; int len = g_token->name.length(); ClassDef *cd=0; bool ambig; @@ -1152,7 +1092,7 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor } else if (compound->definitionType()==Definition::TypeGroup) { - name=((GroupDef*)compound)->groupTitle(); + name=(dynamic_cast<const GroupDef*>(compound))->groupTitle(); } children.append(new DocLinkedWord(parent,name, @@ -1164,7 +1104,7 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor ); } else if (compound->definitionType()==Definition::TypeFile && - ((FileDef*)compound)->generateSourceFile() + (dynamic_cast<const FileDef*>(compound))->generateSourceFile() ) // undocumented file that has source code we can link to { children.append(new @@ -1229,17 +1169,25 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children,bool ignor static void handleParameterType(DocNode *parent,QList<DocNode> &children,const QCString ¶mTypes) { - QCString name = g_token->name; - int p=0,i; + QCString name = g_token->name; // save token name + QCString name1; + int p=0,i,l,ii; while ((i=paramTypes.find('|',p))!=-1) { - g_token->name = paramTypes.mid(p,i-p); + name1 = paramTypes.mid(p,i-p); + ii=name1.find('['); + g_token->name=ii!=-1 ? name1.mid(0,ii) : name1; // take part without [] handleLinkedWord(parent,children); + if (ii!=-1) children.append(new DocWord(parent,name1.mid(ii))); // add [] part p=i+1; + children.append(new DocSeparator(parent,"|")); } - g_token->name = paramTypes.mid(p); + name1 = paramTypes.mid(p); + ii=name1.find('['); + g_token->name=ii!=-1 ? name1.mid(0,ii) : name1; handleLinkedWord(parent,children); - g_token->name = name; + if (ii!=-1) children.append(new DocWord(parent,name1.mid(ii))); + g_token->name = name; // restore original token name } static DocInternalRef *handleInternalRef(DocNode *parent) @@ -1249,7 +1197,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,doctokenizerYYlineno,"expected whitespace after \\%s command", qPrint(tokenName)); return 0; } @@ -1269,7 +1217,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,doctokenizerYYlineno,"expected whitespace after \\%s command", qPrint(g_token->name)); return 0; } @@ -1612,6 +1560,16 @@ reparsetoken: handleStyleLeave(parent,children,DocStyleChange::Strike,tokenName); } break; + case HTML_DEL: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Del,&g_token->attribs); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Del,tokenName); + } + break; case HTML_UNDERLINE: if (!g_token->endTag) { @@ -1622,6 +1580,16 @@ reparsetoken: handleStyleLeave(parent,children,DocStyleChange::Underline,tokenName); } break; + case HTML_INS: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Ins,&g_token->attribs); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Ins,tokenName); + } + break; case HTML_CODE: case XML_C: if (!g_token->endTag) @@ -1878,7 +1846,7 @@ static void readTextFileByName(const QCString &file,QCString &text) // as a fallback we also look in the exampleNameDict bool ambig; FileDef *fd; - if ((fd=findFileDef(Doxygen::exampleNameDict,file,ambig))) + if ((fd=findFileDef(Doxygen::exampleNameDict,file,ambig)) && !ambig) { text = fileToString(fd->absFilePath(),Config_getBool(FILTER_SOURCE_FILES)); } @@ -1929,12 +1897,13 @@ DocLinkedWord::DocLinkedWord(DocNode *parent,const QCString &word, //--------------------------------------------------------------------------- -DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) +DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) { m_parent = parent; if (id.isEmpty()) { warn_doc_error(g_fileName,doctokenizerYYlineno,"Empty anchor label"); + return; } if (id.left(CiteConsts::anchorPrefix.length()) == CiteConsts::anchorPrefix) @@ -1947,7 +1916,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,doctokenizerYYlineno,"Invalid cite anchor id '%s'",qPrint(id)); m_anchor = "invalid"; m_file = "invalid"; } @@ -1972,7 +1941,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,doctokenizerYYlineno,"Invalid anchor id '%s'",qPrint(id)); m_anchor = "invalid"; m_file = "invalid"; } @@ -1999,6 +1968,8 @@ void DocInclude::parse() DBG(("DocInclude::parse(file=%s,text=%s)\n",qPrint(m_file),qPrint(m_text))); switch(m_type) { + case DontIncWithLines: + // fall through case IncWithLines: // fall through case Include: @@ -2009,6 +1980,8 @@ void DocInclude::parse() g_includeFileText = m_text; g_includeFileOffset = 0; g_includeFileLength = m_text.length(); + g_includeFileLine = 0; + g_includeFileShowLineNo = (m_type == DontIncWithLines || m_type == IncWithLines); //printf("g_includeFile=<<%s>>\n",g_includeFileText.data()); break; case VerbInclude: @@ -2043,10 +2016,18 @@ void DocInclude::parse() void DocIncOperator::parse() { + if (g_includeFileName.isEmpty()) + { + warn_doc_error(g_fileName,doctokenizerYYlineno, + "No previous '\\include' or '\\dontinclude' command for '\\%s' present", + typeAsString()); + } + m_includeFileName = g_includeFileName; const char *p = g_includeFileText; uint l = g_includeFileLength; uint o = g_includeFileOffset; + uint il = g_includeFileLine; DBG(("DocIncOperator::parse() text=%s off=%d len=%d\n",qPrint(p),o,l)); uint so = o,bo; bool nonEmpty = FALSE; @@ -2058,6 +2039,7 @@ void DocIncOperator::parse() char c = p[o]; if (c=='\n') { + g_includeFileLine++; if (nonEmpty) break; // we have a pattern to match so=o+1; // no pattern, skip empty line } @@ -2069,10 +2051,12 @@ void DocIncOperator::parse() } if (g_includeFileText.mid(so,o-so).find(m_pattern)!=-1) { + m_line = il; m_text = g_includeFileText.mid(so,o-so); DBG(("DocIncOperator::parse() Line: %s\n",qPrint(m_text))); } g_includeFileOffset = QMIN(l,o+1); // set pointer to start of new line + m_showLineNo = g_includeFileShowLineNo; break; case SkipLine: while (o<l) @@ -2083,6 +2067,7 @@ void DocIncOperator::parse() char c = p[o]; if (c=='\n') { + g_includeFileLine++; if (nonEmpty) break; // we have a pattern to match so=o+1; // no pattern, skip empty line } @@ -2094,6 +2079,7 @@ void DocIncOperator::parse() } if (g_includeFileText.mid(so,o-so).find(m_pattern)!=-1) { + m_line = il; m_text = g_includeFileText.mid(so,o-so); DBG(("DocIncOperator::parse() SkipLine: %s\n",qPrint(m_text))); break; @@ -2101,6 +2087,7 @@ void DocIncOperator::parse() o++; // skip new line } g_includeFileOffset = QMIN(l,o+1); // set pointer to start of new line + m_showLineNo = g_includeFileShowLineNo; break; case Skip: while (o<l) @@ -2111,6 +2098,7 @@ void DocIncOperator::parse() char c = p[o]; if (c=='\n') { + g_includeFileLine++; if (nonEmpty) break; // we have a pattern to match so=o+1; // no pattern, skip empty line } @@ -2127,6 +2115,7 @@ void DocIncOperator::parse() o++; // skip new line } g_includeFileOffset = so; // set pointer to start of new line + m_showLineNo = g_includeFileShowLineNo; break; case Until: bo=o; @@ -2138,6 +2127,7 @@ void DocIncOperator::parse() char c = p[o]; if (c=='\n') { + g_includeFileLine++; if (nonEmpty) break; // we have a pattern to match so=o+1; // no pattern, skip empty line } @@ -2149,6 +2139,7 @@ void DocIncOperator::parse() } if (g_includeFileText.mid(so,o-so).find(m_pattern)!=-1) { + m_line = il; m_text = g_includeFileText.mid(bo,o-bo); DBG(("DocIncOperator::parse() Until: %s\n",qPrint(m_text))); break; @@ -2156,106 +2147,13 @@ void DocIncOperator::parse() o++; // skip new line } g_includeFileOffset = QMIN(l,o+1); // set pointer to start of new line + m_showLineNo = g_includeFileShowLineNo; break; } } //--------------------------------------------------------------------------- -void DocCopy::parse(QList<DocNode> &children) -{ - QCString doc,brief; - Definition *def; - if (findDocsForMemberOrCompound(m_link,&doc,&brief,&def)) - { - if (g_copyStack.findRef(def)==-1) // definition not parsed earlier - { - bool hasParamCommand = g_hasParamCommand; - bool hasReturnCommand = g_hasReturnCommand; - QDict<void> paramsFound = g_paramsFound; - //printf("..1 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n", - // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count()); - - docParserPushContext(FALSE); - g_scope = def; - if (def->definitionType()==Definition::TypeMember && def->getOuterScope()) - { - if (def->getOuterScope()!=Doxygen::globalScope) - { - g_context=def->getOuterScope()->name(); - } - } - else if (def!=Doxygen::globalScope) - { - g_context=def->name(); - } - g_styleStack.clear(); - g_nodeStack.clear(); - g_paramsFound.clear(); - g_copyStack.append(def); - // make sure the descriptions end with a newline, so the parser will correctly - // handle them in all cases. - //printf("doc='%s'\n",doc.data()); - //printf("brief='%s'\n",brief.data()); - if (m_copyBrief) - { - brief+='\n'; - internalValidatingParseDoc(m_parent,children,brief); - - //printf("..2 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n", - // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count()); - hasParamCommand = hasParamCommand || g_hasParamCommand; - hasReturnCommand = hasReturnCommand || g_hasReturnCommand; - QDictIterator<void> it(g_paramsFound); - void *item; - for (;(item=it.current());++it) - { - paramsFound.insert(it.currentKey(),it.current()); - } - } - if (m_copyDetails) - { - doc+='\n'; - internalValidatingParseDoc(m_parent,children,doc); - - //printf("..3 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n", - // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count()); - hasParamCommand = hasParamCommand || g_hasParamCommand; - hasReturnCommand = hasReturnCommand || g_hasReturnCommand; - QDictIterator<void> it(g_paramsFound); - void *item; - for (;(item=it.current());++it) - { - paramsFound.insert(it.currentKey(),it.current()); - } - } - g_copyStack.remove(def); - ASSERT(g_styleStack.isEmpty()); - ASSERT(g_nodeStack.isEmpty()); - docParserPopContext(TRUE); - - g_hasParamCommand = hasParamCommand; - g_hasReturnCommand = hasReturnCommand; - g_paramsFound = paramsFound; - - //printf("..4 hasParamCommand=%d hasReturnCommand=%d paramsFound=%d\n", - // g_hasParamCommand,g_hasReturnCommand,g_paramsFound.count()); - } - else // oops, recursion - { - warn_doc_error(g_fileName,doctokenizerYYlineno,"recursive call chain of \\copydoc commands detected at %d\n", - doctokenizerYYlineno); - } - } - else - { - warn_doc_error(g_fileName,doctokenizerYYlineno,"target %s of \\copydoc command not found", - qPrint(m_link)); - } -} - -//--------------------------------------------------------------------------- - DocXRefItem::DocXRefItem(DocNode *parent,int id,const char *key) : m_id(id), m_key(key), m_relPath(g_relPath) { @@ -2511,7 +2409,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : m_refType(Unknown), m_isSubPage(FALSE) { m_parent = parent; - Definition *compound = 0; + const Definition *compound = 0; QCString anchor; //printf("DocRef::DocRef(target=%s,context=%s)\n",target.data(),context.data()); ASSERT(!target.isEmpty()); @@ -2564,16 +2462,16 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : { if (anchor.isEmpty() && /* compound link */ compound->definitionType()==Definition::TypeGroup && /* is group */ - ((GroupDef *)compound)->groupTitle() /* with title */ + (dynamic_cast<const GroupDef *>(compound))->groupTitle() /* with title */ ) { - m_text=((GroupDef *)compound)->groupTitle(); // use group's title as link + m_text=(dynamic_cast<const GroupDef *>(compound))->groupTitle(); // use group's title as link } else if (compound->definitionType()==Definition::TypeMember && - ((MemberDef*)compound)->isObjCMethod()) + (dynamic_cast<const MemberDef*>(compound))->isObjCMethod()) { // Objective C Method - MemberDef *member = (MemberDef*)compound; + const MemberDef *member = dynamic_cast<const MemberDef*>(compound); bool localLink = g_memberDef ? member->getClassDef()==g_memberDef->getClassDef() : FALSE; m_text = member->objCMethodName(localLink,g_inSeeBlock); } @@ -2585,7 +2483,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) : return; } else if (compound && compound->definitionType()==Definition::TypeFile && - ((FileDef*)compound)->generateSourceFile() + (dynamic_cast<const FileDef*>(compound))->generateSourceFile() ) // undocumented file that has source code we can link to { m_file = compound->getSourceFileBase(); @@ -2594,7 +2492,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,doctokenizerYYlineno,"unable to resolve reference to '%s' for \\ref command", qPrint(target)); } @@ -2692,7 +2590,7 @@ DocCite::DocCite(DocNode *parent,const QCString &target,const QCString &) //cont } else if (cite==0) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unable to resolve reference to `%s' for \\cite command", + warn_doc_error(g_fileName,doctokenizerYYlineno,"unable to resolve reference to '%s' for \\cite command", qPrint(target)); } else @@ -2707,7 +2605,7 @@ DocCite::DocCite(DocNode *parent,const QCString &target,const QCString &) //cont DocLink::DocLink(DocNode *parent,const QCString &target) { m_parent = parent; - Definition *compound = 0; + const Definition *compound = 0; QCString anchor; m_refText = target; m_relPath = g_relPath; @@ -2724,8 +2622,8 @@ DocLink::DocLink(DocNode *parent,const QCString &target) m_file = compound->getOutputFileBase(); m_ref = compound->getReference(); } - else if (compound && compound->definitionType()==Definition::TypeFile && - ((FileDef*)compound)->generateSourceFile() + else if (compound && compound->definitionType()==Definition::TypeFile && + (dynamic_cast<const FileDef*>(compound))->generateSourceFile() ) // undocumented file that has source code we can link to { m_file = compound->getSourceFileBase(); @@ -2735,7 +2633,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,doctokenizerYYlineno,"unable to resolve link to '%s' for \\link command", qPrint(target)); } @@ -2839,8 +2737,9 @@ DocDotFile::DocDotFile(DocNode *parent,const QCString &name,const QCString &cont m_parent = parent; } -void DocDotFile::parse() +bool DocDotFile::parse() { + bool ok = false; defaultHandleTitleAndSize(CMD_DOTFILE,this,m_children,m_width,m_height); bool ambig; @@ -2849,15 +2748,16 @@ void DocDotFile::parse() { fd = findFileDef(Doxygen::dotFileNameDict,m_name+".dot",ambig); } - if (fd) + if (fd && !ambig) { m_file = fd->absFilePath(); + ok = true; } else if (ambig) { warn_doc_error(g_fileName,doctokenizerYYlineno,"included dot file name %s is ambiguous.\n" "Possible candidates:\n%s",qPrint(m_name), - qPrint(showFileDefMatches(Doxygen::exampleNameDict,m_name)) + qPrint(showFileDefMatches(Doxygen::dotFileNameDict,m_name)) ); } else @@ -2865,6 +2765,7 @@ void DocDotFile::parse() warn_doc_error(g_fileName,doctokenizerYYlineno,"included dot file %s is not found " "in any of the paths specified via DOTFILE_DIRS!",qPrint(m_name)); } + return ok; } DocMscFile::DocMscFile(DocNode *parent,const QCString &name,const QCString &context) : @@ -2873,8 +2774,9 @@ DocMscFile::DocMscFile(DocNode *parent,const QCString &name,const QCString &cont m_parent = parent; } -void DocMscFile::parse() +bool DocMscFile::parse() { + bool ok = false; defaultHandleTitleAndSize(CMD_MSCFILE,this,m_children,m_width,m_height); bool ambig; @@ -2883,15 +2785,16 @@ void DocMscFile::parse() { fd = findFileDef(Doxygen::mscFileNameDict,m_name+".msc",ambig); } - if (fd) + if (fd && !ambig) { m_file = fd->absFilePath(); + ok = true; } else if (ambig) { warn_doc_error(g_fileName,doctokenizerYYlineno,"included msc file name %s is ambiguous.\n" "Possible candidates:\n%s",qPrint(m_name), - qPrint(showFileDefMatches(Doxygen::exampleNameDict,m_name)) + qPrint(showFileDefMatches(Doxygen::mscFileNameDict,m_name)) ); } else @@ -2899,6 +2802,7 @@ void DocMscFile::parse() warn_doc_error(g_fileName,doctokenizerYYlineno,"included msc file %s is not found " "in any of the paths specified via MSCFILE_DIRS!",qPrint(m_name)); } + return ok; } //--------------------------------------------------------------------------- @@ -2909,8 +2813,9 @@ DocDiaFile::DocDiaFile(DocNode *parent,const QCString &name,const QCString &cont m_parent = parent; } -void DocDiaFile::parse() +bool DocDiaFile::parse() { + bool ok = false; defaultHandleTitleAndSize(CMD_DIAFILE,this,m_children,m_width,m_height); bool ambig; @@ -2919,15 +2824,16 @@ void DocDiaFile::parse() { fd = findFileDef(Doxygen::diaFileNameDict,m_name+".dia",ambig); } - if (fd) + if (fd && !ambig) { m_file = fd->absFilePath(); + ok = true; } else if (ambig) { warn_doc_error(g_fileName,doctokenizerYYlineno,"included dia file name %s is ambiguous.\n" "Possible candidates:\n%s",qPrint(m_name), - qPrint(showFileDefMatches(Doxygen::exampleNameDict,m_name)) + qPrint(showFileDefMatches(Doxygen::diaFileNameDict,m_name)) ); } else @@ -2935,6 +2841,7 @@ void DocDiaFile::parse() warn_doc_error(g_fileName,doctokenizerYYlineno,"included dia file %s is not found " "in any of the paths specified via DIAFILE_DIRS!",qPrint(m_name)); } + return ok; } //--------------------------------------------------------------------------- @@ -2981,6 +2888,15 @@ DocImage::DocImage(DocNode *parent,const HtmlAttribList &attribs,const QCString m_parent = parent; } +bool DocImage::isSVG() const +{ + QCString locName = m_url.isEmpty() ? m_name : m_url; + int len = locName.length(); + int fnd = locName.find('?'); // ignore part from ? until end + if (fnd!=-1) fnd=len; + return fnd>=4 && locName.mid(fnd-4,4)==".svg"; +} + void DocImage::parse() { defaultHandleTitleAndSize(CMD_IMAGE,this,m_children,m_width,m_height); @@ -3068,7 +2984,7 @@ int DocHtmlHeader::parse() } else if (tagId==HTML_BR) { - DocLineBreak *lb = new DocLineBreak(this); + DocLineBreak *lb = new DocLineBreak(this,g_token->attribs); m_children.append(lb); } else @@ -3312,7 +3228,7 @@ DocHtmlCaption::DocHtmlCaption(DocNode *parent,const HtmlAttribList &attribs) HtmlAttrib *opt; for (li.toFirst();(opt=li.current());++li) { - if (opt->name=="id") // interpret id attribute as an anchor + if (opt->name=="id" && !opt->value.isEmpty()) // interpret id attribute as an anchor { SectionInfo *sec = Doxygen::sectionDict->find(opt->value); if (sec) @@ -3329,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,doctokenizerYYlineno,"Invalid caption id '%s'",qPrint(opt->value)); } } else // copy attribute @@ -4698,8 +4614,8 @@ int DocParamList::parse(const QCString &cmdName) int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", - qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + qPrint(saveCmdName)); retval=0; goto endparamlist; } @@ -4715,19 +4631,19 @@ int DocParamList::parse(const QCString &cmdName) handleParameterType(this,m_paramTypes,g_token->name.left(typeSeparator)); g_token->name = g_token->name.mid(typeSeparator+1); g_hasParamCommand=TRUE; - checkArgumentName(g_token->name,TRUE); + checkArgumentName(g_token->name); ((DocParamSect*)parent())->m_hasTypeSpecifier=TRUE; } else { g_hasParamCommand=TRUE; - checkArgumentName(g_token->name,TRUE); + checkArgumentName(g_token->name); } } else if (m_type==DocParamSect::RetVal) { g_hasReturnCommand=TRUE; - checkArgumentName(g_token->name,FALSE); + checkRetvalName(g_token->name); } //m_params.append(g_token->name); handleLinkedWord(this,m_params); @@ -4737,7 +4653,7 @@ int DocParamList::parse(const QCString &cmdName) if (tok==0) /* premature end of comment block */ { warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " - "argument of command %s",qPrint(cmdName)); + "argument of command %s",qPrint(saveCmdName)); retval=0; goto endparamlist; } @@ -4772,12 +4688,12 @@ int DocParamList::parseXml(const QCString ¶mName) if (m_type==DocParamSect::Param) { g_hasParamCommand=TRUE; - checkArgumentName(g_token->name,TRUE); + checkArgumentName(g_token->name); } else if (m_type==DocParamSect::RetVal) { g_hasReturnCommand=TRUE; - checkArgumentName(g_token->name,FALSE); + checkRetvalName(g_token->name); } handleLinkedWord(this,m_params); @@ -4935,7 +4851,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,doctokenizerYYlineno,"expected whitespace after \\%s command", qPrint("cite")); return; } @@ -4967,7 +4883,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,doctokenizerYYlineno,"expected whitespace after \\%s command", qPrint("emoji")); return; } @@ -5014,12 +4930,13 @@ int DocPara::handleXRefItem() void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type t) { - DBG(("handleIncludeOperator(%s)\n",qPrint(cmdName))); + QCString saveCmdName = cmdName; + DBG(("handleIncludeOperator(%s)\n",qPrint(saveCmdName))); int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", - qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + qPrint(saveCmdName)); return; } doctokenizerYYsetStatePattern(); @@ -5028,13 +4945,13 @@ void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type if (tok==0) { warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " - "argument of command %s", qPrint(cmdName)); + "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", - tokToString(tok),qPrint(cmdName)); + tokToString(tok),qPrint(saveCmdName)); return; } DocIncOperator *op = new DocIncOperator(this,t,g_token->name,g_context,g_isExample,g_exampleName); @@ -5082,7 +4999,7 @@ void DocPara::handleImage(const QCString &cmdName) { if (g_token->name.lower() != "inline") { - warn_doc_error(g_fileName,doctokenizerYYlineno,"currently only 'inline' suported as option of %s command", + warn_doc_error(g_fileName,doctokenizerYYlineno,"currently only 'inline' supported as option of %s command", qPrint(saveCmdName)); } else @@ -5100,7 +5017,7 @@ void DocPara::handleImage(const QCString &cmdName) tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command with option", + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command with option", qPrint(saveCmdName)); return; } @@ -5108,7 +5025,7 @@ void DocPara::handleImage(const QCString &cmdName) } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", qPrint(saveCmdName)); return; } @@ -5123,7 +5040,7 @@ void DocPara::handleImage(const QCString &cmdName) tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", qPrint(saveCmdName)); return; } @@ -5158,11 +5075,12 @@ void DocPara::handleImage(const QCString &cmdName) template<class T> void DocPara::handleFile(const QCString &cmdName) { + QCString saveCmdName = cmdName; int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", - qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + qPrint(saveCmdName)); return; } doctokenizerYYsetStateFile(); @@ -5171,13 +5089,19 @@ void DocPara::handleFile(const QCString &cmdName) if (tok!=TK_WORD) { warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", - tokToString(tok),qPrint(cmdName)); + tokToString(tok),qPrint(saveCmdName)); return; } QCString name = g_token->name; T *df = new T(this,name,g_context); - m_children.append(df); - df->parse(); + if (df->parse()) + { + m_children.append(df); + } + else + { + delete df; + } } void DocPara::handleVhdlFlow() @@ -5189,11 +5113,12 @@ void DocPara::handleVhdlFlow() void DocPara::handleLink(const QCString &cmdName,bool isJavaLink) { + QCString saveCmdName = cmdName; int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", - qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + qPrint(saveCmdName)); return; } doctokenizerYYsetStateLink(); @@ -5201,7 +5126,7 @@ void DocPara::handleLink(const QCString &cmdName,bool isJavaLink) if (tok!=TK_WORD) { warn_doc_error(g_fileName,doctokenizerYYlineno,"%s as the argument of %s", - tokToString(tok),qPrint(cmdName)); + tokToString(tok),qPrint(saveCmdName)); return; } doctokenizerYYsetStatePara(); @@ -5216,12 +5141,13 @@ void DocPara::handleLink(const QCString &cmdName,bool isJavaLink) void DocPara::handleRef(const QCString &cmdName) { - DBG(("handleRef(%s)\n",qPrint(cmdName))); + QCString saveCmdName = cmdName; + DBG(("handleRef(%s)\n",qPrint(saveCmdName))); int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", - qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + qPrint(saveCmdName)); return; } doctokenizerYYsetStateRef(); @@ -5230,7 +5156,7 @@ void DocPara::handleRef(const QCString &cmdName) if (tok!=TK_WORD) { warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", - tokToString(tok),qPrint(cmdName)); + tokToString(tok),qPrint(saveCmdName)); goto endref; } ref = new DocRef(this,g_token->name,g_context); @@ -5243,6 +5169,7 @@ endref: void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) { DBG(("handleInclude(%s)\n",qPrint(cmdName))); + QCString saveCmdName = cmdName; int tok=doctokenizerYYlex(); bool isBlock = false; if (tok==TK_WORD && g_token->name=="{") @@ -5259,6 +5186,10 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) { t = DocInclude::SnipWithLines; } + else if (t==DocInclude::DontInclude && optList.contains("lineno")) + { + t = DocInclude::DontIncWithLines; + } else if (t==DocInclude::Include && optList.contains("doc")) { t = DocInclude::IncludeDoc; @@ -5279,8 +5210,8 @@ 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", - qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", + qPrint(saveCmdName)); return; } doctokenizerYYsetStateFile(); @@ -5289,13 +5220,13 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) if (tok==0) { warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " - "argument of command %s",qPrint(cmdName)); + "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", - tokToString(tok),qPrint(cmdName)); + tokToString(tok),qPrint(saveCmdName)); return; } QCString fileName = g_token->name; @@ -5309,7 +5240,7 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) if (tok!=TK_WORD) { warn_doc_error(g_fileName,doctokenizerYYlineno,"expected block identifier, but found token %s instead while parsing the %s command", - tokToString(tok),qPrint(cmdName)); + tokToString(tok),qPrint(saveCmdName)); return; } blockId = "["+g_token->name+"]"; @@ -5343,25 +5274,26 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) void DocPara::handleSection(const QCString &cmdName) { + QCString saveCmdName = cmdName; // get the argument of the section command. int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", - qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"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 " - "argument of command %s\n", qPrint(cmdName)); + "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", - tokToString(tok),qPrint(cmdName)); + tokToString(tok),qPrint(saveCmdName)); return; } g_token->sectionId = g_token->name; @@ -5419,7 +5351,7 @@ void DocPara::handleInheritDoc() MemberDef *reMd = g_memberDef->reimplements(); if (reMd) // member from which was inherited. { - MemberDef *thisMd = g_memberDef; + const MemberDef *thisMd = g_memberDef; //printf("{InheritDocs:%s=>%s}\n",g_memberDef->qualifiedName().data(),reMd->qualifiedName().data()); docParserPushContext(); g_scope=reMd->getOuterScope(); @@ -5450,7 +5382,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 `\\%s'",qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"Found unknown command '\\%s'",qPrint(cmdName)); break; case CMD_EMPHASIS: m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,TRUE)); @@ -5996,9 +5928,15 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta case HTML_STRIKE: handleStyleEnter(this,m_children,DocStyleChange::Strike,&g_token->attribs); break; + case HTML_DEL: + handleStyleEnter(this,m_children,DocStyleChange::Del,&g_token->attribs); + break; case HTML_UNDERLINE: handleStyleEnter(this,m_children,DocStyleChange::Underline,&g_token->attribs); break; + case HTML_INS: + handleStyleEnter(this,m_children,DocStyleChange::Ins,&g_token->attribs); + break; case HTML_CODE: if (/*getLanguageFromFileName(g_fileName)==SrcLangExt_CSharp ||*/ g_xmlComment) // for C# source or inside a <summary> or <remark> section we @@ -6075,13 +6013,13 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta break; case HTML_BR: { - DocLineBreak *lb = new DocLineBreak(this); + DocLineBreak *lb = new DocLineBreak(this,tagHtmlAttribs); m_children.append(lb); } break; case HTML_HR: { - DocHorRuler *hr = new DocHorRuler(this); + DocHorRuler *hr = new DocHorRuler(this,tagHtmlAttribs); m_children.append(hr); } break; @@ -6411,9 +6349,15 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) case HTML_STRIKE: handleStyleLeave(this,m_children,DocStyleChange::Strike,"strike"); break; + case HTML_DEL: + handleStyleLeave(this,m_children,DocStyleChange::Del,"del"); + break; case HTML_UNDERLINE: handleStyleLeave(this,m_children,DocStyleChange::Underline,"u"); break; + case HTML_INS: + handleStyleLeave(this,m_children,DocStyleChange::Ins,"ins"); + break; case HTML_CODE: handleStyleLeave(this,m_children,DocStyleChange::Code,"code"); break; @@ -6856,6 +6800,11 @@ endparagraph: DocNode *n = g_nodeStack.pop(); ASSERT(n==this); DBG(("DocPara::parse() end retval=%x\n",retval)); + if (!g_token->endTag && n->kind()==DocNode::Kind_Para && + retval==TK_NEWPARA && g_token->name.lower() == "p") + { + ((DocPara *)n)->setAttribs(g_token->attribs); + } INTERNAL_ASSERT(retval==0 || retval==TK_NEWPARA || retval==TK_LISTITEM || retval==TK_ENDLIST || retval>RetVal_OK ); @@ -6931,54 +6880,55 @@ int DocSection::parse() //printf("m_level=%d <-> %d\n",m_level,Doxygen::subpageNestingLevel); - if (retval==RetVal_Subsection && m_level==Doxygen::subpageNestingLevel+1) + while (true) { - // then parse any number of nested sections - while (retval==RetVal_Subsection) // more sections follow + if (retval==RetVal_Subsection && m_level<=Doxygen::subpageNestingLevel+1) { - //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; - DocSection *s=new DocSection(this, - QMIN(2+Doxygen::subpageNestingLevel,5),g_token->sectionId); - m_children.append(s); - retval = s->parse(); + // then parse any number of nested sections + while (retval==RetVal_Subsection) // more sections follow + { + //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; + DocSection *s=new DocSection(this, + QMIN(2+Doxygen::subpageNestingLevel,5),g_token->sectionId); + m_children.append(s); + retval = s->parse(); + } + break; } - } - else if (retval==RetVal_Subsubsection && m_level==Doxygen::subpageNestingLevel+2) - { - // then parse any number of nested sections - while (retval==RetVal_Subsubsection) // more sections follow + else if (retval==RetVal_Subsubsection && m_level<=Doxygen::subpageNestingLevel+2) { - //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; - DocSection *s=new DocSection(this, - QMIN(3+Doxygen::subpageNestingLevel,5),g_token->sectionId); - m_children.append(s); - retval = s->parse(); + if ((m_level<=1+Doxygen::subpageNestingLevel) && !QString(g_token->sectionId).startsWith("autotoc_md")) + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected subsubsection command found inside %s!",sectionLevelToName[m_level]); + // then parse any number of nested sections + while (retval==RetVal_Subsubsection) // more sections follow + { + //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; + DocSection *s=new DocSection(this, + QMIN(3+Doxygen::subpageNestingLevel,5),g_token->sectionId); + m_children.append(s); + retval = s->parse(); + } + if (!(m_level<Doxygen::subpageNestingLevel+2 && retval == RetVal_Subsection)) break; } - } - else if (retval==RetVal_Paragraph && m_level==QMIN(5,Doxygen::subpageNestingLevel+3)) - { - // then parse any number of nested sections - while (retval==RetVal_Paragraph) // more sections follow + else if (retval==RetVal_Paragraph && m_level<=QMIN(5,Doxygen::subpageNestingLevel+3)) { - //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; - DocSection *s=new DocSection(this, - QMIN(4+Doxygen::subpageNestingLevel,5),g_token->sectionId); - m_children.append(s); - retval = s->parse(); + if ((m_level<=2+Doxygen::subpageNestingLevel) && !QString(g_token->sectionId).startsWith("autotoc_md")) + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected paragraph command found inside %s!",sectionLevelToName[m_level]); + // then parse any number of nested sections + while (retval==RetVal_Paragraph) // more sections follow + { + //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; + DocSection *s=new DocSection(this, + QMIN(4+Doxygen::subpageNestingLevel,5),g_token->sectionId); + m_children.append(s); + retval = s->parse(); + } + if (!(m_level<Doxygen::subpageNestingLevel+3 && (retval == RetVal_Subsection || retval == RetVal_Subsubsection))) break; + } + else + { + break; } - } - else if ((m_level<=1+Doxygen::subpageNestingLevel && retval==RetVal_Subsubsection) || - (m_level<=2+Doxygen::subpageNestingLevel && retval==RetVal_Paragraph) - ) - { - int level = (retval==RetVal_Subsubsection) ? 3 : 4; - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected %s " - "command found inside %s!", - sectionLevelToName[level],sectionLevelToName[m_level]); - retval=0; // stop parsing - } - else - { } INTERNAL_ASSERT(retval==0 || @@ -7086,7 +7036,7 @@ 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,doctokenizerYYlineno,"Unexpected command '%s' found", qPrint(g_token->name)); break; } @@ -7123,7 +7073,7 @@ void DocRoot::parse() DocPara *par = new DocPara(this); if (isFirst) { par->markFirst(); isFirst=FALSE; } retval=par->parse(); - if (!par->isEmpty()) + if (!par->isEmpty() || par->attribs().count()>0) { m_children.append(par); lastPar=par; @@ -7132,21 +7082,96 @@ void DocRoot::parse() { delete par; } - if (retval==TK_LISTITEM) + if (retval==RetVal_Paragraph) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid list item found"); + if (!QString(g_token->sectionId).startsWith("autotoc_md")) + warn_doc_error(g_fileName,doctokenizerYYlineno,"found paragraph command outside of subsubsection context!"); + while (retval==RetVal_Paragraph) + { + if (!g_token->sectionId.isEmpty()) + { + SectionInfo *sec=Doxygen::sectionDict->find(g_token->sectionId); + if (sec) + { + DocSection *s=new DocSection(this, + QMIN(4+Doxygen::subpageNestingLevel,5),g_token->sectionId); + m_children.append(s); + retval = s->parse(); + } + else + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"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"); + retval = 0; + } + } } - else if (retval==RetVal_Subsection) + if (retval==RetVal_Subsubsection) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsection command outside of section context!"); + if (!(QString(g_token->sectionId).startsWith("autotoc_md"))) + warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsubsection command outside of subsection context!"); + while (retval==RetVal_Subsubsection) + { + if (!g_token->sectionId.isEmpty()) + { + SectionInfo *sec=Doxygen::sectionDict->find(g_token->sectionId); + if (sec) + { + DocSection *s=new DocSection(this, + QMIN(3+Doxygen::subpageNestingLevel,5),g_token->sectionId); + m_children.append(s); + retval = s->parse(); + } + else + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"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"); + retval = 0; + } + } } - else if (retval==RetVal_Subsubsection) + if (retval==RetVal_Subsection) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsubsection command outside of subsection context!"); + if (!(QString(g_token->sectionId).startsWith("autotoc_md"))) + warn_doc_error(g_fileName,doctokenizerYYlineno,"found subsection command outside of section context!"); + while (retval==RetVal_Subsection) + { + if (!g_token->sectionId.isEmpty()) + { + SectionInfo *sec=Doxygen::sectionDict->find(g_token->sectionId); + if (sec) + { + DocSection *s=new DocSection(this, + QMIN(2+Doxygen::subpageNestingLevel,5),g_token->sectionId); + m_children.append(s); + retval = s->parse(); + } + else + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"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"); + retval = 0; + } + } } - else if (retval==RetVal_Paragraph) + if (retval==TK_LISTITEM) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"found paragraph command outside of subsubsection context!"); + warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid list item found"); } if (retval==RetVal_Internal) { @@ -7161,17 +7186,25 @@ void DocRoot::parse() // then parse any number of level1 sections while (retval==RetVal_Section) { - SectionInfo *sec=Doxygen::sectionDict->find(g_token->sectionId); - if (sec) + if (!g_token->sectionId.isEmpty()) { - DocSection *s=new DocSection(this, - QMIN(1+Doxygen::subpageNestingLevel,5),g_token->sectionId); - m_children.append(s); - retval = s->parse(); + SectionInfo *sec=Doxygen::sectionDict->find(g_token->sectionId); + if (sec) + { + DocSection *s=new DocSection(this, + QMIN(1+Doxygen::subpageNestingLevel,5),g_token->sectionId); + m_children.append(s); + retval = s->parse(); + } + else + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid section id '%s'; ignoring section",qPrint(g_token->sectionId)); + retval = 0; + } } else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Invalid section id `%s'; ignoring section",qPrint(g_token->sectionId)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"Missing id for section; ignoring section"); retval = 0; } } @@ -7316,7 +7349,7 @@ static QCString processCopyDoc(const char *data,uint &len) while (j<len && (data[j]==' ' || data[j]=='\t')) j++; // extract the argument QCString id = extractCopyDocId(data,j,len); - Definition *def; + const Definition *def = 0; QCString doc,brief; //printf("resolving docs='%s'\n",id.data()); if (findDocsForMemberOrCompound(id,&doc,&brief,&def)) @@ -7505,7 +7538,7 @@ QCString getJsDirEmbedingChar(QString::Direction textDir) //--------------------------------------------------------------------------- DocRoot *validatingParseDoc(const char *fileName,int startLine, - Definition *ctx,MemberDef *md, + const Definition *ctx,const MemberDef *md, const char *input,bool indexWords, bool isExample, const char *exampleName, bool singleLine, bool linkFromIndex) @@ -7531,12 +7564,12 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, } else if (ctx && ctx->definitionType()==Definition::TypePage) { - Definition *scope = ((PageDef*)ctx)->getPageScope(); + const Definition *scope = (dynamic_cast<const PageDef*>(ctx))->getPageScope(); if (scope && scope!=Doxygen::globalScope) g_context = scope->name(); } else if (ctx && ctx->definitionType()==Definition::TypeGroup) { - Definition *scope = ((GroupDef*)ctx)->getGroupScope(); + const Definition *scope = (dynamic_cast<const GroupDef*>(ctx))->getGroupScope(); if (scope && scope!=Doxygen::globalScope) g_context = scope->name(); } else @@ -7586,7 +7619,7 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, case Definition::TypePage: { PageDef *pd = (PageDef *)ctx; - if (!pd->title().isEmpty()) + if (pd->hasTitle()) { name = theTranslator->trPage(TRUE,TRUE)+" "+pd->title(); } @@ -7661,6 +7694,8 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, g_exampleName = exampleName; g_hasParamCommand = FALSE; g_hasReturnCommand = FALSE; + g_retvalsFound.setAutoDelete(FALSE); + g_retvalsFound.clear(); g_paramsFound.setAutoDelete(FALSE); g_paramsFound.clear(); g_sectionDict = 0; //sections; @@ -7690,7 +7725,7 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, } checkUnOrMultipleDocumentedParams(); - detectNoDocumentedParams(); + if (g_memberDef) g_memberDef->detectUndocumentedParams(g_hasParamCommand,g_hasReturnCommand); // TODO: These should be called at the end of the program. //doctokenizerYYcleanup(); @@ -7731,6 +7766,8 @@ DocText *validatingParseText(const char *input) g_exampleName = ""; g_hasParamCommand = FALSE; g_hasReturnCommand = FALSE; + g_retvalsFound.setAutoDelete(FALSE); + g_retvalsFound.clear(); g_paramsFound.setAutoDelete(FALSE); g_paramsFound.clear(); g_searchUrl=""; diff --git a/src/docparser.h b/src/docparser.h index ca32b20..e608d8f 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -65,7 +65,7 @@ QCString getJsDirEmbedingChar(QString::Direction textDir); * pointer is handed over to the caller. */ DocRoot *validatingParseDoc(const char *fileName,int startLine, - Definition *context, MemberDef *md, + const Definition *context, const MemberDef *md, const char *input,bool indexWords, bool isExample,const char *exampleName=0, bool singleLine=FALSE,bool linkFromIndex=FALSE); @@ -141,7 +141,8 @@ class DocNode Kind_VhdlFlow = 50, Kind_ParBlock = 51, Kind_DiaFile = 52, - Kind_Emoji = 53 + Kind_Emoji = 53, + Kind_Sep = 54 }; /*! Creates a new node */ DocNode() : m_parent(0), m_insidePre(FALSE) {} @@ -300,22 +301,31 @@ class DocURL : public DocNode class DocLineBreak : public DocNode { public: - DocLineBreak(DocNode *parent) { m_parent=parent; } + DocLineBreak(DocNode *parent) { m_parent = parent; } + DocLineBreak(DocNode *parent,const HtmlAttribList &attribs) + : m_attribs(attribs) { m_parent = parent; } Kind kind() const { return Kind_LineBreak; } void accept(DocVisitor *v) { v->visit(this); } + const HtmlAttribList &attribs() const { return m_attribs; } + private: + HtmlAttribList m_attribs; }; /** Node representing a horizontal ruler */ class DocHorRuler : public DocNode { public: - DocHorRuler(DocNode *parent) { m_parent = parent; } + DocHorRuler(DocNode *parent,const HtmlAttribList &attribs) + : m_attribs(attribs) { m_parent = parent; } Kind kind() const { return Kind_HorRuler; } void accept(DocVisitor *v) { v->visit(this); } + const HtmlAttribList &attribs() const { return m_attribs; } + private: + HtmlAttribList m_attribs; }; /** Node representing an anchor */ @@ -328,9 +338,12 @@ class DocAnchor : public DocNode QCString file() const { return m_file; } void accept(DocVisitor *v) { v->visit(this); } + const HtmlAttribList &attribs() const { return m_attribs; } + private: QCString m_anchor; QCString m_file; + HtmlAttribList m_attribs; }; /** Node representing a citation of some bibliographic reference */ @@ -370,7 +383,9 @@ class DocStyleChange : public DocNode Span = (1<<8), Div = (1<<9), Strike = (1<<10), - Underline = (1<<11) + Underline = (1<<11), + Del = (1<<12), + Ins = (1<<13) }; DocStyleChange(DocNode *parent,uint position,Style s,bool enable, @@ -504,6 +519,19 @@ class DocWhiteSpace : public DocNode QCString m_chars; }; +/** Node representing a separator */ +class DocSeparator : public DocNode +{ + public: + DocSeparator(DocNode *parent,const QCString &chars) : + m_chars(chars) { m_parent = parent; } + Kind kind() const { return Kind_Sep; } + QCString chars() const { return m_chars; } + void accept(DocVisitor *v) { } + private: + QCString m_chars; +}; + /** Node representing a verbatim, unparsed text fragment */ class DocVerbatim : public DocNode { @@ -551,7 +579,8 @@ class DocInclude : public DocNode { public: enum Type { Include, DontInclude, VerbInclude, HtmlInclude, LatexInclude, - IncWithLines, Snippet , IncludeDoc, SnippetDoc, SnipWithLines}; + IncWithLines, Snippet , IncludeDoc, SnippetDoc, SnipWithLines, + DontIncWithLines}; DocInclude(DocNode *parent,const QCString &file, const QCString context, Type t, bool isExample,const QCString exampleFile, @@ -595,11 +624,24 @@ class DocIncOperator : public DocNode enum Type { Line, SkipLine, Skip, Until }; DocIncOperator(DocNode *parent,Type t,const QCString &pat, const QCString &context,bool isExample,const QCString &exampleFile) : - m_type(t), m_pattern(pat), m_context(context), + m_type(t), m_pattern(pat), m_context(context), m_isFirst(FALSE), m_isLast(FALSE), m_isExample(isExample), m_exampleFile(exampleFile) { m_parent = parent; } Kind kind() const { return Kind_IncOperator; } Type type() const { return m_type; } + const char *typeAsString() const + { + switch(m_type) + { + case Line: return "line"; + case SkipLine: return "skipline"; + case Skip: return "skip"; + case Until: return "until"; + } + return ""; + } + int line() const { return m_line; } + bool showLineNo() const { return m_showLineNo; } QCString text() const { return m_text; } QCString pattern() const { return m_pattern; } QCString context() const { return m_context; } @@ -615,6 +657,8 @@ class DocIncOperator : public DocNode private: Type m_type; + int m_line; + bool m_showLineNo; QCString m_text; QCString m_pattern; QCString m_context; @@ -649,41 +693,23 @@ class DocFormula : public DocNode class DocIndexEntry : public DocNode { public: - DocIndexEntry(DocNode *parent,Definition *scope,MemberDef *md) + DocIndexEntry(DocNode *parent,const Definition *scope,const MemberDef *md) : m_scope(scope), m_member(md){ m_parent = parent; } Kind kind() const { return Kind_IndexEntry; } int parse(); - Definition *scope() const { return m_scope; } - MemberDef *member() const { return m_member; } + const Definition *scope() const { return m_scope; } + const MemberDef *member() const { return m_member; } QCString entry() const { return m_entry; } void accept(DocVisitor *v) { v->visit(this); } private: QCString m_entry; - Definition *m_scope; - MemberDef *m_member; + const Definition *m_scope; + const MemberDef *m_member; }; //----------------------------------------------------------------------- -/** Node representing a copy of documentation block. */ -class DocCopy : public DocNode -{ - public: - DocCopy(DocNode *parent,const QCString &link,bool copyBrief,bool copyDetails) - : m_link(link), - m_copyBrief(copyBrief), m_copyDetails(copyDetails) { m_parent = parent; } - Kind kind() const { return Kind_Copy; } - QCString link() const { return m_link; } - void accept(DocVisitor * /*v*/) { /*CompAccept<DocCopy>::accept(this,v);*/ } - void parse(QList<DocNode> &children); - - private: - QCString m_link; - bool m_copyBrief; - bool m_copyDetails; -}; - /** Node representing an auto List */ class DocAutoList : public CompAccept<DocAutoList> { @@ -768,6 +794,7 @@ class DocImage : public CompAccept<DocImage> QCString relPath() const { return m_relPath; } QCString url() const { return m_url; } bool isInlineImage() const { return m_inlineImage; } + bool isSVG() const; const HtmlAttribList &attribs() const { return m_attribs; } void parse(); @@ -787,7 +814,7 @@ class DocDotFile : public CompAccept<DocDotFile> { public: DocDotFile(DocNode *parent,const QCString &name,const QCString &context); - void parse(); + bool parse(); Kind kind() const { return Kind_DotFile; } QCString name() const { return m_name; } QCString file() const { return m_file; } @@ -810,7 +837,7 @@ class DocMscFile : public CompAccept<DocMscFile> { public: DocMscFile(DocNode *parent,const QCString &name,const QCString &context); - void parse(); + bool parse(); Kind kind() const { return Kind_MscFile; } QCString name() const { return m_name; } QCString file() const { return m_file; } @@ -833,7 +860,7 @@ class DocDiaFile : public CompAccept<DocDiaFile> { public: DocDiaFile(DocNode *parent,const QCString &name,const QCString &context); - void parse(); + bool parse(); Kind kind() const { return Kind_DiaFile; } QCString name() const { return m_name; } QCString file() const { return m_file; } @@ -1198,11 +1225,14 @@ class DocPara : public CompAccept<DocPara> int handleHtmlHeader(const HtmlAttribList &tagHtmlAttribs,int level); bool injectToken(int tok,const QCString &tokText); + const HtmlAttribList &attribs() const { return m_attribs; } + void setAttribs(const HtmlAttribList &attribs) { m_attribs = attribs; } private: QCString m_sectionId; bool m_isFirst; bool m_isLast; + HtmlAttribList m_attribs; }; /** Node representing a parameter list. */ diff --git a/src/docsets.cpp b/src/docsets.cpp index 1327d80..055532a 100644 --- a/src/docsets.cpp +++ b/src/docsets.cpp @@ -236,7 +236,7 @@ void DocSets::addContentsItem(bool isDir, const char *anchor, bool /* separateIndex */, bool /* addToNavIndex */, - Definition * /*def*/) + const Definition * /*def*/) { (void)isDir; //printf("DocSets::addContentsItem(%s) m_dc=%d\n",name,m_dc); @@ -274,14 +274,14 @@ void DocSets::addContentsItem(bool isDir, } } -void DocSets::addIndexItem(Definition *context,MemberDef *md, +void DocSets::addIndexItem(const Definition *context,const MemberDef *md, const char *,const char *) { if (md==0 && context==0) return; - FileDef *fd = 0; - ClassDef *cd = 0; - NamespaceDef *nd = 0; + const FileDef *fd = 0; + const ClassDef *cd = 0; + const NamespaceDef *nd = 0; if (md) { @@ -417,7 +417,7 @@ void DocSets::addIndexItem(Definition *context,MemberDef *md, { scope = nd->name(); } - MemberDef *declMd = md->memberDeclaration(); + const MemberDef *declMd = md->memberDeclaration(); if (declMd==0) declMd = md; { fd = md->getFileDef(); @@ -432,15 +432,15 @@ void DocSets::addIndexItem(Definition *context,MemberDef *md, { if (fd==0 && context->definitionType()==Definition::TypeFile) { - fd = (FileDef*)context; + fd = dynamic_cast<const FileDef*>(context); } if (cd==0 && context->definitionType()==Definition::TypeClass) { - cd = (ClassDef*)context; + cd = dynamic_cast<const ClassDef*>(context); } if (nd==0 && context->definitionType()==Definition::TypeNamespace) { - nd = (NamespaceDef*)context; + nd = dynamic_cast<const NamespaceDef*>(context); } if (fd) { diff --git a/src/docsets.h b/src/docsets.h index 548ba75..0d75bfd 100644 --- a/src/docsets.h +++ b/src/docsets.h @@ -45,9 +45,9 @@ class DocSets : public IndexIntf const char *anchor, bool separateIndex, bool addToNavIndex, - Definition *def + const Definition *def ); - void addIndexItem(Definition *context,MemberDef *md, + void addIndexItem(const Definition *context,const MemberDef *md, const char *sectionAnchor,const char *title); void addIndexFile(const char *name); void addImageFile(const char *) {} diff --git a/src/doctokenizer.h b/src/doctokenizer.h index 8b8ca97..b59fc09 100644 --- a/src/doctokenizer.h +++ b/src/doctokenizer.h @@ -71,9 +71,7 @@ enum Tokens /** @brief Data associated with a token used by the comment block parser. */ struct TokenInfo { - // unknown token - char unknownChar; - + TokenInfo() : isEnumList(FALSE), indent(0), id(-1), endTag(FALSE), emptyTag(FALSE), paramDir(Unspecified) {} // command token QCString name; diff --git a/src/doctokenizer.l b/src/doctokenizer.l index eb14470..194327c 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -157,7 +157,7 @@ static int computeIndent(const char *str,int length) static void processSection() { - //printf("%s: found section/anchor with name `%s'\n",g_fileName.data(),g_secLabel.data()); + //printf("%s: found section/anchor with name '%s'\n",g_fileName.data(),g_secLabel.data()); QCString file; if (g_memberGroup) { @@ -211,7 +211,7 @@ static void handleHtmlTag() { char c=tagText.at(i); // skip spaces - while (i<(int)yyleng && isspace(c)) { c=tagText.at(++i); } + while (i<(int)yyleng && isspace((uchar)c)) { c=tagText.at(++i); } // check for end of the tag if (c == '>') break; // Check for XML style "empty" tag. @@ -222,17 +222,17 @@ static void handleHtmlTag() } startName=i; // search for end of name - while (i<(int)yyleng && !isspace(c) && c!='=') { c=tagText.at(++i); } + while (i<(int)yyleng && !isspace((uchar)c) && c!='=') { c=tagText.at(++i); } endName=i; HtmlAttrib opt; opt.name = tagText.mid(startName,endName-startName).lower(); // skip spaces - while (i<(int)yyleng && isspace(c)) { c=tagText.at(++i); } + while (i<(int)yyleng && isspace((uchar)c)) { c=tagText.at(++i); } if (tagText.at(i)=='=') // option has value { c=tagText.at(++i); // skip spaces - while (i<(int)yyleng && isspace(c)) { c=tagText.at(++i); } + while (i<(int)yyleng && isspace((uchar)c)) { c=tagText.at(++i); } if (tagText.at(i)=='\'') // option '...' { c=tagText.at(++i); @@ -256,7 +256,7 @@ static void handleHtmlTag() { startAttrib=i; // search for separator or end symbol - while (i<(int)yyleng && !isspace(c) && c!='>') { c=tagText.at(++i); } + while (i<(int)yyleng && !isspace((uchar)c) && c!='>') { c=tagText.at(++i); } endAttrib=i; if (i<(int)yyleng) c=tagText.at(++i); } @@ -405,8 +405,8 @@ WORD1NQ {ESCWORD}|{CHARWORDQ}+|"{"|"}" WORD2NQ "."|","|"("|")"|"["|"]"|"::"|":"|";"|"\?"|"="|"'" CAPTION [cC][aA][pP][tT][iI][oO][nN] HTMLTAG "<"(("/")?){ID}({WS}+{ATTRIB})*{WS}*(("/")?)">" -HTMLKEYL "strong"|"center"|"table"|"caption"|"small"|"code"|"dfn"|"var"|"img"|"pre"|"sub"|"sup"|"tr"|"td"|"th"|"ol"|"ul"|"li"|"tt"|"kbd"|"em"|"hr"|"dl"|"dt"|"dd"|"br"|"i"|"a"|"b"|"p"|"strike"|"u" -HTMLKEYU "STRONG"|"CENTER"|"TABLE"|"CAPTION"|"SMALL"|"CODE"|"DFN"|"VAR"|"IMG"|"PRE"|"SUB"|"SUP"|"TR"|"TD"|"TH"|"OL"|"UL"|"LI"|"TT"|"KBD"|"EM"|"HR"|"DL"|"DT"|"DD"|"BR"|"I"|"A"|"B"|"P"|"STRIKE"|"U" +HTMLKEYL "strong"|"center"|"table"|"caption"|"small"|"code"|"dfn"|"var"|"img"|"pre"|"sub"|"sup"|"tr"|"td"|"th"|"ol"|"ul"|"li"|"tt"|"kbd"|"em"|"hr"|"dl"|"dt"|"dd"|"br"|"i"|"a"|"b"|"p"|"strike"|"u"|"del"|"ins" +HTMLKEYU "STRONG"|"CENTER"|"TABLE"|"CAPTION"|"SMALL"|"CODE"|"DFN"|"VAR"|"IMG"|"PRE"|"SUB"|"SUP"|"TR"|"TD"|"TH"|"OL"|"UL"|"LI"|"TT"|"KBD"|"EM"|"HR"|"DL"|"DT"|"DD"|"BR"|"I"|"A"|"B"|"P"|"STRIKE"|"U"|"DEL"|"INS" HTMLKEYW {HTMLKEYL}|{HTMLKEYU} REFWORD2_PRE ("#"|"::")?((({ID}{TEMPLPART}?)|{ANONNS})("."|"#"|"::"|"-"|"/"))*({ID}{TEMPLPART}?(":")?) REFWORD2 {REFWORD2_PRE}{FUNCARG2}? @@ -658,7 +658,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->isEMailAddr=TRUE; return TK_URL; } -<St_Para>"$"{ID}":"[^\n$]+"$" { /* RCS tag */ +<St_Para>"$"{ID}":"[^:\n$][^\n$]*"$" { /* RCS tag */ QCString tagName(yytext+1); int index=tagName.find(':'); g_token->name = tagName.left(index); @@ -902,6 +902,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->sectionId = QCString(yytext).stripWhiteSpace(); return RetVal_OK; } +<St_PlantUMLOpt>"\n" | <St_PlantUMLOpt>. { g_token->sectionId = ""; unput(*yytext); @@ -1008,6 +1009,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} return 0; } <St_TitleV,St_TitleA>\n { + unput(*yytext); return 0; } @@ -1149,7 +1151,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->name = g_token->name.left((int)yyleng-2); return TK_WORD; } -<St_Param>({PHPTYPE}{BLANK}*"|"{BLANK}*)*{PHPTYPE}{WS}+("&")?"$"{LABELID} { +<St_Param>({PHPTYPE}{BLANK}*("["{BLANK}*"]")*{BLANK}*"|"{BLANK}*)*{PHPTYPE}{BLANK}*("["{BLANK}*"]")*{WS}+("&")?"$"{LABELID} { QCString params = yytext; int j = params.find('&'); int i = params.find('$'); @@ -1226,7 +1228,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} /* State for the pass used to find the anchors and sections */ <St_Sections>[^\n@\\<]+ -<St_Sections>"@@"|"\\\\"|"@<"|"\\<" +<St_Sections>{CMD}("<"|{CMD}) <St_Sections>"<"{CAPTION}({WS}+{ATTRIB})*">" { QCString tag=yytext; int s=tag.find("id="); @@ -1341,7 +1343,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,yylineno,"Unexpected character '%s' while looking for section label or title",yytext); } <St_Snippet>[^\n]+ | @@ -1356,12 +1358,12 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} warn(g_fileName,yylineno,"Unexpected new line character"); } <*>[\\@<>&$#%~"=] { /* unescaped special character */ - //warn(g_fileName,yylineno,"Unexpected character `%s', assuming command \\%s was meant.",yytext,yytext); + //warn(g_fileName,yylineno,"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,yylineno,"Unexpected character '%s'",yytext); } %% @@ -1373,7 +1375,7 @@ void doctokenizerYYFindSections(const char *input,Definition *d, if (input==0) return; printlex(yy_flex_debug, TRUE, __FILE__, fileName); g_inputString = input; - //printf("parsing --->`%s'<---\n",input); + //printf("parsing --->'%s'<---\n",input); g_inputPos = 0; g_definition = d; g_memberGroup = mg; diff --git a/src/docvisitor.h b/src/docvisitor.h index d2318c9..0a53595 100644 --- a/src/docvisitor.h +++ b/src/docvisitor.h @@ -79,7 +79,6 @@ class DocLinkedWord; class DocParamSect; class DocParamList; class DocInternalRef; -class DocCopy; // TODO: no longer generated => remove class DocText; class DocSimpleSectSep; class DocHtmlBlockQuote; @@ -187,8 +186,6 @@ class DocVisitor virtual void visitPost(DocXRefItem *) = 0; virtual void visitPre(DocInternalRef *) = 0; virtual void visitPost(DocInternalRef *) = 0; - virtual void visitPre(DocCopy *) = 0; - virtual void visitPost(DocCopy *) = 0; virtual void visitPre(DocText *) = 0; virtual void visitPost(DocText *) = 0; virtual void visitPre(DocHtmlBlockQuote *) = 0; diff --git a/src/dot.cpp b/src/dot.cpp index 0944a02..5cdf92c 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -1,13 +1,10 @@ /***************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2019 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * 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. * @@ -26,382 +23,47 @@ #include <qwaitcondition.h> #include <qregexp.h> +#include "config.h" #include "dot.h" -#include "doxygen.h" -#include "message.h" +#include "dotrunner.h" +#include "dotfilepatcher.h" #include "util.h" -#include "config.h" -#include "language.h" -#include "defargs.h" -#include "docparser.h" -#include "debug.h" -#include "pagedef.h" #include "portable.h" -#include "dirdef.h" -#include "vhdldocgen.h" +#include "message.h" #include "ftextstream.h" -#include "md5.h" -#include "memberlist.h" -#include "groupdef.h" -#include "classlist.h" -#include "filename.h" -#include "namespacedef.h" -#include "memberdef.h" -#include "membergroup.h" +#include "doxygen.h" +#include "language.h" +#include "index.h" #define MAP_CMD "cmapx" -//#define FONTNAME "Helvetica" -#define FONTNAME getDotFontName() -#define FONTSIZE getDotFontSize() - -//-------------------------------------------------------------------- - -static const char svgZoomHeader[] = -"<svg id=\"main\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" onload=\"init(evt)\">\n" -"<style type=\"text/css\"><![CDATA[\n" -".edge:hover path { stroke: red; }\n" -".edge:hover polygon { stroke: red; fill: red; }\n" -"]]></style>\n" -"<script type=\"text/javascript\"><![CDATA[\n" -"var edges = document.getElementsByTagName('g');\n" -"if (edges && edges.length) {\n" -" for (var i=0;i<edges.length;i++) {\n" -" if (edges[i].id.substr(0,4)=='edge') {\n" -" edges[i].setAttribute('class','edge');\n" -" }\n" -" }\n" -"}\n" -"]]></script>\n" -" <defs>\n" -" <circle id=\"rim\" cx=\"0\" cy=\"0\" r=\"7\"/>\n" -" <circle id=\"rim2\" cx=\"0\" cy=\"0\" r=\"3.5\"/>\n" -" <g id=\"zoomPlus\">\n" -" <use xlink:href=\"#rim\" fill=\"#404040\">\n" -" <set attributeName=\"fill\" to=\"#808080\" begin=\"zoomplus.mouseover\" end=\"zoomplus.mouseout\"/>\n" -" </use>\n" -" <path d=\"M-4,0h8M0,-4v8\" fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" pointer-events=\"none\"/>\n" -" </g>\n" -" <g id=\"zoomMin\">\n" -" <use xlink:href=\"#rim\" fill=\"#404040\">\n" -" <set attributeName=\"fill\" to=\"#808080\" begin=\"zoomminus.mouseover\" end=\"zoomminus.mouseout\"/>\n" -" </use>\n" -" <path d=\"M-4,0h8\" fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" pointer-events=\"none\"/>\n" -" </g>\n" -" <g id=\"dirArrow\">\n" -" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" -" </g>\n" -" <g id=\"resetDef\">\n" -" <use xlink:href=\"#rim2\" fill=\"#404040\">\n" -" <set attributeName=\"fill\" to=\"#808080\" begin=\"reset.mouseover\" end=\"reset.mouseout\"/>\n" -" </use>\n" -" </g>\n" -" </defs>\n" -"\n" -"<script type=\"text/javascript\">\n" -; - -static const char svgZoomFooter[] = -// navigation panel -" <g id=\"navigator\" transform=\"translate(0 0)\" fill=\"#404254\">\n" -" <rect fill=\"#f2f5e9\" fill-opacity=\"0.5\" stroke=\"#606060\" stroke-width=\".5\" x=\"0\" y=\"0\" width=\"60\" height=\"60\"/>\n" -// zoom in -" <use id=\"zoomplus\" xlink:href=\"#zoomPlus\" x=\"17\" y=\"9\" onmousedown=\"handleZoom(evt,'in')\"/>\n" -// zoom out -" <use id=\"zoomminus\" xlink:href=\"#zoomMin\" x=\"42\" y=\"9\" onmousedown=\"handleZoom(evt,'out')\"/>\n" -// reset zoom -" <use id=\"reset\" xlink:href=\"#resetDef\" x=\"30\" y=\"36\" onmousedown=\"handleReset()\"/>\n" -// arrow up -" <g id=\"arrowUp\" xlink:href=\"#dirArrow\" transform=\"translate(30 24)\" onmousedown=\"handlePan(0,-1)\">\n" -" <use xlink:href=\"#rim\" fill=\"#404040\">\n" -" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowUp.mouseover\" end=\"arrowUp.mouseout\"/>\n" -" </use>\n" -" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" -" </g>\n" -// arrow right -" <g id=\"arrowRight\" xlink:href=\"#dirArrow\" transform=\"rotate(90) translate(36 -43)\" onmousedown=\"handlePan(1,0)\">\n" -" <use xlink:href=\"#rim\" fill=\"#404040\">\n" -" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowRight.mouseover\" end=\"arrowRight.mouseout\"/>\n" -" </use>\n" -" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" -" </g>\n" -// arrow down -" <g id=\"arrowDown\" xlink:href=\"#dirArrow\" transform=\"rotate(180) translate(-30 -48)\" onmousedown=\"handlePan(0,1)\">\n" -" <use xlink:href=\"#rim\" fill=\"#404040\">\n" -" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowDown.mouseover\" end=\"arrowDown.mouseout\"/>\n" -" </use>\n" -" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" -" </g>\n" -// arrow left -" <g id=\"arrowLeft\" xlink:href=\"#dirArrow\" transform=\"rotate(270) translate(-36 17)\" onmousedown=\"handlePan(-1,0)\">\n" -" <use xlink:href=\"#rim\" fill=\"#404040\">\n" -" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowLeft.mouseover\" end=\"arrowLeft.mouseout\"/>\n" -" </use>\n" -" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" -" </g>\n" -" </g>\n" -// link to original SVG -" <svg viewBox=\"0 0 15 15\" width=\"100%\" height=\"30px\" preserveAspectRatio=\"xMaxYMin meet\">\n" -" <g id=\"arrow_out\" transform=\"scale(0.3 0.3)\">\n" -" <a xlink:href=\"$orgname\" target=\"_base\">\n" -" <rect id=\"button\" ry=\"5\" rx=\"5\" y=\"6\" x=\"6\" height=\"38\" width=\"38\"\n" -" fill=\"#f2f5e9\" fill-opacity=\"0.5\" stroke=\"#606060\" stroke-width=\"1.0\"/>\n" -" <path id=\"arrow\"\n" -" d=\"M 11.500037,31.436501 C 11.940474,20.09759 22.043105,11.32322 32.158766,21.979434 L 37.068811,17.246167 C 37.068811,17.246167 37.088388,32 37.088388,32 L 22.160133,31.978069 C 22.160133,31.978069 26.997745,27.140456 26.997745,27.140456 C 18.528582,18.264221 13.291696,25.230495 11.500037,31.436501 z\"\n" -" style=\"fill:#404040;\"/>\n" -" </a>\n" -" </g>\n" -" </svg>\n" -"</svg>\n" -; +static int DOT_NUM_THREADS; // will be initialized in initDot //-------------------------------------------------------------------- -/*! mapping from protection levels to color names */ -static const char *normalEdgeColorMap[] = -{ - "midnightblue", // Public - "darkgreen", // Protected - "firebrick4", // Private - "darkorchid3", // "use" relation - "grey75", // Undocumented - "orange", // template relation - "orange" // type constraint -}; - -static const char *normalArrowStyleMap[] = -{ - "empty", // Public - "empty", // Protected - "empty", // Private - "open", // "use" relation - 0, // Undocumented - 0 // template relation -}; - -static const char *normalEdgeStyleMap[] = -{ - "solid", // inheritance - "dashed" // usage -}; - -static const char *umlEdgeColorMap[] = -{ - "midnightblue", // Public - "darkgreen", // Protected - "firebrick4", // Private - "grey25", // "use" relation - "grey75", // Undocumented - "orange", // template relation - "orange" // type constraint -}; - -static const char *umlArrowStyleMap[] = -{ - "onormal", // Public - "onormal", // Protected - "onormal", // Private - "odiamond", // "use" relation - 0, // Undocumented - 0 // template relation -}; - -static const char *umlEdgeStyleMap[] = -{ - "solid", // inheritance - "solid" // usage -}; - -/** Helper struct holding the properties of a edge in a dot graph. */ -struct EdgeProperties -{ - const char * const *edgeColorMap; - const char * const *arrowStyleMap; - const char * const *edgeStyleMap; -}; - -static EdgeProperties normalEdgeProps = -{ - normalEdgeColorMap, normalArrowStyleMap, normalEdgeStyleMap -}; - -static EdgeProperties umlEdgeProps = +void initDot() { - umlEdgeColorMap, umlArrowStyleMap, umlEdgeStyleMap -}; - - -static QCString getDotFontName() -{ - static QCString dotFontName = Config_getString(DOT_FONTNAME); - if (dotFontName.isEmpty()) + DotGraph::DOT_FONTNAME = Config_getString(DOT_FONTNAME); + if (DotGraph::DOT_FONTNAME.isEmpty()) { - //dotFontName="FreeSans.ttf"; - dotFontName="Helvetica"; + DotGraph::DOT_FONTNAME="Helvetica"; } - return dotFontName; -} -static int getDotFontSize() -{ - static int dotFontSize = Config_getInt(DOT_FONTSIZE); - if (dotFontSize<4) dotFontSize=4; - return dotFontSize; -} + DotGraph::DOT_FONTSIZE = Config_getInt(DOT_FONTSIZE); + if (DotGraph::DOT_FONTSIZE<4) DotGraph::DOT_FONTSIZE=4; -static void writeGraphHeader(FTextStream &t,const QCString &title=QCString()) -{ - static bool interactiveSVG = Config_getBool(INTERACTIVE_SVG); - t << "digraph "; - if (title.isEmpty()) - { - t << "\"Dot Graph\""; - } - else - { - t << "\"" << convertToXML(title) << "\""; - } - t << endl << "{" << endl; - if (interactiveSVG) // insert a comment to force regeneration when this - // option is toggled - { - t << " // INTERACTIVE_SVG=YES\n"; - } - t << " // LATEX_PDF_SIZE\n"; // write placeholder for LaTeX PDF bounding box size repacement - if (Config_getBool(DOT_TRANSPARENT)) - { - t << " bgcolor=\"transparent\";" << endl; - } - t << " edge [fontname=\"" << FONTNAME << "\"," - "fontsize=\"" << FONTSIZE << "\"," - "labelfontname=\"" << FONTNAME << "\"," - "labelfontsize=\"" << FONTSIZE << "\"];\n"; - t << " node [fontname=\"" << FONTNAME << "\"," - "fontsize=\"" << FONTSIZE << "\",shape=record];\n"; -} + DOT_NUM_THREADS = Config_getInt(DOT_NUM_THREADS); + if (DOT_NUM_THREADS > 32) DOT_NUM_THREADS = 32; + if (DOT_NUM_THREADS <= 0) DOT_NUM_THREADS = QMAX(2,QThread::idealThreadCount()+1); -static void writeGraphFooter(FTextStream &t) -{ - t << "}" << endl; -} + // these are copied to be sure to be thread save + DotRunner::DOT_CLEANUP = Config_getBool(DOT_CLEANUP); + DotRunner::DOT_MULTI_TARGETS = Config_getBool(DOT_MULTI_TARGETS); + DotRunner::DOT_EXE.init(Config_getString(DOT_PATH) + "dot"); -static QCString replaceRef(const QCString &buf,const QCString relPath, - bool urlOnly,const QCString &context,const QCString &target=QCString()) -{ - // search for href="...", store ... part in link - QCString href = "href"; - //bool isXLink=FALSE; - int len = 6; - int indexS = buf.find("href=\""), indexE; - bool setTarget = FALSE; - if (indexS>5 && buf.find("xlink:href=\"")!=-1) // XLink href (for SVG) - { - indexS-=6; - len+=6; - href.prepend("xlink:"); - //isXLink=TRUE; - } - if (indexS>=0 && (indexE=buf.find('"',indexS+len))!=-1) - { - QCString link = buf.mid(indexS+len,indexE-indexS-len); - QCString result; - if (urlOnly) // for user defined dot graphs - { - if (link.left(5)=="\\ref " || link.left(5)=="@ref ") // \ref url - { - result=href+"=\""; - // fake ref node to resolve the url - DocRef *df = new DocRef( (DocNode*) 0, link.mid(5), context ); - result+=externalRef(relPath,df->ref(),TRUE); - if (!df->file().isEmpty()) - result += df->file().data() + Doxygen::htmlFileExtension; - if (!df->anchor().isEmpty()) - result += "#" + df->anchor(); - delete df; - result += "\""; - } - else - { - result = href+"=\"" + link + "\""; - } - } - else // ref$url (external ref via tag file), or $url (local ref) - { - int marker = link.find('$'); - if (marker!=-1) - { - QCString ref = link.left(marker); - QCString url = link.mid(marker+1); - if (!ref.isEmpty()) - { - result = externalLinkTarget(); - if (result != "") setTarget = TRUE; - result += externalRef(relPath,ref,FALSE); - } - result+= href+"=\""; - result+=externalRef(relPath,ref,TRUE); - result+= url + "\""; - } - else // should not happen, but handle properly anyway - { - result = href+"=\"" + link + "\""; - } - } - if (!target.isEmpty() && !setTarget) - { - result+=" target=\""+target+"\""; - } - QCString leftPart = buf.left(indexS); - QCString rightPart = buf.mid(indexE+1); - return leftPart + result + rightPart; - } - else - { - return buf; - } + DotGraph::IMG_EXT = getDotImageExtension(); } -/*! converts the rectangles in a client site image map into a stream - * \param t the stream to which the result is written. - * \param mapName the name of the map file. - * \param relPath the relative path to the root of the output directory - * (used in case CREATE_SUBDIRS is enabled). - * \param urlOnly if FALSE the url field in the map contains an external - * references followed by a $ and then the URL. - * \param context the context (file, class, or namespace) in which the - * map file was found - * \returns TRUE if successful. - */ -static bool convertMapFile(FTextStream &t,const char *mapName, - const QCString relPath, bool urlOnly=FALSE, - const QCString &context=QCString()) -{ - QFile f(mapName); - static QRegExp re("id=\"node[0-9]*\""); - if (!f.open(IO_ReadOnly)) - { - err("problems opening map file %s for inclusion in the docs!\n" - "If you installed Graphviz/dot after a previous failing run, \n" - "try deleting the output directory and rerun doxygen.\n",mapName); - return FALSE; - } - const int maxLineLen=10240; - while (!f.atEnd()) // foreach line - { - QCString buf(maxLineLen); - int numBytes = f.readLine(buf.rawData(),maxLineLen); - if (numBytes>0) - { - buf.resize(numBytes+1); - - if (buf.left(5)=="<area") - { - t << replaceRef(buf,relPath,urlOnly,context).replace(re,""); - } - } - } - return TRUE; -} static QCString g_dotFontPath; @@ -440,147 +102,6 @@ static void unsetDotFontPath() g_dotFontPath=""; } -static bool resetPDFSize(const int width,const int height, const char *base) -{ - QString tmpName = QString::fromUtf8(QCString(base)+".tmp"); - QString patchFile = QString::fromUtf8(QCString(base)+".dot"); - if (!QDir::current().rename(patchFile,tmpName)) - { - err("Failed to rename file %s to %s!\n",patchFile.data(),tmpName.data()); - return FALSE; - } - QFile fi(tmpName); - QFile fo(patchFile); - if (!fi.open(IO_ReadOnly)) - { - err("problem opening file %s for patching!\n",tmpName.data()); - QDir::current().rename(tmpName,patchFile); - return FALSE; - } - if (!fo.open(IO_WriteOnly)) - { - err("problem opening file %s for patching!\n",patchFile.data()); - QDir::current().rename(tmpName,patchFile); - fi.close(); - return FALSE; - } - FTextStream t(&fo); - const int maxLineLen=100*1024; - while (!fi.atEnd()) // foreach line - { - QCString line(maxLineLen); - int numBytes = fi.readLine(line.rawData(),maxLineLen); - if (numBytes<=0) - { - break; - } - line.resize(numBytes+1); - if (line.find("LATEX_PDF_SIZE") != -1) - { - double scale = (width > height ? width : height)/double(MAX_LATEX_GRAPH_INCH); - t << " size=\""<<width/scale << "," <<height/scale <<"\";\n"; - } - else - t << line; - } - fi.close(); - fo.close(); - // remove temporary file - QDir::current().remove(tmpName); - return TRUE; -} -static bool readBoundingBox(const char *fileName,int *width,int *height,bool isEps) -{ - QCString bb = isEps ? QCString("%%PageBoundingBox:") : QCString("/MediaBox ["); - QFile f(fileName); - if (!f.open(IO_ReadOnly|IO_Raw)) - { - //printf("readBoundingBox: could not open %s\n",fileName); - return FALSE; - } - const int maxLineLen=1024; - char buf[maxLineLen]; - while (!f.atEnd()) - { - int numBytes = f.readLine(buf,maxLineLen-1); // read line - if (numBytes>0) - { - buf[numBytes]='\0'; - const char *p = strstr(buf,bb); - if (p) // found PageBoundingBox or /MediaBox string - { - int x,y; - if (sscanf(p+bb.length(),"%d %d %d %d",&x,&y,width,height)!=4) - { - //printf("readBoundingBox sscanf fail\n"); - return FALSE; - } - return TRUE; - } - } - else // read error! - { - //printf("Read error %d!\n",numBytes); - return FALSE; - } - } - err("Failed to extract bounding box from generated diagram file %s\n",fileName); - return FALSE; -} - -static bool writeVecGfxFigure(FTextStream &out,const QCString &baseName, - const QCString &figureName) -{ - int width=400,height=550; - static bool usePdfLatex = Config_getBool(USE_PDFLATEX); - if (usePdfLatex) - { - if (!readBoundingBox(figureName+".pdf",&width,&height,FALSE)) - { - //printf("writeVecGfxFigure()=0\n"); - return FALSE; - } - } - else - { - if (!readBoundingBox(figureName+".eps",&width,&height,TRUE)) - { - //printf("writeVecGfxFigure()=0\n"); - return FALSE; - } - } - //printf("Got PDF/EPS size %d,%d\n",width,height); - int maxWidth = 350; /* approx. page width in points, excl. margins */ - int maxHeight = 550; /* approx. page height in points, excl. margins */ - out << "\\nopagebreak\n" - "\\begin{figure}[H]\n" - "\\begin{center}\n" - "\\leavevmode\n"; - if (width>maxWidth || height>maxHeight) // figure too big for page - { - // c*width/maxWidth > c*height/maxHeight, where c=maxWidth*maxHeight>0 - if (width*maxHeight>height*maxWidth) - { - out << "\\includegraphics[width=" << maxWidth << "pt]"; - } - else - { - out << "\\includegraphics[height=" << maxHeight << "pt]"; - } - } - else - { - out << "\\includegraphics[width=" << width << "pt]"; - } - - out << "{" << baseName << "}\n" - "\\end{center}\n" - "\\end{figure}\n"; - - //printf("writeVecGfxFigure()=1\n"); - return TRUE; -} - // extract size from a dot generated SVG file static bool readSVGSize(const QCString &fileName,int *width,int *height) { @@ -628,8 +149,8 @@ static void writeSVGNotSupported(FTextStream &out) // check if a reference to a SVG figure can be written and does so if possible. // return FALSE if not possible (for instance because the SVG file is not yet generated). -static bool writeSVGFigureLink(FTextStream &out,const QCString &relPath, - const QCString &baseName,const QCString &absImgName) +bool writeSVGFigureLink(FTextStream &out,const QCString &relPath, + const QCString &baseName,const QCString &absImgName) { int width=600,height=600; if (!readSVGSize(absImgName,&width,&height)) @@ -670,593 +191,6 @@ static bool writeSVGFigureLink(FTextStream &out,const QCString &relPath, return TRUE; } -// since dot silently reproduces the input file when it does not -// support the PNG format, we need to check the result. -static void checkDotResult(const char *imgExt, const char *imgName) -{ - if (qstrcmp(imgExt,"png")==0) - { - FILE *f = portable_fopen(imgName,"rb"); - if (f) - { - char data[4]; - if (fread(data,1,4,f)==4) - { - if (!(data[1]=='P' && data[2]=='N' && data[3]=='G')) - { - err("Image `%s' produced by dot is not a valid PNG!\n" - "You should either select a different format " - "(DOT_IMAGE_FORMAT in the config file) or install a more " - "recent version of graphviz (1.7+)\n",imgName - ); - } - } - else - { - err("Could not read image `%s' generated by dot!\n",imgName); - } - fclose(f); - } - else - { - err("Could not open image `%s' generated by dot!\n",imgName); - } - } -} - -static bool insertMapFile(FTextStream &out,const QCString &mapFile, - const QCString &relPath,const QCString &mapLabel) -{ - QFileInfo fi(mapFile); - if (fi.exists() && fi.size()>0) // reuse existing map file - { - QGString tmpstr; - FTextStream tmpout(&tmpstr); - convertMapFile(tmpout,mapFile,relPath); - if (!tmpstr.isEmpty()) - { - out << "<map name=\"" << mapLabel << "\" id=\"" << mapLabel << "\">" << endl; - out << tmpstr; - out << "</map>" << endl; - } - return TRUE; - } - return FALSE; // no map file yet, need to generate it -} - -static void removeDotGraph(const QCString &dotName) -{ - static bool dotCleanUp = Config_getBool(DOT_CLEANUP); - if (dotCleanUp) - { - QDir d; - d.remove(dotName); - } -} - - - -/*! Checks if a file "baseName".md5 exists. If so the contents - * are compared with \a md5. If equal FALSE is returned. If the .md5 - * file does not exist or its contents are not equal to \a md5, - * a new .md5 is generated with the \a md5 string as contents. - */ -static bool checkAndUpdateMd5Signature(const QCString &baseName, - const QCString &md5) -{ - QFile f(baseName+".md5"); - if (f.open(IO_ReadOnly)) - { - // read checksum - QCString md5stored(33); - int bytesRead=f.readBlock(md5stored.rawData(),32); - md5stored[32]='\0'; - // compare checksum - if (bytesRead==32 && md5==md5stored) - { - // bail out if equal - return FALSE; - } - } - f.close(); - // create checksum file - if (f.open(IO_WriteOnly)) - { - f.writeBlock(md5.data(),32); - f.close(); - } - return TRUE; -} - -static bool checkDeliverables(const QCString &file1, - const QCString &file2=QCString()) -{ - bool file1Ok = TRUE; - bool file2Ok = TRUE; - if (!file1.isEmpty()) - { - QFileInfo fi(file1); - file1Ok = (fi.exists() && fi.size()>0); - } - if (!file2.isEmpty()) - { - QFileInfo fi(file2); - file2Ok = (fi.exists() && fi.size()>0); - } - return file1Ok && file2Ok; -} - -//-------------------------------------------------------------------- - -inline int DotNode::findParent( DotNode *n ) -{ - if ( !m_parents ) return -1; - return m_parents->find(n); -} - -//-------------------------------------------------------------------- - -int DotNodeList::compareValues(const DotNode *n1,const DotNode *n2) const -{ - return qstricmp(n1->m_label,n2->m_label); -} - -//-------------------------------------------------------------------- - -DotRunner::DotRunner(const QCString &file,const QCString &path, - bool checkResult,const QCString &imageName) - : m_dotExe(Config_getString(DOT_PATH)+"dot"), - m_file(file), m_path(path), - m_checkResult(checkResult), m_imageName(imageName), - m_imgExt(getDotImageExtension()) -{ - static bool dotCleanUp = Config_getBool(DOT_CLEANUP); - static bool dotMultiTargets = Config_getBool(DOT_MULTI_TARGETS); - m_cleanUp = dotCleanUp; - m_multiTargets = dotMultiTargets; - m_jobs.setAutoDelete(TRUE); -} - -void DotRunner::addJob(const char *format,const char *output, const char *base) -{ - QCString args = QCString("-T")+format+" -o \""+output+"\""; - m_jobs.append(new DotConstString(args, base)); -} - -void DotRunner::addPostProcessing(const char *cmd,const char *args) -{ - m_postCmd.set(cmd); - m_postArgs.set(args); -} - -bool DotRunner::run() -{ - int exitCode=0; - int width=0,height=0; - - QCString dotArgs; - QListIterator<DotConstString> li(m_jobs); - DotConstString *s; - if (m_multiTargets) - { - dotArgs=QCString("\"")+m_file.data()+"\""; - for (li.toFirst();(s=li.current());++li) - { - dotArgs+=' '; - dotArgs+=s->data(); - } - if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; - dotArgs=QCString("\"")+m_file.data()+"\""; - bool redo = FALSE; - for (li.toFirst();(s=li.current());++li) - { - if (s->pdfData()) - { - if (!readBoundingBox(QCString(s->pdfData())+".pdf",&width,&height,FALSE)) goto error; - if ((width > MAX_LATEX_GRAPH_SIZE) || (height > MAX_LATEX_GRAPH_SIZE)) - { - if (!resetPDFSize(width,height,s->pdfData())) goto error; - dotArgs+=' '; - dotArgs+=s->data(); - redo = TRUE; - } - } - } - if (redo) - { - if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; - } - } - else - { - for (li.toFirst();(s=li.current());++li) - { - dotArgs=QCString("\"")+m_file.data()+"\" "+s->data(); - if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; - if (s->pdfData()) - { - if (!readBoundingBox(QCString(s->pdfData())+".pdf",&width,&height,FALSE)) goto error; - if ((width > MAX_LATEX_GRAPH_SIZE) || (height > MAX_LATEX_GRAPH_SIZE)) - { - if (!resetPDFSize(width,height,s->pdfData())) goto error; - if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error; - } - } - } - } - if (!m_postCmd.isEmpty() && portable_system(m_postCmd.data(),m_postArgs.data())!=0) - { - err("Problems running '%s' as a post-processing step for dot output\n",m_postCmd.data()); - return FALSE; - } - if (m_checkResult) - { - checkDotResult(m_imgExt.data(),m_imageName.data()); - } - if (m_cleanUp) - { - //printf("removing dot file %s\n",m_file.data()); - //QDir(path).remove(file); - m_cleanupItem.file.set(m_file.data()); - m_cleanupItem.path.set(m_path.data()); - } - return TRUE; -error: - err("Problems running dot: exit code=%d, command='%s', arguments='%s'\n", - exitCode,m_dotExe.data(),dotArgs.data()); - return FALSE; -} - -//-------------------------------------------------------------------- - -DotFilePatcher::DotFilePatcher(const char *patchFile) - : m_patchFile(patchFile) -{ - m_maps.setAutoDelete(TRUE); -} - -QCString DotFilePatcher::file() const -{ - return m_patchFile; -} - -int DotFilePatcher::addMap(const QCString &mapFile,const QCString &relPath, - bool urlOnly,const QCString &context,const QCString &label) -{ - int id = m_maps.count(); - Map *map = new Map; - map->mapFile = mapFile; - map->relPath = relPath; - map->urlOnly = urlOnly; - map->context = context; - map->label = label; - map->zoomable = FALSE; - map->graphId = -1; - m_maps.append(map); - return id; -} - -int DotFilePatcher::addFigure(const QCString &baseName, - const QCString &figureName,bool heightCheck) -{ - int id = m_maps.count(); - Map *map = new Map; - map->mapFile = figureName; - map->urlOnly = heightCheck; - map->label = baseName; - map->zoomable = FALSE; - map->graphId = -1; - m_maps.append(map); - return id; -} - -int DotFilePatcher::addSVGConversion(const QCString &relPath,bool urlOnly, - const QCString &context,bool zoomable, - int graphId) -{ - int id = m_maps.count(); - Map *map = new Map; - map->relPath = relPath; - map->urlOnly = urlOnly; - map->context = context; - map->zoomable = zoomable; - map->graphId = graphId; - m_maps.append(map); - return id; -} - -int DotFilePatcher::addSVGObject(const QCString &baseName, - const QCString &absImgName, - const QCString &relPath) -{ - int id = m_maps.count(); - Map *map = new Map; - map->mapFile = absImgName; - map->relPath = relPath; - map->label = baseName; - map->zoomable = FALSE; - map->graphId = -1; - m_maps.append(map); - return id; -} - -bool DotFilePatcher::run() -{ - //printf("DotFilePatcher::run(): %s\n",m_patchFile.data()); - static bool interactiveSVG = Config_getBool(INTERACTIVE_SVG); - bool isSVGFile = m_patchFile.right(4)==".svg"; - int graphId = -1; - QCString relPath; - if (isSVGFile) - { - Map *map = m_maps.at(0); // there is only one 'map' for a SVG file - interactiveSVG = interactiveSVG && map->zoomable; - graphId = map->graphId; - relPath = map->relPath; - //printf("DotFilePatcher::addSVGConversion: file=%s zoomable=%d\n", - // m_patchFile.data(),map->zoomable); - } - QString tmpName = QString::fromUtf8(m_patchFile+".tmp"); - QString patchFile = QString::fromUtf8(m_patchFile); - if (!QDir::current().rename(patchFile,tmpName)) - { - err("Failed to rename file %s to %s!\n",m_patchFile.data(),tmpName.data()); - return FALSE; - } - QFile fi(tmpName); - QFile fo(patchFile); - if (!fi.open(IO_ReadOnly)) - { - err("problem opening file %s for patching!\n",tmpName.data()); - QDir::current().rename(tmpName,patchFile); - return FALSE; - } - if (!fo.open(IO_WriteOnly)) - { - err("problem opening file %s for patching!\n",m_patchFile.data()); - QDir::current().rename(tmpName,patchFile); - return FALSE; - } - FTextStream t(&fo); - const int maxLineLen=100*1024; - int lineNr=1; - int width,height; - bool insideHeader=FALSE; - bool replacedHeader=FALSE; - bool foundSize=FALSE; - while (!fi.atEnd()) // foreach line - { - QCString line(maxLineLen); - int numBytes = fi.readLine(line.rawData(),maxLineLen); - if (numBytes<=0) - { - break; - } - line.resize(numBytes+1); - - //printf("line=[%s]\n",line.stripWhiteSpace().data()); - int i; - ASSERT(numBytes<maxLineLen); - if (isSVGFile) - { - if (interactiveSVG) - { - if (line.find("<svg")!=-1 && !replacedHeader) - { - int count; - count = sscanf(line.data(),"<svg width=\"%dpt\" height=\"%dpt\"",&width,&height); - //printf("width=%d height=%d\n",width,height); - foundSize = count==2 && (width>500 || height>450); - if (foundSize) insideHeader=TRUE; - } - else if (insideHeader && !replacedHeader && line.find("<title>")!=-1) - { - if (foundSize) - { - // insert special replacement header for interactive SVGs - t << "<!--zoomable " << height << " -->\n"; - t << svgZoomHeader; - t << "var viewWidth = " << width << ";\n"; - t << "var viewHeight = " << height << ";\n"; - if (graphId>=0) - { - t << "var sectionId = 'dynsection-" << graphId << "';\n"; - } - t << "</script>\n"; - t << "<script xlink:href=\"" << relPath << "svgpan.js\"/>\n"; - t << "<svg id=\"graph\" class=\"graph\">\n"; - t << "<g id=\"viewport\">\n"; - } - insideHeader=FALSE; - replacedHeader=TRUE; - } - } - if (!insideHeader || !foundSize) // copy SVG and replace refs, - // unless we are inside the header of the SVG. - // Then we replace it with another header. - { - Map *map = m_maps.at(0); // there is only one 'map' for a SVG file - t << replaceRef(line,map->relPath,map->urlOnly,map->context,"_top"); - } - } - else if ((i=line.find("<!-- SVG"))!=-1 || (i=line.find("[!-- SVG"))!=-1) - { - //printf("Found marker at %d\n",i); - int mapId=-1; - t << line.left(i); - int n = sscanf(line.data()+i+1,"!-- SVG %d",&mapId); - if (n==1 && mapId>=0 && mapId<(int)m_maps.count()) - { - int e = QMAX(line.find("--]"),line.find("-->")); - Map *map = m_maps.at(mapId); - //printf("DotFilePatcher::writeSVGFigure: file=%s zoomable=%d\n", - // m_patchFile.data(),map->zoomable); - if (!writeSVGFigureLink(t,map->relPath,map->label,map->mapFile)) - { - err("Problem extracting size from SVG file %s\n",map->mapFile.data()); - } - if (e!=-1) t << line.mid(e+3); - } - else // error invalid map id! - { - err("Found invalid SVG id in file %s!\n",m_patchFile.data()); - t << line.mid(i); - } - } - else if ((i=line.find("<!-- MAP"))!=-1) - { - int mapId=-1; - t << line.left(i); - int n = sscanf(line.data()+i,"<!-- MAP %d",&mapId); - if (n==1 && mapId>=0 && mapId<(int)m_maps.count()) - { - QGString result; - FTextStream tt(&result); - Map *map = m_maps.at(mapId); - //printf("patching MAP %d in file %s with contents of %s\n", - // mapId,m_patchFile.data(),map->mapFile.data()); - convertMapFile(tt,map->mapFile,map->relPath,map->urlOnly,map->context); - if (!result.isEmpty()) - { - t << "<map name=\"" << map->label << "\" id=\"" << map->label << "\">" << endl; - t << result; - t << "</map>" << endl; - } - } - else // error invalid map id! - { - err("Found invalid MAP id in file %s!\n",m_patchFile.data()); - t << line.mid(i); - } - } - else if ((i=line.find("% FIG"))!=-1) - { - int mapId=-1; - int n = sscanf(line.data()+i+2,"FIG %d",&mapId); - //printf("line='%s' n=%d\n",line.data()+i,n); - if (n==1 && mapId>=0 && mapId<(int)m_maps.count()) - { - Map *map = m_maps.at(mapId); - //printf("patching FIG %d in file %s with contents of %s\n", - // mapId,m_patchFile.data(),map->mapFile.data()); - if (!writeVecGfxFigure(t,map->label,map->mapFile)) - { - err("problem writing FIG %d figure!\n",mapId); - return FALSE; - } - } - else // error invalid map id! - { - err("Found invalid bounding FIG %d in file %s!\n",mapId,m_patchFile.data()); - t << line; - } - } - else - { - t << line; - } - lineNr++; - } - fi.close(); - if (isSVGFile && interactiveSVG && replacedHeader) - { - QCString orgName=m_patchFile.left(m_patchFile.length()-4)+"_org.svg"; - t << substitute(svgZoomFooter,"$orgname",stripPath(orgName)); - fo.close(); - // keep original SVG file so we can refer to it, we do need to replace - // dummy link by real ones - QFile fi(tmpName); - QFile fo(orgName); - if (!fi.open(IO_ReadOnly)) - { - err("problem opening file %s for reading!\n",tmpName.data()); - return FALSE; - } - if (!fo.open(IO_WriteOnly)) - { - err("problem opening file %s for writing!\n",orgName.data()); - return FALSE; - } - FTextStream t(&fo); - while (!fi.atEnd()) // foreach line - { - QCString line(maxLineLen); - int numBytes = fi.readLine(line.rawData(),maxLineLen); - if (numBytes<=0) - { - break; - } - line.resize(numBytes+1); - Map *map = m_maps.at(0); // there is only one 'map' for a SVG file - t << replaceRef(line,map->relPath,map->urlOnly,map->context,"_top"); - } - fi.close(); - fo.close(); - } - // remove temporary file - QDir::current().remove(tmpName); - return TRUE; -} - -//-------------------------------------------------------------------- - -void DotRunnerQueue::enqueue(DotRunner *runner) -{ - QMutexLocker locker(&m_mutex); - m_queue.enqueue(runner); - m_bufferNotEmpty.wakeAll(); -} - -DotRunner *DotRunnerQueue::dequeue() -{ - QMutexLocker locker(&m_mutex); - while (m_queue.isEmpty()) - { - // wait until something is added to the queue - m_bufferNotEmpty.wait(&m_mutex); - } - DotRunner *result = m_queue.dequeue(); - return result; -} - -uint DotRunnerQueue::count() const -{ - QMutexLocker locker(&m_mutex); - return m_queue.count(); -} - -//-------------------------------------------------------------------- - -DotWorkerThread::DotWorkerThread(DotRunnerQueue *queue) - : m_queue(queue) -{ - m_cleanupItems.setAutoDelete(TRUE); -} - -void DotWorkerThread::run() -{ - DotRunner *runner; - while ((runner=m_queue->dequeue())) - { - runner->run(); - const DotRunner::CleanupItem &cleanup = runner->cleanup(); - if (!cleanup.file.isEmpty()) - { - m_cleanupItems.append(new DotRunner::CleanupItem(cleanup)); - } - } -} - -void DotWorkerThread::cleanup() -{ - QListIterator<DotRunner::CleanupItem> it(m_cleanupItems); - DotRunner::CleanupItem *ci; - for (;(ci=it.current());++it) - { - QDir(ci->path.data()).remove(ci->file.data()); - } -} - //-------------------------------------------------------------------- DotManager *DotManager::m_theInstance = 0; @@ -1272,15 +206,13 @@ DotManager *DotManager::instance() DotManager::DotManager() : m_dotMaps(1009) { - m_dotRuns.setAutoDelete(TRUE); + m_runners.setAutoDelete(TRUE); m_dotMaps.setAutoDelete(TRUE); m_queue = new DotRunnerQueue; int i; - int numThreads = QMIN(32,Config_getInt(DOT_NUM_THREADS)); - if (numThreads!=1) + if (DOT_NUM_THREADS!=1) { - if (numThreads==0) numThreads = QMAX(2,QThread::idealThreadCount()+1); - for (i=0;i<numThreads;i++) + for (i=0;i<DOT_NUM_THREADS;i++) { DotWorkerThread *thread = new DotWorkerThread(m_queue); thread->start(); @@ -1302,11 +234,26 @@ DotManager::~DotManager() delete m_queue; } -void DotManager::addRun(DotRunner *run) +DotRunner* DotManager::createRunner(const QCString& absDotName, const QCString& md5Hash) { - m_dotRuns.append(run); + DotRunner * run = m_runners.find(absDotName); + if (run == 0) + { + run = new DotRunner(absDotName, md5Hash); + m_runners.insert(absDotName, run); + } + else + { + // we have a match + if (md5Hash != QCString(run->getMd5Hash().data())) + { + err("md5 hash does not match for two different runs of %s !\n", absDotName.data()); + } + } + return run; } + int DotManager::addMap(const QCString &file,const QCString &mapFile, const QCString &relPath,bool urlOnly,const QCString &context, const QCString &label) @@ -1359,7 +306,7 @@ int DotManager::addSVGObject(const QCString &file,const QCString &baseName, bool DotManager::run() { - uint numDotRuns = m_dotRuns.count(); + uint numDotRuns = m_runners.count(); uint numDotMaps = m_dotMaps.count(); if (numDotRuns+numDotMaps>1) { @@ -1373,7 +320,7 @@ bool DotManager::run() } } int i=1; - QListIterator<DotRunner> li(m_dotRuns); + QDictIterator<DotRunner> li(m_runners); bool setPath=FALSE; if (Config_getBool(GENERATE_HTML)) @@ -1441,11 +388,6 @@ bool DotManager::run() { m_workers.at(i)->wait(); } - // clean up dot files from main thread - for (i=0;i<(int)m_workers.count();i++) - { - m_workers.at(i)->cleanup(); - } } portable_sysTimerStop(); if (setPath) @@ -1484,2756 +426,59 @@ bool DotManager::run() //-------------------------------------------------------------------- - -/*! helper function that deletes all nodes in a connected graph, given - * one of the graph's nodes - */ -static void deleteNodes(DotNode *node,SDict<DotNode> *skipNodes=0) -{ - //printf("deleteNodes skipNodes=%p\n",skipNodes); - static DotNodeList deletedNodes; - deletedNodes.setAutoDelete(TRUE); - node->deleteNode(deletedNodes,skipNodes); // collect nodes to be deleted. - deletedNodes.clear(); // actually remove the nodes. -} - -DotNode::DotNode(int n,const char *lab,const char *tip, const char *url, - bool isRoot,ClassDef *cd) - : m_subgraphId(-1) - , m_number(n) - , m_label(lab) - , m_tooltip(tip) - , m_url(url) - , m_parents(0) - , m_children(0) - , m_edgeInfo(0) - , m_deleted(FALSE) - , m_written(FALSE) - , m_hasDoc(FALSE) - , m_isRoot(isRoot) - , m_classDef(cd) - , m_visible(FALSE) - , m_truncated(Unknown) - , m_distance(1000) - , m_renumbered(false) -{ -} - -DotNode::~DotNode() -{ - delete m_children; - delete m_parents; - delete m_edgeInfo; -} - -void DotNode::addChild(DotNode *n, - int edgeColor, - int edgeStyle, - const char *edgeLab, - const char *edgeURL, - int edgeLabCol - ) -{ - if (m_children==0) - { - m_children = new QList<DotNode>; - m_edgeInfo = new QList<EdgeInfo>; - m_edgeInfo->setAutoDelete(TRUE); - } - m_children->append(n); - EdgeInfo *ei = new EdgeInfo; - ei->m_color = edgeColor; - ei->m_style = edgeStyle; - ei->m_label = edgeLab; - ei->m_url = edgeURL; - if (edgeLabCol==-1) - ei->m_labColor=edgeColor; - else - ei->m_labColor=edgeLabCol; - m_edgeInfo->append(ei); -} - -void DotNode::addParent(DotNode *n) -{ - if (m_parents==0) - { - m_parents = new QList<DotNode>; - } - m_parents->append(n); -} - -void DotNode::removeChild(DotNode *n) -{ - if (m_children) m_children->remove(n); -} - -void DotNode::removeParent(DotNode *n) -{ - if (m_parents) m_parents->remove(n); -} - -void DotNode::deleteNode(DotNodeList &deletedList,SDict<DotNode> *skipNodes) -{ - if (m_deleted) return; // avoid recursive loops in case the graph has cycles - m_deleted=TRUE; - if (m_parents!=0) // delete all parent nodes of this node - { - QListIterator<DotNode> dnlip(*m_parents); - DotNode *pn; - for (dnlip.toFirst();(pn=dnlip.current());++dnlip) - { - //pn->removeChild(this); - pn->deleteNode(deletedList,skipNodes); - } - } - if (m_children!=0) // delete all child nodes of this node - { - QListIterator<DotNode> dnlic(*m_children); - DotNode *cn; - for (dnlic.toFirst();(cn=dnlic.current());++dnlic) - { - //cn->removeParent(this); - cn->deleteNode(deletedList,skipNodes); - } - } - // add this node to the list of deleted nodes. - //printf("skipNodes=%p find(%p)=%p\n",skipNodes,this,skipNodes ? skipNodes->find((int)this) : 0); - if (skipNodes==0 || skipNodes->find((char*)this)==0) - { - //printf("deleting\n"); - deletedList.append(this); - } -} - -void DotNode::setDistance(int distance) -{ - if (distance<m_distance) m_distance = distance; -} - -static QCString convertLabel(const QCString &l) -{ - QString bBefore("\\_/<({[: =-+@%#~?$"); // break before character set - QString bAfter(">]),:;|"); // break after character set - QString p(l); - if (p.isEmpty()) return QCString(); - QString result; - QChar c,pc=0; - uint idx = 0; - int len=p.length(); - int charsLeft=len; - int sinceLast=0; - int foldLen=17; // ideal text length - while (idx < p.length()) - { - c = p[idx++]; - QString replacement; - switch(c) - { - case '\\': replacement="\\\\"; break; - case '\n': replacement="\\n"; break; - case '<': replacement="\\<"; break; - case '>': replacement="\\>"; break; - case '|': replacement="\\|"; break; - case '{': replacement="\\{"; break; - case '}': replacement="\\}"; break; - case '"': replacement="\\\""; break; - default: replacement=c; break; - } - // Some heuristics to insert newlines to prevent too long - // boxes and at the same time prevent ugly breaks - if (c=='\n') - { - result+=replacement; - foldLen = (3*foldLen+sinceLast+2)/4; - sinceLast=1; - } - else if ((pc!=':' || c!=':') && charsLeft>foldLen/3 && sinceLast>foldLen && bBefore.contains(c)) - { - result+="\\l"; - result+=replacement; - foldLen = (foldLen+sinceLast+1)/2; - sinceLast=1; - } - else if (charsLeft>1+foldLen/4 && sinceLast>foldLen+foldLen/3 && - !isupper(c) && p[idx].category()==QChar::Letter_Uppercase) - { - result+=replacement; - result+="\\l"; - foldLen = (foldLen+sinceLast+1)/2; - sinceLast=0; - } - else if (charsLeft>foldLen/3 && sinceLast>foldLen && bAfter.contains(c) && (c!=':' || p[idx]!=':')) - { - result+=replacement; - result+="\\l"; - foldLen = (foldLen+sinceLast+1)/2; - sinceLast=0; - } - else - { - result+=replacement; - sinceLast++; - } - charsLeft--; - pc=c; - } - return result.utf8(); -} - -static QCString escapeTooltip(const QCString &tooltip) -{ - QCString result; - const char *p=tooltip.data(); - if (p==0) return result; - char c; - while ((c=*p++)) - { - switch(c) - { - case '"': result+="\\\""; break; - default: result+=c; break; - } - } - return result; -} - -static void writeBoxMemberList(FTextStream &t, - char prot,MemberList *ml,ClassDef *scope, - bool isStatic=FALSE,const QDict<void> *skipNames=0) -{ - (void)isStatic; - if (ml) - { - MemberListIterator mlia(*ml); - MemberDef *mma; - int totalCount=0; - for (mlia.toFirst();(mma = mlia.current());++mlia) - { - if (mma->getClassDef()==scope && - (skipNames==0 || skipNames->find(mma->name())==0)) - { - totalCount++; - } - } - - int count=0; - for (mlia.toFirst();(mma = mlia.current());++mlia) - { - if (mma->getClassDef() == scope && - (skipNames==0 || skipNames->find(mma->name())==0)) - { - static int limit = Config_getInt(UML_LIMIT_NUM_FIELDS); - if (limit>0 && (totalCount>limit*3/2 && count>=limit)) - { - t << theTranslator->trAndMore(QCString().sprintf("%d",totalCount-count)) << "\\l"; - break; - } - else - { - t << prot << " "; - t << convertLabel(mma->name()); - if (!mma->isObjCMethod() && - (mma->isFunction() || mma->isSlot() || mma->isSignal())) t << "()"; - t << "\\l"; - count++; - } - } - } - // write member groups within the memberlist - MemberGroupList *mgl = ml->getMemberGroupList(); - if (mgl) - { - MemberGroupListIterator mgli(*mgl); - MemberGroup *mg; - for (mgli.toFirst();(mg=mgli.current());++mgli) - { - if (mg->members()) - { - writeBoxMemberList(t,prot,mg->members(),scope,isStatic,skipNames); - } - } - } - } -} - -static QCString stripProtectionPrefix(const QCString &s) -{ - if (!s.isEmpty() && (s[0]=='-' || s[0]=='+' || s[0]=='~' || s[0]=='#')) - { - return s.mid(1); - } - else - { - return s; - } -} - -void DotNode::writeBox(FTextStream &t, - GraphType gt, - GraphOutputFormat /*format*/, - bool hasNonReachableChildren - ) -{ - const char *labCol = - m_url.isEmpty() ? "grey75" : // non link - ( - (hasNonReachableChildren) ? "red" : "black" - ); - t << " Node" << m_number << " [label=\""; - static bool umlLook = Config_getBool(UML_LOOK); - - if (m_classDef && umlLook && (gt==Inheritance || gt==Collaboration)) - { - // add names shown as relations to a dictionary, so we don't show - // them as attributes as well - QDict<void> arrowNames(17); - if (m_edgeInfo) - { - // for each edge - QListIterator<EdgeInfo> li(*m_edgeInfo); - EdgeInfo *ei; - for (li.toFirst();(ei=li.current());++li) - { - if (!ei->m_label.isEmpty()) // labels joined by \n - { - int li=ei->m_label.find('\n'); - int p=0; - QCString lab; - while ((li=ei->m_label.find('\n',p))!=-1) - { - lab = stripProtectionPrefix(ei->m_label.mid(p,li-p)); - arrowNames.insert(lab,(void*)0x8); - p=li+1; - } - lab = stripProtectionPrefix(ei->m_label.right(ei->m_label.length()-p)); - arrowNames.insert(lab,(void*)0x8); - } - } - } - - //printf("DotNode::writeBox for %s\n",m_classDef->name().data()); - static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); - t << "{" << convertLabel(m_label); - t << "\\n|"; - writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubAttribs),m_classDef,FALSE,&arrowNames); - writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubStaticAttribs),m_classDef,TRUE,&arrowNames); - writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_properties),m_classDef,FALSE,&arrowNames); - writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacAttribs),m_classDef,FALSE,&arrowNames); - writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacStaticAttribs),m_classDef,TRUE,&arrowNames); - writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proAttribs),m_classDef,FALSE,&arrowNames); - writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proStaticAttribs),m_classDef,TRUE,&arrowNames); - if (extractPrivate) - { - writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priAttribs),m_classDef,FALSE,&arrowNames); - writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priStaticAttribs),m_classDef,TRUE,&arrowNames); - } - t << "|"; - writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubMethods),m_classDef); - writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubStaticMethods),m_classDef,TRUE); - writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubSlots),m_classDef); - writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacMethods),m_classDef); - writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacStaticMethods),m_classDef,TRUE); - writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proMethods),m_classDef); - writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proStaticMethods),m_classDef,TRUE); - writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proSlots),m_classDef); - if (extractPrivate) - { - writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priMethods),m_classDef); - writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priStaticMethods),m_classDef,TRUE); - writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priSlots),m_classDef); - } - if (m_classDef->getLanguage()!=SrcLangExt_Fortran && - m_classDef->getMemberGroupSDict()) - { - MemberGroupSDict::Iterator mgdi(*m_classDef->getMemberGroupSDict()); - MemberGroup *mg; - for (mgdi.toFirst();(mg=mgdi.current());++mgdi) - { - if (mg->members()) - { - writeBoxMemberList(t,'*',mg->members(),m_classDef,FALSE,&arrowNames); - } - } - } - t << "}"; - } - else // standard look - { - t << convertLabel(m_label); - } - t << "\",height=0.2,width=0.4"; - if (m_isRoot) - { - t << ",color=\"black\", fillcolor=\"grey75\", style=\"filled\", fontcolor=\"black\""; - } - else - { - static bool dotTransparent = Config_getBool(DOT_TRANSPARENT); - if (!dotTransparent) - { - t << ",color=\"" << labCol << "\", fillcolor=\""; - t << "white"; - t << "\", style=\"filled\""; - } - else - { - t << ",color=\"" << labCol << "\""; - } - if (!m_url.isEmpty()) - { - int anchorPos = m_url.findRev('#'); - if (anchorPos==-1) - { - t << ",URL=\"" << m_url << Doxygen::htmlFileExtension << "\""; - } - else - { - t << ",URL=\"" << m_url.left(anchorPos) << Doxygen::htmlFileExtension - << m_url.right(m_url.length()-anchorPos) << "\""; - } - } - } - if (!m_tooltip.isEmpty()) - { - t << ",tooltip=\"" << escapeTooltip(m_tooltip) << "\""; - } - else - { - t << ",tooltip=\" \""; // space in tooltip is required otherwise still something like 'Node0' is used - } - t << "];" << endl; -} - -void DotNode::writeArrow(FTextStream &t, - GraphType gt, - GraphOutputFormat format, - DotNode *cn, - EdgeInfo *ei, - bool topDown, - bool pointBack - ) -{ - t << " Node"; - if (topDown) - t << cn->number(); - else - t << m_number; - t << " -> Node"; - if (topDown) - t << m_number; - else - t << cn->number(); - t << " ["; - - static bool umlLook = Config_getBool(UML_LOOK); - const EdgeProperties *eProps = umlLook ? ¨EdgeProps : &normalEdgeProps; - QCString aStyle = eProps->arrowStyleMap[ei->m_color]; - bool umlUseArrow = aStyle=="odiamond"; - - if (pointBack && !umlUseArrow) t << "dir=\"back\","; - t << "color=\"" << eProps->edgeColorMap[ei->m_color] - << "\",fontsize=\"" << FONTSIZE << "\","; - t << "style=\"" << eProps->edgeStyleMap[ei->m_style] << "\""; - if (!ei->m_label.isEmpty()) - { - t << ",label=\" " << convertLabel(ei->m_label) << "\" "; - } - if (umlLook && - eProps->arrowStyleMap[ei->m_color] && - (gt==Inheritance || gt==Collaboration) - ) - { - bool rev = pointBack; - if (umlUseArrow) rev=!rev; // UML use relates has arrow on the start side - if (rev) - t << ",arrowtail=\"" << eProps->arrowStyleMap[ei->m_color] << "\""; - else - t << ",arrowhead=\"" << eProps->arrowStyleMap[ei->m_color] << "\""; - } - - if (format==GOF_BITMAP) t << ",fontname=\"" << FONTNAME << "\""; - t << "];" << endl; -} - -void DotNode::write(FTextStream &t, - GraphType gt, - GraphOutputFormat format, - bool topDown, - bool toChildren, - bool backArrows - ) -{ - //printf("DotNode::write(%d) name=%s this=%p written=%d visible=%d\n",m_distance,m_label.data(),this,m_written,m_visible); - if (m_written) return; // node already written to the output - if (!m_visible) return; // node is not visible - writeBox(t,gt,format,m_truncated==Truncated); - m_written=TRUE; - QList<DotNode> *nl = toChildren ? m_children : m_parents; - if (nl) - { - if (toChildren) - { - QListIterator<DotNode> dnli1(*nl); - QListIterator<EdgeInfo> dnli2(*m_edgeInfo); - DotNode *cn; - for (dnli1.toFirst();(cn=dnli1.current());++dnli1,++dnli2) - { - if (cn->isVisible()) - { - //printf("write arrow %s%s%s\n",label().data(),backArrows?"<-":"->",cn->label().data()); - writeArrow(t,gt,format,cn,dnli2.current(),topDown,backArrows); - } - cn->write(t,gt,format,topDown,toChildren,backArrows); - } - } - else // render parents - { - QListIterator<DotNode> dnli(*nl); - DotNode *pn; - for (dnli.toFirst();(pn=dnli.current());++dnli) - { - if (pn->isVisible()) - { - //printf("write arrow %s%s%s\n",label().data(),backArrows?"<-":"->",pn->label().data()); - writeArrow(t, - gt, - format, - pn, - pn->m_edgeInfo->at(pn->m_children->findRef(this)), - FALSE, - backArrows - ); - } - pn->write(t,gt,format,TRUE,FALSE,backArrows); - } - } - } - //printf("end DotNode::write(%d) name=%s\n",distance,m_label.data()); -} - -void DotNode::writeXML(FTextStream &t,bool isClassGraph) -{ - t << " <node id=\"" << m_number << "\">" << endl; - t << " <label>" << convertToXML(m_label) << "</label>" << endl; - if (!m_url.isEmpty()) - { - QCString url(m_url); - const char *refPtr = url.data(); - char *urlPtr = strchr(url.rawData(),'$'); - if (urlPtr) - { - *urlPtr++='\0'; - t << " <link refid=\"" << convertToXML(urlPtr) << "\""; - if (*refPtr!='\0') - { - t << " external=\"" << convertToXML(refPtr) << "\""; - } - t << "/>" << endl; - } - } - if (m_children) - { - QListIterator<DotNode> nli(*m_children); - QListIterator<EdgeInfo> eli(*m_edgeInfo); - DotNode *childNode; - EdgeInfo *edgeInfo; - for (;(childNode=nli.current());++nli,++eli) - { - edgeInfo=eli.current(); - t << " <childnode refid=\"" << childNode->m_number << "\" relation=\""; - if (isClassGraph) - { - switch(edgeInfo->m_color) - { - case EdgeInfo::Blue: t << "public-inheritance"; break; - case EdgeInfo::Green: t << "protected-inheritance"; break; - case EdgeInfo::Red: t << "private-inheritance"; break; - case EdgeInfo::Purple: t << "usage"; break; - case EdgeInfo::Orange: t << "template-instance"; break; - case EdgeInfo::Orange2: t << "type-constraint"; break; - case EdgeInfo::Grey: ASSERT(0); break; - } - } - else // include graph - { - t << "include"; - } - t << "\">" << endl; - if (!edgeInfo->m_label.isEmpty()) - { - int p=0; - int ni; - while ((ni=edgeInfo->m_label.find('\n',p))!=-1) - { - t << " <edgelabel>" - << convertToXML(edgeInfo->m_label.mid(p,ni-p)) - << "</edgelabel>" << endl; - p=ni+1; - } - t << " <edgelabel>" - << convertToXML(edgeInfo->m_label.right(edgeInfo->m_label.length()-p)) - << "</edgelabel>" << endl; - } - t << " </childnode>" << endl; - } - } - t << " </node>" << endl; -} - -void DotNode::writeDocbook(FTextStream &t,bool isClassGraph) -{ - t << " <node id=\"" << m_number << "\">" << endl; - t << " <label>" << convertToXML(m_label) << "</label>" << endl; - if (!m_url.isEmpty()) - { - QCString url(m_url); - const char *refPtr = url.data(); - char *urlPtr = strchr(url.rawData(),'$'); - if (urlPtr) - { - *urlPtr++='\0'; - t << " <link refid=\"" << convertToXML(urlPtr) << "\""; - if (*refPtr!='\0') - { - t << " external=\"" << convertToXML(refPtr) << "\""; - } - t << "/>" << endl; - } - } - if (m_children) - { - QListIterator<DotNode> nli(*m_children); - QListIterator<EdgeInfo> eli(*m_edgeInfo); - DotNode *childNode; - EdgeInfo *edgeInfo; - for (;(childNode=nli.current());++nli,++eli) - { - edgeInfo=eli.current(); - t << " <childnode refid=\"" << childNode->m_number << "\" relation=\""; - if (isClassGraph) - { - switch(edgeInfo->m_color) - { - case EdgeInfo::Blue: t << "public-inheritance"; break; - case EdgeInfo::Green: t << "protected-inheritance"; break; - case EdgeInfo::Red: t << "private-inheritance"; break; - case EdgeInfo::Purple: t << "usage"; break; - case EdgeInfo::Orange: t << "template-instance"; break; - case EdgeInfo::Orange2: t << "type-constraint"; break; - case EdgeInfo::Grey: ASSERT(0); break; - } - } - else // include graph - { - t << "include"; - } - t << "\">" << endl; - if (!edgeInfo->m_label.isEmpty()) - { - int p=0; - int ni; - while ((ni=edgeInfo->m_label.find('\n',p))!=-1) - { - t << " <edgelabel>" - << convertToXML(edgeInfo->m_label.mid(p,ni-p)) - << "</edgelabel>" << endl; - p=ni+1; - } - t << " <edgelabel>" - << convertToXML(edgeInfo->m_label.right(edgeInfo->m_label.length()-p)) - << "</edgelabel>" << endl; - } - t << " </childnode>" << endl; - } - } - t << " </node>" << endl; -} - - -void DotNode::writeDEF(FTextStream &t) -{ - const char* nodePrefix = " node-"; - - t << " node = {" << endl; - t << nodePrefix << "id = " << m_number << ';' << endl; - t << nodePrefix << "label = '" << m_label << "';" << endl; - - if (!m_url.isEmpty()) - { - QCString url(m_url); - const char *refPtr = url.data(); - char *urlPtr = strchr(url.rawData(),'$'); - if (urlPtr) - { - *urlPtr++='\0'; - t << nodePrefix << "link = {" << endl << " " - << nodePrefix << "link-id = '" << urlPtr << "';" << endl; - - if (*refPtr!='\0') - { - t << " " << nodePrefix << "link-external = '" - << refPtr << "';" << endl; - } - t << " };" << endl; - } - } - if (m_children) - { - QListIterator<DotNode> nli(*m_children); - QListIterator<EdgeInfo> eli(*m_edgeInfo); - DotNode *childNode; - EdgeInfo *edgeInfo; - for (;(childNode=nli.current());++nli,++eli) - { - edgeInfo=eli.current(); - t << " node-child = {" << endl; - t << " child-id = '" << childNode->m_number << "';" << endl; - t << " relation = "; - - switch(edgeInfo->m_color) - { - case EdgeInfo::Blue: t << "public-inheritance"; break; - case EdgeInfo::Green: t << "protected-inheritance"; break; - case EdgeInfo::Red: t << "private-inheritance"; break; - case EdgeInfo::Purple: t << "usage"; break; - case EdgeInfo::Orange: t << "template-instance"; break; - case EdgeInfo::Orange2: t << "type-constraint"; break; - case EdgeInfo::Grey: ASSERT(0); break; - } - t << ';' << endl; - - if (!edgeInfo->m_label.isEmpty()) - { - t << " edgelabel = <<_EnD_oF_dEf_TeXt_" << endl - << edgeInfo->m_label << endl - << "_EnD_oF_dEf_TeXt_;" << endl; - } - t << " }; /* node-child */" << endl; - } /* for (;childNode...) */ - } - t << " }; /* node */" << endl; -} - - -void DotNode::clearWriteFlag() -{ - m_written=FALSE; - if (m_parents!=0) - { - QListIterator<DotNode> dnlip(*m_parents); - DotNode *pn; - for (dnlip.toFirst();(pn=dnlip.current());++dnlip) - { - if (pn->m_written) - { - pn->clearWriteFlag(); - } - } - } - if (m_children!=0) - { - QListIterator<DotNode> dnlic(*m_children); - DotNode *cn; - for (dnlic.toFirst();(cn=dnlic.current());++dnlic) - { - if (cn->m_written) - { - cn->clearWriteFlag(); - } - } - } -} - -void DotNode::colorConnectedNodes(int curColor) -{ - if (m_children) - { - QListIterator<DotNode> dnlic(*m_children); - DotNode *cn; - for (dnlic.toFirst();(cn=dnlic.current());++dnlic) - { - if (cn->m_subgraphId==-1) // uncolored child node - { - cn->m_subgraphId=curColor; - cn->markAsVisible(); - cn->colorConnectedNodes(curColor); - //printf("coloring node %s (%p): %d\n",cn->m_label.data(),cn,cn->m_subgraphId); - } - } - } - - if (m_parents) - { - QListIterator<DotNode> dnlip(*m_parents); - DotNode *pn; - for (dnlip.toFirst();(pn=dnlip.current());++dnlip) - { - if (pn->m_subgraphId==-1) // uncolored parent node - { - pn->m_subgraphId=curColor; - pn->markAsVisible(); - pn->colorConnectedNodes(curColor); - //printf("coloring node %s (%p): %d\n",pn->m_label.data(),pn,pn->m_subgraphId); - } - } - } -} - -void DotNode::renumberNodes(int &number) -{ - m_number = number++; - if (m_children) - { - QListIterator<DotNode> dnlic(*m_children); - DotNode *cn; - for (dnlic.toFirst();(cn=dnlic.current());++dnlic) - { - if (!cn->m_renumbered) - { - cn->m_renumbered = true; - cn->renumberNodes(number); - } - } - } -} - -const DotNode *DotNode::findDocNode() const -{ - if (!m_url.isEmpty()) return this; - //printf("findDocNode(): `%s'\n",m_label.data()); - if (m_parents) - { - QListIterator<DotNode> dnli(*m_parents); - DotNode *pn; - for (dnli.toFirst();(pn=dnli.current());++dnli) - { - if (!pn->m_hasDoc) - { - pn->m_hasDoc=TRUE; - const DotNode *dn = pn->findDocNode(); - if (dn) return dn; - } - } - } - if (m_children) - { - QListIterator<DotNode> dnli(*m_children); - DotNode *cn; - for (dnli.toFirst();(cn=dnli.current());++dnli) - { - if (!cn->m_hasDoc) - { - cn->m_hasDoc=TRUE; - const DotNode *dn = cn->findDocNode(); - if (dn) return dn; - } - } - } - return 0; -} - -//-------------------------------------------------------------------- - -void DotGfxHierarchyTable::createGraph(DotNode *n,FTextStream &out, - const char *path,const char *fileName,int id) const -{ - QDir d(path); - QCString baseName; - QCString imgExt = getDotImageExtension(); - QCString imgFmt = Config_getEnum(DOT_IMAGE_FORMAT); - if (m_prefix.isEmpty()) - baseName.sprintf("inherit_graph_%d",id); - else - baseName.sprintf("%sinherit_graph_%d",m_prefix.data(),id); - QCString imgName = baseName+"."+ imgExt; - QCString mapName = baseName+".map"; - QCString absImgName = QCString(d.absPath().data())+"/"+imgName; - QCString absMapName = QCString(d.absPath().data())+"/"+mapName; - QCString absBaseName = QCString(d.absPath().data())+"/"+baseName; - QListIterator<DotNode> dnli2(*m_rootNodes); - DotNode *node; - - // compute md5 checksum of the graph were are about to generate - QGString theGraph; - FTextStream md5stream(&theGraph); - writeGraphHeader(md5stream,theTranslator->trGraphicalHierarchy()); - md5stream << " rankdir=\"LR\";" << endl; - for (dnli2.toFirst();(node=dnli2.current());++dnli2) - { - if (node->m_subgraphId==n->m_subgraphId) - { - node->clearWriteFlag(); - } - } - for (dnli2.toFirst();(node=dnli2.current());++dnli2) - { - if (node->m_subgraphId==n->m_subgraphId) - { - node->write(md5stream,DotNode::Hierarchy,GOF_BITMAP,FALSE,TRUE,TRUE); - } - } - writeGraphFooter(md5stream); - uchar md5_sig[16]; - QCString sigStr(33); - MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig); - MD5SigToString(md5_sig,sigStr.rawData(),33); - bool regenerate=FALSE; - if (checkAndUpdateMd5Signature(absBaseName,sigStr) || - !checkDeliverables(absImgName,absMapName)) - { - regenerate=TRUE; - // image was new or has changed - QCString dotName=absBaseName+".dot"; - QFile f(dotName); - if (!f.open(IO_WriteOnly)) return; - FTextStream t(&f); - t << theGraph; - f.close(); - - DotRunner *dotRun = new DotRunner(dotName,d.absPath().data(),TRUE,absImgName); - dotRun->addJob(imgFmt,absImgName); - dotRun->addJob(MAP_CMD,absMapName); - DotManager::instance()->addRun(dotRun); - } - else - { - removeDotGraph(absBaseName+".dot"); - } - Doxygen::indexList->addImageFile(imgName); - // write image and map in a table row - QCString mapLabel = escapeCharsInString(n->m_label,FALSE); - if (imgExt=="svg") // vector graphics - { - if (regenerate || !writeSVGFigureLink(out,QCString(),baseName,absImgName)) - { - if (regenerate) - { - DotManager::instance()->addSVGConversion(absImgName,QCString(), - FALSE,QCString(),FALSE,0); - } - int mapId = DotManager::instance()->addSVGObject(fileName,baseName, - absImgName,QCString()); - out << "<!-- SVG " << mapId << " -->" << endl; - } - } - else // normal bitmap - { - out << "<img src=\"" << imgName << "\" border=\"0\" alt=\"\" usemap=\"#" - << mapLabel << "\"/>" << endl; - - if (regenerate || !insertMapFile(out,absMapName,QCString(),mapLabel)) - { - int mapId = DotManager::instance()->addMap(fileName,absMapName,QCString(), - FALSE,QCString(),mapLabel); - out << "<!-- MAP " << mapId << " -->" << endl; - } - } -} - -void DotGfxHierarchyTable::writeGraph(FTextStream &out, - const char *path,const char *fileName) const -{ - //printf("DotGfxHierarchyTable::writeGraph(%s)\n",name); - //printf("m_rootNodes=%p count=%d\n",m_rootNodes,m_rootNodes->count()); - - if (m_rootSubgraphs->count()==0) return; - - QDir d(path); - // store the original directory - if (!d.exists()) - { - err("Output dir %s does not exist!\n",path); exit(1); - } - - // put each connected subgraph of the hierarchy in a row of the HTML output - out << "<table border=\"0\" cellspacing=\"10\" cellpadding=\"0\">" << endl; - - QListIterator<DotNode> dnli(*m_rootSubgraphs); - DotNode *n; - int count=0; - for (dnli.toFirst();(n=dnli.current());++dnli) - { - out << "<tr><td>"; - createGraph(n,out,path,fileName,count++); - out << "</td></tr>" << endl; - } - out << "</table>" << endl; -} - -void DotGfxHierarchyTable::addHierarchy(DotNode *n,ClassDef *cd,bool hideSuper) -{ - //printf("addHierarchy `%s' baseClasses=%d\n",cd->name().data(),cd->baseClasses()->count()); - if (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())) - { - DotNode *bn; - //printf(" Node `%s' Found visible class=`%s'\n",n->m_label.data(), - // bClass->name().data()); - if ((bn=m_usedNodes->find(bClass->name()))) // node already present - { - if (n->m_children==0 || n->m_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->m_label.data(), - // bn->m_label.data(), - // bn->m_children ? bn->m_children->count() : 0, - // bn->m_parents ? bn->m_parents->count() : 0 - // ); - } - //else - //{ - // printf(" Class already has an arrow!\n"); - //} - } - else - { - QCString tmp_url=""; - if (bClass->isLinkable() && !bClass->isHidden()) - { - tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase(); - if (!bClass->anchor().isEmpty()) - { - tmp_url+="#"+bClass->anchor(); - } - } - QCString tooltip = bClass->briefDescriptionAsTooltip(); - bn = new DotNode(m_curNodeNumber++, - 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->m_label.data(), - // bn->m_label.data(), - // bn->m_children ? bn->m_children->count() : 0, - // bn->m_parents ? bn->m_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->visited && !hideSuper && bClass->subClasses()) - { - bool wasVisited=bClass->visited; - bClass->visited=TRUE; - addHierarchy(bn,bClass,wasVisited); - } - } - } - } - //printf("end addHierarchy\n"); -} - -void DotGfxHierarchyTable::addClassList(ClassSDict *cl) -{ - static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); - ClassSDict::Iterator cli(*cl); - ClassDef *cd; - for (cli.toLast();(cd=cli.current());--cli) - { - //printf("Trying %s subClasses=%d\n",cd->name().data(),cd->subClasses()->count()); - if (cd->getLanguage()==SrcLangExt_VHDL && - (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS - ) - { - continue; - } - if (sliceOpt && cd->compoundType() != m_classType) - { - continue; - } - if (!hasVisibleRoot(cd->baseClasses()) && - cd->isVisibleInHierarchy() - ) // root node in the forest - { - QCString tmp_url=""; - if (cd->isLinkable() && !cd->isHidden()) - { - tmp_url=cd->getReference()+"$"+cd->getOutputFileBase(); - if (!cd->anchor().isEmpty()) - { - tmp_url+="#"+cd->anchor(); - } - } - //printf("Inserting root class %s\n",cd->name().data()); - QCString tooltip = cd->briefDescriptionAsTooltip(); - DotNode *n = new DotNode(m_curNodeNumber++, - cd->displayName(), - tooltip, - tmp_url.data()); - - //m_usedNodes->clear(); - m_usedNodes->insert(cd->name(),n); - m_rootNodes->insert(0,n); - if (!cd->visited && cd->subClasses()) - { - addHierarchy(n,cd,cd->visited); - cd->visited=TRUE; - } - } - } -} - -DotGfxHierarchyTable::DotGfxHierarchyTable(const char *prefix,ClassDef::CompoundType ct) - : m_prefix(prefix) - , m_classType(ct) - , m_curNodeNumber(1) -{ - m_rootNodes = new QList<DotNode>; - m_usedNodes = new QDict<DotNode>(1009); - m_usedNodes->setAutoDelete(TRUE); - m_rootSubgraphs = new DotNodeList; - - // build a graph with each class as a node and the inheritance relations - // as edges - initClassHierarchy(Doxygen::classSDict); - initClassHierarchy(Doxygen::hiddenClasses); - addClassList(Doxygen::classSDict); - addClassList(Doxygen::hiddenClasses); - // m_usedNodes now contains all nodes in the graph - - // color the graph into a set of independent subgraphs - bool done=FALSE; - int curColor=0; - QListIterator<DotNode> dnli(*m_rootNodes); - while (!done) // there are still nodes to color - { - DotNode *n; - done=TRUE; // we are done unless there are still uncolored nodes - for (dnli.toLast();(n=dnli.current());--dnli) - { - if (n->m_subgraphId==-1) // not yet colored - { - //printf("Starting at node %s (%p): %d\n",n->m_label.data(),n,curColor); - done=FALSE; // still uncolored nodes - n->m_subgraphId=curColor; - n->markAsVisible(); - n->colorConnectedNodes(curColor); - curColor++; - const DotNode *dn=n->findDocNode(); - if (dn!=0) - m_rootSubgraphs->inSort(dn); - else - m_rootSubgraphs->inSort(n); - } - } - } - - //printf("Number of independent subgraphs: %d\n",curColor); - QListIterator<DotNode> dnli2(*m_rootSubgraphs); - DotNode *n; - for (dnli2.toFirst();(n=dnli2.current());++dnli2) - { - //printf("Node %s color=%d (c=%d,p=%d)\n", - // n->m_label.data(),n->m_subgraphId, - // n->m_children?n->m_children->count():0, - // n->m_parents?n->m_parents->count():0); - int number=0; - n->renumberNodes(number); - } -} - -DotGfxHierarchyTable::~DotGfxHierarchyTable() -{ - //printf("DotGfxHierarchyTable::~DotGfxHierarchyTable\n"); - - //QDictIterator<DotNode> di(*m_usedNodes); - //DotNode *n; - //for (;(n=di.current());++di) - //{ - // printf("Node %p: %s\n",n,n->label().data()); - //} - - delete m_rootNodes; - delete m_usedNodes; - delete m_rootSubgraphs; -} - -//-------------------------------------------------------------------- - -void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot, - const char *label,const char *usedName,const char *templSpec,bool base,int distance) -{ - if (Config_getBool(HIDE_UNDOC_CLASSES) && !cd->isLinkable()) return; - - int edgeStyle = (label || prot==EdgeInfo::Orange || prot==EdgeInfo::Orange2) ? EdgeInfo::Dashed : EdgeInfo::Solid; - QCString className; - if (cd->isAnonymous()) - { - className="anonymous:"; - className+=label; - } - else if (usedName) // name is a typedef - { - className=usedName; - } - else if (templSpec) // name has a template part - { - className=insertTemplateSpecifierInScope(cd->name(),templSpec); - } - else // just a normal name - { - className=cd->displayName(); - } - //printf("DotClassGraph::addClass(class=`%s',parent=%s,prot=%d,label=%s,dist=%d,usedName=%s,templSpec=%s,base=%d)\n", - // className.data(),n->m_label.data(),prot,label,distance,usedName,templSpec,base); - DotNode *bn = m_usedNodes->find(className); - if (bn) // class already inserted - { - if (base) - { - n->addChild(bn,prot,edgeStyle,label); - bn->addParent(n); - } - else - { - bn->addChild(n,prot,edgeStyle,label); - n->addParent(bn); - } - bn->setDistance(distance); - //printf(" add exiting node %s of %s\n",bn->m_label.data(),n->m_label.data()); - } - else // new class - { - QCString displayName=className; - if (Config_getBool(HIDE_SCOPE_NAMES)) displayName=stripScope(displayName); - QCString tmp_url; - if (cd->isLinkable() && !cd->isHidden()) - { - tmp_url=cd->getReference()+"$"+cd->getOutputFileBase(); - if (!cd->anchor().isEmpty()) - { - tmp_url+="#"+cd->anchor(); - } - } - QCString tooltip = cd->briefDescriptionAsTooltip(); - bn = new DotNode(m_curNodeNumber++, - displayName, - tooltip, - tmp_url.data(), - FALSE, // rootNode - cd - ); - if (base) - { - n->addChild(bn,prot,edgeStyle,label); - bn->addParent(n); - } - else - { - bn->addChild(n,prot,edgeStyle,label); - n->addParent(bn); - } - bn->setDistance(distance); - m_usedNodes->insert(className,bn); - //printf(" add new child node `%s' to %s hidden=%d url=%s\n", - // className.data(),n->m_label.data(),cd->isHidden(),tmp_url.data()); - - buildGraph(cd,bn,base,distance+1); - } -} - -void DotClassGraph::determineTruncatedNodes(QList<DotNode> &queue,bool includeParents) -{ - while (queue.count()>0) - { - DotNode *n = queue.take(0); - if (n->isVisible() && n->isTruncated()==DotNode::Unknown) - { - bool truncated = FALSE; - if (n->m_children) - { - QListIterator<DotNode> li(*n->m_children); - DotNode *dn; - for (li.toFirst();(dn=li.current());++li) - { - if (!dn->isVisible()) - truncated = TRUE; - else - queue.append(dn); - } - } - if (n->m_parents && includeParents) - { - QListIterator<DotNode> li(*n->m_parents); - DotNode *dn; - for (li.toFirst();(dn=li.current());++li) - { - if (!dn->isVisible()) - truncated = TRUE; - else - queue.append(dn); - } - } - n->markAsTruncated(truncated); - } - } -} - -bool DotClassGraph::determineVisibleNodes(DotNode *rootNode, - int maxNodes,bool includeParents) +class GraphLegendDotGraph : public DotGraph { - QList<DotNode> childQueue; - QList<DotNode> parentQueue; - QArray<int> childTreeWidth; - QArray<int> parentTreeWidth; - childQueue.append(rootNode); - if (includeParents) parentQueue.append(rootNode); - bool firstNode=TRUE; // flag to force reprocessing rootNode in the parent loop - // despite being marked visible in the child loop - while ((childQueue.count()>0 || parentQueue.count()>0) && maxNodes>0) - { - static int maxDistance = Config_getInt(MAX_DOT_GRAPH_DEPTH); - if (childQueue.count()>0) - { - DotNode *n = childQueue.take(0); - int distance = n->distance(); - if (!n->isVisible() && distance<=maxDistance) // not yet processed - { - if (distance>0) - { - int oldSize=(int)childTreeWidth.size(); - if (distance>oldSize) - { - childTreeWidth.resize(QMAX(childTreeWidth.size(),(uint)distance)); - int i; for (i=oldSize;i<distance;i++) childTreeWidth[i]=0; - } - childTreeWidth[distance-1]+=n->label().length(); - } - n->markAsVisible(); - maxNodes--; - // add direct children - if (n->m_children) - { - QListIterator<DotNode> li(*n->m_children); - DotNode *dn; - for (li.toFirst();(dn=li.current());++li) - { - childQueue.append(dn); - } - } - } - } - if (includeParents && parentQueue.count()>0) - { - DotNode *n = parentQueue.take(0); - if ((!n->isVisible() || firstNode) && n->distance()<=maxDistance) // not yet processed - { - firstNode=FALSE; - int distance = n->distance(); - if (distance>0) - { - int oldSize = (int)parentTreeWidth.size(); - if (distance>oldSize) - { - parentTreeWidth.resize(QMAX(parentTreeWidth.size(),(uint)distance)); - int i; for (i=oldSize;i<distance;i++) parentTreeWidth[i]=0; - } - parentTreeWidth[distance-1]+=n->label().length(); - } - n->markAsVisible(); - maxNodes--; - // add direct parents - if (n->m_parents) - { - QListIterator<DotNode> li(*n->m_parents); - DotNode *dn; - for (li.toFirst();(dn=li.current());++li) - { - parentQueue.append(dn); - } - } - } - } - } - if (Config_getBool(UML_LOOK)) return FALSE; // UML graph are always top to bottom - int maxWidth=0; - int maxHeight=(int)QMAX(childTreeWidth.size(),parentTreeWidth.size()); - uint i; - for (i=0;i<childTreeWidth.size();i++) - { - if (childTreeWidth.at(i)>maxWidth) maxWidth=childTreeWidth.at(i); - } - for (i=0;i<parentTreeWidth.size();i++) - { - if (parentTreeWidth.at(i)>maxWidth) maxWidth=parentTreeWidth.at(i); - } - //printf("max tree width=%d, max tree height=%d\n",maxWidth,maxHeight); - return maxWidth>80 && maxHeight<12; // used metric to decide to render the tree - // from left to right instead of top to bottom, - // with the idea to render very wide trees in - // left to right order. -} - -void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,bool base,int distance) -{ - static bool templateRelations = Config_getBool(TEMPLATE_RELATIONS); - //printf("DocClassGraph::buildGraph(%s,distance=%d,base=%d)\n", - // cd->name().data(),distance,base); - // ---- Add inheritance relations - - if (m_graphType == DotNode::Inheritance || m_graphType==DotNode::Collaboration) - { - BaseClassList *bcl = base ? cd->baseClasses() : cd->subClasses(); - if (bcl) - { - 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); - } - } - } - if (m_graphType == DotNode::Collaboration) - { - // ---- Add usage relations - - UsesClassDict *dict = - base ? cd->usedImplementationClasses() : - cd->usedByImplementationClasses() - ; - if (dict) - { - UsesClassDictIterator ucdi(*dict); - UsesClassDef *ucd; - for (;(ucd=ucdi.current());++ucdi) - { - QCString label; - QDictIterator<void> dvi(*ucd->accessors); - const char *s; - bool first=TRUE; - int count=0; - int maxLabels=10; - for (;(s=dvi.currentKey()) && count<maxLabels;++dvi,++count) - { - if (first) - { - label=s; - first=FALSE; - } - else - { - label+=QCString("\n")+s; - } - } - if (count==maxLabels) label+="\n..."; - //printf("addClass: %s templSpec=%s\n",ucd->classDef->name().data(),ucd->templSpecifiers.data()); - addClass(ucd->classDef,n,EdgeInfo::Purple,label,0, - ucd->templSpecifiers,base,distance); - } - } - } - if (templateRelations && base) - { - ConstraintClassDict *dict = cd->templateTypeConstraints(); - if (dict) - { - ConstraintClassDictIterator ccdi(*dict); - ConstraintClassDef *ccd; - for (;(ccd=ccdi.current());++ccdi) - { - QCString label; - QDictIterator<void> dvi(*ccd->accessors); - const char *s; - bool first=TRUE; - int count=0; - int maxLabels=10; - for (;(s=dvi.currentKey()) && count<maxLabels;++dvi,++count) - { - if (first) - { - label=s; - first=FALSE; - } - else - { - label+=QCString("\n")+s; - } - } - if (count==maxLabels) label+="\n..."; - //printf("addClass: %s templSpec=%s\n",ucd->classDef->name().data(),ucd->templSpecifiers.data()); - addClass(ccd->classDef,n,EdgeInfo::Orange2,label,0, - 0,TRUE,distance); - } - } - } - - // ---- Add template instantiation relations - - if (templateRelations) - { - if (base) // template relations for base classes - { - ClassDef *templMaster=cd->templateMaster(); - if (templMaster) - { - QDictIterator<ClassDef> cli(*templMaster->getTemplateInstances()); - ClassDef *templInstance; - for (;(templInstance=cli.current());++cli) - { - if (templInstance==cd) - { - addClass(templMaster,n,EdgeInfo::Orange,cli.currentKey(),0, - 0,TRUE,distance); - } - } - } - } - else // template relations for super classes + private: + virtual QCString getBaseName() const { - QDict<ClassDef> *templInstances = cd->getTemplateInstances(); - if (templInstances) - { - QDictIterator<ClassDef> cli(*templInstances); - ClassDef *templInstance; - for (;(templInstance=cli.current());++cli) - { - addClass(templInstance,n,EdgeInfo::Orange,cli.currentKey(),0, - 0,FALSE,distance); - } - } + return "graph_legend"; } - } -} - -int DotClassGraph::m_curNodeNumber = 0; -void DotClassGraph::resetNumbering() -{ - m_curNodeNumber = 0; -} - -DotClassGraph::DotClassGraph(ClassDef *cd,DotNode::GraphType t) -{ - //printf("--------------- DotClassGraph::DotClassGraph `%s'\n",cd->displayName().data()); - m_graphType = t; - QCString tmp_url=""; - if (cd->isLinkable() && !cd->isHidden()) - { - tmp_url=cd->getReference()+"$"+cd->getOutputFileBase(); - if (!cd->anchor().isEmpty()) + virtual void computeTheGraph() { - tmp_url+="#"+cd->anchor(); + FTextStream md5stream(&m_theGraph); + writeGraphHeader(md5stream,theTranslator->trLegendTitle()); + md5stream << " Node9 [shape=\"box\",label=\"Inherited\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",fillcolor=\"grey75\",style=\"filled\" fontcolor=\"black\"];\n"; + md5stream << " Node10 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n"; + md5stream << " Node10 [shape=\"box\",label=\"PublicBase\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classPublicBase" << Doxygen::htmlFileExtension << "\"];\n"; + md5stream << " Node11 -> Node10 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n"; + md5stream << " Node11 [shape=\"box\",label=\"Truncated\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"red\",URL=\"$classTruncated" << Doxygen::htmlFileExtension << "\"];\n"; + md5stream << " Node13 -> Node9 [dir=\"back\",color=\"darkgreen\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n"; + md5stream << " Node13 [shape=\"box\",label=\"ProtectedBase\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classProtectedBase" << Doxygen::htmlFileExtension << "\"];\n"; + md5stream << " Node14 -> Node9 [dir=\"back\",color=\"firebrick4\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n"; + md5stream << " Node14 [shape=\"box\",label=\"PrivateBase\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classPrivateBase" << Doxygen::htmlFileExtension << "\"];\n"; + md5stream << " Node15 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n"; + md5stream << " Node15 [shape=\"box\",label=\"Undocumented\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"grey75\"];\n"; + md5stream << " Node16 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n"; + md5stream << " Node16 [shape=\"box\",label=\"Templ< int >\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension << "\"];\n"; + md5stream << " Node17 -> Node16 [dir=\"back\",color=\"orange\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"dashed\",label=\"< int >\",fontname=\"" << DOT_FONTNAME << "\"];\n"; + md5stream << " Node17 [shape=\"box\",label=\"Templ< T >\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension << "\"];\n"; + md5stream << " Node18 -> Node9 [dir=\"back\",color=\"darkorchid3\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"dashed\",label=\"m_usedClass\",fontname=\"" << DOT_FONTNAME << "\"];\n"; + md5stream << " Node18 [shape=\"box\",label=\"Used\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classUsed" << Doxygen::htmlFileExtension << "\"];\n"; + writeGraphFooter(md5stream); } - } - QCString className = cd->displayName(); - QCString tooltip = cd->briefDescriptionAsTooltip(); - m_startNode = new DotNode(m_curNodeNumber++, - className, - tooltip, - tmp_url.data(), - TRUE, // is a root node - cd - ); - m_startNode->setDistance(0); - m_usedNodes = new QDict<DotNode>(1009); - m_usedNodes->insert(className,m_startNode); - - //printf("Root node %s\n",cd->name().data()); - //if (m_recDepth>0) - //{ - buildGraph(cd,m_startNode,TRUE,1); - if (t==DotNode::Inheritance) buildGraph(cd,m_startNode,FALSE,1); - //} - - static int maxNodes = Config_getInt(DOT_GRAPH_MAX_NODES); - //int directChildNodes = 1; - //if (m_startNode->m_children!=0) - // directChildNodes+=m_startNode->m_children->count(); - //if (t==DotNode::Inheritance && m_startNode->m_parents!=0) - // directChildNodes+=m_startNode->m_parents->count(); - //if (directChildNodes>maxNodes) maxNodes=directChildNodes; - //openNodeQueue.append(m_startNode); - m_lrRank = determineVisibleNodes(m_startNode,maxNodes,t==DotNode::Inheritance); - QList<DotNode> openNodeQueue; - openNodeQueue.append(m_startNode); - determineTruncatedNodes(openNodeQueue,t==DotNode::Inheritance); - - m_collabFileName = cd->collaborationGraphFileName(); - m_inheritFileName = cd->inheritanceGraphFileName(); -} - -bool DotClassGraph::isTrivial() const -{ - static bool umlLook = Config_getBool(UML_LOOK); - if (m_graphType==DotNode::Inheritance) - return m_startNode->m_children==0 && m_startNode->m_parents==0; - else - return !umlLook && m_startNode->m_children==0; -} - -bool DotClassGraph::isTooBig() const -{ - static int maxNodes = Config_getInt(DOT_GRAPH_MAX_NODES); - int numNodes = 0; - numNodes+= m_startNode->m_children ? m_startNode->m_children->count() : 0; - if (m_graphType==DotNode::Inheritance) - { - numNodes+= m_startNode->m_parents ? m_startNode->m_parents->count() : 0; - } - return numNodes>=maxNodes; -} - -DotClassGraph::~DotClassGraph() -{ - deleteNodes(m_startNode); - delete m_usedNodes; -} -/*! Computes a 16 byte md5 checksum for a given dot graph. - * The md5 checksum is returned as a 32 character ASCII string. - */ -QCString computeMd5Signature(DotNode *root, - DotNode::GraphType gt, - GraphOutputFormat format, - const QCString &rank, // either "LR", "RL", or "" - bool renderParents, - bool backArrows, - const QCString &title, - QCString &graphStr - ) -{ - //printf("computeMd5Signature\n"); - QGString buf; - FTextStream md5stream(&buf); - writeGraphHeader(md5stream,title); - if (!rank.isEmpty()) - { - md5stream << " rankdir=\"" << rank << "\";" << endl; - } - root->clearWriteFlag(); - root->write(md5stream, - gt, - format, - gt!=DotNode::CallGraph && gt!=DotNode::Dependency, - TRUE, - backArrows); - if (renderParents && root->m_parents) - { - QListIterator<DotNode> dnli(*root->m_parents); - DotNode *pn; - for (dnli.toFirst();(pn=dnli.current());++dnli) + virtual QCString getMapLabel() const { - if (pn->isVisible()) - { - root->writeArrow(md5stream, // stream - gt, // graph type - format, // output format - pn, // child node - pn->m_edgeInfo->at(pn->m_children->findRef(root)), // edge info - FALSE, // topDown? - backArrows // point back? - ); - } - pn->write(md5stream, // stream - gt, // graph type - format, // output format - TRUE, // topDown? - FALSE, // toChildren? - backArrows // backward pointing arrows? - ); + return ""; } - } - writeGraphFooter(md5stream); - uchar md5_sig[16]; - QCString sigStr(33); - MD5Buffer((const unsigned char *)buf.data(),buf.length(),md5_sig); - MD5SigToString(md5_sig,sigStr.rawData(),33); - graphStr=buf.data(); - //printf("md5: %s | file: %s\n",sigStr,baseName.data()); - return sigStr; -} -static bool updateDotGraph(DotNode *root, - DotNode::GraphType gt, - const QCString &baseName, - GraphOutputFormat format, - const QCString &rank, - bool renderParents, - bool backArrows, - const QCString &title=QCString() - ) -{ - QCString theGraph; - // TODO: write graph to theGraph, then compute md5 checksum - QCString md5 = computeMd5Signature( - root,gt,format,rank,renderParents, - backArrows,title,theGraph); - QFile f(baseName+".dot"); - if (f.open(IO_WriteOnly)) - { - FTextStream t(&f); - t << theGraph; - } - return checkAndUpdateMd5Signature(baseName,md5); // graph needs to be regenerated -} - -QCString DotClassGraph::writeGraph(FTextStream &out, - GraphOutputFormat graphFormat, - EmbeddedOutputFormat textFormat, - const char *path, - const char *fileName, - const char *relPath, - bool /*isTBRank*/, - bool generateImageMap, - int graphId) const -{ - QDir d(path); - // store the original directory - if (!d.exists()) - { - err("Output dir %s does not exist!\n",path); exit(1); - } - static bool usePDFLatex = Config_getBool(USE_PDFLATEX); - - QCString baseName; - QCString mapName; - switch (m_graphType) - { - case DotNode::Collaboration: - mapName="coll_map"; - baseName=m_collabFileName; - break; - case DotNode::Inheritance: - mapName="inherit_map"; - baseName=m_inheritFileName; - break; - default: - ASSERT(0); - break; - } - - // derive target file names from baseName - QCString imgExt = getDotImageExtension(); - QCString imgFmt = Config_getEnum(DOT_IMAGE_FORMAT); - QCString absBaseName = d.absPath().utf8()+"/"+baseName; - QCString absDotName = absBaseName+".dot"; - QCString absMapName = absBaseName+".map"; - QCString absPdfName = absBaseName+".pdf"; - QCString absEpsName = absBaseName+".eps"; - QCString absImgName = absBaseName+"."+imgExt; - - bool regenerate = FALSE; - if (updateDotGraph(m_startNode, - m_graphType, - absBaseName, - graphFormat, - m_lrRank ? "LR" : "", - m_graphType==DotNode::Inheritance, - TRUE, - m_startNode->label() - ) || - !checkDeliverables(graphFormat==GOF_BITMAP ? absImgName : - usePDFLatex ? absPdfName : absEpsName, - graphFormat==GOF_BITMAP && generateImageMap ? absMapName : QCString()) - ) - { - regenerate=TRUE; - if (graphFormat==GOF_BITMAP) // run dot to create a bitmap image - { - DotRunner *dotRun = new DotRunner(absDotName, - d.absPath().data(),TRUE,absImgName); - dotRun->addJob(imgFmt,absImgName); - if (generateImageMap) dotRun->addJob(MAP_CMD,absMapName); - DotManager::instance()->addRun(dotRun); - - } - else if (graphFormat==GOF_EPS) // run dot to create a .eps image - { - DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); - if (usePDFLatex) - { - dotRun->addJob("pdf",absPdfName,absBaseName); - } - else - { - dotRun->addJob("ps",absEpsName); - } - DotManager::instance()->addRun(dotRun); - } - } - Doxygen::indexList->addImageFile(baseName+"."+imgExt); - - if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook) - { - out << "<para>" << endl; - out << " <informalfigure>" << endl; - out << " <mediaobject>" << endl; - out << " <imageobject>" << endl; - out << " <imagedata"; - out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; - out << "</imagedata>" << endl; - out << " </imageobject>" << endl; - out << " </mediaobject>" << endl; - out << " </informalfigure>" << endl; - out << "</para>" << endl; - } - else if (graphFormat==GOF_BITMAP && generateImageMap) // produce HTML to include the image - { - QCString mapLabel = escapeCharsInString(m_startNode->m_label,FALSE)+"_"+ - escapeCharsInString(mapName,FALSE); - if (imgExt=="svg") // add link to SVG file without map file - { - out << "<div class=\"center\">"; - if (regenerate || !writeSVGFigureLink(out,relPath,baseName,absImgName)) // need to patch the links in the generated SVG file - { - if (regenerate) - { - DotManager::instance()->addSVGConversion(absImgName,relPath,FALSE,QCString(),TRUE,graphId); - } - int mapId = DotManager::instance()->addSVGObject(fileName,baseName,absImgName,relPath); - out << "<!-- SVG " << mapId << " -->" << endl; - } - out << "</div>" << endl; - } - else // add link to bitmap file with image map - { - out << "<div class=\"center\">"; - out << "<img src=\"" << relPath << baseName << "." - << imgExt << "\" border=\"0\" usemap=\"#" - << mapLabel << "\" alt=\""; - switch (m_graphType) - { - case DotNode::Collaboration: - out << "Collaboration graph"; - break; - case DotNode::Inheritance: - out << "Inheritance graph"; - break; - default: - ASSERT(0); - break; - } - out << "\"/>"; - out << "</div>" << endl; - if (regenerate || !insertMapFile(out,absMapName,relPath,mapLabel)) - { - int mapId = DotManager::instance()->addMap(fileName,absMapName,relPath, - FALSE,QCString(),mapLabel); - out << "<!-- MAP " << mapId << " -->" << endl; - } - } - } - else if (graphFormat==GOF_EPS) // produce tex to include the .eps image - { - if (regenerate || !writeVecGfxFigure(out,baseName,absBaseName)) - { - int figId = DotManager::instance()->addFigure(fileName,baseName,absBaseName,FALSE /*TRUE*/); - out << endl << "% FIG " << figId << endl; - } - } - if (!regenerate) removeDotGraph(absDotName); - - return baseName; -} - -//-------------------------------------------------------------------- - -void DotClassGraph::writeXML(FTextStream &t) -{ - QDictIterator<DotNode> dni(*m_usedNodes); - DotNode *node; - for (;(node=dni.current());++dni) - { - node->writeXML(t,TRUE); - } -} - -void DotClassGraph::writeDocbook(FTextStream &t) -{ - QDictIterator<DotNode> dni(*m_usedNodes); - DotNode *node; - for (;(node=dni.current());++dni) - { - node->writeDocbook(t,TRUE); - } -} - -void DotClassGraph::writeDEF(FTextStream &t) -{ - QDictIterator<DotNode> dni(*m_usedNodes); - DotNode *node; - for (;(node=dni.current());++dni) - { - node->writeDEF(t); - } -} - -//-------------------------------------------------------------------- - -void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd,int distance) -{ - QList<IncludeInfo> *includeFiles = - m_inverse ? fd->includedByFileList() : fd->includeFileList(); - if (includeFiles) - { - QListIterator<IncludeInfo> ili(*includeFiles); - IncludeInfo *ii; - for (;(ii=ili.current());++ili) - { - FileDef *bfd = ii->fileDef; - QCString in = ii->includeName; - //printf(">>>> in=`%s' bfd=%p\n",ii->includeName.data(),bfd); - bool doc=TRUE,src=FALSE; - if (bfd) - { - in = bfd->absFilePath(); - doc = bfd->isLinkable() && !bfd->isHidden(); - src = bfd->generateSourceFile(); - } - if (doc || src || !Config_getBool(HIDE_UNDOC_RELATIONS)) - { - QCString url=""; - if (bfd) url=bfd->getOutputFileBase().copy(); - if (!doc && src) - { - url=bfd->getSourceFileBase(); - } - DotNode *bn = m_usedNodes->find(in); - if (bn) // file is already a node in the graph - { - n->addChild(bn,0,0,0); - bn->addParent(n); - bn->setDistance(distance); - } - else - { - QCString tmp_url; - QCString tooltip; - if (bfd) - { - tmp_url=doc || src ? bfd->getReference()+"$"+url : QCString(); - tooltip = bfd->briefDescriptionAsTooltip(); - } - bn = new DotNode( - m_curNodeNumber++, // n - ii->includeName, // label - tooltip, // tip - tmp_url, // url - FALSE, // rootNode - 0 // cd - ); - n->addChild(bn,0,0,0); - bn->addParent(n); - m_usedNodes->insert(in,bn); - bn->setDistance(distance); - - if (bfd) buildGraph(bn,bfd,distance+1); - } - } - } - } -} - -void DotInclDepGraph::determineVisibleNodes(QList<DotNode> &queue, int &maxNodes) -{ - while (queue.count()>0 && maxNodes>0) - { - static int maxDistance = Config_getInt(MAX_DOT_GRAPH_DEPTH); - DotNode *n = queue.take(0); - if (!n->isVisible() && n->distance()<=maxDistance) // not yet processed - { - n->markAsVisible(); - maxNodes--; - // add direct children - if (n->m_children) - { - QListIterator<DotNode> li(*n->m_children); - DotNode *dn; - for (li.toFirst();(dn=li.current());++li) - { - queue.append(dn); - } - } - } - } -} - -void DotInclDepGraph::determineTruncatedNodes(QList<DotNode> &queue) -{ - while (queue.count()>0) - { - DotNode *n = queue.take(0); - if (n->isVisible() && n->isTruncated()==DotNode::Unknown) - { - bool truncated = FALSE; - if (n->m_children) - { - QListIterator<DotNode> li(*n->m_children); - DotNode *dn; - for (li.toFirst();(dn=li.current());++li) - { - if (!dn->isVisible()) - truncated = TRUE; - else - queue.append(dn); - } - } - n->markAsTruncated(truncated); - } - } -} - -int DotInclDepGraph::m_curNodeNumber = 0; - -void DotInclDepGraph::resetNumbering() -{ - m_curNodeNumber = 0; -} - -DotInclDepGraph::DotInclDepGraph(FileDef *fd,bool inverse) -{ - m_inverse = inverse; - ASSERT(fd!=0); - m_inclDepFileName = fd->includeDependencyGraphFileName(); - m_inclByDepFileName = fd->includedByDependencyGraphFileName(); - QCString tmp_url=fd->getReference()+"$"+fd->getOutputFileBase(); - QCString tooltip = fd->briefDescriptionAsTooltip(); - m_startNode = new DotNode(m_curNodeNumber++, - fd->docName(), - tooltip, - tmp_url.data(), - TRUE // root node - ); - m_startNode->setDistance(0); - m_usedNodes = new QDict<DotNode>(1009); - m_usedNodes->insert(fd->absFilePath(),m_startNode); - buildGraph(m_startNode,fd,1); - - static int nodes = Config_getInt(DOT_GRAPH_MAX_NODES); - int maxNodes = nodes; - //int directChildNodes = 1; - //if (m_startNode->m_children!=0) - // directChildNodes+=m_startNode->m_children->count(); - //if (directChildNodes>maxNodes) maxNodes=directChildNodes; - QList<DotNode> openNodeQueue; - openNodeQueue.append(m_startNode); - determineVisibleNodes(openNodeQueue,maxNodes); - openNodeQueue.clear(); - openNodeQueue.append(m_startNode); - determineTruncatedNodes(openNodeQueue); -} - -DotInclDepGraph::~DotInclDepGraph() -{ - deleteNodes(m_startNode); - delete m_usedNodes; -} - -QCString DotInclDepGraph::writeGraph(FTextStream &out, - GraphOutputFormat graphFormat, - EmbeddedOutputFormat textFormat, - const char *path, - const char *fileName, - const char *relPath, - bool generateImageMap, - int graphId - ) const -{ - QDir d(path); - // store the original directory - if (!d.exists()) - { - err("Output dir %s does not exist!\n",path); exit(1); - } - static bool usePDFLatex = Config_getBool(USE_PDFLATEX); - - QCString baseName; - if (m_inverse) - { - baseName=m_inclByDepFileName; - } - else - { - baseName=m_inclDepFileName; - } - QCString mapName=escapeCharsInString(m_startNode->m_label,FALSE); - if (m_inverse) mapName+="dep"; - - QCString imgExt = getDotImageExtension(); - QCString imgFmt = Config_getEnum(DOT_IMAGE_FORMAT); - QCString absBaseName = d.absPath().utf8()+"/"+baseName; - QCString absDotName = absBaseName+".dot"; - QCString absMapName = absBaseName+".map"; - QCString absPdfName = absBaseName+".pdf"; - QCString absEpsName = absBaseName+".eps"; - QCString absImgName = absBaseName+"."+imgExt; - - bool regenerate = FALSE; - if (updateDotGraph(m_startNode, - DotNode::Dependency, - absBaseName, - graphFormat, - "", // lrRank - FALSE, // renderParents - m_inverse, // backArrows - m_startNode->label() - ) || - !checkDeliverables(graphFormat==GOF_BITMAP ? absImgName : - usePDFLatex ? absPdfName : absEpsName, - graphFormat==GOF_BITMAP && generateImageMap ? absMapName : QCString()) - ) - { - regenerate=TRUE; - if (graphFormat==GOF_BITMAP) - { - // run dot to create a bitmap image - DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),TRUE,absImgName); - dotRun->addJob(imgFmt,absImgName); - if (generateImageMap) dotRun->addJob(MAP_CMD,absMapName); - DotManager::instance()->addRun(dotRun); - } - else if (graphFormat==GOF_EPS) - { - DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); - if (usePDFLatex) - { - dotRun->addJob("pdf",absPdfName,absBaseName); - } - else - { - dotRun->addJob("ps",absEpsName); - } - DotManager::instance()->addRun(dotRun); - } - } - Doxygen::indexList->addImageFile(baseName+"."+imgExt); - - if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook) - { - out << "<para>" << endl; - out << " <informalfigure>" << endl; - out << " <mediaobject>" << endl; - out << " <imageobject>" << endl; - out << " <imagedata"; - out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; - out << "</imagedata>" << endl; - out << " </imageobject>" << endl; - out << " </mediaobject>" << endl; - out << " </informalfigure>" << endl; - out << "</para>" << endl; - } - else if (graphFormat==GOF_BITMAP && generateImageMap) - { - if (imgExt=="svg") // Scalable vector graphics - { - out << "<div class=\"center\">"; - if (regenerate || !writeSVGFigureLink(out,relPath,baseName,absImgName)) // need to patch the links in the generated SVG file - { - if (regenerate) - { - DotManager::instance()->addSVGConversion(absImgName,relPath,FALSE,QCString(),TRUE,graphId); - } - int mapId = DotManager::instance()->addSVGObject(fileName,baseName,absImgName,relPath); - out << "<!-- SVG " << mapId << " -->" << endl; - } - out << "</div>" << endl; - } - else // bitmap graphics - { - out << "<div class=\"center\"><img src=\"" << relPath << baseName << "." << imgExt << "\" border=\"0\" usemap=\"#" << mapName << "\" alt=\"\"/>"; - out << "</div>" << endl; - - QCString absMapName = absBaseName+".map"; - if (regenerate || !insertMapFile(out,absMapName,relPath,mapName)) - { - int mapId = DotManager::instance()->addMap(fileName,absMapName,relPath, - FALSE,QCString(),mapName); - out << "<!-- MAP " << mapId << " -->" << endl; - } - } - } - else if (graphFormat==GOF_EPS) // encapsulated postscript - { - if (regenerate || !writeVecGfxFigure(out,baseName,absBaseName)) - { - int figId = DotManager::instance()->addFigure(fileName,baseName,absBaseName,FALSE); - out << endl << "% FIG " << figId << endl; - } - } - if (!regenerate) removeDotGraph(absDotName); - - return baseName; -} - -bool DotInclDepGraph::isTrivial() const -{ - return m_startNode->m_children==0; -} - -bool DotInclDepGraph::isTooBig() const -{ - static int maxNodes = Config_getInt(DOT_GRAPH_MAX_NODES); - int numNodes = m_startNode->m_children ? m_startNode->m_children->count() : 0; - return numNodes>=maxNodes; -} - -void DotInclDepGraph::writeXML(FTextStream &t) -{ - QDictIterator<DotNode> dni(*m_usedNodes); - DotNode *node; - for (;(node=dni.current());++dni) - { - node->writeXML(t,FALSE); - } -} - -void DotInclDepGraph::writeDocbook(FTextStream &t) -{ - QDictIterator<DotNode> dni(*m_usedNodes); - DotNode *node; - for (;(node=dni.current());++dni) - { - node->writeDocbook(t,FALSE); - } -} - -//------------------------------------------------------------- - -void DotCallGraph::buildGraph(DotNode *n,MemberDef *md,int distance) -{ - MemberSDict *refs = m_inverse ? md->getReferencedByMembers() : md->getReferencesMembers(); - if (refs) - { - MemberSDict::Iterator mri(*refs); - MemberDef *rmd; - for (;(rmd=mri.current());++mri) - { - if (rmd->showInCallGraph()) - { - QCString uniqueId; - uniqueId=rmd->getReference()+"$"+ - rmd->getOutputFileBase()+"#"+rmd->anchor(); - 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 (Config_getBool(HIDE_SCOPE_NAMES)) - { - name = rmd->getOuterScope()==m_scope ? - rmd->name() : rmd->qualifiedName(); - } - else - { - name = rmd->qualifiedName(); - } - QCString tooltip = rmd->briefDescriptionAsTooltip(); - bn = new DotNode( - m_curNodeNumber++, - 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); - - buildGraph(bn,rmd,distance+1); - } - } - } - } -} - -void DotCallGraph::determineVisibleNodes(QList<DotNode> &queue, int &maxNodes) -{ - while (queue.count()>0 && maxNodes>0) - { - static int maxDistance = Config_getInt(MAX_DOT_GRAPH_DEPTH); - DotNode *n = queue.take(0); - if (!n->isVisible() && n->distance()<=maxDistance) // not yet processed - { - n->markAsVisible(); - maxNodes--; - // add direct children - if (n->m_children) - { - QListIterator<DotNode> li(*n->m_children); - DotNode *dn; - for (li.toFirst();(dn=li.current());++li) - { - queue.append(dn); - } - } - } - } -} - -void DotCallGraph::determineTruncatedNodes(QList<DotNode> &queue) -{ - while (queue.count()>0) - { - DotNode *n = queue.take(0); - if (n->isVisible() && n->isTruncated()==DotNode::Unknown) - { - bool truncated = FALSE; - if (n->m_children) - { - QListIterator<DotNode> li(*n->m_children); - DotNode *dn; - for (li.toFirst();(dn=li.current());++li) - { - if (!dn->isVisible()) - truncated = TRUE; - else - queue.append(dn); - } - } - n->markAsTruncated(truncated); - } - } -} - -int DotCallGraph::m_curNodeNumber = 0; - -void DotCallGraph::resetNumbering() -{ - m_curNodeNumber = 0; -} - -DotCallGraph::DotCallGraph(MemberDef *md,bool inverse) -{ - m_inverse = inverse; - m_diskName = md->getOutputFileBase()+"_"+md->anchor(); - m_scope = md->getOuterScope(); - QCString uniqueId; - uniqueId = md->getReference()+"$"+ - md->getOutputFileBase()+"#"+md->anchor(); - QCString name; - if (Config_getBool(HIDE_SCOPE_NAMES)) - { - name = md->name(); - } - else - { - name = md->qualifiedName(); - } - QCString tooltip = md->briefDescriptionAsTooltip(); - m_startNode = new DotNode(m_curNodeNumber++, - linkToText(md->getLanguage(),name,FALSE), - tooltip, - uniqueId.data(), - TRUE // root node - ); - m_startNode->setDistance(0); - m_usedNodes = new QDict<DotNode>(1009); - m_usedNodes->insert(uniqueId,m_startNode); - buildGraph(m_startNode,md,1); - - static int nodes = Config_getInt(DOT_GRAPH_MAX_NODES); - int maxNodes = nodes; - //int directChildNodes = 1; - //if (m_startNode->m_children!=0) - // directChildNodes+=m_startNode->m_children->count(); - //if (directChildNodes>maxNodes) maxNodes=directChildNodes; - QList<DotNode> openNodeQueue; - openNodeQueue.append(m_startNode); - determineVisibleNodes(openNodeQueue,maxNodes); - openNodeQueue.clear(); - openNodeQueue.append(m_startNode); - determineTruncatedNodes(openNodeQueue); -} - -DotCallGraph::~DotCallGraph() -{ - deleteNodes(m_startNode); - delete m_usedNodes; -} - -QCString DotCallGraph::writeGraph(FTextStream &out, GraphOutputFormat graphFormat, - EmbeddedOutputFormat textFormat, - const char *path,const char *fileName, - const char *relPath,bool generateImageMap,int - graphId) const -{ - QDir d(path); - // store the original directory - if (!d.exists()) - { - err("Output dir %s does not exist!\n",path); exit(1); - } - static bool usePDFLatex = Config_getBool(USE_PDFLATEX); - - QCString baseName = m_diskName + (m_inverse ? "_icgraph" : "_cgraph"); - QCString mapName = baseName; - - QCString imgExt = getDotImageExtension(); - QCString imgFmt = Config_getEnum(DOT_IMAGE_FORMAT); - QCString absBaseName = d.absPath().utf8()+"/"+baseName; - QCString absDotName = absBaseName+".dot"; - QCString absMapName = absBaseName+".map"; - QCString absPdfName = absBaseName+".pdf"; - QCString absEpsName = absBaseName+".eps"; - QCString absImgName = absBaseName+"."+imgExt; - - bool regenerate = FALSE; - - if (updateDotGraph(m_startNode, - DotNode::CallGraph, - absBaseName, - graphFormat, - m_inverse ? "RL" : "LR", // lrRank - FALSE, // renderParents - m_inverse, // backArrows - m_startNode->label() - ) || - !checkDeliverables(graphFormat==GOF_BITMAP ? absImgName : - usePDFLatex ? absPdfName : absEpsName, - graphFormat==GOF_BITMAP && generateImageMap ? absMapName : QCString()) - ) - { - regenerate=TRUE; - if (graphFormat==GOF_BITMAP) - { - // run dot to create a bitmap image - DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),TRUE,absImgName); - dotRun->addJob(imgFmt,absImgName); - if (generateImageMap) dotRun->addJob(MAP_CMD,absMapName); - DotManager::instance()->addRun(dotRun); - - } - else if (graphFormat==GOF_EPS) - { - // run dot to create a .eps image - DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); - if (usePDFLatex) - { - dotRun->addJob("pdf",absPdfName,absBaseName); - } - else - { - dotRun->addJob("ps",absEpsName); - } - DotManager::instance()->addRun(dotRun); - - } - } - Doxygen::indexList->addImageFile(baseName+"."+imgExt); - - if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook) - { - out << "<para>" << endl; - out << " <informalfigure>" << endl; - out << " <mediaobject>" << endl; - out << " <imageobject>" << endl; - out << " <imagedata"; - out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; - out << "</imagedata>" << endl; - out << " </imageobject>" << endl; - out << " </mediaobject>" << endl; - out << " </informalfigure>" << endl; - out << "</para>" << endl; - } - else if (graphFormat==GOF_BITMAP && generateImageMap) - { - if (imgExt=="svg") // Scalable vector graphics - { - out << "<div class=\"center\">"; - if (regenerate || !writeSVGFigureLink(out,relPath,baseName,absImgName)) // need to patch the links in the generated SVG file - { - if (regenerate) - { - DotManager::instance()->addSVGConversion(absImgName,relPath,FALSE,QCString(),TRUE,graphId); - } - int mapId = DotManager::instance()->addSVGObject(fileName,baseName,absImgName,relPath); - out << "<!-- SVG " << mapId << " -->" << endl; - } - out << "</div>" << endl; - } - else // bitmap graphics - { - out << "<div class=\"center\"><img src=\"" << relPath << baseName << "." - << imgExt << "\" border=\"0\" usemap=\"#" - << mapName << "\" alt=\""; - out << "\"/>"; - out << "</div>" << endl; - - if (regenerate || !insertMapFile(out,absMapName,relPath,mapName)) - { - int mapId = DotManager::instance()->addMap(fileName,absMapName,relPath, - FALSE,QCString(),mapName); - out << "<!-- MAP " << mapId << " -->" << endl; - } - } - } - else if (graphFormat==GOF_EPS) // encapsulated postscript - { - if (regenerate || !writeVecGfxFigure(out,baseName,absBaseName)) - { - int figId = DotManager::instance()->addFigure(fileName,baseName,absBaseName,FALSE); - out << endl << "% FIG " << figId << endl; - } - } - if (!regenerate) removeDotGraph(absDotName); - - return baseName; -} - -bool DotCallGraph::isTrivial() const -{ - return m_startNode->m_children==0; -} - -bool DotCallGraph::isTooBig() const -{ - static int maxNodes = Config_getInt(DOT_GRAPH_MAX_NODES); - int numNodes = m_startNode->m_children ? m_startNode->m_children->count() : 0; - return numNodes>=maxNodes; -} - -//------------------------------------------------------------- -static void writeDotDirDepGraph(FTextStream &t,DirDef *dd,bool linkRelations); - -DotDirDeps::DotDirDeps(DirDef *dir) : m_dir(dir) -{ -} - -DotDirDeps::~DotDirDeps() -{ -} - -QCString DotDirDeps::writeGraph(FTextStream &out, - GraphOutputFormat graphFormat, - EmbeddedOutputFormat textFormat, - const char *path, - const char *fileName, - const char *relPath, - bool generateImageMap, - int graphId, - bool linkRelations) const -{ - QDir d(path); - // store the original directory - if (!d.exists()) - { - err("Output dir %s does not exist!\n",path); exit(1); - } - static bool usePDFLatex = Config_getBool(USE_PDFLATEX); - - QCString baseName=m_dir->getOutputFileBase()+"_dep"; - QCString mapName=escapeCharsInString(baseName,FALSE); - - QCString imgExt = getDotImageExtension(); - QCString imgFmt = Config_getEnum(DOT_IMAGE_FORMAT); - QCString absBaseName = d.absPath().utf8()+"/"+baseName; - QCString absDotName = absBaseName+".dot"; - QCString absMapName = absBaseName+".map"; - QCString absPdfName = absBaseName+".pdf"; - QCString absEpsName = absBaseName+".eps"; - QCString absImgName = absBaseName+"."+imgExt; - - // compute md5 checksum of the graph were are about to generate - QGString theGraph; - FTextStream md5stream(&theGraph); - //m_dir->writeDepGraph(md5stream); - writeDotDirDepGraph(md5stream,m_dir,linkRelations); - uchar md5_sig[16]; - QCString sigStr(33); - MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig); - MD5SigToString(md5_sig,sigStr.rawData(),33); - bool regenerate=FALSE; - if (checkAndUpdateMd5Signature(absBaseName,sigStr) || - !checkDeliverables(graphFormat==GOF_BITMAP ? absImgName : - usePDFLatex ? absPdfName : absEpsName, - graphFormat==GOF_BITMAP && generateImageMap ? absMapName : QCString()) - ) - { - regenerate=TRUE; - - QFile f(absDotName); - if (!f.open(IO_WriteOnly)) - { - err("Cannot create file %s.dot for writing!\n",baseName.data()); - } - FTextStream t(&f); - t << theGraph.data(); - f.close(); - - if (graphFormat==GOF_BITMAP) - { - // run dot to create a bitmap image - DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),TRUE,absImgName); - dotRun->addJob(imgFmt,absImgName); - if (generateImageMap) dotRun->addJob(MAP_CMD,absMapName); - DotManager::instance()->addRun(dotRun); - } - else if (graphFormat==GOF_EPS) - { - DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); - if (usePDFLatex) - { - dotRun->addJob("pdf",absPdfName,absBaseName); - } - else - { - dotRun->addJob("ps",absEpsName); - } - DotManager::instance()->addRun(dotRun); - } - } - Doxygen::indexList->addImageFile(baseName+"."+imgExt); - - if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook) - { - out << "<para>" << endl; - out << " <informalfigure>" << endl; - out << " <mediaobject>" << endl; - out << " <imageobject>" << endl; - out << " <imagedata"; - out << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; - out << "</imagedata>" << endl; - out << " </imageobject>" << endl; - out << " </mediaobject>" << endl; - out << " </informalfigure>" << endl; - out << "</para>" << endl; - } - else if (graphFormat==GOF_BITMAP && generateImageMap) - { - if (imgExt=="svg") // Scalable vector graphics - { - out << "<div class=\"center\">"; - if (regenerate || !writeSVGFigureLink(out,relPath,baseName,absImgName)) // need to patch the links in the generated SVG file - { - if (regenerate) - { - DotManager::instance()->addSVGConversion(absImgName,relPath,FALSE,QCString(),TRUE,graphId); - } - int mapId = DotManager::instance()->addSVGObject(fileName,baseName,absImgName,relPath); - out << "<!-- SVG " << mapId << " -->" << endl; - } - out << "</div>" << endl; - } - else // bitmap graphics - { - out << "<div class=\"center\"><img src=\"" << relPath << baseName << "." - << imgExt << "\" border=\"0\" usemap=\"#" - << mapName << "\" alt=\""; - out << convertToXML(m_dir->displayName()); - out << "\"/>"; - out << "</div>" << endl; - - if (regenerate || !insertMapFile(out,absMapName,relPath,mapName)) - { - int mapId = DotManager::instance()->addMap(fileName,absMapName,relPath, - TRUE,QCString(),mapName); - out << "<!-- MAP " << mapId << " -->" << endl; - } - } - } - else if (graphFormat==GOF_EPS) - { - if (regenerate || !writeVecGfxFigure(out,baseName,absBaseName)) - { - int figId = DotManager::instance()->addFigure(fileName,baseName,absBaseName,FALSE); - out << endl << "% FIG " << figId << endl; - } - } - if (!regenerate) removeDotGraph(absDotName); - - return baseName; -} - -bool DotDirDeps::isTrivial() const -{ - return m_dir->depGraphIsTrivial(); -} - -//------------------------------------------------------------- + friend void generateGraphLegend(const char* path); +}; void generateGraphLegend(const char *path) { QDir d(path); - // store the original directory - if (!d.exists()) - { - err("Output dir %s does not exist!\n",path); exit(1); - } - - QGString theGraph; - FTextStream md5stream(&theGraph); - writeGraphHeader(md5stream,theTranslator->trLegendTitle()); - md5stream << " Node9 [shape=\"box\",label=\"Inherited\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",fillcolor=\"grey75\",style=\"filled\" fontcolor=\"black\"];\n"; - md5stream << " Node10 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n"; - md5stream << " Node10 [shape=\"box\",label=\"PublicBase\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classPublicBase" << Doxygen::htmlFileExtension << "\"];\n"; - md5stream << " Node11 -> Node10 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n"; - md5stream << " Node11 [shape=\"box\",label=\"Truncated\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"red\",URL=\"$classTruncated" << Doxygen::htmlFileExtension << "\"];\n"; - md5stream << " Node13 -> Node9 [dir=\"back\",color=\"darkgreen\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n"; - md5stream << " Node13 [shape=\"box\",label=\"ProtectedBase\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classProtectedBase" << Doxygen::htmlFileExtension << "\"];\n"; - md5stream << " Node14 -> Node9 [dir=\"back\",color=\"firebrick4\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n"; - md5stream << " Node14 [shape=\"box\",label=\"PrivateBase\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classPrivateBase" << Doxygen::htmlFileExtension << "\"];\n"; - md5stream << " Node15 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n"; - md5stream << " Node15 [shape=\"box\",label=\"Undocumented\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"grey75\"];\n"; - md5stream << " Node16 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n"; - md5stream << " Node16 [shape=\"box\",label=\"Templ< int >\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension << "\"];\n"; - md5stream << " Node17 -> Node16 [dir=\"back\",color=\"orange\",fontsize=\"" << FONTSIZE << "\",style=\"dashed\",label=\"< int >\",fontname=\"" << FONTNAME << "\"];\n"; - md5stream << " Node17 [shape=\"box\",label=\"Templ< T >\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension << "\"];\n"; - md5stream << " Node18 -> Node9 [dir=\"back\",color=\"darkorchid3\",fontsize=\"" << FONTSIZE << "\",style=\"dashed\",label=\"m_usedClass\",fontname=\"" << FONTNAME << "\"];\n"; - md5stream << " Node18 [shape=\"box\",label=\"Used\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classUsed" << Doxygen::htmlFileExtension << "\"];\n"; - writeGraphFooter(md5stream); - uchar md5_sig[16]; - QCString sigStr(33); - MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig); - MD5SigToString(md5_sig,sigStr.rawData(),33); - QCString absBaseName = (QCString)path+"/graph_legend"; - QCString absDotName = absBaseName+".dot"; - QCString imgExt = getDotImageExtension(); - QCString imgFmt = Config_getEnum(DOT_IMAGE_FORMAT); - QCString imgName = "graph_legend."+imgExt; - QCString absImgName = absBaseName+"."+imgExt; - if (checkAndUpdateMd5Signature(absBaseName,sigStr) || - !checkDeliverables(absImgName)) - { - QFile dotFile(absDotName); - if (!dotFile.open(IO_WriteOnly)) - { - err("Could not open file %s for writing\n",dotFile.name().data()); - return; - } - - FTextStream dotText(&dotFile); - dotText << theGraph; - dotFile.close(); - - // run dot to generate the a bitmap image from the graph + GraphLegendDotGraph dg; + FTextStream ts; + dg.writeGraph(ts, GOF_BITMAP, EOF_Html, path, "", "", FALSE, 0); - DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),TRUE,absImgName); - dotRun->addJob(imgFmt,absImgName); - DotManager::instance()->addRun(dotRun); - } - else - { - removeDotGraph(absDotName); - } - Doxygen::indexList->addImageFile(imgName); - - if (imgExt=="svg") + if (getDotImageExtension()=="svg") { DotManager::instance()->addSVGObject( - absBaseName+Config_getString(HTML_FILE_EXTENSION), + dg.absBaseName()+Config_getString(HTML_FILE_EXTENSION), "graph_legend", - absImgName,QCString()); + dg.absImgName(),QCString()); } } @@ -4248,19 +493,20 @@ void writeDotGraphFromFile(const char *inFile,const char *outDir, } QCString imgExt = getDotImageExtension(); - QCString imgFmt = Config_getEnum(DOT_IMAGE_FORMAT); QCString imgName = (QCString)outFile+"."+imgExt; QCString absImgName = d.absPath().utf8()+"/"+imgName; QCString absOutFile = d.absPath().utf8()+"/"+outFile; - DotRunner dotRun(inFile,d.absPath().data(),FALSE,absImgName); + DotRunner dotRun(inFile, QCString()); if (format==GOF_BITMAP) - dotRun.addJob(imgFmt,absImgName); + { + dotRun.addJob(Config_getEnum(DOT_IMAGE_FORMAT),absImgName); + } else // format==GOF_EPS { if (Config_getBool(USE_PDFLATEX)) { - dotRun.addJob("pdf",absOutFile+".pdf",absOutFile); + dotRun.addJob("pdf",absOutFile+".pdf"); } else { @@ -4274,13 +520,10 @@ void writeDotGraphFromFile(const char *inFile,const char *outDir, return; } - if (format==GOF_BITMAP) checkDotResult(getDotImageExtension(),absImgName); - Doxygen::indexList->addImageFile(imgName); } - /*! Writes user defined image map to the output. * \param t text stream to write to * \param inFile just the basename part of the filename @@ -4304,11 +547,10 @@ void writeDotImageMapFromFile(FTextStream &t, QCString mapName = baseName+".map"; QCString imgExt = getDotImageExtension(); - QCString imgFmt = Config_getEnum(DOT_IMAGE_FORMAT); QCString imgName = baseName+"."+imgExt; QCString absOutFile = d.absPath().utf8()+"/"+mapName; - DotRunner dotRun(inFile,d.absPath().data(),FALSE); + DotRunner dotRun(inFile, QCString()); dotRun.addJob(MAP_CMD,absOutFile); dotRun.preventCleanUp(); if (!dotRun.run()) @@ -4323,7 +565,7 @@ void writeDotImageMapFromFile(FTextStream &t, QCString svgName=outDir+"/"+baseName+".svg"; writeSVGFigureLink(t,relPath,baseName,svgName); DotFilePatcher patcher(svgName); - patcher.addSVGConversion(relPath,TRUE,context,TRUE,graphId); + patcher.addSVGConversion("",TRUE,context,TRUE,graphId); patcher.run(); } else // bitmap graphics @@ -4343,628 +585,3 @@ void writeDotImageMapFromFile(FTextStream &t, } d.remove(absOutFile); } - -//------------------------------------------------------------- - -int DotGroupCollaboration::m_curNodeNumber = 0; - -void DotGroupCollaboration::resetNumbering() -{ - m_curNodeNumber = 0; -} - -DotGroupCollaboration::DotGroupCollaboration(GroupDef* gd) -{ - QCString tmp_url = gd->getReference()+"$"+gd->getOutputFileBase(); - m_usedNodes = new QDict<DotNode>(1009); - QCString tooltip = gd->briefDescriptionAsTooltip(); - m_rootNode = new DotNode(m_curNodeNumber++, gd->groupTitle(), tooltip, tmp_url, TRUE ); - m_rootNode->markAsVisible(); - m_usedNodes->insert(gd->name(), m_rootNode ); - m_edges.setAutoDelete(TRUE); - - m_diskName = gd->getOutputFileBase(); - - buildGraph( gd ); -} - -DotGroupCollaboration::~DotGroupCollaboration() -{ - delete m_usedNodes; -} - -void DotGroupCollaboration::buildGraph(GroupDef* gd) -{ - QCString tmp_url; - //=========================== - // hierarchy. - - // Write parents - GroupList *groups = gd->partOfGroups(); - if ( groups ) - { - GroupListIterator gli(*groups); - GroupDef *d; - for (gli.toFirst();(d=gli.current());++gli) - { - DotNode* nnode = m_usedNodes->find(d->name()); - if ( !nnode ) - { // add node - tmp_url = d->getReference()+"$"+d->getOutputFileBase(); - QCString tooltip = d->briefDescriptionAsTooltip(); - nnode = new DotNode(m_curNodeNumber++, d->groupTitle(), tooltip, tmp_url ); - nnode->markAsVisible(); - m_usedNodes->insert(d->name(), nnode ); - } - tmp_url = ""; - addEdge( nnode, m_rootNode, DotGroupCollaboration::thierarchy, tmp_url, tmp_url ); - } - } - - // Add subgroups - if ( gd->getSubGroups() && gd->getSubGroups()->count() ) - { - QListIterator<GroupDef> defli(*gd->getSubGroups()); - GroupDef *def; - for (;(def=defli.current());++defli) - { - DotNode* nnode = m_usedNodes->find(def->name()); - if ( !nnode ) - { // add node - tmp_url = def->getReference()+"$"+def->getOutputFileBase(); - QCString tooltip = def->briefDescriptionAsTooltip(); - nnode = new DotNode(m_curNodeNumber++, def->groupTitle(), tooltip, tmp_url ); - nnode->markAsVisible(); - m_usedNodes->insert(def->name(), nnode ); - } - tmp_url = ""; - addEdge( m_rootNode, nnode, DotGroupCollaboration::thierarchy, tmp_url, tmp_url ); - } - } - - //======================= - // Write collaboration - - // Add members - addMemberList( gd->getMemberList(MemberListType_allMembersList) ); - - // Add classes - if ( gd->getClasses() && gd->getClasses()->count() ) - { - ClassSDict::Iterator defli(*gd->getClasses()); - ClassDef *def; - for (;(def=defli.current());++defli) - { - tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension; - if (!def->anchor().isEmpty()) - { - tmp_url+="#"+def->anchor(); - } - addCollaborationMember( def, tmp_url, DotGroupCollaboration::tclass ); - } - } - - // Add namespaces - if ( gd->getNamespaces() && gd->getNamespaces()->count() ) - { - NamespaceSDict::Iterator defli(*gd->getNamespaces()); - NamespaceDef *def; - for (;(def=defli.current());++defli) - { - tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension; - addCollaborationMember( def, tmp_url, DotGroupCollaboration::tnamespace ); - } - } - - // Add files - if ( gd->getFiles() && gd->getFiles()->count() ) - { - QListIterator<FileDef> defli(*gd->getFiles()); - FileDef *def; - for (;(def=defli.current());++defli) - { - tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension; - addCollaborationMember( def, tmp_url, DotGroupCollaboration::tfile ); - } - } - - // Add pages - if ( gd->getPages() && gd->getPages()->count() ) - { - PageSDict::Iterator defli(*gd->getPages()); - PageDef *def; - for (;(def=defli.current());++defli) - { - tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension; - addCollaborationMember( def, tmp_url, DotGroupCollaboration::tpages ); - } - } - - // Add directories - if ( gd->getDirs() && gd->getDirs()->count() ) - { - QListIterator<DirDef> defli(*gd->getDirs()); - DirDef *def; - for (;(def=defli.current());++defli) - { - tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension; - addCollaborationMember( def, tmp_url, DotGroupCollaboration::tdir ); - } - } -} - -void DotGroupCollaboration::addMemberList( MemberList* ml ) -{ - if ( !( ml && ml->count()) ) return; - MemberListIterator defli(*ml); - MemberDef *def; - for (;(def=defli.current());++defli) - { - QCString tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension - +"#"+def->anchor(); - addCollaborationMember( def, tmp_url, DotGroupCollaboration::tmember ); - } -} - -DotGroupCollaboration::Edge* DotGroupCollaboration::addEdge( - DotNode* _pNStart, DotNode* _pNEnd, EdgeType _eType, - const QCString& _label, const QCString& _url ) -{ - // search a existing link. - QListIterator<Edge> lli(m_edges); - Edge* newEdge = 0; - for ( lli.toFirst(); (newEdge=lli.current()); ++lli) - { - if ( newEdge->pNStart==_pNStart && - newEdge->pNEnd==_pNEnd && - newEdge->eType==_eType - ) - { // edge already found - break; - } - } - if ( newEdge==0 ) // new link - { - newEdge = new Edge(_pNStart,_pNEnd,_eType); - m_edges.append( newEdge ); - } - - if (!_label.isEmpty()) - { - newEdge->links.append(new Link(_label,_url)); - } - - return newEdge; -} - -void DotGroupCollaboration::addCollaborationMember( - Definition* def, QCString& url, EdgeType eType ) -{ - // Create group nodes - if ( !def->partOfGroups() ) - return; - GroupListIterator gli(*def->partOfGroups()); - GroupDef *d; - QCString tmp_str; - for (;(d=gli.current());++gli) - { - DotNode* nnode = m_usedNodes->find(d->name()); - if ( nnode != m_rootNode ) - { - if ( nnode==0 ) - { // add node - tmp_str = d->getReference()+"$"+d->getOutputFileBase(); - QCString tooltip = d->briefDescriptionAsTooltip(); - nnode = new DotNode(m_curNodeNumber++, d->groupTitle(), tooltip, tmp_str ); - nnode->markAsVisible(); - m_usedNodes->insert(d->name(), nnode ); - } - tmp_str = def->qualifiedName(); - addEdge( m_rootNode, nnode, eType, tmp_str, url ); - } - } -} - - -QCString DotGroupCollaboration::writeGraph( FTextStream &t, - GraphOutputFormat graphFormat, EmbeddedOutputFormat textFormat, - const char *path, const char *fileName, const char *relPath, - bool writeImageMap,int graphId) const -{ - QDir d(path); - // store the original directory - if (!d.exists()) - { - err("Output dir %s does not exist!\n",path); exit(1); - } - static bool usePDFLatex = Config_getBool(USE_PDFLATEX); - - QGString theGraph; - FTextStream md5stream(&theGraph); - writeGraphHeader(md5stream,m_rootNode->label()); - - // clean write flags - QDictIterator<DotNode> dni(*m_usedNodes); - DotNode *pn; - for (dni.toFirst();(pn=dni.current());++dni) - { - pn->clearWriteFlag(); - } - - // write other nodes. - for (dni.toFirst();(pn=dni.current());++dni) - { - pn->write(md5stream,DotNode::Inheritance,graphFormat,TRUE,FALSE,FALSE); - } - - // write edges - QListIterator<Edge> eli(m_edges); - Edge* edge; - for (eli.toFirst();(edge=eli.current());++eli) - { - edge->write( md5stream ); - } - - writeGraphFooter(md5stream); - uchar md5_sig[16]; - QCString sigStr(33); - MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig); - MD5SigToString(md5_sig,sigStr.rawData(),33); - QCString imgExt = getDotImageExtension(); - QCString imgFmt = Config_getEnum(DOT_IMAGE_FORMAT); - QCString baseName = m_diskName; - QCString imgName = baseName+"."+imgExt; - QCString absPath = d.absPath().data(); - QCString absBaseName = absPath+"/"+baseName; - QCString absDotName = absBaseName+".dot"; - QCString absImgName = absBaseName+"."+imgExt; - QCString absMapName = absBaseName+".map"; - QCString absPdfName = absBaseName+".pdf"; - QCString absEpsName = absBaseName+".eps"; - bool regenerate=FALSE; - if (checkAndUpdateMd5Signature(absBaseName,sigStr) || - !checkDeliverables(graphFormat==GOF_BITMAP ? absImgName : - usePDFLatex ? absPdfName : absEpsName, - graphFormat==GOF_BITMAP /*&& generateImageMap*/ ? absMapName : QCString()) - ) - { - regenerate=TRUE; - - QFile dotfile(absDotName); - if (dotfile.open(IO_WriteOnly)) - { - FTextStream tdot(&dotfile); - tdot << theGraph; - dotfile.close(); - } - - if (graphFormat==GOF_BITMAP) // run dot to create a bitmap image - { - DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); - dotRun->addJob(imgFmt,absImgName); - if (writeImageMap) dotRun->addJob(MAP_CMD,absMapName); - DotManager::instance()->addRun(dotRun); - - } - else if (graphFormat==GOF_EPS) - { - DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),FALSE); - if (usePDFLatex) - { - dotRun->addJob("pdf",absPdfName,absBaseName); - } - else - { - dotRun->addJob("ps",absEpsName); - } - DotManager::instance()->addRun(dotRun); - } - - } - if (graphFormat==GOF_BITMAP && textFormat==EOF_DocBook) - { - t << "<para>" << endl; - t << " <informalfigure>" << endl; - t << " <mediaobject>" << endl; - t << " <imageobject>" << endl; - t << " <imagedata"; - t << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << relPath << baseName << "." << imgExt << "\">"; - t << "</imagedata>" << endl; - t << " </imageobject>" << endl; - t << " </mediaobject>" << endl; - t << " </informalfigure>" << endl; - t << "</para>" << endl; - } - else if (graphFormat==GOF_BITMAP && writeImageMap) - { - QCString mapLabel = escapeCharsInString(baseName,FALSE); - t << "<center><table><tr><td>"; - - if (imgExt=="svg") - { - t << "<div class=\"center\">"; - if (regenerate || !writeSVGFigureLink(t,relPath,baseName,absImgName)) // need to patch the links in the generated SVG file - { - if (regenerate) - { - DotManager::instance()->addSVGConversion(absImgName,relPath,FALSE,QCString(),TRUE,graphId); - } - int mapId = DotManager::instance()->addSVGObject(fileName,baseName,absImgName,relPath); - t << "<!-- SVG " << mapId << " -->" << endl; - } - t << "</div>" << endl; - } - else - { - t << "<img src=\"" << relPath << imgName - << "\" border=\"0\" alt=\"\" usemap=\"#" - << mapLabel << "\"/>" << endl; - if (regenerate || !insertMapFile(t,absMapName,relPath,mapLabel)) - { - int mapId = DotManager::instance()->addMap(fileName,absMapName,relPath, - FALSE,QCString(),mapLabel); - t << "<!-- MAP " << mapId << " -->" << endl; - } - } - t << "</td></tr></table></center>" << endl; - } - else if (graphFormat==GOF_EPS) - { - if (regenerate || !writeVecGfxFigure(t,baseName,absBaseName)) - { - int figId = DotManager::instance()->addFigure(fileName,baseName,absBaseName,FALSE); - t << endl << "% FIG " << figId << endl; - } - } - if (!regenerate) removeDotGraph(absDotName); - - return baseName; -} - -void DotGroupCollaboration::Edge::write( FTextStream &t ) const -{ - const char* linkTypeColor[] = { - "darkorchid3" - ,"orange" - ,"blueviolet" - ,"darkgreen" - ,"firebrick4" - ,"grey75" - ,"midnightblue" - }; - QCString arrowStyle = "dir=\"none\", style=\"dashed\""; - t << " Node" << pNStart->number(); - t << "->"; - t << "Node" << pNEnd->number(); - - t << " [shape=plaintext"; - if (links.count()>0) // there are links - { - t << ", "; - // HTML-like edge labels crash on my Mac with Graphviz 2.0! and - // are not supported by older version of dot. - // - //t << label=<<TABLE BORDER=\"0\" CELLBORDER=\"0\">"; - //QListIterator<Link> lli(links); - //Link *link; - //for( lli.toFirst(); (link=lli.current()); ++lli) - //{ - // t << "<TR><TD"; - // if ( !link->url.isEmpty() ) - // t << " HREF=\"" << link->url << "\""; - // t << ">" << link->label << "</TD></TR>"; - //} - //t << "</TABLE>>"; - - t << "label=\""; - QListIterator<Link> lli(links); - Link *link; - bool first=TRUE; - int count=0; - const int maxLabels = 10; - for( lli.toFirst(); (link=lli.current()) && count<maxLabels; ++lli,++count) - { - if (first) first=FALSE; else t << "\\n"; - t << convertLabel(link->label); - } - if (count==maxLabels) t << "\\n..."; - t << "\""; - - } - switch( eType ) - { - case thierarchy: - arrowStyle = "dir=\"back\", style=\"solid\""; - break; - default: - t << ", color=\"" << linkTypeColor[(int)eType] << "\""; - break; - } - t << ", " << arrowStyle; - t << "];" << endl; -} - -bool DotGroupCollaboration::isTrivial() const -{ - return m_usedNodes->count() <= 1; -} - -void DotGroupCollaboration::writeGraphHeader(FTextStream &t, - const QCString &title) const -{ - t << "digraph "; - if (title.isEmpty()) - { - t << "\"Dot Graph\""; - } - else - { - t << "\"" << convertToXML(title) << "\""; - } - t << endl; - t << "{" << endl; - if (Config_getBool(DOT_TRANSPARENT)) - { - t << " bgcolor=\"transparent\";" << endl; - } - t << " edge [fontname=\"" << FONTNAME << "\",fontsize=\"" << FONTSIZE << "\"," - "labelfontname=\"" << FONTNAME << "\",labelfontsize=\"" << FONTSIZE << "\"];\n"; - t << " node [fontname=\"" << FONTNAME << "\",fontsize=\"" << FONTSIZE << "\",shape=box];\n"; - t << " rankdir=LR;\n"; -} - -void writeDotDirDepGraph(FTextStream &t,DirDef *dd,bool linkRelations) -{ - t << "digraph \"" << dd->displayName() << "\" {\n"; - if (Config_getBool(DOT_TRANSPARENT)) - { - t << " bgcolor=transparent;\n"; - } - t << " compound=true\n"; - t << " node [ fontsize=\"" << FONTSIZE << "\", fontname=\"" << FONTNAME << "\"];\n"; - t << " edge [ labelfontsize=\"" << FONTSIZE << "\", labelfontname=\"" << FONTNAME << "\"];\n"; - - QDict<DirDef> dirsInGraph(257); - - dirsInGraph.insert(dd->getOutputFileBase(),dd); - if (dd->parent()) - { - t << " subgraph cluster" << dd->parent()->getOutputFileBase() << " {\n"; - t << " graph [ bgcolor=\"#ddddee\", pencolor=\"black\", label=\"" - << dd->parent()->shortName() - << "\" fontname=\"" << FONTNAME << "\", fontsize=\"" << FONTSIZE << "\", URL=\""; - t << dd->parent()->getOutputFileBase() << Doxygen::htmlFileExtension; - t << "\"]\n"; - } - if (dd->isCluster()) - { - t << " subgraph cluster" << dd->getOutputFileBase() << " {\n"; - t << " graph [ bgcolor=\"#eeeeff\", pencolor=\"black\", label=\"\"" - << " URL=\"" << dd->getOutputFileBase() << Doxygen::htmlFileExtension - << "\"];\n"; - t << " " << dd->getOutputFileBase() << " [shape=plaintext label=\"" - << dd->shortName() << "\"];\n"; - - // add nodes for sub directories - QListIterator<DirDef> sdi(dd->subDirs()); - DirDef *sdir; - for (sdi.toFirst();(sdir=sdi.current());++sdi) - { - t << " " << sdir->getOutputFileBase() << " [shape=box label=\"" - << sdir->shortName() << "\""; - if (sdir->isCluster()) - { - t << " color=\"red\""; - } - else - { - t << " color=\"black\""; - } - t << " fillcolor=\"white\" style=\"filled\""; - t << " URL=\"" << sdir->getOutputFileBase() - << Doxygen::htmlFileExtension << "\""; - t << "];\n"; - dirsInGraph.insert(sdir->getOutputFileBase(),sdir); - } - t << " }\n"; - } - else - { - t << " " << dd->getOutputFileBase() << " [shape=box, label=\"" - << dd->shortName() << "\", style=\"filled\", fillcolor=\"#eeeeff\"," - << " pencolor=\"black\", URL=\"" << dd->getOutputFileBase() - << Doxygen::htmlFileExtension << "\"];\n"; - } - if (dd->parent()) - { - t << " }\n"; - } - - // add nodes for other used directories - QDictIterator<UsedDir> udi(*dd->usedDirs()); - UsedDir *udir; - //printf("*** For dir %s\n",shortName().data()); - for (udi.toFirst();(udir=udi.current());++udi) - // for each used dir (=directly used or a parent of a directly used dir) - { - const DirDef *usedDir=udir->dir(); - DirDef *dir=dd; - while (dir) - { - //printf("*** check relation %s->%s same_parent=%d !%s->isParentOf(%s)=%d\n", - // dir->shortName().data(),usedDir->shortName().data(), - // dir->parent()==usedDir->parent(), - // usedDir->shortName().data(), - // shortName().data(), - // !usedDir->isParentOf(this) - // ); - if (dir!=usedDir && dir->parent()==usedDir->parent() && - !usedDir->isParentOf(dd)) - // include if both have the same parent (or no parent) - { - t << " " << usedDir->getOutputFileBase() << " [shape=box label=\"" - << usedDir->shortName() << "\""; - if (usedDir->isCluster()) - { - if (!Config_getBool(DOT_TRANSPARENT)) - { - t << " fillcolor=\"white\" style=\"filled\""; - } - t << " color=\"red\""; - } - t << " URL=\"" << usedDir->getOutputFileBase() - << Doxygen::htmlFileExtension << "\"];\n"; - dirsInGraph.insert(usedDir->getOutputFileBase(),usedDir); - break; - } - dir=dir->parent(); - } - } - - // add relations between all selected directories - DirDef *dir; - QDictIterator<DirDef> di(dirsInGraph); - for (di.toFirst();(dir=di.current());++di) // foreach dir in the graph - { - QDictIterator<UsedDir> udi(*dir->usedDirs()); - UsedDir *udir; - for (udi.toFirst();(udir=udi.current());++udi) // foreach used dir - { - const DirDef *usedDir=udir->dir(); - if ((dir!=dd || !udir->inherited()) && // only show direct dependendies for this dir - (usedDir!=dd || !udir->inherited()) && // only show direct dependendies for this dir - !usedDir->isParentOf(dir) && // don't point to own parent - dirsInGraph.find(usedDir->getOutputFileBase())) // only point to nodes that are in the graph - { - QCString relationName; - relationName.sprintf("dir_%06d_%06d",dir->dirCount(),usedDir->dirCount()); - if (Doxygen::dirRelations.find(relationName)==0) - { - // new relation - Doxygen::dirRelations.append(relationName, - new DirRelation(relationName,dir,udir)); - } - int nrefs = udir->filePairs().count(); - t << " " << dir->getOutputFileBase() << "->" - << usedDir->getOutputFileBase(); - t << " [headlabel=\"" << nrefs << "\", labeldistance=1.5"; - if (linkRelations) - { - t << " headhref=\"" << relationName << Doxygen::htmlFileExtension << "\""; - } - t << "];\n"; - } - } - } - - t << "}\n"; -} - -void resetDotNodeNumbering() -{ - DotClassGraph::resetNumbering(); - DotInclDepGraph::resetNumbering(); - DotCallGraph::resetNumbering(); - DotGroupCollaboration::resetNumbering(); -} - @@ -1,13 +1,10 @@ /****************************************************************************** * - * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2019 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -16,8 +13,8 @@ * */ -#ifndef _DOT_H -#define _DOT_H +#ifndef DOT_H +#define DOT_H #include <qlist.h> #include <qdict.h> @@ -26,466 +23,24 @@ #include <qqueue.h> #include <qthread.h> #include "sortdict.h" -#include "classdef.h" +#include "qgstring.h" +#include "qdir.h" +#include "qcstring.h" +#include "dotgraph.h" +#include "dotfilepatcher.h" +#include "dotrunner.h" -class FileDef; class FTextStream; -class DotNodeList; -class ClassSDict; -class MemberDef; -class Definition; -class DirDef; -class GroupDef; -class DotGroupCollaboration; +class DotRunner; class DotRunnerQueue; - -enum GraphOutputFormat { GOF_BITMAP, GOF_EPS }; -enum EmbeddedOutputFormat { EOF_Html, EOF_LaTeX, EOF_Rtf, EOF_DocBook }; - -// the graphicx LaTeX has a limitation of maximum size of 16384 -// To be on the save side we take it a little bit smaller i.e. 150 inch * 72 dpi -// It is anyway hard to view these size of images -#define MAX_LATEX_GRAPH_INCH 150 -#define MAX_LATEX_GRAPH_SIZE (MAX_LATEX_GRAPH_INCH * 72) - -/** Attributes of an edge of a dot graph */ -struct EdgeInfo -{ - enum Colors { Blue=0, Green=1, Red=2, Purple=3, Grey=4, Orange=5, Orange2=6 }; - enum Styles { Solid=0, Dashed=1 }; - EdgeInfo() : m_color(0), m_style(0), m_labColor(0) {} - ~EdgeInfo() {} - int m_color; - int m_style; - QCString m_label; - QCString m_url; - int m_labColor; -}; - -/** A node in a dot graph */ -class DotNode -{ - public: - enum GraphType { Dependency, Inheritance, Collaboration, Hierarchy, CallGraph }; - enum TruncState { Unknown, Truncated, Untruncated }; - DotNode(int n,const char *lab,const char *tip,const char *url, - bool rootNode=FALSE,ClassDef *cd=0); - ~DotNode(); - void addChild(DotNode *n, - int edgeColor=EdgeInfo::Purple, - int edgeStyle=EdgeInfo::Solid, - const char *edgeLab=0, - const char *edgeURL=0, - int edgeLabCol=-1 - ); - void addParent(DotNode *n); - void deleteNode(DotNodeList &deletedList,SDict<DotNode> *skipNodes=0); - void removeChild(DotNode *n); - void removeParent(DotNode *n); - int findParent( DotNode *n ); - void write(FTextStream &t,GraphType gt,GraphOutputFormat f, - bool topDown,bool toChildren,bool backArrows); - int m_subgraphId; - void clearWriteFlag(); - void writeXML(FTextStream &t,bool isClassGraph); - void writeDocbook(FTextStream &t,bool isClassGraph); - void writeDEF(FTextStream &t); - QCString label() const { return m_label; } - int number() const { return m_number; } - bool isVisible() const { return m_visible; } - TruncState isTruncated() const { return m_truncated; } - int distance() const { return m_distance; } - void renumberNodes(int &number); - - private: - void colorConnectedNodes(int curColor); - void writeBox(FTextStream &t,GraphType gt,GraphOutputFormat f, - bool hasNonReachableChildren); - void writeArrow(FTextStream &t,GraphType gt,GraphOutputFormat f,DotNode *cn, - EdgeInfo *ei,bool topDown, bool pointBack=TRUE); - void setDistance(int distance); - const DotNode *findDocNode() const; // only works for acyclic graphs! - void markAsVisible(bool b=TRUE) { m_visible=b; } - void markAsTruncated(bool b=TRUE) { m_truncated=b ? Truncated : Untruncated; } - int m_number; - QCString m_label; //!< label text - QCString m_tooltip; //!< node's tooltip - QCString m_url; //!< url of the node (format: remote$local) - QList<DotNode> *m_parents; //!< list of parent nodes (incoming arrows) - QList<DotNode> *m_children; //!< list of child nodes (outgoing arrows) - QList<EdgeInfo> *m_edgeInfo; //!< edge info for each child - bool m_deleted; //!< used to mark a node as deleted - bool m_written; //!< used to mark a node as written - bool m_hasDoc; //!< used to mark a node as documented - bool m_isRoot; //!< indicates if this is a root node - ClassDef * m_classDef; //!< class representing this node (can be 0) - bool m_visible; //!< is the node visible in the output - TruncState m_truncated; //!< does the node have non-visible children/parents - int m_distance; //!< shortest path to the root node - bool m_renumbered;//!< indicates if the node has been renumbered (to prevent endless loops) - - friend class DotGfxHierarchyTable; - friend class DotClassGraph; - friend class DotInclDepGraph; - friend class DotNodeList; - friend class DotCallGraph; - friend class DotGroupCollaboration; - friend class DotInheritanceGraph; - - friend QCString computeMd5Signature( - DotNode *root, GraphType gt, - GraphOutputFormat f, - const QCString &rank, - bool renderParents, - bool backArrows, - const QCString &title, - QCString &graphStr - ); -}; - -/** Class representing a list of DotNode objects. */ -class DotNodeList : public QList<DotNode> -{ - public: - DotNodeList() : QList<DotNode>() {} - ~DotNodeList() {} - private: - int compareValues(const DotNode *n1,const DotNode *n2) const; -}; - -/** Represents a graphical class hierarchy */ -class DotGfxHierarchyTable -{ - public: - DotGfxHierarchyTable(const char *prefix="",ClassDef::CompoundType ct=ClassDef::Class); - ~DotGfxHierarchyTable(); - void writeGraph(FTextStream &t,const char *path, const char *fileName) const; - void createGraph(DotNode *rootNode,FTextStream &t,const char *path,const char *fileName,int id) const; - const DotNodeList *subGraphs() const { return m_rootSubgraphs; } - - private: - void addHierarchy(DotNode *n,ClassDef *cd,bool hide); - void addClassList(ClassSDict *cl); - - QCString m_prefix; - ClassDef::CompoundType m_classType; - QList<DotNode> *m_rootNodes; - QDict<DotNode> *m_usedNodes; - int m_curNodeNumber; - DotNodeList *m_rootSubgraphs; -}; - -/** Representation of a class inheritance or dependency graph */ -class DotClassGraph -{ - public: - DotClassGraph(ClassDef *cd,DotNode::GraphType t); - ~DotClassGraph(); - bool isTrivial() const; - bool isTooBig() const; - QCString writeGraph(FTextStream &t,GraphOutputFormat gf,EmbeddedOutputFormat ef, - const char *path, const char *fileName, const char *relPath, - bool TBRank=TRUE,bool imageMap=TRUE,int graphId=-1) const; - - void writeXML(FTextStream &t); - void writeDocbook(FTextStream &t); - void writeDEF(FTextStream &t); - static void resetNumbering(); - - private: - void buildGraph(ClassDef *cd,DotNode *n,bool base,int distance); - bool determineVisibleNodes(DotNode *rootNode,int maxNodes,bool includeParents); - void determineTruncatedNodes(QList<DotNode> &queue,bool includeParents); - void addClass(ClassDef *cd,DotNode *n,int prot,const char *label, - const char *usedName,const char *templSpec, - bool base,int distance); - - DotNode * m_startNode; - QDict<DotNode> * m_usedNodes; - static int m_curNodeNumber; - DotNode::GraphType m_graphType; - QCString m_collabFileName; - QCString m_inheritFileName; - bool m_lrRank; -}; - -/** Representation of an include dependency graph */ -class DotInclDepGraph -{ - public: - DotInclDepGraph(FileDef *fd,bool inverse); - ~DotInclDepGraph(); - QCString writeGraph(FTextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, - const char *path,const char *fileName,const char *relPath, - bool writeImageMap=TRUE,int graphId=-1) const; - bool isTrivial() const; - bool isTooBig() const; - QCString diskName() const; - void writeXML(FTextStream &t); - void writeDocbook(FTextStream &t); - static void resetNumbering(); - - private: - void buildGraph(DotNode *n,FileDef *fd,int distance); - void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes); - void determineTruncatedNodes(QList<DotNode> &queue); - - DotNode *m_startNode; - QDict<DotNode> *m_usedNodes; - static int m_curNodeNumber; - QCString m_inclDepFileName; - QCString m_inclByDepFileName; - bool m_inverse; -}; - -/** Representation of an call graph */ -class DotCallGraph -{ - public: - DotCallGraph(MemberDef *md,bool inverse); - ~DotCallGraph(); - QCString writeGraph(FTextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, - const char *path,const char *fileName, - const char *relPath,bool writeImageMap=TRUE, - int graphId=-1) const; - void buildGraph(DotNode *n,MemberDef *md,int distance); - bool isTrivial() const; - bool isTooBig() const; - void determineVisibleNodes(QList<DotNode> &queue, int &maxNodes); - void determineTruncatedNodes(QList<DotNode> &queue); - static void resetNumbering(); - - private: - DotNode *m_startNode; - static int m_curNodeNumber; - QDict<DotNode> *m_usedNodes; - bool m_inverse; - QCString m_diskName; - Definition * m_scope; -}; - -/** Representation of an directory dependency graph */ -class DotDirDeps -{ - public: - DotDirDeps(DirDef *dir); - ~DotDirDeps(); - bool isTrivial() const; - QCString writeGraph(FTextStream &out, - GraphOutputFormat gf, - EmbeddedOutputFormat ef, - const char *path, - const char *fileName, - const char *relPath, - bool writeImageMap=TRUE, - int graphId=-1, - bool linkRelations=TRUE) const; - private: - DirDef *m_dir; -}; - -/** Representation of a group collaboration graph */ -class DotGroupCollaboration -{ - public : - enum EdgeType - { tmember = 0, - tclass, - tnamespace, - tfile, - tpages, - tdir, - thierarchy - }; - - class Link - { - public: - Link(const QCString lab,const QCString &u) : label(lab), url(u) {} - QCString label; - QCString url; - }; - - class Edge - { - public : - Edge(DotNode *start,DotNode *end,EdgeType type) - : pNStart(start), pNEnd(end), eType(type) - { links.setAutoDelete(TRUE); } - - DotNode* pNStart; - DotNode* pNEnd; - EdgeType eType; - - QList<Link> links; - void write( FTextStream &t ) const; - }; - - DotGroupCollaboration(GroupDef* gd); - ~DotGroupCollaboration(); - QCString writeGraph(FTextStream &t, GraphOutputFormat gf,EmbeddedOutputFormat ef, - const char *path,const char *fileName,const char *relPath, - bool writeImageMap=TRUE,int graphId=-1) const; - void buildGraph(GroupDef* gd); - bool isTrivial() const; - static void resetNumbering(); - - private : - void addCollaborationMember( Definition* def, QCString& url, EdgeType eType ); - void addMemberList( class MemberList* ml ); - void writeGraphHeader(FTextStream &t,const QCString &title) const; - Edge* addEdge( DotNode* _pNStart, DotNode* _pNEnd, EdgeType _eType, - const QCString& _label, const QCString& _url ); - - DotNode *m_rootNode; - static int m_curNodeNumber; - QDict<DotNode> *m_usedNodes; - QCString m_diskName; - QList<Edge> m_edges; -}; - -/** Minimal constant string class that is thread safe, once initialized. */ -class DotConstString -{ - public: - DotConstString() { m_str=0; m_pdfstr=0;} - ~DotConstString() { delete[] m_str; delete[] m_pdfstr;} - DotConstString(const QCString &s, const QCString &p = NULL) : m_str(0), m_pdfstr(0) { set(s); setpdf(p);} - DotConstString(const DotConstString &s) : m_str(0), m_pdfstr(0) { set(s.data()); } - const char *data() const { return m_str; } - const char *pdfData() const { return m_pdfstr; } - bool isEmpty() const { return m_str==0 || m_str[0]=='\0'; } - void set(const QCString &s) - { - delete[] m_str; - m_str=0; - if (!s.isEmpty()) - { - m_str=new char[s.length()+1]; - qstrcpy(m_str,s.data()); - } - } - void setpdf(const QCString &p) - { - delete[] m_pdfstr; - m_pdfstr=0; - if (!p.isEmpty()) - { - m_pdfstr=new char[p.length()+1]; - qstrcpy(m_pdfstr,p.data()); - } - } - private: - DotConstString &operator=(const DotConstString &); - char *m_str; - char *m_pdfstr; -}; - -/** Helper class to run dot from doxygen. - */ -class DotRunner -{ - public: - struct CleanupItem - { - DotConstString path; - DotConstString file; - }; - - /** Creates a runner for a dot \a file. */ - DotRunner(const QCString &file,const QCString &fontPath,bool checkResult, - const QCString &imageName = QCString()); - - /** Adds an additional job to the run. - * Performing multiple jobs one file can be faster. - */ - void addJob(const char *format,const char *output, const char *base = NULL); - - void addPostProcessing(const char *cmd,const char *args); - - void preventCleanUp() { m_cleanUp = FALSE; } - - /** Runs dot for all jobs added. */ - bool run(); - const CleanupItem &cleanup() const { return m_cleanupItem; } - - private: - DotConstString m_dotExe; - bool m_multiTargets; - QList<DotConstString> m_jobs; - DotConstString m_postArgs; - DotConstString m_postCmd; - DotConstString m_file; - DotConstString m_path; - bool m_checkResult; - DotConstString m_imageName; - DotConstString m_imgExt; - bool m_cleanUp; - CleanupItem m_cleanupItem; -}; - -/** Helper class to insert a set of map file into an output file */ -class DotFilePatcher -{ - public: - struct Map - { - QCString mapFile; - QCString relPath; - bool urlOnly; - QCString context; - QCString label; - bool zoomable; - int graphId; - }; - DotFilePatcher(const char *patchFile); - int addMap(const QCString &mapFile,const QCString &relPath, - bool urlOnly,const QCString &context,const QCString &label); - int addFigure(const QCString &baseName, - const QCString &figureName,bool heightCheck); - int addSVGConversion(const QCString &relPath,bool urlOnly, - const QCString &context,bool zoomable,int graphId); - int addSVGObject(const QCString &baseName, const QCString &figureName, - const QCString &relPath); - bool run(); - QCString file() const; - - private: - QList<Map> m_maps; - QCString m_patchFile; -}; - -/** Queue of dot jobs to run. */ -class DotRunnerQueue -{ - public: - void enqueue(DotRunner *runner); - DotRunner *dequeue(); - uint count() const; - private: - QWaitCondition m_bufferNotEmpty; - QQueue<DotRunner> m_queue; - mutable QMutex m_mutex; -}; - -/** Worker thread to execute a dot run */ -class DotWorkerThread : public QThread -{ - public: - DotWorkerThread(DotRunnerQueue *queue); - void run(); - void cleanup(); - private: - DotRunnerQueue *m_queue; - QList<DotRunner::CleanupItem> m_cleanupItems; -}; +class DotWorkerThread; /** Singleton that manages dot relation actions */ class DotManager { public: static DotManager *instance(); - void addRun(DotRunner *run); + DotRunner* createRunner(const QCString& absDotName, const QCString& md5Hash); int addMap(const QCString &file,const QCString &mapFile, const QCString &relPath,bool urlOnly, const QCString &context,const QCString &label); @@ -500,13 +55,15 @@ class DotManager private: DotManager(); virtual ~DotManager(); - QList<DotRunner> m_dotRuns; + + QDict<DotRunner> m_runners; SDict<DotFilePatcher> m_dotMaps; static DotManager *m_theInstance; DotRunnerQueue *m_queue; QList<DotWorkerThread> m_workers; }; +void initDot(); /** Generated a graphs legend page */ void generateGraphLegend(const char *path); @@ -517,7 +74,10 @@ void writeDotImageMapFromFile(FTextStream &t, const QCString& inFile, const QCString& outDir, const QCString& relPath,const QCString& baseName, const QCString& context,int graphId=-1); - -void resetDotNodeNumbering(); +bool writeSVGFigureLink(FTextStream &out,const QCString &relPath, + const QCString &baseName,const QCString &absImgName); +bool convertMapFile(FTextStream &t,const char *mapName, + const QCString relPath, bool urlOnly=FALSE, + const QCString &context=QCString()); #endif diff --git a/src/dotcallgraph.cpp b/src/dotcallgraph.cpp new file mode 100644 index 0000000..15d408a --- /dev/null +++ b/src/dotcallgraph.cpp @@ -0,0 +1,217 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#include "dotcallgraph.h" + +#include "dotnode.h" +#include "memberlist.h" +#include "config.h" +#include "util.h" + +#define HIDE_SCOPE_NAMES Config_getBool(HIDE_SCOPE_NAMES) +#define DOT_GRAPH_MAX_NODES Config_getInt(DOT_GRAPH_MAX_NODES) +#define MAX_DOT_GRAPH_DEPTH Config_getInt(MAX_DOT_GRAPH_DEPTH) + +void DotCallGraph::buildGraph(DotNode *n,const MemberDef *md,int distance) +{ + MemberSDict *refs = m_inverse ? md->getReferencedByMembers() : md->getReferencesMembers(); + if (refs) + { + refs->sort(); + MemberSDict::Iterator mri(*refs); + MemberDef *rmd; + for (;(rmd=mri.current());++mri) + { + if (rmd->showInCallGraph()) + { + QCString uniqueId; + uniqueId=rmd->getReference()+"$"+ + rmd->getOutputFileBase()+"#"+rmd->anchor(); + 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) + { + name = rmd->getOuterScope()==m_scope ? + rmd->name() : rmd->qualifiedName(); + } + else + { + 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); + + buildGraph(bn,rmd,distance+1); + } + } + } + } +} + +void DotCallGraph::determineVisibleNodes(QList<DotNode> &queue, int &maxNodes) +{ + while (queue.count()>0 && maxNodes>0) + { + DotNode *n = queue.take(0); + if (!n->isVisible() && n->distance()<=MAX_DOT_GRAPH_DEPTH) // not yet processed + { + n->markAsVisible(); + maxNodes--; + // add direct children + if (n->children()) + { + QListIterator<DotNode> li(*n->children()); + DotNode *dn; + for (li.toFirst();(dn=li.current());++li) + { + queue.append(dn); + } + } + } + } +} + +void DotCallGraph::determineTruncatedNodes(QList<DotNode> &queue) +{ + while (queue.count()>0) + { + DotNode *n = queue.take(0); + if (n->isVisible() && n->isTruncated()==DotNode::Unknown) + { + bool truncated = FALSE; + if (n->children()) + { + QListIterator<DotNode> li(*n->children()); + const DotNode *dn; + for (li.toFirst();(dn=li.current());++li) + { + if (!dn->isVisible()) + truncated = TRUE; + else + queue.append(dn); + } + } + n->markAsTruncated(truncated); + } + } +} + +DotCallGraph::DotCallGraph(const MemberDef *md,bool inverse) +{ + m_inverse = inverse; + m_diskName = md->getOutputFileBase()+"_"+md->anchor(); + m_scope = md->getOuterScope(); + QCString uniqueId; + uniqueId = md->getReference()+"$"+ + md->getOutputFileBase()+"#"+md->anchor(); + QCString name; + if (HIDE_SCOPE_NAMES) + { + name = md->name(); + } + else + { + name = md->qualifiedName(); + } + QCString tooltip = md->briefDescriptionAsTooltip(); + m_startNode = new DotNode(getNextNodeNumber(), + linkToText(md->getLanguage(),name,FALSE), + tooltip, + uniqueId.data(), + TRUE // root node + ); + m_startNode->setDistance(0); + m_usedNodes = new QDict<DotNode>(1009); + m_usedNodes->insert(uniqueId,m_startNode); + buildGraph(m_startNode,md,1); + + int maxNodes = DOT_GRAPH_MAX_NODES; + QList<DotNode> openNodeQueue; + openNodeQueue.append(m_startNode); + determineVisibleNodes(openNodeQueue,maxNodes); + openNodeQueue.clear(); + openNodeQueue.append(m_startNode); + determineTruncatedNodes(openNodeQueue); +} + +DotCallGraph::~DotCallGraph() +{ + DotNode::deleteNodes(m_startNode); + delete m_usedNodes; +} + +QCString DotCallGraph::getBaseName() const +{ + return m_diskName + (m_inverse ? "_icgraph" : "_cgraph"); +} + +void DotCallGraph::computeTheGraph() +{ + computeGraph( + m_startNode, + CallGraph, + m_graphFormat, + m_inverse ? "RL" : "LR", + FALSE, + m_inverse, + m_startNode->label(), + m_theGraph); +} + +QCString DotCallGraph::getMapLabel() const +{ + return m_baseName; +} + +QCString DotCallGraph::writeGraph( + FTextStream &out, + GraphOutputFormat graphFormat, + EmbeddedOutputFormat textFormat, + const char *path, + const char *fileName, + const char *relPath,bool generateImageMap, + int graphId) +{ + return DotGraph::writeGraph(out, graphFormat, textFormat, path, fileName, relPath, generateImageMap, graphId); +} + +bool DotCallGraph::isTrivial() const +{ + return m_startNode->children()==0; +} + +bool DotCallGraph::isTooBig() const +{ + int numNodes = m_startNode->children() ? m_startNode->children()->count() : 0; + return numNodes>=DOT_GRAPH_MAX_NODES; +} diff --git a/src/dotcallgraph.h b/src/dotcallgraph.h new file mode 100644 index 0000000..c96b9cf --- /dev/null +++ b/src/dotcallgraph.h @@ -0,0 +1,52 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#ifndef DOTCALLGRAPH_H +#define DOTCALLGRAPH_H + +#include "dotgraph.h" +#include "ftextstream.h" +#include "memberdef.h" + +/** Representation of an call graph */ +class DotCallGraph : public DotGraph +{ + public: + DotCallGraph(const MemberDef *md,bool inverse); + ~DotCallGraph(); + bool isTrivial() const; + bool isTooBig() const; + QCString writeGraph(FTextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, + const char *path,const char *fileName, + const char *relPath,bool writeImageMap=TRUE, + int graphId=-1); + + protected: + virtual QCString getBaseName() const; + virtual QCString getMapLabel() const; + virtual void computeTheGraph(); + + private: + void buildGraph(DotNode *n,const MemberDef *md,int distance); + void determineVisibleNodes(QList<DotNode> &queue, int &maxNodes); + void determineTruncatedNodes(QList<DotNode> &queue); + DotNode *m_startNode; + QDict<DotNode> *m_usedNodes; + bool m_inverse; + QCString m_diskName; + const Definition * m_scope; +}; + +#endif diff --git a/src/dotclassgraph.cpp b/src/dotclassgraph.cpp new file mode 100644 index 0000000..3f5d228 --- /dev/null +++ b/src/dotclassgraph.cpp @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#include "dotclassgraph.h" +#include "dotnode.h" + +#include "config.h" +#include "util.h" + +#define HIDE_SCOPE_NAMES Config_getBool(HIDE_SCOPE_NAMES) +#define MAX_DOT_GRAPH_DEPTH Config_getInt(MAX_DOT_GRAPH_DEPTH) +#define UML_LOOK Config_getBool(UML_LOOK) +#define TEMPLATE_RELATIONS Config_getBool(TEMPLATE_RELATIONS) +#define DOT_GRAPH_MAX_NODES Config_getInt(DOT_GRAPH_MAX_NODES) + +void DotClassGraph::addClass(const ClassDef *cd,DotNode *n,int prot, + const char *label,const char *usedName,const char *templSpec,bool base,int distance) +{ + if (Config_getBool(HIDE_UNDOC_CLASSES) && !cd->isLinkable()) return; + + int edgeStyle = (label || prot==EdgeInfo::Orange || prot==EdgeInfo::Orange2) ? EdgeInfo::Dashed : EdgeInfo::Solid; + QCString className; + if (cd->isAnonymous()) + { + className="anonymous:"; + className+=label; + } + else if (usedName) // name is a typedef + { + className=usedName; + } + else if (templSpec) // name has a template part + { + className=insertTemplateSpecifierInScope(cd->name(),templSpec); + } + else // just a normal name + { + className=cd->displayName(); + } + //printf("DotClassGraph::addClass(class='%s',parent=%s,prot=%d,label=%s,dist=%d,usedName=%s,templSpec=%s,base=%d)\n", + // className.data(),n->label().data(),prot,label,distance,usedName,templSpec,base); + DotNode *bn = m_usedNodes->find(className); + if (bn) // class already inserted + { + if (base) + { + n->addChild(bn,prot,edgeStyle,label); + bn->addParent(n); + } + else + { + bn->addChild(n,prot,edgeStyle,label); + n->addParent(bn); + } + bn->setDistance(distance); + //printf(" add exiting node %s of %s\n",bn->label().data(),n->label().data()); + } + else // new class + { + QCString displayName=className; + if (HIDE_SCOPE_NAMES) displayName=stripScope(displayName); + QCString tmp_url; + if (cd->isLinkable() && !cd->isHidden()) + { + tmp_url=cd->getReference()+"$"+cd->getOutputFileBase(); + if (!cd->anchor().isEmpty()) + { + tmp_url+="#"+cd->anchor(); + } + } + QCString tooltip = cd->briefDescriptionAsTooltip(); + bn = new DotNode(getNextNodeNumber(), + displayName, + tooltip, + tmp_url.data(), + FALSE, // rootNode + cd + ); + if (base) + { + n->addChild(bn,prot,edgeStyle,label); + bn->addParent(n); + } + else + { + bn->addChild(n,prot,edgeStyle,label); + n->addParent(bn); + } + bn->setDistance(distance); + m_usedNodes->insert(className,bn); + //printf(" add new child node '%s' to %s hidden=%d url=%s\n", + // className.data(),n->label().data(),cd->isHidden(),tmp_url.data()); + + buildGraph(cd,bn,base,distance+1); + } +} + +void DotClassGraph::determineTruncatedNodes(QList<DotNode> &queue,bool includeParents) +{ + while (queue.count()>0) + { + DotNode *n = queue.take(0); + if (n->isVisible() && n->isTruncated()==DotNode::Unknown) + { + bool truncated = FALSE; + if (n->children()) + { + QListIterator<DotNode> li(*n->children()); + const DotNode *dn; + for (li.toFirst();(dn=li.current());++li) + { + if (!dn->isVisible()) + truncated = TRUE; + else + queue.append(dn); + } + } + if (n->parents() && includeParents) + { + QListIterator<DotNode> li(*n->parents()); + const DotNode *dn; + for (li.toFirst();(dn=li.current());++li) + { + if (!dn->isVisible()) + truncated = TRUE; + else + queue.append(dn); + } + } + n->markAsTruncated(truncated); + } + } +} + +bool DotClassGraph::determineVisibleNodes(DotNode *rootNode, + int maxNodes,bool includeParents) +{ + QList<DotNode> childQueue; + QList<DotNode> parentQueue; + QArray<int> childTreeWidth; + QArray<int> parentTreeWidth; + childQueue.append(rootNode); + if (includeParents) parentQueue.append(rootNode); + bool firstNode=TRUE; // flag to force reprocessing rootNode in the parent loop + // despite being marked visible in the child loop + while ((childQueue.count()>0 || parentQueue.count()>0) && maxNodes>0) + { + if (childQueue.count()>0) + { + DotNode *n = childQueue.take(0); + int distance = n->distance(); + if (!n->isVisible() && distance<=MAX_DOT_GRAPH_DEPTH) // not yet processed + { + if (distance>0) + { + int oldSize=(int)childTreeWidth.size(); + if (distance>oldSize) + { + childTreeWidth.resize(QMAX(childTreeWidth.size(),(uint)distance)); + int i; for (i=oldSize;i<distance;i++) childTreeWidth[i]=0; + } + childTreeWidth[distance-1]+=n->label().length(); + } + n->markAsVisible(); + maxNodes--; + // add direct children + if (n->children()) + { + QListIterator<DotNode> li(*n->children()); + const DotNode *dn; + for (li.toFirst();(dn=li.current());++li) + { + childQueue.append(dn); + } + } + } + } + if (includeParents && parentQueue.count()>0) + { + DotNode *n = parentQueue.take(0); + if ((!n->isVisible() || firstNode) && n->distance()<=MAX_DOT_GRAPH_DEPTH) // not yet processed + { + firstNode=FALSE; + int distance = n->distance(); + if (distance>0) + { + int oldSize = (int)parentTreeWidth.size(); + if (distance>oldSize) + { + parentTreeWidth.resize(QMAX(parentTreeWidth.size(),(uint)distance)); + int i; for (i=oldSize;i<distance;i++) parentTreeWidth[i]=0; + } + parentTreeWidth[distance-1]+=n->label().length(); + } + n->markAsVisible(); + maxNodes--; + // add direct parents + if (n->parents()) + { + QListIterator<DotNode> li(*n->parents()); + const DotNode *dn; + for (li.toFirst();(dn=li.current());++li) + { + parentQueue.append(dn); + } + } + } + } + } + if (UML_LOOK) return FALSE; // UML graph are always top to bottom + int maxWidth=0; + int maxHeight=(int)QMAX(childTreeWidth.size(),parentTreeWidth.size()); + uint i; + for (i=0;i<childTreeWidth.size();i++) + { + if (childTreeWidth.at(i)>maxWidth) maxWidth=childTreeWidth.at(i); + } + for (i=0;i<parentTreeWidth.size();i++) + { + if (parentTreeWidth.at(i)>maxWidth) maxWidth=parentTreeWidth.at(i); + } + //printf("max tree width=%d, max tree height=%d\n",maxWidth,maxHeight); + return maxWidth>80 && maxHeight<12; // used metric to decide to render the tree + // from left to right instead of top to bottom, + // with the idea to render very wide trees in + // left to right order. +} + +void DotClassGraph::buildGraph(const ClassDef *cd,DotNode *n,bool base,int distance) +{ + //printf("DocClassGraph::buildGraph(%s,distance=%d,base=%d)\n", + // cd->name().data(),distance,base); + // ---- Add inheritance relations + + if (m_graphType == Inheritance || m_graphType==Collaboration) + { + BaseClassList *bcl = base ? cd->baseClasses() : cd->subClasses(); + if (bcl) + { + 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); + } + } + } + if (m_graphType == Collaboration) + { + // ---- Add usage relations + + UsesClassDict *dict = + base ? cd->usedImplementationClasses() : + cd->usedByImplementationClasses() + ; + if (dict) + { + UsesClassDictIterator ucdi(*dict); + UsesClassDef *ucd; + for (;(ucd=ucdi.current());++ucdi) + { + QCString label; + QDictIterator<void> dvi(*ucd->accessors); + const char *s; + bool first=TRUE; + int count=0; + int maxLabels=10; + for (;(s=dvi.currentKey()) && count<maxLabels;++dvi,++count) + { + if (first) + { + label=s; + first=FALSE; + } + else + { + label+=QCString("\n")+s; + } + } + if (count==maxLabels) label+="\n..."; + //printf("addClass: %s templSpec=%s\n",ucd->classDef->name().data(),ucd->templSpecifiers.data()); + addClass(ucd->classDef,n,EdgeInfo::Purple,label,0, + ucd->templSpecifiers,base,distance); + } + } + } + if (TEMPLATE_RELATIONS && base) + { + ConstraintClassDict *dict = cd->templateTypeConstraints(); + if (dict) + { + ConstraintClassDictIterator ccdi(*dict); + ConstraintClassDef *ccd; + for (;(ccd=ccdi.current());++ccdi) + { + QCString label; + QDictIterator<void> dvi(*ccd->accessors); + const char *s; + bool first=TRUE; + int count=0; + int maxLabels=10; + for (;(s=dvi.currentKey()) && count<maxLabels;++dvi,++count) + { + if (first) + { + label=s; + first=FALSE; + } + else + { + label+=QCString("\n")+s; + } + } + if (count==maxLabels) label+="\n..."; + //printf("addClass: %s templSpec=%s\n",ucd->classDef->name().data(),ucd->templSpecifiers.data()); + addClass(ccd->classDef,n,EdgeInfo::Orange2,label,0, + 0,TRUE,distance); + } + } + } + + // ---- Add template instantiation relations + + if (TEMPLATE_RELATIONS) + { + if (base) // template relations for base classes + { + const ClassDef *templMaster=cd->templateMaster(); + if (templMaster) + { + QDictIterator<ClassDef> cli(*templMaster->getTemplateInstances()); + const ClassDef *templInstance; + for (;(templInstance=cli.current());++cli) + { + if (templInstance==cd) + { + addClass(templMaster,n,EdgeInfo::Orange,cli.currentKey(),0, + 0,TRUE,distance); + } + } + } + } + else // template relations for super classes + { + const QDict<ClassDef> *templInstances = cd->getTemplateInstances(); + if (templInstances) + { + QDictIterator<ClassDef> cli(*templInstances); + const ClassDef *templInstance; + for (;(templInstance=cli.current());++cli) + { + addClass(templInstance,n,EdgeInfo::Orange,cli.currentKey(),0, + 0,FALSE,distance); + } + } + } + } +} + +DotClassGraph::DotClassGraph(const ClassDef *cd,GraphType t) +{ + //printf("--------------- DotClassGraph::DotClassGraph '%s'\n",cd->displayName().data()); + m_graphType = t; + QCString tmp_url=""; + if (cd->isLinkable() && !cd->isHidden()) + { + tmp_url=cd->getReference()+"$"+cd->getOutputFileBase(); + if (!cd->anchor().isEmpty()) + { + tmp_url+="#"+cd->anchor(); + } + } + QCString className = cd->displayName(); + QCString tooltip = cd->briefDescriptionAsTooltip(); + m_startNode = new DotNode(getNextNodeNumber(), + className, + tooltip, + tmp_url.data(), + TRUE, // is a root node + cd + ); + m_startNode->setDistance(0); + m_usedNodes = new QDict<DotNode>(1009); + m_usedNodes->insert(className,m_startNode); + + buildGraph(cd,m_startNode,TRUE,1); + if (t==Inheritance) buildGraph(cd,m_startNode,FALSE,1); + + m_lrRank = determineVisibleNodes(m_startNode,DOT_GRAPH_MAX_NODES,t==Inheritance); + QList<DotNode> openNodeQueue; + openNodeQueue.append(m_startNode); + determineTruncatedNodes(openNodeQueue,t==Inheritance); + + m_collabFileName = cd->collaborationGraphFileName(); + m_inheritFileName = cd->inheritanceGraphFileName(); +} + +bool DotClassGraph::isTrivial() const +{ + if (m_graphType==Inheritance) + return m_startNode->children()==0 && m_startNode->parents()==0; + else + return !UML_LOOK && m_startNode->children()==0; +} + +bool DotClassGraph::isTooBig() const +{ + int numNodes = 0; + numNodes+= m_startNode->children() ? m_startNode->children()->count() : 0; + if (m_graphType==Inheritance) + { + numNodes+= m_startNode->parents() ? m_startNode->parents()->count() : 0; + } + return numNodes>=DOT_GRAPH_MAX_NODES; +} + +DotClassGraph::~DotClassGraph() +{ + DotNode::deleteNodes(m_startNode); + delete m_usedNodes; +} + +QCString DotClassGraph::getBaseName() const +{ + switch (m_graphType) + { + case Collaboration: + return m_collabFileName; + break; + case Inheritance: + return m_inheritFileName; + break; + default: + ASSERT(0); + break; + } + return ""; +} + +void DotClassGraph::computeTheGraph() +{ + computeGraph( + m_startNode, + m_graphType, + m_graphFormat, + m_lrRank ? "LR" : "", + m_graphType == Inheritance, + TRUE, + m_startNode->label(), + m_theGraph + ); +} + +QCString DotClassGraph::getMapLabel() const +{ + QCString mapName; + switch (m_graphType) + { + case Collaboration: + mapName="coll_map"; + break; + case Inheritance: + mapName="inherit_map"; + break; + default: + ASSERT(0); + break; + } + + return escapeCharsInString(m_startNode->label(),FALSE)+"_"+escapeCharsInString(mapName,FALSE); +} + +QCString DotClassGraph::getImgAltText() const +{ + switch (m_graphType) + { + case Collaboration: + return "Collaboration graph"; + break; + case Inheritance: + return "Inheritance graph"; + break; + default: + ASSERT(0); + break; + } + return ""; +} + +QCString DotClassGraph::writeGraph(FTextStream &out, + GraphOutputFormat graphFormat, + EmbeddedOutputFormat textFormat, + const char *path, + const char *fileName, + const char *relPath, + bool /*isTBRank*/, + bool generateImageMap, + int graphId) +{ + return DotGraph::writeGraph(out, graphFormat, textFormat, path, fileName, relPath, generateImageMap, graphId); +} + +//-------------------------------------------------------------------- + +void DotClassGraph::writeXML(FTextStream &t) +{ + QDictIterator<DotNode> dni(*m_usedNodes); + DotNode *node; + for (;(node=dni.current());++dni) + { + node->writeXML(t,TRUE); + } +} + +void DotClassGraph::writeDocbook(FTextStream &t) +{ + QDictIterator<DotNode> dni(*m_usedNodes); + DotNode *node; + for (;(node=dni.current());++dni) + { + node->writeDocbook(t,TRUE); + } +} + +void DotClassGraph::writeDEF(FTextStream &t) +{ + QDictIterator<DotNode> dni(*m_usedNodes); + DotNode *node; + for (;(node=dni.current());++dni) + { + node->writeDEF(t); + } +} diff --git a/src/dotclassgraph.h b/src/dotclassgraph.h new file mode 100644 index 0000000..b3b9291 --- /dev/null +++ b/src/dotclassgraph.h @@ -0,0 +1,62 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#ifndef DOTCLASSGRAPH_H +#define DOTCLASSGRAPH_H + +#include "classdef.h" + +#include "dotgraph.h" + +/** Representation of a class inheritance or dependency graph */ +class DotClassGraph : public DotGraph +{ +public: + DotClassGraph(const ClassDef *cd,GraphType t); + ~DotClassGraph(); + bool isTrivial() const; + bool isTooBig() const; + QCString writeGraph(FTextStream &t,GraphOutputFormat gf,EmbeddedOutputFormat ef, + const char *path, const char *fileName, const char *relPath, + bool TBRank=TRUE,bool imageMap=TRUE,int graphId=-1); + + void writeXML(FTextStream &t); + void writeDocbook(FTextStream &t); + void writeDEF(FTextStream &t); + +protected: + virtual QCString getBaseName() const; + virtual QCString getMapLabel() const; + virtual void computeTheGraph(); + virtual QCString getImgAltText() const; + +private: + void buildGraph(const ClassDef *cd,DotNode *n,bool base,int distance); + bool determineVisibleNodes(DotNode *rootNode,int maxNodes,bool includeParents); + void determineTruncatedNodes(QList<DotNode> &queue,bool includeParents); + void addClass(const ClassDef *cd,DotNode *n,int prot,const char *label, + const char *usedName,const char *templSpec, + bool base,int distance); + + DotNode * m_startNode; + QDict<DotNode> * m_usedNodes; + GraphType m_graphType; + QCString m_collabFileName; + QCString m_inheritFileName; + bool m_lrRank; +}; + + +#endif diff --git a/src/dotdirdeps.cpp b/src/dotdirdeps.cpp new file mode 100644 index 0000000..85906d1 --- /dev/null +++ b/src/dotdirdeps.cpp @@ -0,0 +1,220 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#include "dotdirdeps.h" + +#include "ftextstream.h" +#include "util.h" +#include "doxygen.h" +#include "config.h" + +void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations) +{ + t << "digraph \"" << dd->displayName() << "\" {\n"; + if (Config_getBool(DOT_TRANSPARENT)) + { + t << " bgcolor=transparent;\n"; + } + t << " compound=true\n"; + t << " node [ fontsize=\"" << DotGraph::DOT_FONTSIZE << "\", fontname=\"" << DotGraph::DOT_FONTNAME << "\"];\n"; + t << " edge [ labelfontsize=\"" << DotGraph::DOT_FONTSIZE << "\", labelfontname=\"" << DotGraph::DOT_FONTNAME << "\"];\n"; + + QDict<DirDef> dirsInGraph(257); + + dirsInGraph.insert(dd->getOutputFileBase(),dd); + if (dd->parent()) + { + t << " subgraph cluster" << dd->parent()->getOutputFileBase() << " {\n"; + t << " graph [ bgcolor=\"#ddddee\", pencolor=\"black\", label=\"" + << dd->parent()->shortName() + << "\" fontname=\"" << DotGraph::DOT_FONTNAME << "\", fontsize=\"" << DotGraph::DOT_FONTSIZE << "\", URL=\""; + t << dd->parent()->getOutputFileBase() << Doxygen::htmlFileExtension; + t << "\"]\n"; + } + if (dd->isCluster()) + { + t << " subgraph cluster" << dd->getOutputFileBase() << " {\n"; + t << " graph [ bgcolor=\"#eeeeff\", pencolor=\"black\", label=\"\"" + << " URL=\"" << dd->getOutputFileBase() << Doxygen::htmlFileExtension + << "\"];\n"; + t << " " << dd->getOutputFileBase() << " [shape=plaintext label=\"" + << dd->shortName() << "\"];\n"; + + // add nodes for sub directories + QListIterator<DirDef> sdi(dd->subDirs()); + const DirDef *sdir; + for (sdi.toFirst();(sdir=sdi.current());++sdi) + { + t << " " << sdir->getOutputFileBase() << " [shape=box label=\"" + << sdir->shortName() << "\""; + if (sdir->isCluster()) + { + t << " color=\"red\""; + } + else + { + t << " color=\"black\""; + } + t << " fillcolor=\"white\" style=\"filled\""; + t << " URL=\"" << sdir->getOutputFileBase() + << Doxygen::htmlFileExtension << "\""; + t << "];\n"; + dirsInGraph.insert(sdir->getOutputFileBase(),sdir); + } + t << " }\n"; + } + else + { + t << " " << dd->getOutputFileBase() << " [shape=box, label=\"" + << dd->shortName() << "\", style=\"filled\", fillcolor=\"#eeeeff\"," + << " pencolor=\"black\", URL=\"" << dd->getOutputFileBase() + << Doxygen::htmlFileExtension << "\"];\n"; + } + if (dd->parent()) + { + t << " }\n"; + } + + // add nodes for other used directories + QDictIterator<UsedDir> udi(*dd->usedDirs()); + UsedDir *udir; + //printf("*** For dir %s\n",shortName().data()); + for (udi.toFirst();(udir=udi.current());++udi) + // for each used dir (=directly used or a parent of a directly used dir) + { + const DirDef *usedDir=udir->dir(); + const DirDef *dir=dd; + while (dir) + { + //printf("*** check relation %s->%s same_parent=%d !%s->isParentOf(%s)=%d\n", + // dir->shortName().data(),usedDir->shortName().data(), + // dir->parent()==usedDir->parent(), + // usedDir->shortName().data(), + // shortName().data(), + // !usedDir->isParentOf(this) + // ); + if (dir!=usedDir && dir->parent()==usedDir->parent() && + !usedDir->isParentOf(dd)) + // include if both have the same parent (or no parent) + { + t << " " << usedDir->getOutputFileBase() << " [shape=box label=\"" + << usedDir->shortName() << "\""; + if (usedDir->isCluster()) + { + if (!Config_getBool(DOT_TRANSPARENT)) + { + t << " fillcolor=\"white\" style=\"filled\""; + } + t << " color=\"red\""; + } + t << " URL=\"" << usedDir->getOutputFileBase() + << Doxygen::htmlFileExtension << "\"];\n"; + dirsInGraph.insert(usedDir->getOutputFileBase(),usedDir); + break; + } + dir=dir->parent(); + } + } + + // add relations between all selected directories + const DirDef *dir; + QDictIterator<DirDef> di(dirsInGraph); + for (di.toFirst();(dir=di.current());++di) // foreach dir in the graph + { + QDictIterator<UsedDir> udi(*dir->usedDirs()); + UsedDir *udir; + for (udi.toFirst();(udir=udi.current());++udi) // foreach used dir + { + const DirDef *usedDir=udir->dir(); + if ((dir!=dd || !udir->inherited()) && // only show direct dependendies for this dir + (usedDir!=dd || !udir->inherited()) && // only show direct dependendies for this dir + !usedDir->isParentOf(dir) && // don't point to own parent + dirsInGraph.find(usedDir->getOutputFileBase())) // only point to nodes that are in the graph + { + QCString relationName; + relationName.sprintf("dir_%06d_%06d",dir->dirCount(),usedDir->dirCount()); + if (Doxygen::dirRelations.find(relationName)==0) + { + // new relation + Doxygen::dirRelations.append(relationName, + new DirRelation(relationName,dir,udir)); + } + int nrefs = udir->filePairs().count(); + t << " " << dir->getOutputFileBase() << "->" + << usedDir->getOutputFileBase(); + t << " [headlabel=\"" << nrefs << "\", labeldistance=1.5"; + if (linkRelations) + { + t << " headhref=\"" << relationName << Doxygen::htmlFileExtension << "\""; + } + t << "];\n"; + } + } + } + + t << "}\n"; +} + +DotDirDeps::DotDirDeps(const DirDef *dir) : m_dir(dir) +{ +} + +DotDirDeps::~DotDirDeps() +{ +} + +QCString DotDirDeps::getBaseName() const +{ + return m_dir->getOutputFileBase()+"_dep"; + +} + +void DotDirDeps::computeTheGraph() +{ + // compute md5 checksum of the graph were are about to generate + FTextStream md5stream(&m_theGraph); + //m_dir->writeDepGraph(md5stream); + writeDotDirDepGraph(md5stream,m_dir,m_linkRelations); +} + +QCString DotDirDeps::getMapLabel() const +{ + return escapeCharsInString(m_baseName,FALSE); +} + +QCString DotDirDeps::getImgAltText() const +{ + return convertToXML(m_dir->displayName()); +} + +QCString DotDirDeps::writeGraph(FTextStream &out, + GraphOutputFormat graphFormat, + EmbeddedOutputFormat textFormat, + const char *path, + const char *fileName, + const char *relPath, + bool generateImageMap, + int graphId, + bool linkRelations) +{ + m_linkRelations = linkRelations; + m_urlOnly = TRUE; + return DotGraph::writeGraph(out, graphFormat, textFormat, path, fileName, relPath, generateImageMap, graphId); +} + +bool DotDirDeps::isTrivial() const +{ + return m_dir->depGraphIsTrivial(); +} diff --git a/src/dotdirdeps.h b/src/dotdirdeps.h new file mode 100644 index 0000000..f5eef65 --- /dev/null +++ b/src/dotdirdeps.h @@ -0,0 +1,51 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#ifndef DOTDIRDEPS_H +#define DOTDIRDEPS_H + +#include "dotgraph.h" +#include "dirdef.h" + +/** Representation of an directory dependency graph */ +class DotDirDeps : public DotGraph +{ + public: + DotDirDeps(const DirDef *dir); + ~DotDirDeps(); + bool isTrivial() const; + QCString writeGraph(FTextStream &out, + GraphOutputFormat gf, + EmbeddedOutputFormat ef, + const char *path, + const char *fileName, + const char *relPath, + bool writeImageMap=TRUE, + int graphId=-1, + bool linkRelations=TRUE); + + protected: + virtual QCString getBaseName() const; + virtual QCString getMapLabel() const; + virtual void computeTheGraph(); + virtual QCString getImgAltText() const; + + private: + const DirDef *m_dir; + + bool m_linkRelations; +}; + +#endif diff --git a/src/dotfilepatcher.cpp b/src/dotfilepatcher.cpp new file mode 100644 index 0000000..91b7c78 --- /dev/null +++ b/src/dotfilepatcher.cpp @@ -0,0 +1,539 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#include "dotfilepatcher.h" + +#include "qstring.h" +#include "config.h" +#include "qdir.h" +#include "message.h" +#include "ftextstream.h" +#include "docparser.h" +#include "doxygen.h" +#include "util.h" +#include "dot.h" + +static const char svgZoomHeader[] = +"<svg id=\"main\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" onload=\"init(evt)\">\n" +"<style type=\"text/css\"><![CDATA[\n" +".edge:hover path { stroke: red; }\n" +".edge:hover polygon { stroke: red; fill: red; }\n" +"]]></style>\n" +"<script type=\"text/javascript\"><![CDATA[\n" +"var edges = document.getElementsByTagName('g');\n" +"if (edges && edges.length) {\n" +" for (var i=0;i<edges.length;i++) {\n" +" if (edges[i].id.substr(0,4)=='edge') {\n" +" edges[i].setAttribute('class','edge');\n" +" }\n" +" }\n" +"}\n" +"]]></script>\n" +" <defs>\n" +" <circle id=\"rim\" cx=\"0\" cy=\"0\" r=\"7\"/>\n" +" <circle id=\"rim2\" cx=\"0\" cy=\"0\" r=\"3.5\"/>\n" +" <g id=\"zoomPlus\">\n" +" <use xlink:href=\"#rim\" fill=\"#404040\">\n" +" <set attributeName=\"fill\" to=\"#808080\" begin=\"zoomplus.mouseover\" end=\"zoomplus.mouseout\"/>\n" +" </use>\n" +" <path d=\"M-4,0h8M0,-4v8\" fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" pointer-events=\"none\"/>\n" +" </g>\n" +" <g id=\"zoomMin\">\n" +" <use xlink:href=\"#rim\" fill=\"#404040\">\n" +" <set attributeName=\"fill\" to=\"#808080\" begin=\"zoomminus.mouseover\" end=\"zoomminus.mouseout\"/>\n" +" </use>\n" +" <path d=\"M-4,0h8\" fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" pointer-events=\"none\"/>\n" +" </g>\n" +" <g id=\"dirArrow\">\n" +" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" +" </g>\n" +" <g id=\"resetDef\">\n" +" <use xlink:href=\"#rim2\" fill=\"#404040\">\n" +" <set attributeName=\"fill\" to=\"#808080\" begin=\"reset.mouseover\" end=\"reset.mouseout\"/>\n" +" </use>\n" +" </g>\n" +" </defs>\n" +"\n" +"<script type=\"text/javascript\">\n" +; + +static const char svgZoomFooter[] = +// navigation panel +" <g id=\"navigator\" transform=\"translate(0 0)\" fill=\"#404254\">\n" +" <rect fill=\"#f2f5e9\" fill-opacity=\"0.5\" stroke=\"#606060\" stroke-width=\".5\" x=\"0\" y=\"0\" width=\"60\" height=\"60\"/>\n" +// zoom in +" <use id=\"zoomplus\" xlink:href=\"#zoomPlus\" x=\"17\" y=\"9\" onmousedown=\"handleZoom(evt,'in')\"/>\n" +// zoom out +" <use id=\"zoomminus\" xlink:href=\"#zoomMin\" x=\"42\" y=\"9\" onmousedown=\"handleZoom(evt,'out')\"/>\n" +// reset zoom +" <use id=\"reset\" xlink:href=\"#resetDef\" x=\"30\" y=\"36\" onmousedown=\"handleReset()\"/>\n" +// arrow up +" <g id=\"arrowUp\" xlink:href=\"#dirArrow\" transform=\"translate(30 24)\" onmousedown=\"handlePan(0,-1)\">\n" +" <use xlink:href=\"#rim\" fill=\"#404040\">\n" +" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowUp.mouseover\" end=\"arrowUp.mouseout\"/>\n" +" </use>\n" +" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" +" </g>\n" +// arrow right +" <g id=\"arrowRight\" xlink:href=\"#dirArrow\" transform=\"rotate(90) translate(36 -43)\" onmousedown=\"handlePan(1,0)\">\n" +" <use xlink:href=\"#rim\" fill=\"#404040\">\n" +" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowRight.mouseover\" end=\"arrowRight.mouseout\"/>\n" +" </use>\n" +" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" +" </g>\n" +// arrow down +" <g id=\"arrowDown\" xlink:href=\"#dirArrow\" transform=\"rotate(180) translate(-30 -48)\" onmousedown=\"handlePan(0,1)\">\n" +" <use xlink:href=\"#rim\" fill=\"#404040\">\n" +" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowDown.mouseover\" end=\"arrowDown.mouseout\"/>\n" +" </use>\n" +" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" +" </g>\n" +// arrow left +" <g id=\"arrowLeft\" xlink:href=\"#dirArrow\" transform=\"rotate(270) translate(-36 17)\" onmousedown=\"handlePan(-1,0)\">\n" +" <use xlink:href=\"#rim\" fill=\"#404040\">\n" +" <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowLeft.mouseover\" end=\"arrowLeft.mouseout\"/>\n" +" </use>\n" +" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" +" </g>\n" +" </g>\n" +// link to original SVG +" <svg viewBox=\"0 0 15 15\" width=\"100%\" height=\"30px\" preserveAspectRatio=\"xMaxYMin meet\">\n" +" <g id=\"arrow_out\" transform=\"scale(0.3 0.3)\">\n" +" <a xlink:href=\"$orgname\" target=\"_base\">\n" +" <rect id=\"button\" ry=\"5\" rx=\"5\" y=\"6\" x=\"6\" height=\"38\" width=\"38\"\n" +" fill=\"#f2f5e9\" fill-opacity=\"0.5\" stroke=\"#606060\" stroke-width=\"1.0\"/>\n" +" <path id=\"arrow\"\n" +" d=\"M 11.500037,31.436501 C 11.940474,20.09759 22.043105,11.32322 32.158766,21.979434 L 37.068811,17.246167 C 37.068811,17.246167 37.088388,32 37.088388,32 L 22.160133,31.978069 C 22.160133,31.978069 26.997745,27.140456 26.997745,27.140456 C 18.528582,18.264221 13.291696,25.230495 11.500037,31.436501 z\"\n" +" style=\"fill:#404040;\"/>\n" +" </a>\n" +" </g>\n" +" </svg>\n" +"</svg>\n" +; + +static QCString replaceRef(const QCString &buf,const QCString relPath, + bool urlOnly,const QCString &context,const QCString &target=QCString()) +{ + // search for href="...", store ... part in link + QCString href = "href"; + //bool isXLink=FALSE; + int len = 6; + int indexS = buf.find("href=\""), indexE; + bool setTarget = FALSE; + if (indexS>5 && buf.find("xlink:href=\"")!=-1) // XLink href (for SVG) + { + indexS-=6; + len+=6; + href.prepend("xlink:"); + //isXLink=TRUE; + } + if (indexS>=0 && (indexE=buf.find('"',indexS+len))!=-1) + { + QCString link = buf.mid(indexS+len,indexE-indexS-len); + QCString result; + if (urlOnly) // for user defined dot graphs + { + if (link.left(5)=="\\ref " || link.left(5)=="@ref ") // \ref url + { + result=href+"=\""; + // fake ref node to resolve the url + DocRef *df = new DocRef( (DocNode*) 0, link.mid(5), context ); + result+=externalRef(relPath,df->ref(),TRUE); + if (!df->file().isEmpty()) + result += df->file().data() + Doxygen::htmlFileExtension; + if (!df->anchor().isEmpty()) + result += "#" + df->anchor(); + delete df; + result += "\""; + } + else + { + result = href+"=\"" + link + "\""; + } + } + else // ref$url (external ref via tag file), or $url (local ref) + { + int marker = link.find('$'); + if (marker!=-1) + { + QCString ref = link.left(marker); + QCString url = link.mid(marker+1); + if (!ref.isEmpty()) + { + result = externalLinkTarget(); + if (result != "") setTarget = TRUE; + } + result+= href+"=\""; + result+=externalRef(relPath,ref,TRUE); + result+= url + "\""; + } + else // should not happen, but handle properly anyway + { + result = href+"=\"" + link + "\""; + } + } + if (!target.isEmpty() && !setTarget) + { + result+=" target=\""+target+"\""; + } + QCString leftPart = buf.left(indexS); + QCString rightPart = buf.mid(indexE+1); + return leftPart + result + rightPart; + } + else + { + return buf; + } +} + +/*! converts the rectangles in a client site image map into a stream +* \param t the stream to which the result is written. +* \param mapName the name of the map file. +* \param relPath the relative path to the root of the output directory +* (used in case CREATE_SUBDIRS is enabled). +* \param urlOnly if FALSE the url field in the map contains an external +* references followed by a $ and then the URL. +* \param context the context (file, class, or namespace) in which the +* map file was found +* \returns TRUE if successful. +*/ +bool convertMapFile(FTextStream &t,const char *mapName, + const QCString relPath, bool urlOnly, + const QCString &context) +{ + QFile f(mapName); + if (!f.open(IO_ReadOnly)) + { + err("problems opening map file %s for inclusion in the docs!\n" + "If you installed Graphviz/dot after a previous failing run, \n" + "try deleting the output directory and rerun doxygen.\n",mapName); + return FALSE; + } + const int maxLineLen=10240; + while (!f.atEnd()) // foreach line + { + QCString buf(maxLineLen); + int numBytes = f.readLine(buf.rawData(),maxLineLen); + if (numBytes>0) + { + buf.resize(numBytes+1); + + if (buf.left(5)=="<area") + { + QCString replBuf = replaceRef(buf,relPath,urlOnly,context); + // strip id="..." from replBuf since the id's are not needed and not unique. + int indexS = replBuf.find("id=\""), indexE; + if (indexS>0 && (indexE=replBuf.find('"',indexS+4))!=-1) + { + t << replBuf.left(indexS-1) << replBuf.right(replBuf.length() - indexE - 1); + } + else + { + t << replBuf; + } + } + } + } + return TRUE; +} + +DotFilePatcher::DotFilePatcher(const char *patchFile) + : m_patchFile(patchFile) +{ + m_maps.setAutoDelete(TRUE); +} + +QCString DotFilePatcher::file() const +{ + return m_patchFile; +} + +int DotFilePatcher::addMap(const QCString &mapFile,const QCString &relPath, + bool urlOnly,const QCString &context,const QCString &label) +{ + int id = m_maps.count(); + Map *map = new Map; + map->mapFile = mapFile; + map->relPath = relPath; + map->urlOnly = urlOnly; + map->context = context; + map->label = label; + map->zoomable = FALSE; + map->graphId = -1; + m_maps.append(map); + return id; +} + +int DotFilePatcher::addFigure(const QCString &baseName, + const QCString &figureName,bool heightCheck) +{ + int id = m_maps.count(); + Map *map = new Map; + map->mapFile = figureName; + map->urlOnly = heightCheck; + map->label = baseName; + map->zoomable = FALSE; + map->graphId = -1; + m_maps.append(map); + return id; +} + +int DotFilePatcher::addSVGConversion(const QCString &relPath,bool urlOnly, + const QCString &context,bool zoomable, + int graphId) +{ + int id = m_maps.count(); + Map *map = new Map; + map->relPath = relPath; + map->urlOnly = urlOnly; + map->context = context; + map->zoomable = zoomable; + map->graphId = graphId; + m_maps.append(map); + return id; +} + +int DotFilePatcher::addSVGObject(const QCString &baseName, + const QCString &absImgName, + const QCString &relPath) +{ + int id = m_maps.count(); + Map *map = new Map; + map->mapFile = absImgName; + map->relPath = relPath; + map->label = baseName; + map->zoomable = FALSE; + map->graphId = -1; + m_maps.append(map); + return id; +} + +bool DotFilePatcher::run() +{ + //printf("DotFilePatcher::run(): %s\n",m_patchFile.data()); + bool interactiveSVG_local = Config_getBool(INTERACTIVE_SVG); + bool isSVGFile = m_patchFile.right(4)==".svg"; + int graphId = -1; + QCString relPath; + if (isSVGFile) + { + Map *map = m_maps.at(0); // there is only one 'map' for a SVG file + interactiveSVG_local = interactiveSVG_local && map->zoomable; + graphId = map->graphId; + relPath = map->relPath; + //printf("DotFilePatcher::addSVGConversion: file=%s zoomable=%d\n", + // m_patchFile.data(),map->zoomable); + } + QString tmpName = QString::fromUtf8(m_patchFile+".tmp"); + QString patchFile = QString::fromUtf8(m_patchFile); + if (!QDir::current().rename(patchFile,tmpName)) + { + err("Failed to rename file %s to %s!\n",m_patchFile.data(),tmpName.data()); + return FALSE; + } + QFile fi(tmpName); + QFile fo(patchFile); + if (!fi.open(IO_ReadOnly)) + { + err("problem opening file %s for patching!\n",tmpName.data()); + QDir::current().rename(tmpName,patchFile); + return FALSE; + } + if (!fo.open(IO_WriteOnly)) + { + err("problem opening file %s for patching!\n",m_patchFile.data()); + QDir::current().rename(tmpName,patchFile); + return FALSE; + } + FTextStream t(&fo); + const int maxLineLen=100*1024; + int lineNr=1; + int width,height; + bool insideHeader=FALSE; + bool replacedHeader=FALSE; + bool foundSize=FALSE; + while (!fi.atEnd()) // foreach line + { + QCString line(maxLineLen); + int numBytes = fi.readLine(line.rawData(),maxLineLen); + if (numBytes<=0) + { + break; + } + line.resize(numBytes+1); + + //printf("line=[%s]\n",line.stripWhiteSpace().data()); + int i; + ASSERT(numBytes<maxLineLen); + if (isSVGFile) + { + if (interactiveSVG_local) + { + if (line.find("<svg")!=-1 && !replacedHeader) + { + int count; + count = sscanf(line.data(),"<svg width=\"%dpt\" height=\"%dpt\"",&width,&height); + //printf("width=%d height=%d\n",width,height); + foundSize = count==2 && (width>500 || height>450); + if (foundSize) insideHeader=TRUE; + } + else if (insideHeader && !replacedHeader && line.find("<title>")!=-1) + { + if (foundSize) + { + // insert special replacement header for interactive SVGs + t << "<!--zoomable " << height << " -->\n"; + t << svgZoomHeader; + t << "var viewWidth = " << width << ";\n"; + t << "var viewHeight = " << height << ";\n"; + if (graphId>=0) + { + t << "var sectionId = 'dynsection-" << graphId << "';\n"; + } + t << "</script>\n"; + t << "<script xlink:href=\"" << relPath << "svgpan.js\"/>\n"; + t << "<svg id=\"graph\" class=\"graph\">\n"; + t << "<g id=\"viewport\">\n"; + } + insideHeader=FALSE; + replacedHeader=TRUE; + } + } + if (!insideHeader || !foundSize) // copy SVG and replace refs, + // unless we are inside the header of the SVG. + // Then we replace it with another header. + { + Map *map = m_maps.at(0); // there is only one 'map' for a SVG file + t << replaceRef(line,map->relPath,map->urlOnly,map->context,"_top"); + } + } + else if ((i=line.find("<!-- SVG"))!=-1 || (i=line.find("[!-- SVG"))!=-1) + { + //printf("Found marker at %d\n",i); + int mapId=-1; + t << line.left(i); + int n = sscanf(line.data()+i+1,"!-- SVG %d",&mapId); + if (n==1 && mapId>=0 && mapId<(int)m_maps.count()) + { + int e = QMAX(line.find("--]"),line.find("-->")); + Map *map = m_maps.at(mapId); + //printf("DotFilePatcher::writeSVGFigure: file=%s zoomable=%d\n", + // m_patchFile.data(),map->zoomable); + if (!writeSVGFigureLink(t,map->relPath,map->label,map->mapFile)) + { + err("Problem extracting size from SVG file %s\n",map->mapFile.data()); + } + if (e!=-1) t << line.mid(e+3); + } + else // error invalid map id! + { + err("Found invalid SVG id in file %s!\n",m_patchFile.data()); + t << line.mid(i); + } + } + else if ((i=line.find("<!-- MAP"))!=-1) + { + int mapId=-1; + t << line.left(i); + int n = sscanf(line.data()+i,"<!-- MAP %d",&mapId); + if (n==1 && mapId>=0 && mapId<(int)m_maps.count()) + { + QGString result; + FTextStream tt(&result); + Map *map = m_maps.at(mapId); + //printf("patching MAP %d in file %s with contents of %s\n", + // mapId,m_patchFile.data(),map->mapFile.data()); + convertMapFile(tt,map->mapFile,map->relPath,map->urlOnly,map->context); + if (!result.isEmpty()) + { + t << "<map name=\"" << map->label << "\" id=\"" << map->label << "\">" << endl; + t << result; + t << "</map>" << endl; + } + } + else // error invalid map id! + { + err("Found invalid MAP id in file %s!\n",m_patchFile.data()); + t << line.mid(i); + } + } + else if ((i=line.find("% FIG"))!=-1) + { + int mapId=-1; + int n = sscanf(line.data()+i+2,"FIG %d",&mapId); + //printf("line='%s' n=%d\n",line.data()+i,n); + if (n==1 && mapId>=0 && mapId<(int)m_maps.count()) + { + Map *map = m_maps.at(mapId); + //printf("patching FIG %d in file %s with contents of %s\n", + // mapId,m_patchFile.data(),map->mapFile.data()); + if (!DotGraph::writeVecGfxFigure(t,map->label,map->mapFile)) + { + err("problem writing FIG %d figure!\n",mapId); + return FALSE; + } + } + else // error invalid map id! + { + err("Found invalid bounding FIG %d in file %s!\n",mapId,m_patchFile.data()); + t << line; + } + } + else + { + t << line; + } + lineNr++; + } + fi.close(); + if (isSVGFile && interactiveSVG_local && replacedHeader) + { + QCString orgName=m_patchFile.left(m_patchFile.length()-4)+"_org.svg"; + t << substitute(svgZoomFooter,"$orgname",stripPath(orgName)); + fo.close(); + // keep original SVG file so we can refer to it, we do need to replace + // dummy link by real ones + QFile fi(tmpName); + QFile fo(orgName); + if (!fi.open(IO_ReadOnly)) + { + err("problem opening file %s for reading!\n",tmpName.data()); + return FALSE; + } + if (!fo.open(IO_WriteOnly)) + { + err("problem opening file %s for writing!\n",orgName.data()); + return FALSE; + } + FTextStream t(&fo); + while (!fi.atEnd()) // foreach line + { + QCString line(maxLineLen); + int numBytes = fi.readLine(line.rawData(),maxLineLen); + if (numBytes<=0) + { + break; + } + line.resize(numBytes+1); + Map *map = m_maps.at(0); // there is only one 'map' for a SVG file + t << replaceRef(line,map->relPath,map->urlOnly,map->context,"_top"); + } + fi.close(); + fo.close(); + } + // remove temporary file + QDir::current().remove(tmpName); + return TRUE; +} diff --git a/src/dotfilepatcher.h b/src/dotfilepatcher.h new file mode 100644 index 0000000..dd5c511 --- /dev/null +++ b/src/dotfilepatcher.h @@ -0,0 +1,53 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#ifndef DOTFILEPATCHER_H +#define DOTFILEPATCHER_H + +#include "qcstring.h" +#include "qlist.h" + +/** Helper class to insert a set of map file into an output file */ +class DotFilePatcher +{ + public: + DotFilePatcher(const char *patchFile); + int addMap(const QCString &mapFile,const QCString &relPath, + bool urlOnly,const QCString &context,const QCString &label); + int addFigure(const QCString &baseName, + const QCString &figureName,bool heightCheck); + int addSVGConversion(const QCString &relPath,bool urlOnly, + const QCString &context,bool zoomable,int graphId); + int addSVGObject(const QCString &baseName, const QCString &figureName, + const QCString &relPath); + bool run(); + QCString file() const; + + private: + struct Map + { + QCString mapFile; + QCString relPath; + bool urlOnly; + QCString context; + QCString label; + bool zoomable; + int graphId; + }; + QList<Map> m_maps; + QCString m_patchFile; +}; + +#endif diff --git a/src/dotgfxhierarchytable.cpp b/src/dotgfxhierarchytable.cpp new file mode 100644 index 0000000..0a7942f --- /dev/null +++ b/src/dotgfxhierarchytable.cpp @@ -0,0 +1,302 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#include "dotgfxhierarchytable.h" + +#include "language.h" +#include "util.h" +#include "message.h" +#include "doxygen.h" +#include "classlist.h" + +#define OPTIMIZE_OUTPUT_SLICE Config_getBool(OPTIMIZE_OUTPUT_SLICE) + +QCString DotGfxHierarchyTable::getBaseName() const +{ + QCString baseName; + if (m_prefix.isEmpty()) + baseName.sprintf("inherit_graph_%d", m_graphId); + else + baseName.sprintf("%sinherit_graph_%d",m_prefix.data(), m_graphId); + return baseName; +} + +void DotGfxHierarchyTable::computeTheGraph() +{ + QListIterator<DotNode> dnli2(*m_rootNodes); + DotNode *node; + + FTextStream md5stream(&m_theGraph); + writeGraphHeader(md5stream,theTranslator->trGraphicalHierarchy()); + md5stream << " rankdir=\"LR\";" << endl; + for (dnli2.toFirst();(node=dnli2.current());++dnli2) + { + if (node->subgraphId()==m_rootSubgraphNode->subgraphId()) + { + node->clearWriteFlag(); + } + } + for (dnli2.toFirst();(node=dnli2.current());++dnli2) + { + if (node->subgraphId()==m_rootSubgraphNode->subgraphId()) + { + node->write(md5stream,Hierarchy,GOF_BITMAP,FALSE,TRUE,TRUE); + } + } + writeGraphFooter(md5stream); + +} + +QCString DotGfxHierarchyTable::getMapLabel() const +{ + return escapeCharsInString(m_rootSubgraphNode->label(),FALSE); +} + +void DotGfxHierarchyTable::createGraph(DotNode *n,FTextStream &out, + const char *path,const char *fileName,int id) +{ + m_rootSubgraphNode = n; + m_graphId = id; + m_noDivTag = TRUE; + m_zoomable = FALSE; + DotGraph::writeGraph(out, GOF_BITMAP, EOF_Html, path, fileName, "", TRUE, 0); +} + +void DotGfxHierarchyTable::writeGraph(FTextStream &out, + const char *path,const char *fileName) +{ + //printf("DotGfxHierarchyTable::writeGraph(%s)\n",name); + //printf("m_rootNodes=%p count=%d\n",m_rootNodes,m_rootNodes->count()); + + if (m_rootSubgraphs->count()==0) return; + + QDir d(path); + // store the original directory + if (!d.exists()) + { + err("Output dir %s does not exist!\n",path); exit(1); + } + + // put each connected subgraph of the hierarchy in a row of the HTML output + out << "<table border=\"0\" cellspacing=\"10\" cellpadding=\"0\">" << endl; + + QListIterator<DotNode> dnli(*m_rootSubgraphs); + DotNode *n; + int count=0; + for (dnli.toFirst();(n=dnli.current());++dnli) + { + out << "<tr><td>"; + createGraph(n,out,path,fileName,count++); + out << "</td></tr>" << endl; + } + out << "</table>" << endl; +} + +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()) + { + 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())) + { + 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 + { + 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"); + //} + } + else + { + QCString tmp_url=""; + if (bClass->isLinkable() && !bClass->isHidden()) + { + tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase(); + if (!bClass->anchor().isEmpty()) + { + tmp_url+="#"+bClass->anchor(); + } + } + 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); + } + } + } + } + //printf("end addHierarchy\n"); +} + +void DotGfxHierarchyTable::addClassList(const ClassSDict *cl) +{ + ClassSDict::Iterator cli(*cl); + ClassDef *cd; + for (cli.toLast();(cd=cli.current());--cli) + { + //printf("Trying %s subClasses=%d\n",cd->name().data(),cd->subClasses()->count()); + if (cd->getLanguage()==SrcLangExt_VHDL && + (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS + ) + { + continue; + } + if (OPTIMIZE_OUTPUT_SLICE && cd->compoundType() != m_classType) + { + continue; + } + if (!hasVisibleRoot(cd->baseClasses()) && + cd->isVisibleInHierarchy() + ) // root node in the forest + { + QCString tmp_url=""; + if (cd->isLinkable() && !cd->isHidden()) + { + tmp_url=cd->getReference()+"$"+cd->getOutputFileBase(); + if (!cd->anchor().isEmpty()) + { + tmp_url+="#"+cd->anchor(); + } + } + //printf("Inserting root class %s\n",cd->name().data()); + QCString tooltip = cd->briefDescriptionAsTooltip(); + DotNode *n = new DotNode(getNextNodeNumber(), + cd->displayName(), + tooltip, + tmp_url.data()); + + //m_usedNodes->clear(); + m_usedNodes->insert(cd->name(),n); + m_rootNodes->insert(0,n); + if (!cd->isVisited() && cd->subClasses()) + { + addHierarchy(n,cd,cd->isVisited()); + cd->setVisited(TRUE); + } + } + } +} + +DotGfxHierarchyTable::DotGfxHierarchyTable(const char *prefix,ClassDef::CompoundType ct) + : m_prefix(prefix) + , m_classType(ct) +{ + m_rootNodes = new QList<DotNode>; + m_usedNodes = new QDict<DotNode>(1009); + m_usedNodes->setAutoDelete(TRUE); + m_rootSubgraphs = new DotNodeList; + + // build a graph with each class as a node and the inheritance relations + // as edges + initClassHierarchy(Doxygen::classSDict); + initClassHierarchy(Doxygen::hiddenClasses); + addClassList(Doxygen::classSDict); + addClassList(Doxygen::hiddenClasses); + // m_usedNodes now contains all nodes in the graph + + // color the graph into a set of independent subgraphs + bool done=FALSE; + int curColor=0; + QListIterator<DotNode> dnli(*m_rootNodes); + while (!done) // there are still nodes to color + { + DotNode *n; + done=TRUE; // we are done unless there are still uncolored nodes + for (dnli.toLast();(n=dnli.current());--dnli) + { + if (n->subgraphId()==-1) // not yet colored + { + //printf("Starting at node %s (%p): %d\n",n->label().data(),n,curColor); + done=FALSE; // still uncolored nodes + n->setSubgraphId(curColor); + n->markAsVisible(); + n->colorConnectedNodes(curColor); + curColor++; + const DotNode *dn=n->findDocNode(); + if (dn!=0) + m_rootSubgraphs->inSort(dn); + else + m_rootSubgraphs->inSort(n); + } + } + } + + //printf("Number of independent subgraphs: %d\n",curColor); + QListIterator<DotNode> dnli2(*m_rootSubgraphs); + DotNode *n; + for (dnli2.toFirst();(n=dnli2.current());++dnli2) + { + //printf("Node %s color=%d (c=%d,p=%d)\n", + // n->label().data(),n->m_subgraphId, + // n->children()?n->children()->count():0, + // n->parents()?n->parents()->count():0); + int number=0; + n->renumberNodes(number); + } +} + +DotGfxHierarchyTable::~DotGfxHierarchyTable() +{ + //printf("DotGfxHierarchyTable::~DotGfxHierarchyTable\n"); + + //QDictIterator<DotNode> di(*m_usedNodes); + //DotNode *n; + //for (;(n=di.current());++di) + //{ + // printf("Node %p: %s\n",n,n->label().data()); + //} + + delete m_rootNodes; + delete m_usedNodes; + delete m_rootSubgraphs; +} diff --git a/src/dotgfxhierarchytable.h b/src/dotgfxhierarchytable.h new file mode 100644 index 0000000..5a5bcad --- /dev/null +++ b/src/dotgfxhierarchytable.h @@ -0,0 +1,55 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#ifndef DOTGFXHIERARCHYTABLE_H +#define DOTGFXHIERARCHYTABLE_H + +#include "classdef.h" +#include "ftextstream.h" + +#include "dotgraph.h" +#include "dotnode.h" + +/** Represents a graphical class hierarchy */ +class DotGfxHierarchyTable : public DotGraph +{ + public: + DotGfxHierarchyTable(const char *prefix="",ClassDef::CompoundType ct=ClassDef::Class); + ~DotGfxHierarchyTable(); + void createGraph(DotNode *rootNode,FTextStream &t,const char *path, + const char *fileName,int id); + void writeGraph(FTextStream &t,const char *path, const char *fileName); + const DotNodeList *subGraphs() const { return m_rootSubgraphs; } + + protected: + virtual QCString getBaseName() const; + virtual QCString getMapLabel() const; + virtual void computeTheGraph(); + + private: + void addHierarchy(DotNode *n,const ClassDef *cd,bool hide); + void addClassList(const ClassSDict *cl); + + int m_graphId; + QCString m_prefix; + ClassDef::CompoundType m_classType; + QList<DotNode> *m_rootNodes; + QDict<DotNode> *m_usedNodes; + DotNodeList *m_rootSubgraphs; + DotNode * m_rootSubgraphNode; +}; + + +#endif diff --git a/src/dotgraph.cpp b/src/dotgraph.cpp new file mode 100644 index 0000000..ca6bcca --- /dev/null +++ b/src/dotgraph.cpp @@ -0,0 +1,400 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#include "config.h" +#include "doxygen.h" +#include "index.h" +#include "md5.h" +#include "message.h" +#include "util.h" + +#include "dot.h" +#include "dotrunner.h" +#include "dotgraph.h" +#include "dotnode.h" + +#define MAP_CMD "cmapx" + +QCString DotGraph::DOT_FONTNAME; // will be initialized in initDot +int DotGraph::DOT_FONTSIZE; // will be initialized in initDot + +/*! Checks if a file "baseName".md5 exists. If so the contents +* are compared with \a md5. If equal FALSE is returned. +* The .md5 is created or updated after successful creation of the output file. +*/ +static bool checkMd5Signature(const QCString &baseName, + const QCString &md5) +{ + QFile f(baseName+".md5"); + if (f.open(IO_ReadOnly)) + { + // read checksum + QCString md5stored(33); + int bytesRead=f.readBlock(md5stored.rawData(),32); + md5stored[32]='\0'; + // compare checksum + if (bytesRead==32 && md5==md5stored) + { + // bail out if equal + return FALSE; + } + } + f.close(); + return TRUE; +} + +static bool checkDeliverables(const QCString &file1, + const QCString &file2=QCString()) +{ + bool file1Ok = TRUE; + bool file2Ok = TRUE; + if (!file1.isEmpty()) + { + QFileInfo fi(file1); + file1Ok = (fi.exists() && fi.size()>0); + } + if (!file2.isEmpty()) + { + QFileInfo fi(file2); + file2Ok = (fi.exists() && fi.size()>0); + } + return file1Ok && file2Ok; +} + +static void removeDotGraph(const QCString &dotName) +{ + if (Config_getBool(DOT_CLEANUP)) + { + QDir d; + d.remove(dotName); + } +} + +static bool insertMapFile(FTextStream &out,const QCString &mapFile, + const QCString &relPath,const QCString &mapLabel) +{ + QFileInfo fi(mapFile); + if (fi.exists() && fi.size()>0) // reuse existing map file + { + QGString tmpstr; + FTextStream tmpout(&tmpstr); + convertMapFile(tmpout,mapFile,relPath,FALSE); + if (!tmpstr.isEmpty()) + { + out << "<map name=\"" << mapLabel << "\" id=\"" << mapLabel << "\">" << endl; + out << tmpstr; + out << "</map>" << endl; + } + return TRUE; + } + return FALSE; // no map file yet, need to generate it +} + +//-------------------------------------------------------------------- + +QCString DotGraph::IMG_EXT; + +QCString DotGraph::imgName() const +{ + return m_baseName + ((m_graphFormat == GOF_BITMAP) ? + ("." + IMG_EXT) : (Config_getBool(USE_PDFLATEX) ? ".pdf" : ".eps")); +} + +QCString DotGraph::writeGraph( + FTextStream& t, // output stream for the code file (html, ...) + GraphOutputFormat gf, // bitmap(png/svg) or ps(eps/pdf) + EmbeddedOutputFormat ef, // html, latex, ... + const char* path, // output folder + const char* fileName, // name of the code file (for code patcher) + const char* relPath, // output folder relativ to code file + bool generateImageMap, // in case of bitmap, shall there be code generated? + int graphId) // number of this graph in the current code, used in svg code +{ + m_graphFormat = gf; + m_textFormat = ef; + m_dir = QDir(path); + m_fileName = fileName; + m_relPath = relPath; + m_generateImageMap = generateImageMap; + m_graphId = graphId; + + m_absPath = QCString(m_dir.absPath().data()) + "/"; + m_baseName = getBaseName(); + + computeTheGraph(); + + m_regenerate = prepareDotFile(); + + if (!m_doNotAddImageToIndex) Doxygen::indexList->addImageFile(imgName()); + + generateCode(t); + + return m_baseName; +} + +bool DotGraph::prepareDotFile() +{ + if (!m_dir.exists()) + { + err("Output dir %s does not exist!\n", m_dir.path().data()); exit(1); + } + + QCString sigStr(33); + uchar md5_sig[16]; + // calculate md5 + MD5Buffer((const unsigned char*)m_theGraph.data(), m_theGraph.length(), md5_sig); + // convert result to a string + MD5SigToString(md5_sig, sigStr.rawData(), 33); + + // already queued files are processed again in case the output format has changed + + if (!checkMd5Signature(absBaseName(), sigStr) && + checkDeliverables(absImgName(), + m_graphFormat == GOF_BITMAP && m_generateImageMap ? absMapName() : QCString() + ) + ) + { + // all needed files are there + removeDotGraph(absDotName()); + return FALSE; + } + + // need to rebuild the image + + // write .dot file because image was new or has changed + QFile f(absDotName()); + if (!f.open(IO_WriteOnly)) + { + err("Could not open file %s for writing\n",f.name().data()); + return TRUE; + } + FTextStream t(&f); + t << m_theGraph; + f.close(); + + if (m_graphFormat == GOF_BITMAP) + { + // run dot to create a bitmap image + DotRunner * dotRun = DotManager::instance()->createRunner(absDotName(), sigStr); + dotRun->addJob(Config_getEnum(DOT_IMAGE_FORMAT), absImgName()); + if (m_generateImageMap) dotRun->addJob(MAP_CMD, absMapName()); + } + else if (m_graphFormat == GOF_EPS) + { + // run dot to create a .eps image + DotRunner *dotRun = DotManager::instance()->createRunner(absDotName(), sigStr); + if (Config_getBool(USE_PDFLATEX)) + { + dotRun->addJob("pdf",absImgName()); + } + else + { + dotRun->addJob("ps",absImgName()); + } + } + return TRUE; +} + +void DotGraph::generateCode(FTextStream &t) +{ + if (m_graphFormat==GOF_BITMAP && m_textFormat==EOF_DocBook) + { + t << "<para>" << endl; + t << " <informalfigure>" << endl; + t << " <mediaobject>" << endl; + t << " <imageobject>" << endl; + t << " <imagedata"; + t << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << m_relPath << m_baseName << "." << IMG_EXT << "\">"; + t << "</imagedata>" << endl; + t << " </imageobject>" << endl; + t << " </mediaobject>" << endl; + t << " </informalfigure>" << endl; + t << "</para>" << endl; + } + else if (m_graphFormat==GOF_BITMAP && m_generateImageMap) // produce HTML to include the image + { + if (IMG_EXT=="svg") // add link to SVG file without map file + { + if (!m_noDivTag) t << "<div class=\"center\">"; + if (m_regenerate || !writeSVGFigureLink(t,m_relPath,m_baseName,absImgName())) // need to patch the links in the generated SVG file + { + if (m_regenerate) + { + DotManager::instance()->addSVGConversion(absImgName(),m_relPath,FALSE,QCString(),m_zoomable,m_graphId); + } + int mapId = DotManager::instance()->addSVGObject(m_fileName,m_baseName,absImgName(),m_relPath); + t << "<!-- SVG " << mapId << " -->" << endl; + } + if (!m_noDivTag) t << "</div>" << endl; + } + else // add link to bitmap file with image map + { + if (!m_noDivTag) t << "<div class=\"center\">"; + t << "<img src=\"" << relImgName() << "\" border=\"0\" usemap=\"#" << getMapLabel() << "\" alt=\"" << getImgAltText() << "\"/>"; + if (!m_noDivTag) t << "</div>"; + t << endl; + if (m_regenerate || !insertMapFile(t, absMapName(), m_relPath, getMapLabel())) + { + int mapId = DotManager::instance()->addMap(m_fileName, absMapName(), m_relPath, m_urlOnly, QCString(), getMapLabel()); + t << "<!-- MAP " << mapId << " -->" << endl; + } + } + } + else if (m_graphFormat==GOF_EPS) // produce tex to include the .eps image + { + if (m_regenerate || !writeVecGfxFigure(t,m_baseName,absBaseName())) + { + int figId = DotManager::instance()->addFigure(m_fileName,m_baseName,absBaseName(),FALSE /*TRUE*/); + t << endl << "% FIG " << figId << endl; + } + } +} + +void DotGraph::writeGraphHeader(FTextStream &t,const QCString &title) +{ + t << "digraph "; + if (title.isEmpty()) + { + t << "\"Dot Graph\""; + } + else + { + t << "\"" << convertToXML(title) << "\""; + } + t << endl << "{" << endl; + if (Config_getBool(INTERACTIVE_SVG)) // insert a comment to force regeneration when this + // option is toggled + { + t << " // INTERACTIVE_SVG=YES\n"; + } + t << " // LATEX_PDF_SIZE\n"; // write placeholder for LaTeX PDF bounding box size repacement + if (Config_getBool(DOT_TRANSPARENT)) + { + t << " bgcolor=\"transparent\";" << endl; + } + t << " edge [fontname=\"" << DOT_FONTNAME << "\"," + "fontsize=\"" << DOT_FONTSIZE << "\"," + "labelfontname=\"" << DOT_FONTNAME << "\"," + "labelfontsize=\"" << DOT_FONTSIZE << "\"];\n"; + t << " node [fontname=\"" << DOT_FONTNAME << "\"," + "fontsize=\"" << DOT_FONTSIZE << "\",shape=record];\n"; +} + +void DotGraph::writeGraphFooter(FTextStream &t) +{ + t << "}" << endl; +} + +void DotGraph::computeGraph(DotNode *root, + GraphType gt, + GraphOutputFormat format, + const QCString &rank, // either "LR", "RL", or "" + bool renderParents, + bool backArrows, + const QCString &title, + QGString &graphStr) +{ + //printf("computeMd5Signature\n"); + QGString buf; + FTextStream md5stream(&buf); + writeGraphHeader(md5stream,title); + if (!rank.isEmpty()) + { + md5stream << " rankdir=\"" << rank << "\";" << endl; + } + root->clearWriteFlag(); + root->write(md5stream, gt, format, gt!=CallGraph && gt!=Dependency, TRUE, backArrows); + if (renderParents && root->parents()) + { + QListIterator<DotNode> dnli(*root->parents()); + const DotNode *pn; + for (dnli.toFirst();(pn=dnli.current());++dnli) + { + if (pn->isVisible()) + { + root->writeArrow(md5stream, // stream + gt, // graph type + format, // output format + pn, // child node + pn->edgeInfo()->at(pn->children()->findRef(root)), // edge info + FALSE, // topDown? + backArrows // point back? + ); + } + pn->write(md5stream, // stream + gt, // graph type + format, // output format + TRUE, // topDown? + FALSE, // toChildren? + backArrows // backward pointing arrows? + ); + } + } + writeGraphFooter(md5stream); + + graphStr=buf.data(); +} + +bool DotGraph::writeVecGfxFigure(FTextStream &out,const QCString &baseName, + const QCString &figureName) +{ + int width=400,height=550; + if (Config_getBool(USE_PDFLATEX)) + { + if (!DotRunner::readBoundingBox(figureName+".pdf",&width,&height,FALSE)) + { + //printf("writeVecGfxFigure()=0\n"); + return FALSE; + } + } + else + { + if (!DotRunner::readBoundingBox(figureName+".eps",&width,&height,TRUE)) + { + //printf("writeVecGfxFigure()=0\n"); + return FALSE; + } + } + //printf("Got PDF/EPS size %d,%d\n",width,height); + int maxWidth = 350; /* approx. page width in points, excl. margins */ + int maxHeight = 550; /* approx. page height in points, excl. margins */ + out << "\\nopagebreak\n" + "\\begin{figure}[H]\n" + "\\begin{center}\n" + "\\leavevmode\n"; + if (width>maxWidth || height>maxHeight) // figure too big for page + { + // c*width/maxWidth > c*height/maxHeight, where c=maxWidth*maxHeight>0 + if (width*maxHeight>height*maxWidth) + { + out << "\\includegraphics[width=" << maxWidth << "pt]"; + } + else + { + out << "\\includegraphics[height=" << maxHeight << "pt]"; + } + } + else + { + out << "\\includegraphics[width=" << width << "pt]"; + } + + out << "{" << baseName << "}\n" + "\\end{center}\n" + "\\end{figure}\n"; + + //printf("writeVecGfxFigure()=1\n"); + return TRUE; +} diff --git a/src/dotgraph.h b/src/dotgraph.h new file mode 100644 index 0000000..27d6938 --- /dev/null +++ b/src/dotgraph.h @@ -0,0 +1,113 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2019 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef DOTGRAPH_H +#define DOTGRAPH_H + +#include <qcstring.h> +#include <qgstring.h> +#include <qdir.h> + +class FTextStream; +class DotNode; + +enum GraphOutputFormat { GOF_BITMAP, GOF_EPS }; +enum EmbeddedOutputFormat { EOF_Html, EOF_LaTeX, EOF_Rtf, EOF_DocBook }; +enum GraphType { Dependency, Inheritance, Collaboration, Hierarchy, CallGraph }; + +/** A dot graph */ +class DotGraph +{ + public: + DotGraph() : m_curNodeNumber(0), m_doNotAddImageToIndex(FALSE), m_noDivTag(FALSE), m_zoomable(TRUE), m_urlOnly(FALSE) {} + virtual ~DotGraph() {} + + static QCString DOT_FONTNAME; // will be initialized in initDot + static int DOT_FONTSIZE; // will be initialized in initDot + + static bool writeVecGfxFigure(FTextStream& out, const QCString& baseName, const QCString& figureName); + + protected: + /** returns node numbers. The Counter is reset by the constructor */ + int getNextNodeNumber() { return ++m_curNodeNumber; } + + QCString writeGraph(FTextStream &t, + GraphOutputFormat gf, + EmbeddedOutputFormat ef, + const char *path, + const char *fileName, + const char *relPath, + bool writeImageMap=TRUE, + int graphId=-1 + ); + + static void writeGraphHeader(FTextStream& t, const QCString& title = QCString()); + static void writeGraphFooter(FTextStream& t); + static void computeGraph(DotNode* root, + GraphType gt, + GraphOutputFormat format, + const QCString& rank, // either "LR", "RL", or "" + bool renderParents, + bool backArrows, + const QCString& title, + QGString& graphStr + ); + + virtual QCString getBaseName() const = 0; + virtual QCString absMapName() const { return m_absPath + m_baseName + ".map"; } + virtual QCString getMapLabel() const = 0; + virtual QCString getImgAltText() const { return ""; } + + virtual void computeTheGraph() = 0; + + static QCString IMG_EXT; + + friend void initDot(); + + QCString absBaseName() const { return m_absPath + m_baseName; } + QCString absDotName() const { return m_absPath + m_baseName + ".dot"; } + QCString imgName() const; + QCString absImgName() const { return m_absPath + imgName(); } + QCString relImgName() const { return m_relPath + imgName(); } + + // the following variables are used while writing the graph to a .dot file + GraphOutputFormat m_graphFormat; + EmbeddedOutputFormat m_textFormat; + QDir m_dir; + QCString m_fileName; + QCString m_relPath; + bool m_generateImageMap; + int m_graphId; + + QCString m_absPath; + QCString m_baseName; + QGString m_theGraph; + bool m_regenerate; + bool m_doNotAddImageToIndex; + bool m_noDivTag; + bool m_zoomable; + bool m_urlOnly; + + private: + DotGraph(const DotGraph &); + DotGraph &operator=(const DotGraph &); + + bool prepareDotFile(); + void generateCode(FTextStream &t); + + int m_curNodeNumber; +}; + +#endif diff --git a/src/dotgroupcollaboration.cpp b/src/dotgroupcollaboration.cpp new file mode 100644 index 0000000..be55ac0 --- /dev/null +++ b/src/dotgroupcollaboration.cpp @@ -0,0 +1,381 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#include "dotgroupcollaboration.h" + +#include "dotnode.h" +#include "classlist.h" +#include "doxygen.h" +#include "namespacedef.h" +#include "pagedef.h" +#include "util.h" +#include "config.h" + +#define DOT_TRANSPARENT Config_getBool(DOT_TRANSPARENT) + +DotGroupCollaboration::DotGroupCollaboration(const GroupDef* gd) +{ + QCString tmp_url = gd->getReference()+"$"+gd->getOutputFileBase(); + m_usedNodes = new QDict<DotNode>(1009); + QCString tooltip = gd->briefDescriptionAsTooltip(); + m_rootNode = new DotNode(getNextNodeNumber(), gd->groupTitle(), tooltip, tmp_url, TRUE ); + m_rootNode->markAsVisible(); + m_usedNodes->insert(gd->name(), m_rootNode ); + m_edges.setAutoDelete(TRUE); + + m_diskName = gd->getOutputFileBase(); + + buildGraph( gd ); +} + +DotGroupCollaboration::~DotGroupCollaboration() +{ + delete m_usedNodes; +} + +void DotGroupCollaboration::buildGraph(const GroupDef* gd) +{ + QCString tmp_url; + //=========================== + // hierarchy. + + // Write parents + const GroupList *groups = gd->partOfGroups(); + if ( groups ) + { + GroupListIterator gli(*groups); + const GroupDef *d; + for (gli.toFirst();(d=gli.current());++gli) + { + DotNode* nnode = m_usedNodes->find(d->name()); + if ( !nnode ) + { // add node + tmp_url = d->getReference()+"$"+d->getOutputFileBase(); + QCString tooltip = d->briefDescriptionAsTooltip(); + nnode = new DotNode(getNextNodeNumber(), d->groupTitle(), tooltip, tmp_url ); + nnode->markAsVisible(); + m_usedNodes->insert(d->name(), nnode ); + } + tmp_url = ""; + addEdge( nnode, m_rootNode, DotGroupCollaboration::thierarchy, tmp_url, tmp_url ); + } + } + + // Add subgroups + if ( gd->getSubGroups() && gd->getSubGroups()->count() ) + { + QListIterator<GroupDef> defli(*gd->getSubGroups()); + const GroupDef *def; + for (;(def=defli.current());++defli) + { + DotNode* nnode = m_usedNodes->find(def->name()); + if ( !nnode ) + { // add node + tmp_url = def->getReference()+"$"+def->getOutputFileBase(); + QCString tooltip = def->briefDescriptionAsTooltip(); + nnode = new DotNode(getNextNodeNumber(), def->groupTitle(), tooltip, tmp_url ); + nnode->markAsVisible(); + m_usedNodes->insert(def->name(), nnode ); + } + tmp_url = ""; + addEdge( m_rootNode, nnode, DotGroupCollaboration::thierarchy, tmp_url, tmp_url ); + } + } + + //======================= + // Write collaboration + + // Add members + addMemberList( gd->getMemberList(MemberListType_allMembersList) ); + + // Add classes + if ( gd->getClasses() && gd->getClasses()->count() ) + { + ClassSDict::Iterator defli(*gd->getClasses()); + ClassDef *def; + for (;(def=defli.current());++defli) + { + tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension; + if (!def->anchor().isEmpty()) + { + tmp_url+="#"+def->anchor(); + } + addCollaborationMember( def, tmp_url, DotGroupCollaboration::tclass ); + } + } + + // Add namespaces + if ( gd->getNamespaces() && gd->getNamespaces()->count() ) + { + NamespaceSDict::Iterator defli(*gd->getNamespaces()); + NamespaceDef *def; + for (;(def=defli.current());++defli) + { + tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension; + addCollaborationMember( def, tmp_url, DotGroupCollaboration::tnamespace ); + } + } + + // Add files + if ( gd->getFiles() && gd->getFiles()->count() ) + { + QListIterator<FileDef> defli(*gd->getFiles()); + const FileDef *def; + for (;(def=defli.current());++defli) + { + tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension; + addCollaborationMember( def, tmp_url, DotGroupCollaboration::tfile ); + } + } + + // Add pages + if ( gd->getPages() && gd->getPages()->count() ) + { + PageSDict::Iterator defli(*gd->getPages()); + PageDef *def; + for (;(def=defli.current());++defli) + { + tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension; + addCollaborationMember( def, tmp_url, DotGroupCollaboration::tpages ); + } + } + + // Add directories + if ( gd->getDirs() && gd->getDirs()->count() ) + { + QListIterator<DirDef> defli(*gd->getDirs()); + const DirDef *def; + for (;(def=defli.current());++defli) + { + tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension; + addCollaborationMember( def, tmp_url, DotGroupCollaboration::tdir ); + } + } +} + +void DotGroupCollaboration::addMemberList( MemberList* ml ) +{ + if ( !( ml && ml->count()) ) return; + MemberListIterator defli(*ml); + MemberDef *def; + for (;(def=defli.current());++defli) + { + QCString tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension + +"#"+def->anchor(); + addCollaborationMember( def, tmp_url, DotGroupCollaboration::tmember ); + } +} + +DotGroupCollaboration::Edge* DotGroupCollaboration::addEdge( + DotNode* _pNStart, DotNode* _pNEnd, EdgeType _eType, + const QCString& _label, const QCString& _url ) +{ + // search a existing link. + QListIterator<Edge> lli(m_edges); + Edge* newEdge = 0; + for ( lli.toFirst(); (newEdge=lli.current()); ++lli) + { + if ( newEdge->pNStart==_pNStart && + newEdge->pNEnd==_pNEnd && + newEdge->eType==_eType + ) + { // edge already found + break; + } + } + if ( newEdge==0 ) // new link + { + newEdge = new Edge(_pNStart,_pNEnd,_eType); + m_edges.append( newEdge ); + } + + if (!_label.isEmpty()) + { + newEdge->links.append(new Link(_label,_url)); + } + + return newEdge; +} + +void DotGroupCollaboration::addCollaborationMember( + const Definition* def, QCString& url, EdgeType eType ) +{ + // Create group nodes + if ( !def->partOfGroups() ) + return; + GroupListIterator gli(*def->partOfGroups()); + GroupDef *d; + QCString tmp_str; + for (;(d=gli.current());++gli) + { + DotNode* nnode = m_usedNodes->find(d->name()); + if ( nnode != m_rootNode ) + { + if ( nnode==0 ) + { // add node + tmp_str = d->getReference()+"$"+d->getOutputFileBase(); + QCString tooltip = d->briefDescriptionAsTooltip(); + nnode = new DotNode(getNextNodeNumber(), d->groupTitle(), tooltip, tmp_str ); + nnode->markAsVisible(); + m_usedNodes->insert(d->name(), nnode ); + } + tmp_str = def->qualifiedName(); + addEdge( m_rootNode, nnode, eType, tmp_str, url ); + } + } +} + +QCString DotGroupCollaboration::getBaseName() const +{ + return m_diskName; +} + +void DotGroupCollaboration::computeTheGraph() +{ + FTextStream md5stream(&m_theGraph); + writeGraphHeader(md5stream,m_rootNode->label()); + + // clean write flags + QDictIterator<DotNode> dni(*m_usedNodes); + DotNode *pn; + for (dni.toFirst();(pn=dni.current());++dni) + { + pn->clearWriteFlag(); + } + + // write other nodes. + for (dni.toFirst();(pn=dni.current());++dni) + { + pn->write(md5stream,Inheritance,m_graphFormat,TRUE,FALSE,FALSE); + } + + // write edges + QListIterator<Edge> eli(m_edges); + Edge* edge; + for (eli.toFirst();(edge=eli.current());++eli) + { + edge->write( md5stream ); + } + + writeGraphFooter(md5stream); + +} + +QCString DotGroupCollaboration::getMapLabel() const +{ + return escapeCharsInString(m_baseName, FALSE); +} + +QCString DotGroupCollaboration::writeGraph( FTextStream &t, + GraphOutputFormat graphFormat, EmbeddedOutputFormat textFormat, + const char *path, const char *fileName, const char *relPath, + bool generateImageMap,int graphId) +{ + m_doNotAddImageToIndex = TRUE; + + return DotGraph::writeGraph(t, graphFormat, textFormat, path, fileName, relPath, generateImageMap, graphId); +} + +void DotGroupCollaboration::Edge::write( FTextStream &t ) const +{ + const char* linkTypeColor[] = { + "darkorchid3" + ,"orange" + ,"blueviolet" + ,"darkgreen" + ,"firebrick4" + ,"grey75" + ,"midnightblue" + }; + QCString arrowStyle = "dir=\"none\", style=\"dashed\""; + t << " Node" << pNStart->number(); + t << "->"; + t << "Node" << pNEnd->number(); + + t << " [shape=plaintext"; + if (links.count()>0) // there are links + { + t << ", "; + // HTML-like edge labels crash on my Mac with Graphviz 2.0! and + // are not supported by older version of dot. + // + //t << label=<<TABLE BORDER=\"0\" CELLBORDER=\"0\">"; + //QListIterator<Link> lli(links); + //Link *link; + //for( lli.toFirst(); (link=lli.current()); ++lli) + //{ + // t << "<TR><TD"; + // if ( !link->url.isEmpty() ) + // t << " HREF=\"" << link->url << "\""; + // t << ">" << link->label << "</TD></TR>"; + //} + //t << "</TABLE>>"; + + t << "label=\""; + QListIterator<Link> lli(links); + Link *link; + bool first=TRUE; + int count=0; + const int maxLabels = 10; + for( lli.toFirst(); (link=lli.current()) && count<maxLabels; ++lli,++count) + { + if (first) first=FALSE; else t << "\\n"; + t << DotNode::convertLabel(link->label); + } + if (count==maxLabels) t << "\\n..."; + t << "\""; + + } + switch( eType ) + { + case thierarchy: + arrowStyle = "dir=\"back\", style=\"solid\""; + break; + default: + t << ", color=\"" << linkTypeColor[(int)eType] << "\""; + break; + } + t << ", " << arrowStyle; + t << "];" << endl; +} + +bool DotGroupCollaboration::isTrivial() const +{ + return m_usedNodes->count() <= 1; +} + +void DotGroupCollaboration::writeGraphHeader(FTextStream &t, + const QCString &title) const +{ + t << "digraph "; + if (title.isEmpty()) + { + t << "\"Dot Graph\""; + } + else + { + t << "\"" << convertToXML(title) << "\""; + } + t << endl; + t << "{" << endl; + if (DOT_TRANSPARENT) + { + t << " bgcolor=\"transparent\";" << endl; + } + t << " edge [fontname=\"" << DOT_FONTNAME << "\",fontsize=\"" << DOT_FONTSIZE << "\"," + "labelfontname=\"" << DOT_FONTNAME << "\",labelfontsize=\"" << DOT_FONTSIZE << "\"];\n"; + t << " node [fontname=\"" << DOT_FONTNAME << "\",fontsize=\"" << DOT_FONTSIZE << "\",shape=box];\n"; + t << " rankdir=LR;\n"; +} diff --git a/src/dotgroupcollaboration.h b/src/dotgroupcollaboration.h new file mode 100644 index 0000000..539637f --- /dev/null +++ b/src/dotgroupcollaboration.h @@ -0,0 +1,85 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#ifndef DOTGROUPCOLLABORATION_H +#define DOTGROUPCOLLABORATION_H + +#include "dotgraph.h" +#include "qlist.h" +#include "groupdef.h" + +/** Representation of a group collaboration graph */ +class DotGroupCollaboration : public DotGraph +{ + public : + DotGroupCollaboration(const GroupDef* gd); + ~DotGroupCollaboration(); + QCString writeGraph(FTextStream &t, GraphOutputFormat gf,EmbeddedOutputFormat ef, + const char *path,const char *fileName,const char *relPath, + bool writeImageMap=TRUE,int graphId=-1); + bool isTrivial() const; + + protected: + virtual QCString getBaseName() const; + virtual QCString getMapLabel() const; + virtual void computeTheGraph(); + + private : + enum EdgeType + { + tmember = 0, + tclass, + tnamespace, + tfile, + tpages, + tdir, + thierarchy + }; + + struct Link + { + Link(const QCString lab,const QCString &u) : label(lab), url(u) {} + QCString label; + QCString url; + }; + + struct Edge + { + Edge(DotNode *start,DotNode *end,EdgeType type) + : pNStart(start), pNEnd(end), eType(type) + { links.setAutoDelete(TRUE); } + + DotNode* pNStart; + DotNode* pNEnd; + EdgeType eType; + + QList<Link> links; + void write( FTextStream &t ) const; + }; + + void buildGraph(const GroupDef* gd); + void addCollaborationMember(const Definition* def, QCString& url, EdgeType eType ); + void addMemberList( class MemberList* ml ); + void writeGraphHeader(FTextStream &t,const QCString &title) const; + Edge* addEdge( DotNode* _pNStart, DotNode* _pNEnd, EdgeType _eType, + const QCString& _label, const QCString& _url ); + + DotNode *m_rootNode; + QDict<DotNode> *m_usedNodes; + QCString m_diskName; + QList<Edge> m_edges; +}; + +#endif diff --git a/src/dotincldepgraph.cpp b/src/dotincldepgraph.cpp new file mode 100644 index 0000000..23588db --- /dev/null +++ b/src/dotincldepgraph.cpp @@ -0,0 +1,238 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#include "dotincldepgraph.h" +#include "dotnode.h" +#include "util.h" +#include "config.h" + +void DotInclDepGraph::buildGraph(DotNode *n,const FileDef *fd,int distance) +{ + QList<IncludeInfo> *includeFiles = m_inverse ? fd->includedByFileList() : fd->includeFileList(); + if (includeFiles) + { + QListIterator<IncludeInfo> ili(*includeFiles); + IncludeInfo *ii; + for (;(ii=ili.current());++ili) + { + const FileDef *bfd = ii->fileDef; + QCString in = ii->includeName; + //printf(">>>> in='%s' bfd=%p\n",ii->includeName.data(),bfd); + bool doc=TRUE,src=FALSE; + if (bfd) + { + in = bfd->absFilePath(); + doc = bfd->isLinkable() && !bfd->isHidden(); + src = bfd->generateSourceFile(); + } + if (doc || src || !Config_getBool(HIDE_UNDOC_RELATIONS)) + { + QCString url=""; + if (bfd) url=bfd->getOutputFileBase().copy(); + if (!doc && src) + { + url=bfd->getSourceFileBase(); + } + DotNode *bn = m_usedNodes->find(in); + if (bn) // file is already a node in the graph + { + n->addChild(bn,0,0,0); + bn->addParent(n); + bn->setDistance(distance); + } + else + { + QCString tmp_url; + QCString tooltip; + if (bfd) + { + tmp_url=doc || src ? bfd->getReference()+"$"+url : QCString(); + tooltip = bfd->briefDescriptionAsTooltip(); + } + bn = new DotNode(getNextNodeNumber(),// n + ii->includeName, // label + tooltip, // tip + tmp_url, // url + FALSE, // rootNode + 0); // cd + n->addChild(bn,0,0,0); + bn->addParent(n); + m_usedNodes->insert(in,bn); + bn->setDistance(distance); + + if (bfd) buildGraph(bn,bfd,distance+1); + } + } + } + } +} + +void DotInclDepGraph::determineVisibleNodes(QList<DotNode> &queue, int &maxNodes) +{ + while (queue.count()>0 && maxNodes>0) + { + DotNode *n = queue.take(0); + if (!n->isVisible() && n->distance()<=Config_getInt(MAX_DOT_GRAPH_DEPTH)) // not yet processed + { + n->markAsVisible(); + maxNodes--; + // add direct children + if (n->children()) + { + QListIterator<DotNode> li(*n->children()); + const DotNode *dn; + for (li.toFirst();(dn=li.current());++li) + { + queue.append(dn); + } + } + } + } +} + +void DotInclDepGraph::determineTruncatedNodes(QList<DotNode> &queue) +{ + while (queue.count()>0) + { + DotNode *n = queue.take(0); + if (n->isVisible() && n->isTruncated()==DotNode::Unknown) + { + bool truncated = FALSE; + if (n->children()) + { + QListIterator<DotNode> li(*n->children()); + const DotNode *dn; + for (li.toFirst();(dn=li.current());++li) + { + if (!dn->isVisible()) + { + truncated = TRUE; + } + else + { + queue.append(dn); + } + } + } + n->markAsTruncated(truncated); + } + } +} + +DotInclDepGraph::DotInclDepGraph(const FileDef *fd,bool inverse) +{ + m_inverse = inverse; + ASSERT(fd!=0); + m_inclDepFileName = fd->includeDependencyGraphFileName(); + m_inclByDepFileName = fd->includedByDependencyGraphFileName(); + QCString tmp_url=fd->getReference()+"$"+fd->getOutputFileBase(); + QCString tooltip = fd->briefDescriptionAsTooltip(); + m_startNode = new DotNode(getNextNodeNumber(), + fd->docName(), + tooltip, + tmp_url.data(), + TRUE); // root node + m_startNode->setDistance(0); + m_usedNodes = new QDict<DotNode>(1009); + m_usedNodes->insert(fd->absFilePath(),m_startNode); + buildGraph(m_startNode,fd,1); + + int maxNodes = Config_getInt(DOT_GRAPH_MAX_NODES); + QList<DotNode> openNodeQueue; + openNodeQueue.append(m_startNode); + determineVisibleNodes(openNodeQueue,maxNodes); + openNodeQueue.clear(); + openNodeQueue.append(m_startNode); + determineTruncatedNodes(openNodeQueue); +} + +DotInclDepGraph::~DotInclDepGraph() +{ + DotNode::deleteNodes(m_startNode); + delete m_usedNodes; +} + +QCString DotInclDepGraph::getBaseName() const +{ + if (m_inverse) + { + return m_inclByDepFileName; + } + else + { + return m_inclDepFileName; + } +} + +void DotInclDepGraph::computeTheGraph() +{ + computeGraph(m_startNode, Dependency, m_graphFormat, "", FALSE, + m_inverse, m_startNode->label(), m_theGraph); +} + +QCString DotInclDepGraph::getMapLabel() const +{ + if (m_inverse) + { + return escapeCharsInString(m_startNode->label(),FALSE) + "dep"; + } + else + { + return escapeCharsInString(m_startNode->label(),FALSE); + } +} + +QCString DotInclDepGraph::writeGraph(FTextStream &out, + GraphOutputFormat graphFormat, + EmbeddedOutputFormat textFormat, + const char *path, + const char *fileName, + const char *relPath, + bool generateImageMap, + int graphId) +{ + return DotGraph::writeGraph(out, graphFormat, textFormat, path, fileName, relPath, generateImageMap, graphId); +} + +bool DotInclDepGraph::isTrivial() const +{ + return m_startNode->children()==0; +} + +bool DotInclDepGraph::isTooBig() const +{ + int numNodes = m_startNode->children() ? m_startNode->children()->count() : 0; + return numNodes>=Config_getInt(DOT_GRAPH_MAX_NODES); +} + +void DotInclDepGraph::writeXML(FTextStream &t) +{ + QDictIterator<DotNode> dni(*m_usedNodes); + DotNode *node; + for (;(node=dni.current());++dni) + { + node->writeXML(t,FALSE); + } +} + +void DotInclDepGraph::writeDocbook(FTextStream &t) +{ + QDictIterator<DotNode> dni(*m_usedNodes); + DotNode *node; + for (;(node=dni.current());++dni) + { + node->writeDocbook(t,FALSE); + } +} diff --git a/src/dotincldepgraph.h b/src/dotincldepgraph.h new file mode 100644 index 0000000..b664ccb --- /dev/null +++ b/src/dotincldepgraph.h @@ -0,0 +1,56 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#ifndef DOTINCLDEPGRAPH_H +#define DOTINCLDEPGRAPH_H + +#include "qcstring.h" +#include "filedef.h" + +#include "dotgraph.h" + +/** Representation of an include dependency graph */ +class DotInclDepGraph : public DotGraph +{ + public: + DotInclDepGraph(const FileDef *fd,bool inverse); + ~DotInclDepGraph(); + QCString writeGraph(FTextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, + const char *path,const char *fileName,const char *relPath, + bool writeImageMap=TRUE,int graphId=-1); + bool isTrivial() const; + bool isTooBig() const; + void writeXML(FTextStream &t); + void writeDocbook(FTextStream &t); + + protected: + virtual QCString getBaseName() const; + virtual QCString getMapLabel() const; + virtual void computeTheGraph(); + + private: + QCString diskName() const; + void buildGraph(DotNode *n,const FileDef *fd,int distance); + void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes); + void determineTruncatedNodes(QList<DotNode> &queue); + + DotNode *m_startNode; + QDict<DotNode> *m_usedNodes; + QCString m_inclDepFileName; + QCString m_inclByDepFileName; + bool m_inverse; +}; + +#endif diff --git a/src/dotnode.cpp b/src/dotnode.cpp new file mode 100644 index 0000000..ae06fb2 --- /dev/null +++ b/src/dotnode.cpp @@ -0,0 +1,950 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#include "dotnode.h" + +#include "ftextstream.h" +#include "classdef.h" +#include "config.h" +#include "memberlist.h" +#include "membergroup.h" +#include "language.h" +#include "doxygen.h" +#include "util.h" + +/** Helper struct holding the properties of a edge in a dot graph. */ +struct EdgeProperties +{ + const char * const *edgeColorMap; + const char * const *arrowStyleMap; + const char * const *edgeStyleMap; +}; + +/*! mapping from protection levels to color names */ +static const char *normalEdgeColorMap[] = +{ + "midnightblue", // Public + "darkgreen", // Protected + "firebrick4", // Private + "darkorchid3", // "use" relation + "grey75", // Undocumented + "orange", // template relation + "orange" // type constraint +}; + +static const char *normalArrowStyleMap[] = +{ + "empty", // Public + "empty", // Protected + "empty", // Private + "open", // "use" relation + 0, // Undocumented + 0 // template relation +}; + +static const char *normalEdgeStyleMap[] = +{ + "solid", // inheritance + "dashed" // usage +}; + +static const char *umlEdgeColorMap[] = +{ + "midnightblue", // Public + "darkgreen", // Protected + "firebrick4", // Private + "grey25", // "use" relation + "grey75", // Undocumented + "orange", // template relation + "orange" // type constraint +}; + +static const char *umlArrowStyleMap[] = +{ + "onormal", // Public + "onormal", // Protected + "onormal", // Private + "odiamond", // "use" relation + 0, // Undocumented + 0 // template relation +}; + +static const char *umlEdgeStyleMap[] = +{ + "solid", // inheritance + "solid" // usage +}; + +static EdgeProperties normalEdgeProps = +{ + normalEdgeColorMap, normalArrowStyleMap, normalEdgeStyleMap +}; + +static EdgeProperties umlEdgeProps = +{ + umlEdgeColorMap, umlArrowStyleMap, umlEdgeStyleMap +}; + +static QCString escapeTooltip(const QCString &tooltip) +{ + QCString result; + const char *p=tooltip.data(); + if (p==0) return result; + char c; + while ((c=*p++)) + { + switch(c) + { + case '"': result+="\\\""; break; + case '\\': result+="\\\\"; break; + default: result+=c; break; + } + } + return result; +} + +static void writeBoxMemberList(FTextStream &t, + char prot,MemberList *ml,const ClassDef *scope, + bool isStatic=FALSE,const QDict<void> *skipNames=0) +{ + (void)isStatic; + if (ml) + { + MemberListIterator mlia(*ml); + MemberDef *mma; + int totalCount=0; + for (mlia.toFirst();(mma = mlia.current());++mlia) + { + if (mma->getClassDef()==scope && + (skipNames==0 || skipNames->find(mma->name())==0)) + { + totalCount++; + } + } + + int count=0; + for (mlia.toFirst();(mma = mlia.current());++mlia) + { + if (mma->getClassDef() == scope && + (skipNames==0 || skipNames->find(mma->name())==0)) + { + int numFields = Config_getInt(UML_LIMIT_NUM_FIELDS); + if (numFields>0 && (totalCount>numFields*3/2 && count>=numFields)) + { + t << theTranslator->trAndMore(QCString().sprintf("%d",totalCount-count)) << "\\l"; + break; + } + else + { + t << prot << " "; + t << DotNode::convertLabel(mma->name()); + if (!mma->isObjCMethod() && + (mma->isFunction() || mma->isSlot() || mma->isSignal())) t << "()"; + t << "\\l"; + count++; + } + } + } + // write member groups within the memberlist + MemberGroupList *mgl = ml->getMemberGroupList(); + if (mgl) + { + MemberGroupListIterator mgli(*mgl); + MemberGroup *mg; + for (mgli.toFirst();(mg=mgli.current());++mgli) + { + if (mg->members()) + { + writeBoxMemberList(t,prot,mg->members(),scope,isStatic,skipNames); + } + } + } + } +} + +QCString DotNode::convertLabel(const QCString &l) +{ + QString bBefore("\\_/<({[: =-+@%#~?$"); // break before character set + QString bAfter(">]),:;|"); // break after character set + QString p(l); + if (p.isEmpty()) return QCString(); + QString result; + QChar c,pc=0; + uint idx = 0; + int len=p.length(); + int charsLeft=len; + int sinceLast=0; + int foldLen=17; // ideal text length + while (idx < p.length()) + { + c = p[idx++]; + QString replacement; + switch(c) + { + case '\\': replacement="\\\\"; break; + case '\n': replacement="\\n"; break; + case '<': replacement="\\<"; break; + case '>': replacement="\\>"; break; + case '|': replacement="\\|"; break; + case '{': replacement="\\{"; break; + case '}': replacement="\\}"; break; + case '"': replacement="\\\""; break; + default: replacement=c; break; + } + // Some heuristics to insert newlines to prevent too long + // boxes and at the same time prevent ugly breaks + if (c=='\n') + { + result+=replacement; + foldLen = (3*foldLen+sinceLast+2)/4; + sinceLast=1; + } + else if ((pc!=':' || c!=':') && charsLeft>foldLen/3 && sinceLast>foldLen && bBefore.contains(c)) + { + result+="\\l"; + result+=replacement; + foldLen = (foldLen+sinceLast+1)/2; + sinceLast=1; + } + else if (charsLeft>1+foldLen/4 && sinceLast>foldLen+foldLen/3 && + !isupper(c) && p[idx].category()==QChar::Letter_Uppercase) + { + result+=replacement; + result+="\\l"; + foldLen = (foldLen+sinceLast+1)/2; + sinceLast=0; + } + else if (charsLeft>foldLen/3 && sinceLast>foldLen && bAfter.contains(c) && (c!=':' || p[idx]!=':')) + { + result+=replacement; + result+="\\l"; + foldLen = (foldLen+sinceLast+1)/2; + sinceLast=0; + } + else + { + result+=replacement; + sinceLast++; + } + charsLeft--; + pc=c; + } + return result.utf8(); +} + +static QCString stripProtectionPrefix(const QCString &s) +{ + if (!s.isEmpty() && (s[0]=='-' || s[0]=='+' || s[0]=='~' || s[0]=='#')) + { + return s.mid(1); + } + else + { + return s; + } +} + +DotNode::DotNode(int n,const char *lab,const char *tip, const char *url, + bool isRoot,const ClassDef *cd) + : m_subgraphId(-1) + , m_number(n) + , m_label(lab) + , m_tooltip(tip) + , m_url(url) + , m_parents(0) + , m_children(0) + , m_edgeInfo(0) + , m_deleted(FALSE) + , m_written(FALSE) + , m_hasDoc(FALSE) + , m_isRoot(isRoot) + , m_classDef(cd) + , m_visible(FALSE) + , m_truncated(Unknown) + , m_distance(1000) + , m_renumbered(false) +{ +} + +DotNode::~DotNode() +{ + delete m_children; + delete m_parents; + delete m_edgeInfo; +} + +void DotNode::addChild(DotNode *n, + int edgeColor, + int edgeStyle, + const char *edgeLab, + const char *edgeURL, + int edgeLabCol +) +{ + if (m_children==0) + { + m_children = new QList<DotNode>; + m_edgeInfo = new QList<EdgeInfo>; + m_edgeInfo->setAutoDelete(TRUE); + } + m_children->append(n); + EdgeInfo *ei = new EdgeInfo( + edgeColor, + edgeStyle, + edgeLab, + edgeURL, + edgeLabCol==-1 ? edgeColor : edgeLabCol); + m_edgeInfo->append(ei); +} + +void DotNode::addParent(DotNode *n) +{ + if (m_parents==0) + { + m_parents = new QList<DotNode>; + } + m_parents->append(n); +} + +void DotNode::removeChild(DotNode *n) +{ + if (m_children) m_children->remove(n); +} + +void DotNode::removeParent(DotNode *n) +{ + if (m_parents) m_parents->remove(n); +} + +void DotNode::deleteNode(DotNodeList &deletedList,SDict<DotNode> *skipNodes) +{ + if (m_deleted) return; // avoid recursive loops in case the graph has cycles + m_deleted=TRUE; + if (m_parents!=0) // delete all parent nodes of this node + { + QListIterator<DotNode> dnlip(*m_parents); + DotNode *pn; + for (dnlip.toFirst();(pn=dnlip.current());++dnlip) + { + //pn->removeChild(this); + pn->deleteNode(deletedList,skipNodes); + } + } + if (m_children!=0) // delete all child nodes of this node + { + QListIterator<DotNode> dnlic(*m_children); + DotNode *cn; + for (dnlic.toFirst();(cn=dnlic.current());++dnlic) + { + //cn->removeParent(this); + cn->deleteNode(deletedList,skipNodes); + } + } + // add this node to the list of deleted nodes. + //printf("skipNodes=%p find(%p)=%p\n",skipNodes,this,skipNodes ? skipNodes->find((int)this) : 0); + if (skipNodes==0 || skipNodes->find((char*)this)==0) + { + //printf("deleting\n"); + deletedList.append(this); + } +} + +void DotNode::setDistance(int distance) +{ + if (distance<m_distance) m_distance = distance; +} + +inline int DotNode::findParent( DotNode *n ) +{ + if ( !m_parents ) return -1; + return m_parents->find(n); +} + +/*! helper function that deletes all nodes in a connected graph, given +* one of the graph's nodes +*/ +void DotNode::deleteNodes(DotNode *node,SDict<DotNode> *skipNodes) +{ + //printf("deleteNodes skipNodes=%p\n",skipNodes); + static DotNodeList deletedNodes; + deletedNodes.setAutoDelete(TRUE); + node->deleteNode(deletedNodes,skipNodes); // collect nodes to be deleted. + deletedNodes.clear(); // actually remove the nodes. +} + +void DotNode::writeBox(FTextStream &t, + GraphType gt, + GraphOutputFormat /*format*/, + bool hasNonReachableChildren) const +{ + const char *labCol = + m_url.isEmpty() ? "grey75" : // non link + (hasNonReachableChildren ? "red" : "black"); + t << " Node" << m_number << " [label=\""; + + if (m_classDef && Config_getBool(UML_LOOK) && (gt==Inheritance || gt==Collaboration)) + { + // add names shown as relations to a dictionary, so we don't show + // them as attributes as well + QDict<void> arrowNames(17); + if (m_edgeInfo) + { + // for each edge + QListIterator<EdgeInfo> li(*m_edgeInfo); + EdgeInfo *ei; + for (li.toFirst();(ei=li.current());++li) + { + if (!ei->label().isEmpty()) // labels joined by \n + { + int li=ei->label().find('\n'); + int p=0; + QCString lab; + while ((li=ei->label().find('\n',p))!=-1) + { + lab = stripProtectionPrefix(ei->label().mid(p,li-p)); + arrowNames.insert(lab,(void*)0x8); + p=li+1; + } + lab = stripProtectionPrefix(ei->label().right(ei->label().length()-p)); + arrowNames.insert(lab,(void*)0x8); + } + } + } + + //printf("DotNode::writeBox for %s\n",m_classDef->name().data()); + t << "{" << convertLabel(m_label); + t << "\\n|"; + writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubAttribs),m_classDef,FALSE,&arrowNames); + writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubStaticAttribs),m_classDef,TRUE,&arrowNames); + writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_properties),m_classDef,FALSE,&arrowNames); + writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacAttribs),m_classDef,FALSE,&arrowNames); + writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacStaticAttribs),m_classDef,TRUE,&arrowNames); + writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proAttribs),m_classDef,FALSE,&arrowNames); + writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proStaticAttribs),m_classDef,TRUE,&arrowNames); + if (Config_getBool(EXTRACT_PRIVATE)) + { + writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priAttribs),m_classDef,FALSE,&arrowNames); + writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priStaticAttribs),m_classDef,TRUE,&arrowNames); + } + t << "|"; + writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubMethods),m_classDef); + writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubStaticMethods),m_classDef,TRUE); + writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType_pubSlots),m_classDef); + writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacMethods),m_classDef); + writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType_pacStaticMethods),m_classDef,TRUE); + writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proMethods),m_classDef); + writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proStaticMethods),m_classDef,TRUE); + writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType_proSlots),m_classDef); + if (Config_getBool(EXTRACT_PRIVATE)) + { + writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priMethods),m_classDef); + writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priStaticMethods),m_classDef,TRUE); + writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priSlots),m_classDef); + } + if (m_classDef->getLanguage()!=SrcLangExt_Fortran && + m_classDef->getMemberGroupSDict()) + { + MemberGroupSDict::Iterator mgdi(*m_classDef->getMemberGroupSDict()); + MemberGroup *mg; + for (mgdi.toFirst();(mg=mgdi.current());++mgdi) + { + if (mg->members()) + { + writeBoxMemberList(t,'*',mg->members(),m_classDef,FALSE,&arrowNames); + } + } + } + t << "}"; + } + else // standard look + { + t << convertLabel(m_label); + } + t << "\",height=0.2,width=0.4"; + if (m_isRoot) + { + t << ",color=\"black\", fillcolor=\"grey75\", style=\"filled\", fontcolor=\"black\""; + } + else + { + if (!Config_getBool(DOT_TRANSPARENT)) + { + t << ",color=\"" << labCol << "\", fillcolor=\""; + t << "white"; + t << "\", style=\"filled\""; + } + else + { + t << ",color=\"" << labCol << "\""; + } + if (!m_url.isEmpty()) + { + int anchorPos = m_url.findRev('#'); + if (anchorPos==-1) + { + t << ",URL=\"" << m_url << Doxygen::htmlFileExtension << "\""; + } + else + { + t << ",URL=\"" << m_url.left(anchorPos) << Doxygen::htmlFileExtension + << m_url.right(m_url.length()-anchorPos) << "\""; + } + } + } + if (!m_tooltip.isEmpty()) + { + t << ",tooltip=\"" << escapeTooltip(m_tooltip) << "\""; + } + else + { + t << ",tooltip=\" \""; // space in tooltip is required otherwise still something like 'Node0' is used + } + t << "];" << endl; +} + +void DotNode::writeArrow(FTextStream &t, + GraphType gt, + GraphOutputFormat format, + const DotNode *cn, + const EdgeInfo *ei, + bool topDown, + bool pointBack) const +{ + t << " Node"; + if (topDown) + t << cn->number(); + else + t << m_number; + t << " -> Node"; + if (topDown) + t << m_number; + else + t << cn->number(); + t << " ["; + + const EdgeProperties *eProps = Config_getBool(UML_LOOK) ? ¨EdgeProps : &normalEdgeProps; + QCString aStyle = eProps->arrowStyleMap[ei->color()]; + bool umlUseArrow = aStyle=="odiamond"; + + if (pointBack && !umlUseArrow) t << "dir=\"back\","; + t << "color=\"" << eProps->edgeColorMap[ei->color()] + << "\",fontsize=\"" << DotGraph::DOT_FONTSIZE << "\","; + t << "style=\"" << eProps->edgeStyleMap[ei->style()] << "\""; + if (!ei->label().isEmpty()) + { + t << ",label=\" " << convertLabel(ei->label()) << "\" "; + } + if (Config_getBool(UML_LOOK) && + eProps->arrowStyleMap[ei->color()] && + (gt==Inheritance || gt==Collaboration) + ) + { + bool rev = pointBack; + if (umlUseArrow) rev=!rev; // UML use relates has arrow on the start side + if (rev) + t << ",arrowtail=\"" << eProps->arrowStyleMap[ei->color()] << "\""; + else + t << ",arrowhead=\"" << eProps->arrowStyleMap[ei->color()] << "\""; + } + + if (format==GOF_BITMAP) t << ",fontname=\"" << DotGraph::DOT_FONTNAME << "\""; + t << "];" << endl; +} + +void DotNode::write(FTextStream &t, + GraphType gt, + GraphOutputFormat format, + bool topDown, + bool toChildren, + bool backArrows) const +{ + //printf("DotNode::write(%d) name=%s this=%p written=%d visible=%d\n",m_distance,m_label.data(),this,m_written,m_visible); + if (m_written) return; // node already written to the output + if (!m_visible) return; // node is not visible + writeBox(t,gt,format,m_truncated==Truncated); + m_written=TRUE; + QList<DotNode> *nl = toChildren ? m_children : m_parents; + if (nl) + { + if (toChildren) + { + QListIterator<DotNode> dnli1(*nl); + QListIterator<EdgeInfo> dnli2(*m_edgeInfo); + const DotNode *cn; + for (dnli1.toFirst();(cn=dnli1.current());++dnli1,++dnli2) + { + if (cn->isVisible()) + { + //printf("write arrow %s%s%s\n",label().data(),backArrows?"<-":"->",cn->label().data()); + writeArrow(t,gt,format,cn,dnli2.current(),topDown,backArrows); + } + cn->write(t,gt,format,topDown,toChildren,backArrows); + } + } + else // render parents + { + QListIterator<DotNode> dnli(*nl); + DotNode *pn; + for (dnli.toFirst();(pn=dnli.current());++dnli) + { + if (pn->isVisible()) + { + //printf("write arrow %s%s%s\n",label().data(),backArrows?"<-":"->",pn->label().data()); + writeArrow(t, + gt, + format, + pn, + pn->edgeInfo()->at(pn->children()->findRef(this)), + FALSE, + backArrows + ); + } + pn->write(t,gt,format,TRUE,FALSE,backArrows); + } + } + } + //printf("end DotNode::write(%d) name=%s\n",distance,m_label.data()); +} + +void DotNode::writeXML(FTextStream &t,bool isClassGraph) const +{ + t << " <node id=\"" << m_number << "\">" << endl; + t << " <label>" << convertToXML(m_label) << "</label>" << endl; + if (!m_url.isEmpty()) + { + QCString url(m_url); + const char *refPtr = url.data(); + char *urlPtr = strchr(url.rawData(),'$'); + if (urlPtr) + { + *urlPtr++='\0'; + t << " <link refid=\"" << convertToXML(urlPtr) << "\""; + if (*refPtr!='\0') + { + t << " external=\"" << convertToXML(refPtr) << "\""; + } + t << "/>" << endl; + } + } + if (m_children) + { + QListIterator<DotNode> nli(*m_children); + QListIterator<EdgeInfo> eli(*m_edgeInfo); + DotNode *childNode; + EdgeInfo *edgeInfo; + for (;(childNode=nli.current());++nli,++eli) + { + edgeInfo=eli.current(); + t << " <childnode refid=\"" << childNode->number() << "\" relation=\""; + if (isClassGraph) + { + switch(edgeInfo->color()) + { + case EdgeInfo::Blue: t << "public-inheritance"; break; + case EdgeInfo::Green: t << "protected-inheritance"; break; + case EdgeInfo::Red: t << "private-inheritance"; break; + case EdgeInfo::Purple: t << "usage"; break; + case EdgeInfo::Orange: t << "template-instance"; break; + case EdgeInfo::Orange2: t << "type-constraint"; break; + case EdgeInfo::Grey: ASSERT(0); break; + } + } + else // include graph + { + t << "include"; + } + t << "\">" << endl; + if (!edgeInfo->label().isEmpty()) + { + int p=0; + int ni; + while ((ni=edgeInfo->label().find('\n',p))!=-1) + { + t << " <edgelabel>" + << convertToXML(edgeInfo->label().mid(p,ni-p)) + << "</edgelabel>" << endl; + p=ni+1; + } + t << " <edgelabel>" + << convertToXML(edgeInfo->label().right(edgeInfo->label().length()-p)) + << "</edgelabel>" << endl; + } + t << " </childnode>" << endl; + } + } + t << " </node>" << endl; +} + +void DotNode::writeDocbook(FTextStream &t,bool isClassGraph) const +{ + t << " <node id=\"" << m_number << "\">" << endl; + t << " <label>" << convertToXML(m_label) << "</label>" << endl; + if (!m_url.isEmpty()) + { + QCString url(m_url); + const char *refPtr = url.data(); + char *urlPtr = strchr(url.rawData(),'$'); + if (urlPtr) + { + *urlPtr++='\0'; + t << " <link refid=\"" << convertToXML(urlPtr) << "\""; + if (*refPtr!='\0') + { + t << " external=\"" << convertToXML(refPtr) << "\""; + } + t << "/>" << endl; + } + } + if (m_children) + { + QListIterator<DotNode> nli(*m_children); + QListIterator<EdgeInfo> eli(*m_edgeInfo); + DotNode *childNode; + EdgeInfo *edgeInfo; + for (;(childNode=nli.current());++nli,++eli) + { + edgeInfo=eli.current(); + t << " <childnode refid=\"" << childNode->number() << "\" relation=\""; + if (isClassGraph) + { + switch(edgeInfo->color()) + { + case EdgeInfo::Blue: t << "public-inheritance"; break; + case EdgeInfo::Green: t << "protected-inheritance"; break; + case EdgeInfo::Red: t << "private-inheritance"; break; + case EdgeInfo::Purple: t << "usage"; break; + case EdgeInfo::Orange: t << "template-instance"; break; + case EdgeInfo::Orange2: t << "type-constraint"; break; + case EdgeInfo::Grey: ASSERT(0); break; + } + } + else // include graph + { + t << "include"; + } + t << "\">" << endl; + if (!edgeInfo->label().isEmpty()) + { + int p=0; + int ni; + while ((ni=edgeInfo->label().find('\n',p))!=-1) + { + t << " <edgelabel>" + << convertToXML(edgeInfo->label().mid(p,ni-p)) + << "</edgelabel>" << endl; + p=ni+1; + } + t << " <edgelabel>" + << convertToXML(edgeInfo->label().right(edgeInfo->label().length()-p)) + << "</edgelabel>" << endl; + } + t << " </childnode>" << endl; + } + } + t << " </node>" << endl; +} + + +void DotNode::writeDEF(FTextStream &t) const +{ + const char* nodePrefix = " node-"; + + t << " node = {" << endl; + t << nodePrefix << "id = " << m_number << ';' << endl; + t << nodePrefix << "label = '" << m_label << "';" << endl; + + if (!m_url.isEmpty()) + { + QCString url(m_url); + const char *refPtr = url.data(); + char *urlPtr = strchr(url.rawData(),'$'); + if (urlPtr) + { + *urlPtr++='\0'; + t << nodePrefix << "link = {" << endl << " " + << nodePrefix << "link-id = '" << urlPtr << "';" << endl; + + if (*refPtr!='\0') + { + t << " " << nodePrefix << "link-external = '" + << refPtr << "';" << endl; + } + t << " };" << endl; + } + } + if (m_children) + { + QListIterator<DotNode> nli(*m_children); + QListIterator<EdgeInfo> eli(*m_edgeInfo); + DotNode *childNode; + EdgeInfo *edgeInfo; + for (;(childNode=nli.current());++nli,++eli) + { + edgeInfo=eli.current(); + t << " node-child = {" << endl; + t << " child-id = '" << childNode->number() << "';" << endl; + t << " relation = "; + + switch(edgeInfo->color()) + { + case EdgeInfo::Blue: t << "public-inheritance"; break; + case EdgeInfo::Green: t << "protected-inheritance"; break; + case EdgeInfo::Red: t << "private-inheritance"; break; + case EdgeInfo::Purple: t << "usage"; break; + case EdgeInfo::Orange: t << "template-instance"; break; + case EdgeInfo::Orange2: t << "type-constraint"; break; + case EdgeInfo::Grey: ASSERT(0); break; + } + t << ';' << endl; + + if (!edgeInfo->label().isEmpty()) + { + t << " edgelabel = <<_EnD_oF_dEf_TeXt_" << endl + << edgeInfo->label() << endl + << "_EnD_oF_dEf_TeXt_;" << endl; + } + t << " }; /* node-child */" << endl; + } /* for (;childNode...) */ + } + t << " }; /* node */" << endl; +} + + +void DotNode::clearWriteFlag() +{ + m_written=FALSE; + if (m_parents!=0) + { + QListIterator<DotNode> dnlip(*m_parents); + DotNode *pn; + for (dnlip.toFirst();(pn=dnlip.current());++dnlip) + { + if (pn->isWritten()) + { + pn->clearWriteFlag(); + } + } + } + if (m_children!=0) + { + QListIterator<DotNode> dnlic(*m_children); + DotNode *cn; + for (dnlic.toFirst();(cn=dnlic.current());++dnlic) + { + if (cn->isWritten()) + { + cn->clearWriteFlag(); + } + } + } +} + +void DotNode::colorConnectedNodes(int curColor) +{ + if (m_children) + { + QListIterator<DotNode> dnlic(*m_children); + DotNode *cn; + for (dnlic.toFirst();(cn=dnlic.current());++dnlic) + { + if (cn->subgraphId()==-1) // uncolored child node + { + cn->setSubgraphId(curColor); + cn->markAsVisible(); + cn->colorConnectedNodes(curColor); + //printf("coloring node %s (%p): %d\n",cn->label().data(),cn,cn->subgraphId()); + } + } + } + + if (m_parents) + { + QListIterator<DotNode> dnlip(*m_parents); + DotNode *pn; + for (dnlip.toFirst();(pn=dnlip.current());++dnlip) + { + if (pn->subgraphId()==-1) // uncolored parent node + { + pn->setSubgraphId(curColor); + pn->markAsVisible(); + pn->colorConnectedNodes(curColor); + //printf("coloring node %s (%p): %d\n",pn->label().data(),pn,pn->subgraphId()); + } + } + } +} + +void DotNode::renumberNodes(int &number) +{ + m_number = number++; + if (m_children) + { + QListIterator<DotNode> dnlic(*m_children); + DotNode *cn; + for (dnlic.toFirst();(cn=dnlic.current());++dnlic) + { + if (!cn->isRenumbered()) + { + cn->markRenumbered(); + cn->renumberNodes(number); + } + } + } +} + +const DotNode *DotNode::findDocNode() const +{ + if (!m_url.isEmpty()) return this; + //printf("findDocNode(): '%s'\n",m_label.data()); + if (m_parents) + { + QListIterator<DotNode> dnli(*m_parents); + DotNode *pn; + for (dnli.toFirst();(pn=dnli.current());++dnli) + { + if (!pn->hasDocumentation()) + { + pn->markHasDocumentation(); + const DotNode *dn = pn->findDocNode(); + if (dn) return dn; + } + } + } + if (m_children) + { + QListIterator<DotNode> dnli(*m_children); + DotNode *cn; + for (dnli.toFirst();(cn=dnli.current());++dnli) + { + if (!cn->hasDocumentation()) + { + cn->markHasDocumentation(); + const DotNode *dn = cn->findDocNode(); + if (dn) return dn; + } + } + } + return 0; +} + +//-------------------------------------------------------------- + +int DotNodeList::compareValues(const DotNode *n1,const DotNode *n2) const +{ + return qstricmp(n1->label(),n2->label()); +} + + + diff --git a/src/dotnode.h b/src/dotnode.h new file mode 100644 index 0000000..334fdef --- /dev/null +++ b/src/dotnode.h @@ -0,0 +1,138 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#ifndef DOTNODE_H +#define DOTNODE_H + +#include "sortdict.h" + +#include "dotgraph.h" + +class ClassDef; +class DotNodeList; +class FTextStream; + +/** Attributes of an edge of a dot graph */ +class EdgeInfo +{ + public: + enum Colors { Blue=0, Green=1, Red=2, Purple=3, Grey=4, Orange=5, Orange2=6 }; + enum Styles { Solid=0, Dashed=1 }; + EdgeInfo(int color,int style,const QCString &lab,const QCString &url,int labColor) + : m_color(color), m_style(style), m_label(lab), m_url(url), m_labColor(labColor) {} + ~EdgeInfo() {} + int color() const { return m_color; } + int style() const { return m_style; } + QCString label() const { return m_label; } + QCString url() const { return m_url; } + int labelColor() const { return m_labColor; } + private: + int m_color; + int m_style; + QCString m_label; + QCString m_url; + int m_labColor; +}; + +/** A node in a dot graph */ +class DotNode +{ + public: + static void deleteNodes(DotNode* node, SDict<DotNode>* skipNodes = 0); + static QCString convertLabel(const QCString& l); + DotNode(int n,const char *lab,const char *tip,const char *url, + bool rootNode=FALSE,const ClassDef *cd=0); + ~DotNode(); + + enum TruncState { Unknown, Truncated, Untruncated }; + + void addChild(DotNode *n, + int edgeColor=EdgeInfo::Purple, + int edgeStyle=EdgeInfo::Solid, + const char *edgeLab=0, + const char *edgeURL=0, + int edgeLabCol=-1); + void addParent(DotNode *n); + void deleteNode(DotNodeList &deletedList,SDict<DotNode> *skipNodes=0); + void removeChild(DotNode *n); + void removeParent(DotNode *n); + int findParent( DotNode *n ); + + void write(FTextStream &t,GraphType gt,GraphOutputFormat f, + bool topDown,bool toChildren,bool backArrows) const; + void writeXML(FTextStream &t,bool isClassGraph) const; + void writeDocbook(FTextStream &t,bool isClassGraph) const; + void writeDEF(FTextStream &t) const; + void writeBox(FTextStream &t,GraphType gt,GraphOutputFormat f, + bool hasNonReachableChildren) const; + void writeArrow(FTextStream &t,GraphType gt,GraphOutputFormat f,const DotNode *cn, + const EdgeInfo *ei,bool topDown, bool pointBack=TRUE) const; + + QCString label() const { return m_label; } + int number() const { return m_number; } + bool isVisible() const { return m_visible; } + TruncState isTruncated() const { return m_truncated; } + int distance() const { return m_distance; } + int subgraphId() const { return m_subgraphId; } + bool isRenumbered() const { return m_renumbered; } + bool hasDocumentation() const { return m_hasDoc; } + bool isWritten() const { return m_written; } + + void clearWriteFlag(); + void renumberNodes(int &number); + void markRenumbered() { m_renumbered = true; } + void markHasDocumentation() { m_hasDoc = true; } + void setSubgraphId(int id) { m_subgraphId = id; } + + void colorConnectedNodes(int curColor); + void setDistance(int distance); + const DotNode *findDocNode() const; // only works for acyclic graphs! + void markAsVisible(bool b=TRUE) { m_visible=b; } + void markAsTruncated(bool b=TRUE) { m_truncated=b ? Truncated : Untruncated; } + const QList<DotNode> *children() const { return m_children; } + const QList<DotNode> *parents() const { return m_parents; } + const QList<EdgeInfo> *edgeInfo() const { return m_edgeInfo; } + + private: + int m_number; + QCString m_label; //!< label text + QCString m_tooltip; //!< node's tooltip + QCString m_url; //!< url of the node (format: remote$local) + QList<DotNode> *m_parents; //!< list of parent nodes (incoming arrows) + QList<DotNode> *m_children; //!< list of child nodes (outgoing arrows) + QList<EdgeInfo> *m_edgeInfo; //!< edge info for each child + bool m_deleted; //!< used to mark a node as deleted + mutable bool m_written; //!< used to mark a node as written + bool m_hasDoc; //!< used to mark a node as documented + bool m_isRoot; //!< indicates if this is a root node + const ClassDef * m_classDef; //!< class representing this node (can be 0) + bool m_visible; //!< is the node visible in the output + TruncState m_truncated; //!< does the node have non-visible children/parents + int m_distance; //!< shortest path to the root node + bool m_renumbered;//!< indicates if the node has been renumbered (to prevent endless loops) + int m_subgraphId; +}; + +/** Class representing a list of DotNode objects. */ +class DotNodeList : public QList<DotNode> +{ + public: + DotNodeList() : QList<DotNode>() {} + ~DotNodeList() {} + private: + int compareValues(const DotNode *n1,const DotNode *n2) const; +}; + +#endif diff --git a/src/dotrunner.cpp b/src/dotrunner.cpp new file mode 100644 index 0000000..3a621c7 --- /dev/null +++ b/src/dotrunner.cpp @@ -0,0 +1,294 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#include "dotrunner.h" + +#include "util.h" +#include "portable.h" +#include "dot.h" +#include "message.h" +#include "ftextstream.h" +#include "config.h" + +// the graphicx LaTeX has a limitation of maximum size of 16384 +// To be on the save side we take it a little bit smaller i.e. 150 inch * 72 dpi +// It is anyway hard to view these size of images +#define MAX_LATEX_GRAPH_INCH 150 +#define MAX_LATEX_GRAPH_SIZE (MAX_LATEX_GRAPH_INCH * 72) + + +// since dot silently reproduces the input file when it does not +// support the PNG format, we need to check the result. +static void checkPngResult(const char *imgName) +{ + FILE *f = portable_fopen(imgName,"rb"); + if (f) + { + char data[4]; + if (fread(data,1,4,f)==4) + { + if (!(data[1]=='P' && data[2]=='N' && data[3]=='G')) + { + err("Image '%s' produced by dot is not a valid PNG!\n" + "You should either select a different format " + "(DOT_IMAGE_FORMAT in the config file) or install a more " + "recent version of graphviz (1.7+)\n",imgName + ); + } + } + else + { + err("Could not read image '%s' generated by dot!\n",imgName); + } + fclose(f); + } + else + { + err("Could not open image '%s' generated by dot!\n",imgName); + } +} + +static bool resetPDFSize(const int width,const int height, const char *base) +{ + QString tmpName = QString::fromUtf8(QCString(base)+".tmp"); + QString patchFile = QString::fromUtf8(QCString(base)+".dot"); + if (!QDir::current().rename(patchFile,tmpName)) + { + err("Failed to rename file %s to %s!\n",patchFile.data(),tmpName.data()); + return FALSE; + } + QFile fi(tmpName); + QFile fo(patchFile); + if (!fi.open(IO_ReadOnly)) + { + err("problem opening file %s for patching!\n",tmpName.data()); + QDir::current().rename(tmpName,patchFile); + return FALSE; + } + if (!fo.open(IO_WriteOnly)) + { + err("problem opening file %s for patching!\n",patchFile.data()); + QDir::current().rename(tmpName,patchFile); + fi.close(); + return FALSE; + } + FTextStream t(&fo); + const int maxLineLen=100*1024; + while (!fi.atEnd()) // foreach line + { + QCString line(maxLineLen); + int numBytes = fi.readLine(line.rawData(),maxLineLen); + if (numBytes<=0) + { + break; + } + line.resize(numBytes+1); + if (line.find("LATEX_PDF_SIZE") != -1) + { + double scale = (width > height ? width : height)/double(MAX_LATEX_GRAPH_INCH); + t << " size=\""<<width/scale << "," <<height/scale <<"\";\n"; + } + else + t << line; + } + fi.close(); + fo.close(); + // remove temporary file + QDir::current().remove(tmpName); + return TRUE; +} + +bool DotRunner::readBoundingBox(const char *fileName,int *width,int *height,bool isEps) +{ + const char *bb = isEps ? "%%PageBoundingBox:" : "/MediaBox ["; + int bblen = strlen(bb); + FILE *f = portable_fopen(fileName,"rb"); + if (!f) + { + //printf("readBoundingBox: could not open %s\n",fileName); + return FALSE; + } + const int maxLineLen=1024; + char buf[maxLineLen]; + while (fgets(buf,maxLineLen,f)!=NULL) + { + const char *p = strstr(buf,bb); + if (p) // found PageBoundingBox or /MediaBox string + { + int x,y; + fclose(f); + if (sscanf(p+bblen,"%d %d %d %d",&x,&y,width,height)!=4) + { + //printf("readBoundingBox sscanf fail\n"); + return FALSE; + } + return TRUE; + } + } + err("Failed to extract bounding box from generated diagram file %s\n",fileName); + fclose(f); + return FALSE; +} + +bool DotRunner::DOT_CLEANUP; +bool DotRunner::DOT_MULTI_TARGETS; +DotConstString DotRunner::DOT_EXE; + +DotRunner::DotRunner(const QCString& absDotName, const QCString& md5Hash) + : m_file(absDotName), m_md5Hash(md5Hash), m_cleanUp(DOT_CLEANUP) +{ + m_jobs.setAutoDelete(TRUE); +} + +void DotRunner::addJob(const char *format,const char *output) +{ + QListIterator<DotJob> li(m_jobs); + DotJob *s; + for (li.toFirst(); (s = li.current()); ++li) + { + if (qstrcmp(s->format.data(), format) != 0) continue; + if (qstrcmp(s->output.data(), output) != 0) continue; + // we have this job already + return; + } + QCString args = QCString("-T")+format+" -o \""+output+"\""; + m_jobs.append(new DotJob(format, output, args)); +} + +QCString getBaseNameOfOutput(QCString const& output) +{ + int index = output.findRev('.'); + if (index < 0) return output; + return output.left(index); +} + +bool DotRunner::run() +{ + int exitCode=0; + + QCString dotArgs; + QListIterator<DotJob> li(m_jobs); + DotJob *s; + + // create output + if (DOT_MULTI_TARGETS) + { + dotArgs=QCString("\"")+m_file.data()+"\""; + for (li.toFirst();(s=li.current());++li) + { + dotArgs+=' '; + dotArgs+=s->args.data(); + } + if ((exitCode=portable_system(DOT_EXE.data(),dotArgs,FALSE))!=0) goto error; + } + else + { + for (li.toFirst();(s=li.current());++li) + { + dotArgs=QCString("\"")+m_file.data()+"\" "+s->args.data(); + if ((exitCode=portable_system(DOT_EXE.data(),dotArgs,FALSE))!=0) goto error; + } + } + + // check output + // As there should be only one pdf file be generated, we don't need code for regenerating multiple pdf files in one call + for (li.toFirst();(s=li.current());++li) + { + if (qstrncmp(s->format.data(), "pdf", 3) == 0) + { + int width=0,height=0; + if (!readBoundingBox(s->output.data(),&width,&height,FALSE)) goto error; + if ((width > MAX_LATEX_GRAPH_SIZE) || (height > MAX_LATEX_GRAPH_SIZE)) + { + if (!resetPDFSize(width,height,getBaseNameOfOutput(s->output.data()))) goto error; + dotArgs=QCString("\"")+m_file.data()+"\" "+s->args.data(); + if ((exitCode=portable_system(DOT_EXE.data(),dotArgs,FALSE))!=0) goto error; + } + } + + if (qstrncmp(s->format.data(), "png", 3) == 0) + { + checkPngResult(s->output.data()); + } + } + + // remove .dot files + if (m_cleanUp) + { + //printf("removing dot file %s\n",m_file.data()); + portable_unlink(m_file.data()); + } + + // create checksum file + if (!m_md5Hash.isEmpty()) + { + QCString md5Name = getBaseNameOfOutput(m_file.data()) + ".md5"; + FILE *f = portable_fopen(md5Name,"w"); + if (f) + { + fwrite(m_md5Hash.data(),1,32,f); + fclose(f); + } + } + return TRUE; +error: + err("Problems running dot: exit code=%d, command='%s', arguments='%s'\n", + exitCode,DOT_EXE.data(),dotArgs.data()); + return FALSE; +} + + +//-------------------------------------------------------------------- + +void DotRunnerQueue::enqueue(DotRunner *runner) +{ + QMutexLocker locker(&m_mutex); + m_queue.enqueue(runner); + m_bufferNotEmpty.wakeAll(); +} + +DotRunner *DotRunnerQueue::dequeue() +{ + QMutexLocker locker(&m_mutex); + while (m_queue.isEmpty()) + { + // wait until something is added to the queue + m_bufferNotEmpty.wait(&m_mutex); + } + DotRunner *result = m_queue.dequeue(); + return result; +} + +uint DotRunnerQueue::count() const +{ + QMutexLocker locker(&m_mutex); + return m_queue.count(); +} + +//-------------------------------------------------------------------- + +DotWorkerThread::DotWorkerThread(DotRunnerQueue *queue) + : m_queue(queue) +{ +} + +void DotWorkerThread::run() +{ + DotRunner *runner; + while ((runner=m_queue->dequeue())) + { + runner->run(); + } +} diff --git a/src/dotrunner.h b/src/dotrunner.h new file mode 100644 index 0000000..4128fe8 --- /dev/null +++ b/src/dotrunner.h @@ -0,0 +1,138 @@ +/****************************************************************************** +* +* Copyright (C) 1997-2019 by Dimitri van Heesch. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation under the terms of the GNU General Public License is hereby +* granted. No representations are made about the suitability of this software +* for any purpose. It is provided "as is" without express or implied warranty. +* See the GNU General Public License for more details. +* +* Documents produced by Doxygen are derivative works derived from the +* input used in their production; they are not affected by this license. +* +*/ + +#ifndef DOTRUNNER_H +#define DOTRUNNER_H + +#include "qcstring.h" +#include "qlist.h" +#include "qwaitcondition.h" +#include "qthread.h" +#include "qqueue.h" +#include "qmutex.h" + +/** Minimal constant string class that is thread safe, once initialized. */ +class DotConstString +{ + public: + DotConstString() { m_str=0;} + ~DotConstString() { delete[] m_str;} + DotConstString(char const* s) : m_str(0) { set(s); } + DotConstString(const QCString &s) : m_str(0) { set(s); } + DotConstString(const DotConstString &s) : m_str(0) { set(s.data()); } + const char *data() const { return m_str; } + bool isEmpty() const { return m_str==0 || m_str[0]=='\0'; } + void init(const char *s) { set(s); } + + private: + void set(char const* s) + { + delete[] m_str; + m_str=0; + if (s) + { + m_str=new char[strlen(s) + 1]; + qstrcpy(m_str,s); + } + } + + void set(const QCString &s) + { + delete[] m_str; + m_str=0; + if (!s.isEmpty()) + { + m_str=new char[s.length()+1]; + qstrcpy(m_str,s.data()); + } + } + + DotConstString &operator=(const DotConstString &); + + char *m_str; +}; + +/** Helper class to run dot from doxygen from multiple threads. */ +class DotRunner +{ + public: + struct DotJob + { + DotJob(const DotConstString & format, + const DotConstString & output, + const DotConstString & args) + : format(format), output(output), args(args) {} + DotConstString format; + DotConstString output; + DotConstString args; + }; + + /** Creates a runner for a dot \a file. */ + DotRunner(const QCString& absDotName, const QCString& md5Hash); + + /** Adds an additional job to the run. + * Performing multiple jobs one file can be faster. + */ + void addJob(const char *format,const char *output); + + /** Prevent cleanup of the dot file (for user provided dot files) */ + void preventCleanUp() { m_cleanUp = FALSE; } + + /** Runs dot for all jobs added. */ + bool run(); + + // DotConstString const& getFileName() { return m_file; } + DotConstString const& getMd5Hash() { return m_md5Hash; } + + static bool readBoundingBox(const char* fileName, int* width, int* height, bool isEps); + + private: + DotConstString m_file; + DotConstString m_md5Hash; + bool m_cleanUp; + QList<DotJob> m_jobs; + + static bool DOT_CLEANUP; + static bool DOT_MULTI_TARGETS; + static DotConstString DOT_EXE; + friend void initDot(); + +}; + +/** Queue of dot jobs to run. */ +// all methods are thread save +class DotRunnerQueue +{ + public: + void enqueue(DotRunner *runner); + DotRunner *dequeue(); + uint count() const; + private: + QWaitCondition m_bufferNotEmpty; + QQueue<DotRunner> m_queue; + mutable QMutex m_mutex; +}; + +/** Worker thread to execute a dot run */ +class DotWorkerThread : public QThread +{ + public: + DotWorkerThread(DotRunnerQueue *queue); + void run(); + private: + DotRunnerQueue *m_queue; +}; + +#endif diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 2d55ae6..6bf67a0 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -38,7 +38,6 @@ #include "scanner.h" #include "entry.h" #include "index.h" -#include "logos.h" #include "message.h" #include "config.h" #include "util.h" @@ -80,14 +79,11 @@ #include "tclscanner.h" #include "code.h" #include "objcache.h" -#include "store.h" -#include "marshal.h" #include "portable.h" #include "vhdljjparser.h" #include "vhdldocgen.h" #include "eclipsehelp.h" #include "cite.h" -#include "filestorage.h" #include "markdown.h" #include "arguments.h" #include "memberlist.h" @@ -104,13 +100,14 @@ #include "context.h" #include "fileparser.h" #include "emoji.h" +#include "plantuml.h" // provided by the generated file resources.cpp extern void initResources(); #define RECURSE_ENTRYTREE(func,var) \ do { if (var->children()) { \ - EntryNavListIterator eli(*var->children()); \ + EntryListIterator eli(*var->children()); \ for (;eli.current();++eli) func(eli.current()); \ } } while(0) @@ -165,7 +162,7 @@ SDict<DirRelation> Doxygen::dirRelations(257); ParserManager *Doxygen::parserManager = 0; QCString Doxygen::htmlFileExtension; bool Doxygen::suppressDocWarnings = FALSE; -Store *Doxygen::symbolStorage; +//Store *Doxygen::symbolStorage; QCString Doxygen::objDBFileName; QCString Doxygen::entryDBFileName; QCString Doxygen::filterDBFileName; @@ -177,14 +174,14 @@ QCString Doxygen::spaces; bool Doxygen::generatingXmlOutput = FALSE; bool Doxygen::markdownSupport = TRUE; GenericsSDict *Doxygen::genericsDict; +DocGroup Doxygen::docGroup; // locally accessible globals -static QDict<EntryNav> g_classEntries(1009); +static QDict<Entry> g_classEntries(1009); static StringList g_inputFiles; static QDict<void> g_compoundKeywordDict(7); // keywords recognised as compounds static OutputList *g_outputList = 0; // list of output generating objects static QDict<FileDef> g_usingDeclarations(1009); // used classes -static FileStorage *g_storage = 0; static bool g_successfulRun = FALSE; static bool g_dumpSymbolMap = FALSE; static bool g_useOutputTemplate = FALSE; @@ -300,9 +297,9 @@ void statistics() -static void addMemberDocs(EntryNav *rootNav,MemberDef *md, const char *funcDecl, +static void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl, ArgumentList *al,bool over_load,NamespaceSDict *nl=0); -static void findMember(EntryNav *rootNav, +static void findMember(Entry *root, QCString funcDecl, bool overloaded, bool isFunc @@ -316,7 +313,7 @@ enum FindBaseClassRelation_Mode }; static bool findClassRelation( - EntryNav *rootNav, + Entry *root, Definition *context, ClassDef *cd, BaseInfo *bi, @@ -423,7 +420,7 @@ static STLInfo g_stlinfo[] = { 0, 0, 0, 0, 0, 0, 0, FALSE, FALSE } }; -static void addSTLMember(EntryNav *rootNav,const char *type,const char *name) +static void addSTLMember(Entry *root,const char *type,const char *name) { Entry *memEntry = new Entry; memEntry->name = name; @@ -434,13 +431,13 @@ static void addSTLMember(EntryNav *rootNav,const char *type,const char *name) memEntry->hidden = FALSE; memEntry->artificial = TRUE; //memEntry->parent = root; - //root->addSubEntry(memEntry); - EntryNav *memEntryNav = new EntryNav(rootNav,memEntry); - memEntryNav->setEntry(memEntry); - rootNav->addChild(memEntryNav); + root->addSubEntry(memEntry); + //EntryNav *memEntryNav = new EntryNav(root,memEntry); + //memEntryNav->setEntry(memEntry); + //rootNav->addChild(memEntryNav); } -static void addSTLIterator(EntryNav *classEntryNav,const char *name) +static void addSTLIterator(Entry *classEntry,const char *name) { Entry *iteratorClassEntry = new Entry; iteratorClassEntry->fileName = "[STL]"; @@ -450,13 +447,14 @@ static void addSTLIterator(EntryNav *classEntryNav,const char *name) iteratorClassEntry->brief = "STL iterator class"; iteratorClassEntry->hidden = FALSE; iteratorClassEntry->artificial= TRUE; - EntryNav *iteratorClassEntryNav = new EntryNav(classEntryNav,iteratorClassEntry); - iteratorClassEntryNav->setEntry(iteratorClassEntry); - classEntryNav->addChild(iteratorClassEntryNav); + classEntry->addSubEntry(iteratorClassEntry); + //EntryNav *iteratorClassEntryNav = new EntryNav(classEntryNav,iteratorClassEntry); + //iteratorClassEntryNav->setEntry(iteratorClassEntry); + //classEntryNav->addChild(iteratorClassEntryNav); } -static void addSTLClasses(EntryNav *rootNav) +static void addSTLClasses(Entry *root) { Entry *namespaceEntry = new Entry; namespaceEntry->fileName = "[STL]"; @@ -467,10 +465,10 @@ static void addSTLClasses(EntryNav *rootNav) namespaceEntry->brief = "STL namespace"; namespaceEntry->hidden = FALSE; namespaceEntry->artificial= TRUE; - //root->addSubEntry(namespaceEntry); - EntryNav *namespaceEntryNav = new EntryNav(rootNav,namespaceEntry); - namespaceEntryNav->setEntry(namespaceEntry); - rootNav->addChild(namespaceEntryNav); + root->addSubEntry(namespaceEntry); + //EntryNav *namespaceEntryNav = new EntryNav(rootNav,namespaceEntry); + //namespaceEntryNav->setEntry(namespaceEntry); + //rootNav->addChild(namespaceEntryNav); STLInfo *info = g_stlinfo; while (info->className) @@ -484,15 +482,14 @@ static void addSTLClasses(EntryNav *rootNav) classEntry->fileName = "[STL]"; classEntry->startLine = 1; classEntry->name = fullName; - //classEntry->parent = namespaceEntry; classEntry->section = Entry::CLASS_SEC; classEntry->brief = "STL class"; classEntry->hidden = FALSE; classEntry->artificial= TRUE; - //namespaceEntry->addSubEntry(classEntry); - EntryNav *classEntryNav = new EntryNav(namespaceEntryNav,classEntry); - classEntryNav->setEntry(classEntry); - namespaceEntryNav->addChild(classEntryNav); + namespaceEntry->addSubEntry(classEntry); + //EntryNav *classEntryNav = new EntryNav(namespaceEntryNav,classEntry); + //classEntryNav->setEntry(classEntry); + //namespaceEntryNav->addChild(classEntryNav); // add template arguments to class if (info->templType1) @@ -516,11 +513,11 @@ static void addSTLClasses(EntryNav *rootNav) // add member variables if (info->templName1) { - addSTLMember(classEntryNav,info->templType1,info->templName1); + addSTLMember(classEntry,info->templType1,info->templName1); } if (info->templName2) { - addSTLMember(classEntryNav,info->templType2,info->templName2); + addSTLMember(classEntry,info->templType2,info->templName2); } if (fullName=="std::auto_ptr" || fullName=="std::smart_ptr" || fullName=="std::shared_ptr" || fullName=="std::unique_ptr" || fullName=="std::weak_ptr") @@ -534,9 +531,10 @@ static void addSTLClasses(EntryNav *rootNav) memEntry->brief = "STL member"; memEntry->hidden = FALSE; memEntry->artificial = FALSE; - EntryNav *memEntryNav = new EntryNav(classEntryNav,memEntry); - memEntryNav->setEntry(memEntry); - classEntryNav->addChild(memEntryNav); + classEntry->addSubEntry(memEntry); + //EntryNav *memEntryNav = new EntryNav(classEntryNav,memEntry); + //memEntryNav->setEntry(memEntry); + //classEntryNav->addChild(memEntryNav); } if (info->baseClass1) { @@ -549,10 +547,10 @@ static void addSTLClasses(EntryNav *rootNav) if (info->iterators) { // add iterator class - addSTLIterator(classEntryNav,fullName+"::iterator"); - addSTLIterator(classEntryNav,fullName+"::const_iterator"); - addSTLIterator(classEntryNav,fullName+"::reverse_iterator"); - addSTLIterator(classEntryNav,fullName+"::const_reverse_iterator"); + addSTLIterator(classEntry,fullName+"::iterator"); + addSTLIterator(classEntry,fullName+"::const_iterator"); + addSTLIterator(classEntry,fullName+"::reverse_iterator"); + addSTLIterator(classEntry,fullName+"::const_reverse_iterator"); } info++; } @@ -563,18 +561,18 @@ static void addSTLClasses(EntryNav *rootNav) static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n, FileDef *fileScope,TagInfo *tagInfo); -static void addPageToContext(PageDef *pd,EntryNav *rootNav) +static void addPageToContext(PageDef *pd,Entry *root) { - if (rootNav->parent()) // add the page to it's scope + if (root->parent()) // add the page to it's scope { - QCString scope = rootNav->parent()->name(); - if (rootNav->parent()->section()==Entry::PACKAGEDOC_SEC) + QCString scope = root->parent()->name; + if (root->parent()->section==Entry::PACKAGEDOC_SEC) { scope=substitute(scope,".","::"); } scope = stripAnonymousNamespaceScope(scope); scope+="::"+pd->name(); - Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,rootNav->tagInfo()); + Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo); if (d) { pd->setPageScope(d); @@ -582,9 +580,8 @@ static void addPageToContext(PageDef *pd,EntryNav *rootNav) } } -static void addRelatedPage(EntryNav *rootNav) +static void addRelatedPage(Entry *root) { - Entry *root = rootNav->entry(); GroupDef *gd=0; QListIterator<Grouping> gli(*root->groups); Grouping *g; @@ -605,7 +602,7 @@ static void addRelatedPage(EntryNav *rootNav) PageDef *pd = addRelatedPage(root->name,root->args,doc,root->anchors, root->docFile,root->docLine, root->sli, - gd,rootNav->tagInfo(), + gd,root->tagInfo, root->lang ); if (pd) @@ -613,20 +610,17 @@ static void addRelatedPage(EntryNav *rootNav) pd->setBriefDescription(root->brief,root->briefFile,root->briefLine); pd->addSectionsToDefinition(root->anchors); pd->setLocalToc(root->localToc); - addPageToContext(pd,rootNav); + addPageToContext(pd,root); } } -static void buildGroupListFiltered(EntryNav *rootNav,bool additional, bool includeExternal) +static void buildGroupListFiltered(Entry *root,bool additional, bool includeExternal) { - if (rootNav->section()==Entry::GROUPDOC_SEC && !rootNav->name().isEmpty() && - ((!includeExternal && rootNav->tagInfo()==0) || - ( includeExternal && rootNav->tagInfo()!=0)) + if (root->section==Entry::GROUPDOC_SEC && !root->name.isEmpty() && + ((!includeExternal && root->tagInfo==0) || + ( includeExternal && root->tagInfo!=0)) ) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) || (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional)) { @@ -655,14 +649,14 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional, bool inclu } else { - if (rootNav->tagInfo()) + if (root->tagInfo) { - gd = new GroupDef(root->fileName,root->startLine,root->name,root->type,rootNav->tagInfo()->fileName); - gd->setReference(rootNav->tagInfo()->tagName); + gd = createGroupDef(root->fileName,root->startLine,root->name,root->type,root->tagInfo->fileName); + gd->setReference(root->tagInfo->tagName); } else { - gd = new GroupDef(root->fileName,root->startLine,root->name,root->type); + gd = createGroupDef(root->fileName,root->startLine,root->name,root->type); } gd->setBriefDescription(root->brief,root->briefFile,root->briefLine); // allow empty docs for group @@ -674,13 +668,11 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional, bool inclu gd->setLanguage(root->lang); } } - - rootNav->releaseEntry(); } - if (rootNav->children()) + if (root->children()) { - EntryNavListIterator eli(*rootNav->children()); - EntryNav *e; + EntryListIterator eli(*root->children()); + Entry *e; for (;(e=eli.current());++eli) { buildGroupListFiltered(e,additional,includeExternal); @@ -688,53 +680,50 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional, bool inclu } } -static void buildGroupList(EntryNav *rootNav) +static void buildGroupList(Entry *root) { // --- first process only local groups // first process the @defgroups blocks - buildGroupListFiltered(rootNav,FALSE,FALSE); + buildGroupListFiltered(root,FALSE,FALSE); // then process the @addtogroup, @weakgroup blocks - buildGroupListFiltered(rootNav,TRUE,FALSE); + buildGroupListFiltered(root,TRUE,FALSE); // --- then also process external groups // first process the @defgroups blocks - buildGroupListFiltered(rootNav,FALSE,TRUE); + buildGroupListFiltered(root,FALSE,TRUE); // then process the @addtogroup, @weakgroup blocks - buildGroupListFiltered(rootNav,TRUE,TRUE); + buildGroupListFiltered(root,TRUE,TRUE); } -static void findGroupScope(EntryNav *rootNav) +static void findGroupScope(Entry *root) { - if (rootNav->section()==Entry::GROUPDOC_SEC && !rootNav->name().isEmpty() && - rootNav->parent() && !rootNav->parent()->name().isEmpty()) + if (root->section==Entry::GROUPDOC_SEC && !root->name.isEmpty() && + root->parent() && !root->parent()->name.isEmpty()) { GroupDef *gd; - if ((gd=Doxygen::groupSDict->find(rootNav->name()))) + if ((gd=Doxygen::groupSDict->find(root->name))) { - QCString scope = rootNav->parent()->name(); - if (rootNav->parent()->section()==Entry::PACKAGEDOC_SEC) + QCString scope = root->parent()->name; + if (root->parent()->section==Entry::PACKAGEDOC_SEC) { scope=substitute(scope,".","::"); } scope = stripAnonymousNamespaceScope(scope); scope+="::"+gd->name(); - Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,rootNav->tagInfo()); + Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo); if (d) { gd->setGroupScope(d); } } } - RECURSE_ENTRYTREE(findGroupScope,rootNav); + RECURSE_ENTRYTREE(findGroupScope,root); } -static void organizeSubGroupsFiltered(EntryNav *rootNav,bool additional) +static void organizeSubGroupsFiltered(Entry *root,bool additional) { - if (rootNav->section()==Entry::GROUPDOC_SEC && !rootNav->name().isEmpty()) + if (root->section==Entry::GROUPDOC_SEC && !root->name.isEmpty()) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) || (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional)) { @@ -745,13 +734,11 @@ static void organizeSubGroupsFiltered(EntryNav *rootNav,bool additional) addGroupToGroups(root,gd); } } - - rootNav->releaseEntry(); } - if (rootNav->children()) + if (root->children()) { - EntryNavListIterator eli(*rootNav->children()); - EntryNav *e; + EntryListIterator eli(*root->children()); + Entry *e; for (;(e=eli.current());++eli) { organizeSubGroupsFiltered(e,additional); @@ -759,66 +746,58 @@ static void organizeSubGroupsFiltered(EntryNav *rootNav,bool additional) } } -static void organizeSubGroups(EntryNav *rootNav) +static void organizeSubGroups(Entry *root) { //printf("Defining groups\n"); // first process the @defgroups blocks - organizeSubGroupsFiltered(rootNav,FALSE); + organizeSubGroupsFiltered(root,FALSE); //printf("Additional groups\n"); // then process the @addtogroup, @weakgroup blocks - organizeSubGroupsFiltered(rootNav,TRUE); + organizeSubGroupsFiltered(root,TRUE); } //---------------------------------------------------------------------- -static void buildFileList(EntryNav *rootNav) +static void buildFileList(Entry *root) { - if (((rootNav->section()==Entry::FILEDOC_SEC) || - ((rootNav->section() & Entry::FILE_MASK) && Config_getBool(EXTRACT_ALL))) && - !rootNav->name().isEmpty() && !rootNav->tagInfo() // skip any file coming from tag files + if (((root->section==Entry::FILEDOC_SEC) || + ((root->section & Entry::FILE_MASK) && Config_getBool(EXTRACT_ALL))) && + !root->name.isEmpty() && !root->tagInfo // skip any file coming from tag files ) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - bool ambig; FileDef *fd=findFileDef(Doxygen::inputNameDict,root->name,ambig); + if (!fd || ambig) + { + int save_ambig = ambig; + // use the directory of the file to see if the described file is in the same + // directory as the describing file. + QCString fn = root->fileName; + int newIndex=fn.findRev('/'); + fd=findFileDef(Doxygen::inputNameDict,fn.left(newIndex) + "/" + root->name,ambig); + if (!fd) ambig = save_ambig; + } //printf("**************** root->name=%s fd=%p\n",root->name.data(),fd); if (fd && !ambig) { -#if 0 - if ((!root->doc.isEmpty() && !fd->documentation().isEmpty()) || - (!root->brief.isEmpty() && !fd->briefDescription().isEmpty())) + //printf("Adding documentation!\n"); + // using FALSE in setDocumentation is small hack to make sure a file + // is documented even if a \file command is used without further + // documentation + fd->setDocumentation(root->doc,root->docFile,root->docLine,FALSE); + fd->setBriefDescription(root->brief,root->briefFile,root->briefLine); + fd->addSectionsToDefinition(root->anchors); + fd->setRefItems(root->sli); + QListIterator<Grouping> gli(*root->groups); + Grouping *g; + for (;(g=gli.current());++gli) { - warn( - root->fileName,root->startLine, - "file %s already documented. " - "Skipping documentation.", - root->name.data() - ); - } - else -#endif - { - //printf("Adding documentation!\n"); - // using FALSE in setDocumentation is small hack to make sure a file - // is documented even if a \file command is used without further - // documentation - fd->setDocumentation(root->doc,root->docFile,root->docLine,FALSE); - fd->setBriefDescription(root->brief,root->briefFile,root->briefLine); - fd->addSectionsToDefinition(root->anchors); - fd->setRefItems(root->sli); - QListIterator<Grouping> gli(*root->groups); - Grouping *g; - for (;(g=gli.current());++gli) + GroupDef *gd=0; + if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) { - GroupDef *gd=0; - if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) - { - gd->addFile(fd); - fd->makePartOfGroup(gd); - //printf("File %s: in group %s\n",fd->name().data(),s->data()); - } + gd->addFile(fd); + fd->makePartOfGroup(gd); + //printf("File %s: in group %s\n",fd->name().data(),s->data()); } } } @@ -826,8 +805,8 @@ static void buildFileList(EntryNav *rootNav) { const char *fn = root->fileName.data(); QCString text(4096); - text.sprintf("the name `%s' supplied as " - "the second argument in the \\file statement ", + text.sprintf("the name '%s' supplied as " + "the argument in the \\file statement ", qPrint(root->name)); if (ambig) // name is ambiguous { @@ -842,10 +821,8 @@ static void buildFileList(EntryNav *rootNav) } warn(fn,root->startLine,text); } - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(buildFileList,rootNav); + RECURSE_ENTRYTREE(buildFileList,root); } static void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root) @@ -881,7 +858,7 @@ static void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root) ) { // explicit request QCString text; - text.sprintf("the name `%s' supplied as " + text.sprintf("the name '%s' supplied as " "the argument of the \\class, \\struct, \\union, or \\include command ", qPrint(includeFile) ); @@ -1034,7 +1011,7 @@ static Definition *buildScopeFromQualifiedName(const QCString name, { // introduce bogus namespace //printf("++ adding dummy namespace %s to %s tagInfo=%p\n",nsName.data(),prevScope->name().data(),tagInfo); - nd=new NamespaceDef( + nd=createNamespaceDef( "[generated]",1,1,fullScope, tagInfo?tagInfo->tagName:QCString(), tagInfo?tagInfo->fileName:QCString()); @@ -1241,19 +1218,14 @@ ClassDef::CompoundType convertToCompoundType(int section,uint64 specifier) } -static void addClassToContext(EntryNav *rootNav) +static void addClassToContext(Entry *root) { - //printf("Loading entry for rootNav=%p name=%s\n",rootNav,rootNav->name().data()); - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - - //NamespaceDef *nd = 0; - FileDef *fd = rootNav->fileDef(); + FileDef *fd = root->fileDef(); QCString scName; - if (rootNav->parent()->section()&Entry::SCOPE_MASK) + if (root->parent()->section&Entry::SCOPE_MASK) { - scName=rootNav->parent()->name(); + scName=root->parent()->name; } // name without parent's scope QCString fullName = root->name; @@ -1316,12 +1288,12 @@ static void addClassToContext(EntryNav *rootNav) QCString namespaceName; extractNamespaceName(fullName,className,namespaceName); - //printf("New class: fullname %s namespace `%s' name=`%s' brief=`%s' docs=`%s'\n", + //printf("New class: fullname %s namespace '%s' name='%s' brief='%s' docs='%s'\n", // fullName.data(),namespaceName.data(),className.data(),root->brief.data(),root->doc.data()); QCString tagName; QCString refFileName; - TagInfo *tagInfo = rootNav->tagInfo(); + TagInfo *tagInfo = root->tagInfo; int i; if (tagInfo) { @@ -1347,9 +1319,9 @@ static void addClassToContext(EntryNav *rootNav) { tArgList = getTemplateArgumentsFromName(fullName,root->tArgLists); } - cd=new ClassDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn, + cd=createClassDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn, fullName,sec,tagName,refFileName,TRUE,root->spec&Entry::Enum); - Debug::print(Debug::Classes,0," New class `%s' (sec=0x%08x)! #tArgLists=%d tagInfo=%p\n", + Debug::print(Debug::Classes,0," New class '%s' (sec=0x%08x)! #tArgLists=%d tagInfo=%p\n", qPrint(fullName),sec,root->tArgLists ? (int)root->tArgLists->count() : -1, tagInfo); cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition cd->setBriefDescription(root->brief,root->briefFile,root->briefLine); @@ -1397,7 +1369,7 @@ static void addClassToContext(EntryNav *rootNav) } if (fd && (root->section & Entry::COMPOUND_MASK)) { - //printf(">> Inserting class `%s' in file `%s' (root->fileName=`%s')\n", + //printf(">> Inserting class '%s' in file '%s' (root->fileName='%s')\n", // cd->name().data(), // fd->name().data(), // root->fileName.data() @@ -1407,40 +1379,38 @@ static void addClassToContext(EntryNav *rootNav) } addClassToGroups(root,cd); cd->setRefItems(root->sli); - - rootNav->releaseEntry(); } //---------------------------------------------------------------------- // build a list of all classes mentioned in the documentation // and all classes that have a documentation block before their definition. -static void buildClassList(EntryNav *rootNav) +static void buildClassList(Entry *root) { if ( - ((rootNav->section() & Entry::COMPOUND_MASK) || - rootNav->section()==Entry::OBJCIMPL_SEC) && !rootNav->name().isEmpty() + ((root->section & Entry::COMPOUND_MASK) || + root->section==Entry::OBJCIMPL_SEC) && !root->name.isEmpty() ) { - addClassToContext(rootNav); + addClassToContext(root); } - RECURSE_ENTRYTREE(buildClassList,rootNav); + RECURSE_ENTRYTREE(buildClassList,root); } -static void buildClassDocList(EntryNav *rootNav) +static void buildClassDocList(Entry *root) { if ( - (rootNav->section() & Entry::COMPOUNDDOC_MASK) && !rootNav->name().isEmpty() + (root->section & Entry::COMPOUNDDOC_MASK) && !root->name.isEmpty() ) { - addClassToContext(rootNav); + addClassToContext(root); } - RECURSE_ENTRYTREE(buildClassDocList,rootNav); + RECURSE_ENTRYTREE(buildClassDocList,root); } static void resolveClassNestingRelations() { ClassSDict::Iterator cli(*Doxygen::classSDict); - for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE; + for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); bool done=FALSE; int iteration=0; @@ -1451,7 +1421,7 @@ static void resolveClassNestingRelations() ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { - if (!cd->visited) + if (!cd->isVisited()) { QCString name = stripAnonymousNamespaceScope(cd->name()); //printf("processing=%s, iteration=%d\n",cd->name().data(),iteration); @@ -1463,7 +1433,32 @@ static void resolveClassNestingRelations() //printf("****** adding %s to scope %s in iteration %d\n",cd->name().data(),d->name().data(),iteration); d->addInnerCompound(cd); cd->setOuterScope(d); - cd->visited=TRUE; + + // for inline namespace add an alias of the class to the outer scope + while (d->definitionType()==DefinitionIntf::TypeNamespace) + { + NamespaceDef *nd = dynamic_cast<NamespaceDef*>(d); + //printf("d->isInline()=%d\n",nd->isInline()); + if (nd->isInline()) + { + d = d->getOuterScope(); + if (d) + { + ClassDef *aliasCd = createClassDefAlias(d,cd); + d->addInnerCompound(aliasCd); + QCString aliasFullName = d->qualifiedName()+"::"+aliasCd->localName(); + Doxygen::classSDict->append(aliasFullName,aliasCd); + printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName)); + aliasCd->setVisited(TRUE); + } + } + else + { + break; + } + } + + cd->setVisited(TRUE); done=FALSE; } //else @@ -1478,7 +1473,7 @@ static void resolveClassNestingRelations() ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { - if (!cd->visited) + if (!cd->isVisited()) { QCString name = stripAnonymousNamespaceScope(cd->name()); //printf("processing unresolved=%s, iteration=%d\n",cd->name().data(),iteration); @@ -1508,14 +1503,14 @@ void distributeClassGroupRelations() //printf("** distributeClassGroupRelations()\n"); ClassSDict::Iterator cli(*Doxygen::classSDict); - for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE; + for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) { //printf("Checking %s\n",cd->name().data()); // distribute the group to nested classes as well - if (!cd->visited && cd->partOfGroups()!=0 && cd->getClassSDict()) + if (!cd->isVisited() && cd->partOfGroups()!=0 && cd->getClassSDict()) { //printf(" Candidate for merging\n"); ClassSDict::Iterator ncli(*cd->getClassSDict()); @@ -1531,7 +1526,7 @@ void distributeClassGroupRelations() gd->addClass(ncd); } } - cd->visited=TRUE; // only visit every class once + cd->setVisited(TRUE); // only visit every class once } } } @@ -1543,7 +1538,7 @@ static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QC QCString fullName = removeAnonymousScopes(templ->name()); if (fullName.right(2)=="::") fullName=fullName.left(fullName.length()-2); fullName+="."+fieldName; - ClassDef *cd = new ClassDef(templ->getDefFileName(), + ClassDef *cd = createClassDef(templ->getDefFileName(), templ->getDefLine(), templ->getDefColumn(), fullName, @@ -1588,7 +1583,7 @@ static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QC for (li.toFirst();(md=li.current());++li) { //printf(" Member %s type=%s\n",md->name().data(),md->typeString()); - MemberDef *imd = new MemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(), + MemberDef *imd = createMemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(), md->typeString(),md->name(),md->argsString(),md->excpString(), md->protection(),md->virtualness(),md->isStatic(),Member, md->memberType(), @@ -1720,19 +1715,16 @@ static void findTagLessClasses() //---------------------------------------------------------------------- // build a list of all namespaces mentioned in the documentation // and all namespaces that have a documentation block before their definition. -static void buildNamespaceList(EntryNav *rootNav) +static void buildNamespaceList(Entry *root) { if ( - (rootNav->section()==Entry::NAMESPACE_SEC || - rootNav->section()==Entry::NAMESPACEDOC_SEC || - rootNav->section()==Entry::PACKAGEDOC_SEC + (root->section==Entry::NAMESPACE_SEC || + root->section==Entry::NAMESPACEDOC_SEC || + root->section==Entry::PACKAGEDOC_SEC ) && - !rootNav->name().isEmpty() + !root->name.isEmpty() ) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - //printf("** buildNamespaceList(%s)\n",root->name.data()); QCString fName = root->name; @@ -1757,7 +1749,7 @@ static void buildNamespaceList(EntryNav *rootNav) { nd->setLanguage(root->lang); } - if (rootNav->tagInfo()==0) // if we found the namespace in a tag file + if (root->tagInfo==0) // if we found the namespace in a tag file // and also in a project file, then remove // the tag file reference { @@ -1767,7 +1759,7 @@ static void buildNamespaceList(EntryNav *rootNav) nd->setMetaData(root->metaData); // file definition containing the namespace nd - FileDef *fd=rootNav->fileDef(); + FileDef *fd=root->fileDef(); // insert the namespace in the file definition if (fd) fd->insertNamespace(nd); addNamespaceToGroups(root,nd); @@ -1777,14 +1769,14 @@ static void buildNamespaceList(EntryNav *rootNav) { QCString tagName; QCString tagFileName; - TagInfo *tagInfo = rootNav->tagInfo(); + TagInfo *tagInfo = root->tagInfo; if (tagInfo) { tagName = tagInfo->tagName; tagFileName = tagInfo->fileName; } //printf("++ new namespace %s lang=%s tagName=%s\n",fullName.data(),langToString(root->lang).data(),tagName.data()); - NamespaceDef *nd=new NamespaceDef(tagInfo?tagName:root->fileName,root->startLine, + NamespaceDef *nd=createNamespaceDef(tagInfo?tagName:root->fileName,root->startLine, root->startColumn,fullName,tagName,tagFileName, root->type,root->spec&Entry::Published); nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition @@ -1795,13 +1787,14 @@ static void buildNamespaceList(EntryNav *rootNav) nd->setLanguage(root->lang); nd->setId(root->id); nd->setMetaData(root->metaData); + nd->setInline((root->spec&Entry::Inline)!=0); //printf("Adding namespace to group\n"); addNamespaceToGroups(root,nd); nd->setRefItems(root->sli); // file definition containing the namespace nd - FileDef *fd=rootNav->fileDef(); + FileDef *fd=root->fileDef(); // insert the namespace in the file definition if (fd) fd->insertNamespace(nd); @@ -1829,43 +1822,57 @@ static void buildNamespaceList(EntryNav *rootNav) { d->addInnerCompound(nd); nd->setOuterScope(d); + // in case of d is an inline namespace, alias insert nd in the part scope of d. + while (d->definitionType()==DefinitionIntf::TypeNamespace) + { + NamespaceDef *pnd = dynamic_cast<NamespaceDef*>(d); + if (pnd->isInline()) + { + d = d->getOuterScope(); + if (d) + { + NamespaceDef *aliasNd = createNamespaceDefAlias(d,nd); + //printf("adding %s to %s\n",qPrint(aliasNd->name()),qPrint(d->name())); + d->addInnerCompound(aliasNd); + } + } + else + { + break; + } + } } } } - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(buildNamespaceList,rootNav); + RECURSE_ENTRYTREE(buildNamespaceList,root); } //---------------------------------------------------------------------- -static NamespaceDef *findUsedNamespace(NamespaceSDict *unl, +static const NamespaceDef *findUsedNamespace(const NamespaceSDict *unl, const QCString &name) { - NamespaceDef *usingNd =0; + const NamespaceDef *usingNd =0; if (unl) { //printf("Found namespace dict %d\n",unl->count()); NamespaceSDict::Iterator unli(*unl); - NamespaceDef *und; + const NamespaceDef *und; for (unli.toFirst();(und=unli.current());++unli) { QCString uScope=und->name()+"::"; usingNd = getResolvedNamespace(uScope+name); - //printf("Also trying with scope=`%s' usingNd=%p\n",(uScope+name).data(),usingNd); + //printf("Also trying with scope='%s' usingNd=%p\n",(uScope+name).data(),usingNd); } } return usingNd; } -static void findUsingDirectives(EntryNav *rootNav) +static void findUsingDirectives(Entry *root) { - if (rootNav->section()==Entry::USINGDIR_SEC) + if (root->section==Entry::USINGDIR_SEC) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - //printf("Found using directive %s at line %d of %s\n", // root->name.data(),root->startLine,root->fileName.data()); QCString name=substitute(root->name,".","::"); @@ -1875,25 +1882,25 @@ static void findUsingDirectives(EntryNav *rootNav) } if (!name.isEmpty()) { - NamespaceDef *usingNd = 0; + const NamespaceDef *usingNd = 0; NamespaceDef *nd = 0; - FileDef *fd = rootNav->fileDef(); + FileDef *fd = root->fileDef(); QCString nsName; // see if the using statement was found inside a namespace or inside // the global file scope. - if (rootNav->parent() && rootNav->parent()->section()==Entry::NAMESPACE_SEC && + if (root->parent() && root->parent()->section==Entry::NAMESPACE_SEC && (fd==0 || fd->getLanguage()!=SrcLangExt_Java) // not a .java file ) { - nsName=stripAnonymousNamespaceScope(rootNav->parent()->name()); + nsName=stripAnonymousNamespaceScope(root->parent()->name); if (!nsName.isEmpty()) { nd = getResolvedNamespace(nsName); } } - // find the scope in which the `using' namespace is defined by prepending + // find the scope in which the 'using' namespace is defined by prepending // the possible scopes in which the using statement was found, starting // with the most inner scope and going to the most outer scope (i.e. // file scope). @@ -1903,7 +1910,7 @@ static void findUsingDirectives(EntryNav *rootNav) QCString scope=scopeOffset>0 ? nsName.left(scopeOffset)+"::" : QCString(); usingNd = getResolvedNamespace(scope+name); - //printf("Trying with scope=`%s' usingNd=%p\n",(scope+name).data(),usingNd); + //printf("Trying with scope='%s' usingNd=%p\n",(scope+name).data(),usingNd); if (scopeOffset==0) { scopeOffset=-1; @@ -1917,17 +1924,17 @@ static void findUsingDirectives(EntryNav *rootNav) if (usingNd==0 && nd) // not found, try used namespaces in this scope // or in one of the parent namespace scopes { - NamespaceDef *pnd = nd; + const NamespaceDef *pnd = nd; while (pnd && usingNd==0) { // also try with one of the used namespaces found earlier usingNd = findUsedNamespace(pnd->getUsedNamespaces(),name); // goto the parent - Definition *s = pnd->getOuterScope(); + const Definition *s = pnd->getOuterScope(); if (s && s->definitionType()==Definition::TypeNamespace) { - pnd = (NamespaceDef*)s; + pnd = dynamic_cast<const NamespaceDef*>(s); } else { @@ -1961,7 +1968,7 @@ static void findUsingDirectives(EntryNav *rootNav) else // unknown namespace, but add it anyway. { //printf("++ new unknown namespace %s lang=%s\n",name.data(),langToString(root->lang).data()); - NamespaceDef *nd=new NamespaceDef(root->fileName,root->startLine,root->startColumn,name); + NamespaceDef *nd=createNamespaceDef(root->fileName,root->startLine,root->startColumn,name); nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition nd->setBriefDescription(root->brief,root->briefFile,root->briefLine); nd->addSectionsToDefinition(root->anchors); @@ -1971,6 +1978,7 @@ static void findUsingDirectives(EntryNav *rootNav) nd->setLanguage(root->lang); nd->setId(root->id); nd->setMetaData(root->metaData); + nd->setInline((root->spec&Entry::Inline)!=0); QListIterator<Grouping> gli(*root->groups); Grouping *g; @@ -1996,49 +2004,39 @@ static void findUsingDirectives(EntryNav *rootNav) nd->setRefItems(root->sli); } } - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(findUsingDirectives,rootNav); + RECURSE_ENTRYTREE(findUsingDirectives,root); } //---------------------------------------------------------------------- -static void buildListOfUsingDecls(EntryNav *rootNav) +static void buildListOfUsingDecls(Entry *root) { - if (rootNav->section()==Entry::USINGDECL_SEC && - !(rootNav->parent()->section()&Entry::COMPOUND_MASK) // not a class/struct member + if (root->section==Entry::USINGDECL_SEC && + !(root->parent()->section&Entry::COMPOUND_MASK) // not a class/struct member ) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - QCString name = substitute(root->name,".","::"); if (g_usingDeclarations.find(name)==0) { - FileDef *fd = rootNav->fileDef(); + FileDef *fd = root->fileDef(); if (fd) { g_usingDeclarations.insert(name,fd); } } - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(buildListOfUsingDecls,rootNav); + RECURSE_ENTRYTREE(buildListOfUsingDecls,root); } -static void findUsingDeclarations(EntryNav *rootNav) +static void findUsingDeclarations(Entry *root) { - if (rootNav->section()==Entry::USINGDECL_SEC && - !(rootNav->parent()->section()&Entry::COMPOUND_MASK) // not a class/struct member + if (root->section==Entry::USINGDECL_SEC && + !(root->parent()->section&Entry::COMPOUND_MASK) // not a class/struct member ) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - //printf("Found using declaration %s at line %d of %s inside section %x\n", // root->name.data(),root->startLine,root->fileName.data(), // rootNav->parent()->section()); @@ -2046,14 +2044,14 @@ static void findUsingDeclarations(EntryNav *rootNav) { ClassDef *usingCd = 0; NamespaceDef *nd = 0; - FileDef *fd = rootNav->fileDef(); + FileDef *fd = root->fileDef(); QCString scName; // see if the using statement was found inside a namespace or inside // the global file scope. - if (rootNav->parent()->section() == Entry::NAMESPACE_SEC) + if (root->parent()->section == Entry::NAMESPACE_SEC) { - scName=rootNav->parent()->name(); + scName=root->parent()->name; if (!scName.isEmpty()) { nd = getResolvedNamespace(scName); @@ -2061,7 +2059,7 @@ static void findUsingDeclarations(EntryNav *rootNav) } // Assume the using statement was used to import a class. - // Find the scope in which the `using' namespace is defined by prepending + // Find the scope in which the 'using' namespace is defined by prepending // the possible scopes in which the using statement was found, starting // with the most inner scope and going to the most outer scope (i.e. // file scope). @@ -2072,7 +2070,7 @@ static void findUsingDeclarations(EntryNav *rootNav) // vector -> std::vector if (usingCd==0) { - usingCd = getResolvedClass(nd,fd,name); // try via resolving (see also bug757509) + usingCd = const_cast<ClassDef*>(getResolvedClass(nd,fd,name)); // try via resolving (see also bug757509) } if (usingCd==0) { @@ -2082,9 +2080,9 @@ static void findUsingDeclarations(EntryNav *rootNav) //printf("%s -> %p\n",root->name.data(),usingCd); if (usingCd==0) // definition not in the input => add an artificial class { - Debug::print(Debug::Classes,0," New using class `%s' (sec=0x%08x)! #tArgLists=%d\n", + Debug::print(Debug::Classes,0," New using class '%s' (sec=0x%08x)! #tArgLists=%d\n", qPrint(name),root->section,root->tArgLists ? (int)root->tArgLists->count() : -1); - usingCd = new ClassDef( + usingCd = createClassDef( "<using>",1,1, name, ClassDef::Class); @@ -2112,35 +2110,33 @@ static void findUsingDeclarations(EntryNav *rootNav) fd->addUsingDeclaration(usingCd); } } - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(findUsingDeclarations,rootNav); + RECURSE_ENTRYTREE(findUsingDeclarations,root); } //---------------------------------------------------------------------- -static void findUsingDeclImports(EntryNav *rootNav) +static void findUsingDeclImports(Entry *root) { - if (rootNav->section()==Entry::USINGDECL_SEC && - (rootNav->parent()->section()&Entry::COMPOUND_MASK) // in a class/struct member + if (root->section==Entry::USINGDECL_SEC && + (root->parent()->section&Entry::COMPOUND_MASK) // in a class/struct member ) { //printf("Found using declaration %s inside section %x\n", // rootNav->name().data(), rootNav->parent()->section()); - QCString fullName=removeRedundantWhiteSpace(rootNav->parent()->name()); + QCString fullName=removeRedundantWhiteSpace(root->parent()->name); fullName=stripAnonymousNamespaceScope(fullName); fullName=stripTemplateSpecifiersFromScope(fullName); ClassDef *cd = getClass(fullName); if (cd) { //printf("found class %s\n",cd->name().data()); - int i=rootNav->name().find("::"); + int i=root->name.find("::"); if (i!=-1) { - QCString scope=rootNav->name().left(i); - QCString memName=rootNav->name().right(rootNav->name().length()-i-2); - ClassDef *bcd = getResolvedClass(cd,0,scope); // todo: file in fileScope parameter + QCString scope=root->name.left(i); + QCString memName=root->name.right(root->name.length()-i-2); + const ClassDef *bcd = getResolvedClass(cd,0,scope); // todo: file in fileScope parameter if (bcd) { //printf("found class %s memName=%s\n",bcd->name().data(),memName.data()); @@ -2157,21 +2153,17 @@ static void findUsingDeclImports(EntryNav *rootNav) MemberDef *md = mi->memberDef; if (md && md->protection()!=Private) { - - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - //printf("found member %s\n",mni->memberName()); MemberDef *newMd = 0; { QCString fileName = root->fileName; - if (fileName.isEmpty() && rootNav->tagInfo()) + if (fileName.isEmpty() && root->tagInfo) { - fileName = rootNav->tagInfo()->tagName; + fileName = root->tagInfo->tagName; } - ArgumentList *templAl = md->templateArguments(); - ArgumentList *al = md->templateArguments(); - newMd = new MemberDef( + const ArgumentList *templAl = md->templateArguments(); + const ArgumentList *al = md->templateArguments(); + newMd = createMemberDef( fileName,root->startLine,root->startColumn, md->typeString(),memName,md->argsString(), md->excpString(),root->protection,root->virt, @@ -2208,8 +2200,6 @@ static void findUsingDeclImports(EntryNav *rootNav) newMd->setMemberSpecifiers(md->getMemberSpecifiers()); newMd->setLanguage(root->lang); newMd->setId(root->id); - - rootNav->releaseEntry(); } } } @@ -2219,7 +2209,7 @@ static void findUsingDeclImports(EntryNav *rootNav) } } - RECURSE_ENTRYTREE(findUsingDeclImports,rootNav); + RECURSE_ENTRYTREE(findUsingDeclImports,root); } //---------------------------------------------------------------------- @@ -2235,7 +2225,7 @@ static void findIncludedUsingDirectives() FileDef *fd; for (;(fd=fni.current());++fni) { - fd->visited=FALSE; + fd->setVisited(FALSE); } } // then recursively add using directives found in #include files @@ -2246,7 +2236,7 @@ static void findIncludedUsingDirectives() FileDef *fd; for (fni.toFirst();(fd=fni.current());++fni) { - if (!fd->visited) + if (!fd->isVisited()) { //printf("----- adding using directives for file %s\n",fd->name().data()); fd->addIncludedUsingDirectives(); @@ -2258,7 +2248,7 @@ static void findIncludedUsingDirectives() //---------------------------------------------------------------------- static MemberDef *addVariableToClass( - EntryNav *rootNav, + Entry *root, ClassDef *cd, MemberType mtype, const QCString &name, @@ -2267,8 +2257,6 @@ static MemberDef *addVariableToClass( Protection prot, Relationship related) { - Entry *root = rootNav->entry(); - QCString qualScope = cd->qualifiedNameWithTemplateParameters(); QCString scopeSeparator="::"; SrcLangExt lang = cd->getLanguage(); @@ -2279,7 +2267,7 @@ static MemberDef *addVariableToClass( } Debug::print(Debug::Variables,0, " class variable:\n" - " `%s' `%s'::`%s' `%s' prot=`%d ann=%d init=`%s'\n", + " '%s' '%s'::'%s' '%s' prot=%d ann=%d init='%s'\n", qPrint(root->type), qPrint(qualScope), qPrint(name), @@ -2340,7 +2328,8 @@ static MemberDef *addVariableToClass( { //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n", // md->getClassDef(),cd,root->type.data(),md->typeString()); - if (md->getClassDef()==cd && + if (!md->isAlias() && + md->getClassDef()==cd && removeRedundantWhiteSpace(root->type)==md->typeString()) // member already in the scope { @@ -2353,7 +2342,7 @@ static MemberDef *addVariableToClass( md->setProtection(root->protection); cd->reclassifyMember(md,MemberType_Property); } - addMemberDocs(rootNav,md,def,0,FALSE); + addMemberDocs(root,md,def,0,FALSE); //printf(" Member already found!\n"); return md; } @@ -2361,18 +2350,18 @@ static MemberDef *addVariableToClass( } QCString fileName = root->fileName; - if (fileName.isEmpty() && rootNav->tagInfo()) + if (fileName.isEmpty() && root->tagInfo) { - fileName = rootNav->tagInfo()->tagName; + fileName = root->tagInfo->tagName; } // new member variable, typedef or enum value - MemberDef *md=new MemberDef( + MemberDef *md=createMemberDef( fileName,root->startLine,root->startColumn, root->type,name,root->args,root->exception, prot,Normal,root->stat,related, mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0, root->metaData); - md->setTagInfo(rootNav->tagInfo()); + md->setTagInfo(root->tagInfo); md->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope()) //md->setDefFile(root->fileName); //md->setDefLine(root->startLine); @@ -2406,7 +2395,7 @@ static MemberDef *addVariableToClass( // printf("memberdef %s in memberGroup %d\n",name.data(),root->mGrpId); // md->setMemberGroup(memberGroupDict[root->mGrpId]); // - md->setBodyDef(rootNav->fileDef()); + md->setBodyDef(root->fileDef()); //printf(" Adding member=%s\n",md->name().data()); // add the member to the global list @@ -2429,15 +2418,15 @@ static MemberDef *addVariableToClass( md->setRefItems(root->sli); //TODO: insert FileDef instead of filename strings. - cd->insertUsedFile(rootNav->fileDef()); - rootNav->changeSection(Entry::EMPTY_SEC); + cd->insertUsedFile(root->fileDef()); + root->changeSection(Entry::EMPTY_SEC); return md; } //---------------------------------------------------------------------- static MemberDef *addVariableToFile( - EntryNav *rootNav, + Entry *root, MemberType mtype, const QCString &scope, const QCString &name, @@ -2445,10 +2434,10 @@ static MemberDef *addVariableToFile( /*int indentDepth,*/ MemberDef *fromAnnMemb) { - Entry *root = rootNav->entry(); Debug::print(Debug::Variables,0, " global variable:\n" - " type=`%s' scope=`%s' name=`%s' args=`%s' prot=`%d mtype=%d lang=%d\n", + " file='%s' type='%s' scope='%s' name='%s' args='%s' prot=`%d mtype=%d lang=%d\n", + qPrint(root->fileName), qPrint(root->type), qPrint(scope), qPrint(name), @@ -2458,7 +2447,7 @@ static MemberDef *addVariableToFile( root->lang ); - FileDef *fd = rootNav->fileDef(); + FileDef *fd = root->fileDef(); // see if we have a typedef that should hide a struct or union if (mtype==MemberType_Typedef && Config_getBool(TYPEDEF_HIDES_STRUCT)) @@ -2568,7 +2557,7 @@ static MemberDef *addVariableToFile( MemberDef *md; for (mni.toFirst();(md=mni.current());++mni) { - if ( + if (!md->isAlias() && ((nd==0 && md->getNamespaceDef()==0 && md->getFileDef() && root->fileName==md->getFileDef()->absFilePath() ) // both variable names in the same file @@ -2592,11 +2581,23 @@ static MemberDef *addVariableToFile( ) // not a php array variable { - Debug::print(Debug::Variables,0, " variable already found: scope=%s\n",qPrint(md->getOuterScope()->name())); - addMemberDocs(rootNav,md,def,0,FALSE); + addMemberDocs(root,md,def,0,FALSE); md->setRefItems(root->sli); + // if md is a variable forward declaration and root is the definition that + // turn md into the defintion + if (!root->explicitExternal && md->isExternal()) + { + md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn()); + md->setExplicitExternal(FALSE,root->fileName,root->startLine,root->startColumn); + } + // if md is the definition and root point at a declaration, then add the + // declaration info + else if (root->explicitExternal && !md->isExternal()) + { + md->setDeclFile(root->fileName,root->startLine,root->startColumn); + } return md; } } @@ -2604,20 +2605,20 @@ static MemberDef *addVariableToFile( } QCString fileName = root->fileName; - if (fileName.isEmpty() && rootNav->tagInfo()) + if (fileName.isEmpty() && root->tagInfo) { - fileName = rootNav->tagInfo()->tagName; + fileName = root->tagInfo->tagName; } Debug::print(Debug::Variables,0, - " new variable, nd=%s tagInfo=%p!\n",nd?qPrint(nd->name()):"<global>",rootNav->tagInfo()); + " new variable, nd=%s tagInfo=%p!\n",nd?qPrint(nd->name()):"<global>",root->tagInfo); // new global variable, enum value or typedef - MemberDef *md=new MemberDef( + MemberDef *md=createMemberDef( fileName,root->startLine,root->startColumn, root->type,name,root->args,0, root->protection, Normal,root->stat,Member, mtype,root->tArgLists ? root->tArgLists->getLast() : 0,0, root->metaData); - md->setTagInfo(rootNav->tagInfo()); + md->setTagInfo(root->tagInfo); md->setMemberSpecifiers(root->spec); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setBriefDescription(root->brief,root->briefFile,root->briefLine); @@ -2635,7 +2636,7 @@ static MemberDef *addVariableToFile( md->enableCallerGraph(root->callerGraph); md->enableReferencedByRelation(root->referencedByRelation); md->enableReferencesRelation(root->referencesRelation); - md->setExplicitExternal(root->explicitExternal); + md->setExplicitExternal(root->explicitExternal,fileName,root->startLine,root->startColumn); //md->setOuterScope(fd); if (!root->explicitExternal) { @@ -2670,7 +2671,7 @@ static MemberDef *addVariableToFile( mn->append(md); Doxygen::functionNameSDict->append(name,mn); } - rootNav->changeSection(Entry::EMPTY_SEC); + root->changeSection(Entry::EMPTY_SEC); return md; } @@ -2711,7 +2712,7 @@ static int findFunctionPtr(const QCString &type,int lang, int *pLength=0) /*! Returns TRUE iff \a type is a class within scope \a context. * Used to detect variable declarations that look like function prototypes. */ -static bool isVarWithConstructor(EntryNav *rootNav) +static bool isVarWithConstructor(Entry *root) { static QRegExp initChars("[0-9\"'&*!^]+"); static QRegExp idChars("[a-z_A-Z][a-z_A-Z0-9]*"); @@ -2723,15 +2724,12 @@ static bool isVarWithConstructor(EntryNav *rootNav) int ti; //printf("isVarWithConstructor(%s)\n",rootNav->name().data()); - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - - if (rootNav->parent()->section() & Entry::COMPOUND_MASK) + if (root->parent()->section & Entry::COMPOUND_MASK) { // inside a class result=FALSE; goto done; } - else if ((fd = rootNav->fileDef()) && + else if ((fd = root->fileDef()) && (fd->name().right(2)==".c" || fd->name().right(2)==".h") ) { // inside a .c file @@ -2743,9 +2741,9 @@ static bool isVarWithConstructor(EntryNav *rootNav) result=FALSE; goto done; } - if (!rootNav->parent()->name().isEmpty()) + if (!root->parent()->name.isEmpty()) { - ctx=Doxygen::namespaceSDict->find(rootNav->parent()->name()); + ctx=Doxygen::namespaceSDict->find(root->parent()->name); } type = root->type; // remove qualifiers @@ -2830,20 +2828,16 @@ static bool isVarWithConstructor(EntryNav *rootNav) done: //printf("isVarWithConstructor(%s,%s)=%d\n",rootNav->parent()->name().data(), // root->type.data(),result); - rootNav->releaseEntry(); return result; } -static void addVariable(EntryNav *rootNav,int isFuncPtr=-1) +static void addVariable(Entry *root,int isFuncPtr=-1) { static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - Debug::print(Debug::Variables,0, "VARIABLE_SEC: \n" - " type=`%s' name=`%s' args=`%s' bodyLine=`%d' mGrpId=%d relates=%s\n", + " type='%s' name='%s' args='%s' bodyLine=%d mGrpId=%d relates='%s'\n", qPrint(root->type), qPrint(root->name), qPrint(root->args), @@ -2869,7 +2863,7 @@ static void addVariable(EntryNav *rootNav,int isFuncPtr=-1) root->name=root->args.mid(i,l); root->args=root->args.mid(i+l,root->args.find(')',i+l)-i-l); } - //printf("new: type=`%s' name=`%s' args=`%s'\n", + //printf("new: type='%s' name='%s' args='%s'\n", // root->type.data(),root->name.data(),root->args.data()); } else @@ -2897,10 +2891,10 @@ static void addVariable(EntryNav *rootNav,int isFuncPtr=-1) QCString scope,name=removeRedundantWhiteSpace(root->name); // find the scope of this variable - EntryNav *p = rootNav->parent(); - while ((p->section() & Entry::SCOPE_MASK)) + Entry *p = root->parent(); + while ((p->section & Entry::SCOPE_MASK)) { - QCString scopeName = p->name(); + QCString scopeName = p->name; if (!scopeName.isEmpty()) { scope.prepend(scopeName); @@ -2927,7 +2921,7 @@ static void addVariable(EntryNav *rootNav,int isFuncPtr=-1) cd=getClass(scope); if (cd) { - addVariableToClass(rootNav, // entry + addVariableToClass(root, // entry cd, // class to add member to MemberType_Friend, // type of member name, // name of the member @@ -2938,8 +2932,7 @@ static void addVariable(EntryNav *rootNav,int isFuncPtr=-1) ); } } - goto nextMember; - /* skip this member, because it is a + return; /* skip this member, because it is a * static variable definition (always?), which will be * found in a class scope as well, but then we know the * correct protection level, so only then it will be @@ -3003,7 +2996,7 @@ static void addVariable(EntryNav *rootNav,int isFuncPtr=-1) { if (!pScope.isEmpty() && (pcd=getClass(pScope))) { - md=addVariableToClass(rootNav, // entry + md=addVariableToClass(root, // entry pcd, // class to add member to mtype, // member type name, // member name @@ -3018,17 +3011,17 @@ static void addVariable(EntryNav *rootNav,int isFuncPtr=-1) { if (mtype==MemberType_Variable) { - md=addVariableToFile(rootNav,mtype,pScope,name,TRUE,0); + md=addVariableToFile(root,mtype,pScope,name,TRUE,0); } //added=TRUE; } } } - //printf("name=`%s' scope=%s scope.right=%s\n", + //printf("name='%s' scope=%s scope.right=%s\n", // name.data(),scope.data(), // scope.right(scope.length()-si).data()); - addVariableToClass(rootNav, // entry + addVariableToClass(root, // entry cd, // class to add member to mtype, // member type name, // name of the member @@ -3040,33 +3033,31 @@ static void addVariable(EntryNav *rootNav,int isFuncPtr=-1) else if (!name.isEmpty()) // global variable { //printf("Inserting member in global scope %s!\n",scope.data()); - addVariableToFile(rootNav,mtype,scope,name,FALSE,/*0,*/0); + addVariableToFile(root,mtype,scope,name,FALSE,/*0,*/0); } -nextMember: - rootNav->releaseEntry(); } //---------------------------------------------------------------------- // Searches the Entry tree for typedef documentation sections. // If found they are stored in their class or in the global list. -static void buildTypedefList(EntryNav *rootNav) +static void buildTypedefList(Entry *root) { //printf("buildVarList(%s)\n",rootNav->name().data()); - if (!rootNav->name().isEmpty() && - rootNav->section()==Entry::VARIABLE_SEC && - rootNav->type().find("typedef ")!=-1 // its a typedef + if (!root->name.isEmpty() && + root->section==Entry::VARIABLE_SEC && + root->type.find("typedef ")!=-1 // its a typedef ) { - addVariable(rootNav); + addVariable(root); } - if (rootNav->children()) + if (root->children()) { - EntryNavListIterator eli(*rootNav->children()); - EntryNav *e; + EntryListIterator eli(*root->children()); + Entry *e; for (;(e=eli.current());++eli) { - if (e->section()!=Entry::ENUM_SEC) + if (e->section!=Entry::ENUM_SEC) { buildTypedefList(e); } @@ -3077,22 +3068,22 @@ static void buildTypedefList(EntryNav *rootNav) //---------------------------------------------------------------------- // Searches the Entry tree for sequence documentation sections. // If found they are stored in the global list. -static void buildSequenceList(EntryNav *rootNav) +static void buildSequenceList(Entry *root) { - if (!rootNav->name().isEmpty() && - rootNav->section()==Entry::VARIABLE_SEC && - rootNav->type().find("sequence<")!=-1 // it's a sequence + if (!root->name.isEmpty() && + root->section==Entry::VARIABLE_SEC && + root->type.find("sequence<")!=-1 // it's a sequence ) { - addVariable(rootNav); + addVariable(root); } - if (rootNav->children()) + if (root->children()) { - EntryNavListIterator eli(*rootNav->children()); - EntryNav *e; + EntryListIterator eli(*root->children()); + Entry *e; for (;(e=eli.current());++eli) { - if (e->section()!=Entry::ENUM_SEC) + if (e->section!=Entry::ENUM_SEC) { buildSequenceList(e); } @@ -3103,22 +3094,22 @@ static void buildSequenceList(EntryNav *rootNav) //---------------------------------------------------------------------- // Searches the Entry tree for dictionary documentation sections. // If found they are stored in the global list. -static void buildDictionaryList(EntryNav *rootNav) +static void buildDictionaryList(Entry *root) { - if (!rootNav->name().isEmpty() && - rootNav->section()==Entry::VARIABLE_SEC && - rootNav->type().find("dictionary<")!=-1 // it's a dictionary + if (!root->name.isEmpty() && + root->section==Entry::VARIABLE_SEC && + root->type.find("dictionary<")!=-1 // it's a dictionary ) { - addVariable(rootNav); + addVariable(root); } - if (rootNav->children()) + if (root->children()) { - EntryNavListIterator eli(*rootNav->children()); - EntryNav *e; + EntryListIterator eli(*root->children()); + Entry *e; for (;(e=eli.current());++eli) { - if (e->section()!=Entry::ENUM_SEC) + if (e->section!=Entry::ENUM_SEC) { buildDictionaryList(e); } @@ -3130,33 +3121,33 @@ static void buildDictionaryList(EntryNav *rootNav) // Searches the Entry tree for Variable documentation sections. // If found they are stored in their class or in the global list. -static void buildVarList(EntryNav *rootNav) +static void buildVarList(Entry *root) { //printf("buildVarList(%s) section=%08x\n",rootNav->name().data(),rootNav->section()); int isFuncPtr=-1; - if (!rootNav->name().isEmpty() && - (rootNav->type().isEmpty() || g_compoundKeywordDict.find(rootNav->type())==0) && + if (!root->name.isEmpty() && + (root->type.isEmpty() || g_compoundKeywordDict.find(root->type)==0) && ( - (rootNav->section()==Entry::VARIABLE_SEC // it's a variable + (root->section==Entry::VARIABLE_SEC // it's a variable ) || - (rootNav->section()==Entry::FUNCTION_SEC && // or maybe a function pointer variable - (isFuncPtr=findFunctionPtr(rootNav->type(),rootNav->lang()))!=-1 + (root->section==Entry::FUNCTION_SEC && // or maybe a function pointer variable + (isFuncPtr=findFunctionPtr(root->type,root->lang))!=-1 ) || - (rootNav->section()==Entry::FUNCTION_SEC && // class variable initialized by constructor - isVarWithConstructor(rootNav) + (root->section==Entry::FUNCTION_SEC && // class variable initialized by constructor + isVarWithConstructor(root) ) ) ) // documented variable { - addVariable(rootNav,isFuncPtr); + addVariable(root,isFuncPtr); } - if (rootNav->children()) + if (root->children()) { - EntryNavListIterator eli(*rootNav->children()); - EntryNav *e; + EntryListIterator eli(*root->children()); + Entry *e; for (;(e=eli.current());++eli) { - if (e->section()!=Entry::ENUM_SEC) + if (e->section!=Entry::ENUM_SEC) { buildVarList(e); } @@ -3170,25 +3161,24 @@ static void buildVarList(EntryNav *rootNav) // static void addInterfaceOrServiceToServiceOrSingleton( - EntryNav *const rootNav, + Entry *const root, ClassDef *const cd, QCString const& rname) { - Entry *const root = rootNav->entry(); - FileDef *const fd = rootNav->fileDef(); - enum MemberType const type = (rootNav->section()==Entry::EXPORTED_INTERFACE_SEC) + FileDef *fd = root->fileDef(); + enum MemberType type = (root->section==Entry::EXPORTED_INTERFACE_SEC) ? MemberType_Interface : MemberType_Service; QCString fileName = root->fileName; - if (fileName.isEmpty() && rootNav->tagInfo()) + if (fileName.isEmpty() && root->tagInfo) { - fileName = rootNav->tagInfo()->tagName; + fileName = root->tagInfo->tagName; } - MemberDef *const md = new MemberDef( + MemberDef *const md = createMemberDef( fileName, root->startLine, root->startColumn, root->type, rname, "", "", root->protection, root->virt, root->stat, Member, type, 0, root->argList, root->metaData); - md->setTagInfo(rootNav->tagInfo()); + md->setTagInfo(root->tagInfo); md->setMemberClass(cd); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocsForDefinition(false); @@ -3211,8 +3201,8 @@ static void addInterfaceOrServiceToServiceOrSingleton( Debug::print(Debug::Functions,0, " Interface Member:\n" - " `%s' `%s' proto=%d\n" - " def=`%s'\n", + " '%s' '%s' proto=%d\n" + " def='%s'\n", qPrint(root->type), qPrint(rname), root->proto, @@ -3238,29 +3228,25 @@ static void addInterfaceOrServiceToServiceOrSingleton( // "optional" interface/service get Protected which turns into dashed line BaseInfo base(rname, (root->spec & (Entry::Optional)) ? Protected : Public,Normal); - findClassRelation(rootNav,cd,cd,&base,0,DocumentedOnly,true) - || findClassRelation(rootNav,cd,cd,&base,0,Undocumented,true); + findClassRelation(root,cd,cd,&base,0,DocumentedOnly,true) || findClassRelation(root,cd,cd,&base,0,Undocumented,true); // add file to list of used files cd->insertUsedFile(fd); addMemberToGroups(root,md); - rootNav->changeSection(Entry::EMPTY_SEC); + root->changeSection(Entry::EMPTY_SEC); md->setRefItems(root->sli); } -static void buildInterfaceAndServiceList(EntryNav *const rootNav) +static void buildInterfaceAndServiceList(Entry *root) { - if (rootNav->section()==Entry::EXPORTED_INTERFACE_SEC || - rootNav->section()==Entry::INCLUDED_SERVICE_SEC) + if (root->section==Entry::EXPORTED_INTERFACE_SEC || + root->section==Entry::INCLUDED_SERVICE_SEC) { - rootNav->loadEntry(g_storage); - Entry *const root = rootNav->entry(); - Debug::print(Debug::Functions,0, "EXPORTED_INTERFACE_SEC:\n" - " `%s' `%s'::`%s' `%s' relates=`%s' relatesType=`%d' file=`%s' line=`%d' bodyLine=`%d' #tArgLists=%d mGrpId=%d spec=%lld proto=%d docFile=%s\n", + " '%s' '%s'::'%s' '%s' relates='%s' relatesType='%d' file='%s' line='%d' bodyLine='%d' #tArgLists=%d mGrpId=%d spec=%lld proto=%d docFile=%s\n", qPrint(root->type), - qPrint(rootNav->parent()->name()), + qPrint(root->parent()->name), qPrint(root->name), qPrint(root->args), qPrint(root->relates), @@ -3275,18 +3261,18 @@ static void buildInterfaceAndServiceList(EntryNav *const rootNav) qPrint(root->docFile) ); - QCString const rname = removeRedundantWhiteSpace(root->name); + QCString rname = removeRedundantWhiteSpace(root->name); if (!rname.isEmpty()) { - QCString const scope = rootNav->parent()->name(); - ClassDef *const cd = getClass(scope); + QCString scope = root->parent()->name; + ClassDef *cd = getClass(scope); assert(cd); if (cd && ((ClassDef::Interface == cd->compoundType()) || (ClassDef::Service == cd->compoundType()) || (ClassDef::Singleton == cd->compoundType()))) { - addInterfaceOrServiceToServiceOrSingleton(rootNav,cd,rname); + addInterfaceOrServiceToServiceOrSingleton(root,cd,rname); } else { @@ -3298,15 +3284,13 @@ static void buildInterfaceAndServiceList(EntryNav *const rootNav) warn(root->fileName,root->startLine, "Illegal member name found."); } - - rootNav->releaseEntry(); } // can only have these in IDL anyway - switch (rootNav->lang()) + switch (root->lang) { case SrcLangExt_Unknown: // fall through (root node always is Unknown) case SrcLangExt_IDL: - RECURSE_ENTRYTREE(buildInterfaceAndServiceList,rootNav); + RECURSE_ENTRYTREE(buildInterfaceAndServiceList,root); break; default: return; // nothing to do here @@ -3318,11 +3302,10 @@ static void buildInterfaceAndServiceList(EntryNav *const rootNav) // Searches the Entry tree for Function sections. // If found they are stored in their class or in the global list. -static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, +static void addMethodToClass(Entry *root,ClassDef *cd, const QCString &rname,bool isFriend) { - Entry *root = rootNav->entry(); - FileDef *fd=rootNav->fileDef(); + FileDef *fd=root->fileDef(); int l; static QRegExp re("([a-z_A-Z0-9: ]*[ &*]+[ ]*"); @@ -3359,17 +3342,17 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, } QCString fileName = root->fileName; - if (fileName.isEmpty() && rootNav->tagInfo()) + if (fileName.isEmpty() && root->tagInfo) { - fileName = rootNav->tagInfo()->tagName; + fileName = root->tagInfo->tagName; } - //printf("root->name=`%s; root->args=`%s' root->argList=`%s'\n", + //printf("root->name='%s; root->args='%s' root->argList='%s'\n", // root->name.data(),root->args.data(),argListToString(root->argList).data() // ); // adding class member - MemberDef *md=new MemberDef( + MemberDef *md=createMemberDef( fileName,root->startLine,root->startColumn, root->type,name,root->args,root->exception, root->protection,root->virt, @@ -3377,7 +3360,7 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, root->relates.isEmpty() ? Member : root->relatesType == MemberOf ? Foreign : Related, mtype,root->tArgLists ? root->tArgLists->getLast() : 0,root->argList, root->metaData); - md->setTagInfo(rootNav->tagInfo()); + md->setTagInfo(root->tagInfo); md->setMemberClass(cd); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocsForDefinition(!root->proto); @@ -3465,8 +3448,8 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, Debug::print(Debug::Functions,0, " Func Member:\n" - " `%s' `%s'::`%s' `%s' proto=%d\n" - " def=`%s'\n", + " '%s' '%s'::'%s' '%s' proto=%d\n" + " def='%s'\n", qPrint(root->type), qPrint(qualScope), qPrint(rname), @@ -3495,23 +3478,20 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, cd->insertUsedFile(fd); addMemberToGroups(root,md); - rootNav->changeSection(Entry::EMPTY_SEC); + root->changeSection(Entry::EMPTY_SEC); md->setRefItems(root->sli); } -static void buildFunctionList(EntryNav *rootNav) +static void buildFunctionList(Entry *root) { - if (rootNav->section()==Entry::FUNCTION_SEC) + if (root->section==Entry::FUNCTION_SEC) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - Debug::print(Debug::Functions,0, "FUNCTION_SEC:\n" - " `%s' `%s'::`%s' `%s' relates=`%s' relatesType=`%d' file=`%s' line=`%d' bodyLine=`%d' #tArgLists=%d mGrpId=%d spec=%lld proto=%d docFile=%s\n", + " '%s' '%s'::'%s' '%s' relates='%s' relatesType='%d' file='%s' line='%d' bodyLine='%d' #tArgLists=%d mGrpId=%d spec=%lld proto=%d docFile=%s\n", qPrint(root->type), - qPrint(rootNav->parent()->name()), + qPrint(root->parent()->name), qPrint(root->name), qPrint(root->args), qPrint(root->relates), @@ -3530,14 +3510,14 @@ static void buildFunctionList(EntryNav *rootNav) QCString rname = removeRedundantWhiteSpace(root->name); //printf("rname=%s\n",rname.data()); - QCString scope=rootNav->parent()->name(); //stripAnonymousNamespaceScope(root->parent->name); + QCString scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name); if (!rname.isEmpty() && scope.find('@')==-1) { ClassDef *cd=0; // check if this function's parent is a class scope=stripTemplateSpecifiersFromScope(scope,FALSE); - FileDef *rfd=rootNav->fileDef(); + FileDef *rfd=root->fileDef(); int memIndex=rname.findRev("::"); @@ -3545,7 +3525,7 @@ static void buildFunctionList(EntryNav *rootNav) if (cd && scope+"::"==rname.left(scope.length()+2)) // found A::f inside A { // strip scope from name - rname=rname.right(rname.length()-rootNav->parent()->name().length()-2); + rname=rname.right(rname.length()-root->parent()->name.length()-2); } NamespaceDef *nd = 0; @@ -3579,8 +3559,8 @@ static void buildFunctionList(EntryNav *rootNav) int ts=root->type.find('<'); int te=root->type.findRev('>'); int ti; - if (!rootNav->parent()->name().isEmpty() && - (rootNav->parent()->section() & Entry::COMPOUND_MASK) && + if (!root->parent()->name.isEmpty() && + (root->parent()->section & Entry::COMPOUND_MASK) && cd && // do some fuzzy things to exclude function pointers (root->type.isEmpty() || @@ -3594,10 +3574,10 @@ static void buildFunctionList(EntryNav *rootNav) { Debug::print(Debug::Functions,0," --> member %s of class %s!\n", qPrint(rname),qPrint(cd->name())); - addMethodToClass(rootNav,cd,rname,isFriend); + addMethodToClass(root,cd,rname,isFriend); } - else if (!((rootNav->parent()->section() & Entry::COMPOUND_MASK) - || rootNav->parent()->section()==Entry::OBJCIMPL_SEC + else if (!((root->parent()->section & Entry::COMPOUND_MASK) + || root->parent()->section==Entry::OBJCIMPL_SEC ) && !isMember && (root->relates.isEmpty() || root->relatesType == Duplicate) && @@ -3618,140 +3598,149 @@ static void buildFunctionList(EntryNav *rootNav) MemberNameIterator mni(*mn); for (mni.toFirst();(!found && (md=mni.current()));++mni) { - NamespaceDef *mnd = md->getNamespaceDef(); - NamespaceDef *rnd = 0; - //printf("root namespace=%s\n",rootNav->parent()->name().data()); - QCString fullScope = scope; - QCString parentScope = rootNav->parent()->name(); - if (!parentScope.isEmpty() && !leftScopeMatch(parentScope,scope)) - { - if (!scope.isEmpty()) fullScope.prepend("::"); - fullScope.prepend(parentScope); - } - //printf("fullScope=%s\n",fullScope.data()); - rnd = getResolvedNamespace(fullScope); - FileDef *mfd = md->getFileDef(); - QCString nsName,rnsName; - if (mnd) nsName = mnd->name().copy(); - if (rnd) rnsName = rnd->name().copy(); - //printf("matching arguments for %s%s %s%s\n", - // md->name().data(),md->argsString(),rname.data(),argListToString(root->argList).data()); - ArgumentList *mdAl = md->argumentList(); - ArgumentList *mdTempl = md->templateArguments(); - - // in case of template functions, we need to check if the - // functions have the same number of template parameters - bool sameNumTemplateArgs = TRUE; - bool matchingReturnTypes = TRUE; - if (mdTempl!=0 && root->tArgLists) + if (!md->isAlias()) { - if (mdTempl->count()!=root->tArgLists->getLast()->count()) + const NamespaceDef *mnd = md->getNamespaceDef(); + NamespaceDef *rnd = 0; + //printf("root namespace=%s\n",rootNav->parent()->name().data()); + QCString fullScope = scope; + QCString parentScope = root->parent()->name; + if (!parentScope.isEmpty() && !leftScopeMatch(parentScope,scope)) { - sameNumTemplateArgs = FALSE; + if (!scope.isEmpty()) fullScope.prepend("::"); + fullScope.prepend(parentScope); } - if (md->typeString()!=removeRedundantWhiteSpace(root->type)) + //printf("fullScope=%s\n",fullScope.data()); + rnd = getResolvedNamespace(fullScope); + const FileDef *mfd = md->getFileDef(); + QCString nsName,rnsName; + if (mnd) nsName = mnd->name().copy(); + if (rnd) rnsName = rnd->name().copy(); + //printf("matching arguments for %s%s %s%s\n", + // md->name().data(),md->argsString(),rname.data(),argListToString(root->argList).data()); + ArgumentList *mdAl = md->argumentList(); + const ArgumentList *mdTempl = md->templateArguments(); + + // in case of template functions, we need to check if the + // functions have the same number of template parameters + bool sameNumTemplateArgs = TRUE; + bool matchingReturnTypes = TRUE; + if (mdTempl!=0 && root->tArgLists) { - matchingReturnTypes = FALSE; + if (mdTempl->count()!=root->tArgLists->getLast()->count()) + { + sameNumTemplateArgs = FALSE; + } + if (md->typeString()!=removeRedundantWhiteSpace(root->type)) + { + matchingReturnTypes = FALSE; + } } - } - bool staticsInDifferentFiles = - root->stat && md->isStatic() && root->fileName!=md->getDefFileName(); + bool staticsInDifferentFiles = + root->stat && md->isStatic() && root->fileName!=md->getDefFileName(); - if ( - matchArguments2(md->getOuterScope(),mfd,mdAl, - rnd ? rnd : Doxygen::globalScope,rfd,root->argList, - FALSE) && - sameNumTemplateArgs && - matchingReturnTypes && - !staticsInDifferentFiles - ) - { - GroupDef *gd=0; - if (root->groups->getFirst()!=0) - { - gd = Doxygen::groupSDict->find(root->groups->getFirst()->groupname.data()); - } - //printf("match!\n"); - //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,nsName.data(),rnsName.data()); - // see if we need to create a new member - found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace - ((mnd==0 && rnd==0 && mfd!=0 && // no external reference and - mfd->absFilePath()==root->fileName // prototype in the same file - ) - ); - // otherwise, allow a duplicate global member with the same argument list - if (!found && gd && gd==md->getGroupDef() && nsName==rnsName) + if ( + matchArguments2(md->getOuterScope(),mfd,mdAl, + rnd ? rnd : Doxygen::globalScope,rfd,root->argList, + FALSE) && + sameNumTemplateArgs && + matchingReturnTypes && + !staticsInDifferentFiles + ) { - // member is already in the group, so we don't want to add it again. - found=TRUE; - } + GroupDef *gd=0; + if (root->groups->getFirst() && !root->groups->getFirst()->groupname.isEmpty()) + { + gd = Doxygen::groupSDict->find(root->groups->getFirst()->groupname); + } + //printf("match!\n"); + //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,nsName.data(),rnsName.data()); + // see if we need to create a new member + found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace + ((mnd==0 && rnd==0 && mfd!=0 && // no external reference and + mfd->absFilePath()==root->fileName // prototype in the same file + ) + ); + // otherwise, allow a duplicate global member with the same argument list + if (!found && gd && gd==md->getGroupDef() && nsName==rnsName) + { + // member is already in the group, so we don't want to add it again. + found=TRUE; + } - //printf("combining function with prototype found=%d in namespace %s\n", - // found,nsName.data()); + //printf("combining function with prototype found=%d in namespace %s\n", + // found,nsName.data()); - if (found) - { - // merge argument lists - mergeArguments(mdAl,root->argList,!root->doc.isEmpty()); - // merge documentation - if (md->documentation().isEmpty() && !root->doc.isEmpty()) + if (found) { - ArgumentList *argList = new ArgumentList; - stringToArgumentList(root->args,argList); - if (root->proto) + // merge argument lists + mergeArguments(mdAl,root->argList,!root->doc.isEmpty()); + // merge documentation + if (md->documentation().isEmpty() && !root->doc.isEmpty()) { - //printf("setDeclArgumentList to %p\n",argList); - md->setDeclArgumentList(argList); + ArgumentList *argList = new ArgumentList; + stringToArgumentList(root->args,argList); + if (root->proto) + { + //printf("setDeclArgumentList to %p\n",argList); + md->setDeclArgumentList(argList); + } + else + { + md->setArgumentList(argList); + } } - else + + md->setDocumentation(root->doc,root->docFile,root->docLine); + md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); + md->setDocsForDefinition(!root->proto); + if (md->getStartBodyLine()==-1 && root->bodyLine!=-1) { - md->setArgumentList(argList); + md->setBodySegment(root->bodyLine,root->endBodyLine); + md->setBodyDef(rfd); } - } - md->setDocumentation(root->doc,root->docFile,root->docLine); - md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setDocsForDefinition(!root->proto); - if (md->getStartBodyLine()==-1 && root->bodyLine!=-1) - { - md->setBodySegment(root->bodyLine,root->endBodyLine); - md->setBodyDef(rfd); - } - - if (md->briefDescription().isEmpty() && !root->brief.isEmpty()) - { - md->setArgsString(root->args); - } - md->setBriefDescription(root->brief,root->briefFile,root->briefLine); + if (md->briefDescription().isEmpty() && !root->brief.isEmpty()) + { + md->setArgsString(root->args); + } + md->setBriefDescription(root->brief,root->briefFile,root->briefLine); - md->addSectionsToDefinition(root->anchors); + md->addSectionsToDefinition(root->anchors); - md->enableCallGraph(md->hasCallGraph() || root->callGraph); - md->enableCallerGraph(md->hasCallerGraph() || root->callerGraph); - md->enableReferencedByRelation(md->hasReferencedByRelation() || root->referencedByRelation); - md->enableReferencesRelation(md->hasReferencesRelation() || root->referencesRelation); + md->enableCallGraph(md->hasCallGraph() || root->callGraph); + md->enableCallerGraph(md->hasCallerGraph() || root->callerGraph); + md->enableReferencedByRelation(md->hasReferencedByRelation() || root->referencedByRelation); + md->enableReferencesRelation(md->hasReferencesRelation() || root->referencesRelation); - // merge ingroup specifiers - if (md->getGroupDef()==0 && root->groups->getFirst()!=0) - { - addMemberToGroups(root,md); - } - else if (md->getGroupDef()!=0 && root->groups->count()==0) - { - //printf("existing member is grouped, new member not\n"); - root->groups->append(new Grouping(md->getGroupDef()->name(), md->getGroupPri())); - } - else if (md->getGroupDef()!=0 && root->groups->getFirst()!=0) - { - //printf("both members are grouped\n"); - } + // merge ingroup specifiers + if (md->getGroupDef()==0 && root->groups->getFirst()!=0) + { + addMemberToGroups(root,md); + } + else if (md->getGroupDef()!=0 && root->groups->count()==0) + { + //printf("existing member is grouped, new member not\n"); + root->groups->append(new Grouping(md->getGroupDef()->name(), md->getGroupPri())); + } + else if (md->getGroupDef()!=0 && root->groups->getFirst()!=0) + { + //printf("both members are grouped\n"); + } - // if md is a declaration and root is the corresponding - // definition, then turn md into a definition. - if (md->isPrototype() && !root->proto) - { - md->setPrototype(FALSE); + // if md is a declaration and root is the corresponding + // definition, then turn md into a definition. + if (md->isPrototype() && !root->proto) + { + md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn()); + md->setPrototype(FALSE,root->fileName,root->startLine,root->startColumn); + } + // if md is already the definition, then add the declaration info + else if (!md->isPrototype() && root->proto) + { + md->setDeclFile(root->fileName,root->startLine,root->startColumn); + } } } } @@ -3760,19 +3749,19 @@ static void buildFunctionList(EntryNav *rootNav) if (!found) /* global function is unique with respect to the file */ { Debug::print(Debug::Functions,0," --> new function %s found!\n",qPrint(rname)); - //printf("New function type=`%s' name=`%s' args=`%s' bodyLine=%d\n", + //printf("New function type='%s' name='%s' args='%s' bodyLine=%d\n", // root->type.data(),rname.data(),root->args.data(),root->bodyLine); // new global function ArgumentList *tArgList = root->tArgLists ? root->tArgLists->getLast() : 0; QCString name=removeRedundantWhiteSpace(rname); - md=new MemberDef( + md=createMemberDef( root->fileName,root->startLine,root->startColumn, root->type,name,root->args,root->exception, root->protection,root->virt,root->stat,Member, MemberType_Function,tArgList,root->argList,root->metaData); - md->setTagInfo(rootNav->tagInfo()); + md->setTagInfo(root->tagInfo); md->setLanguage(root->lang); md->setId(root->id); //md->setDefFile(root->fileName); @@ -3780,12 +3769,12 @@ static void buildFunctionList(EntryNav *rootNav) md->setDocumentation(root->doc,root->docFile,root->docLine); md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setPrototype(root->proto); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); md->setDocsForDefinition(!root->proto); md->setTypeConstraints(root->typeConstr); //md->setBody(root->body); md->setBodySegment(root->bodyLine,root->endBodyLine); - FileDef *fd=rootNav->fileDef(); + FileDef *fd=root->fileDef(); md->setBodyDef(fd); md->addSectionsToDefinition(root->anchors); md->setMemberSpecifiers(root->spec); @@ -3793,10 +3782,10 @@ static void buildFunctionList(EntryNav *rootNav) // see if the function is inside a namespace that was not part of // the name already (in that case nd should be non-zero already) - if (nd==0 && rootNav->parent()->section() == Entry::NAMESPACE_SEC ) + if (nd==0 && root->parent()->section == Entry::NAMESPACE_SEC ) { - //QCString nscope=removeAnonymousScopes(rootNav->parent()->name()); - QCString nscope=rootNav->parent()->name(); + //QCString nscope=removeAnonymousScopes(root->parent()->name); + QCString nscope=root->parent()->name; if (!nscope.isEmpty()) { nd = getResolvedNamespace(nscope); @@ -3838,10 +3827,10 @@ static void buildFunctionList(EntryNav *rootNav) } Debug::print(Debug::Functions,0, " Global Function:\n" - " `%s' `%s'::`%s' `%s' proto=%d\n" - " def=`%s'\n", + " '%s' '%s'::'%s' '%s' proto=%d\n" + " def='%s'\n", qPrint(root->type), - qPrint(rootNav->parent()->name()), + qPrint(root->parent()->name), qPrint(rname), qPrint(root->args), root->proto, @@ -3889,14 +3878,14 @@ static void buildFunctionList(EntryNav *rootNav) if (root->relatesType == Simple) // if this is a relatesalso command, // allow find Member to pick it up { - rootNav->changeSection(Entry::EMPTY_SEC); // Otherwise we have finished - // with this entry. + root->changeSection(Entry::EMPTY_SEC); // Otherwise we have finished + // with this entry. } } else { - FileDef *fd=rootNav->fileDef(); + FileDef *fd=root->fileDef(); if (fd) { // add member to the file (we do this even if we have already @@ -3905,7 +3894,7 @@ static void buildFunctionList(EntryNav *rootNav) } } - //printf("unrelated function %d `%s' `%s' `%s'\n", + //printf("unrelated function %d '%s' '%s' '%s'\n", // root->parent->section,root->type.data(),rname.data(),root->args.data()); } else @@ -3919,10 +3908,8 @@ static void buildFunctionList(EntryNav *rootNav) "Illegal member name found." ); } - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(buildFunctionList,rootNav); + RECURSE_ENTRYTREE(buildFunctionList,root); } //---------------------------------------------------------------------- @@ -3934,7 +3921,7 @@ static void findFriends() MemberName *fn; for (;(fn=fnli.current());++fnli) // for each global function name { - //printf("Function name=`%s'\n",fn->memberName()); + //printf("Function name='%s'\n",fn->memberName()); MemberName *mn; if ((mn=Doxygen::memberNameSDict->find(fn->memberName()))) { // there are members with the same name @@ -3943,24 +3930,27 @@ static void findFriends() MemberDef *fmd; for (;(fmd=fni.current());++fni) // for each function with that name { + const MemberDef *cfmd = const_cast<const MemberDef*>(fmd); MemberNameIterator mni(*mn); MemberDef *mmd; for (;(mmd=mni.current());++mni) // for each member with that name { + const MemberDef *cmmd = const_cast<const MemberDef*>(mmd); //printf("Checking for matching arguments // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n", // mmd->isRelated(),mmd->isFriend(),mmd->isFunction()); - ArgumentList *mmdAl = mmd->argumentList(); - ArgumentList *fmdAl = fmd->argumentList(); - if ((mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) && - matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), mmdAl, - fmd->getOuterScope(), fmd->getFileDef(), fmdAl, + if ((cmmd->isFriend() || (cmmd->isRelated() && cmmd->isFunction())) && + !fmd->isAlias() && !mmd->isAlias() && + matchArguments2(cmmd->getOuterScope(), cmmd->getFileDef(), cmmd->argumentList(), + cfmd->getOuterScope(), cfmd->getFileDef(), cfmd->argumentList(), TRUE ) ) // if the member is related and the arguments match then the // function is actually a friend. { + ArgumentList *mmdAl = mmd->argumentList(); + ArgumentList *fmdAl = fmd->argumentList(); mergeArguments(mmdAl,fmdAl); if (!fmd->documentation().isEmpty()) { @@ -4041,7 +4031,10 @@ static void transferFunctionDocumentation() MemberNameIterator mni2(*mn); for (;(mdef=mni2.current());++mni2) { - combineDeclarationAndDefinition(mdec,mdef); + if (!mdec->isAlias() && !mdef->isAlias()) + { + combineDeclarationAndDefinition(mdec,mdef); + } } } } @@ -4155,7 +4148,7 @@ static void transferRelatedFunctionDocumentation() /* find a matching function declaration and definition for this function */ for (mni.toFirst();(md=mni.current());++mni) // for each global function { - //printf(" Function `%s'\n",md->name().data()); + //printf(" Function '%s'\n",md->name().data()); MemberName *rmn; if ((rmn=Doxygen::memberNameSDict->find(md->name()))) // check if there is a member with the same name { @@ -4164,17 +4157,16 @@ static void transferRelatedFunctionDocumentation() MemberNameIterator rmni(*rmn); for (rmni.toFirst();(rmd=rmni.current());++rmni) // for each member with the same name { - ArgumentList *mdAl = md->argumentList(); - ArgumentList *rmdAl = rmd->argumentList(); - //printf(" Member found: related=`%d'\n",rmd->isRelated()); + //printf(" Member found: related='%d'\n",rmd->isRelated()); if ((rmd->isRelated() || rmd->isForeign()) && // related function - matchArguments2( md->getOuterScope(), md->getFileDef(), mdAl, - rmd->getOuterScope(),rmd->getFileDef(),rmdAl, + !md->isAlias() && !rmd->isAlias() && + matchArguments2( md->getOuterScope(), md->getFileDef(), md->argumentList(), + rmd->getOuterScope(),rmd->getFileDef(),rmd->argumentList(), TRUE ) ) { - //printf(" Found related member `%s'\n",md->name().data()); + //printf(" Found related member '%s'\n",md->name().data()); if (rmd->relatedAlso()) md->setRelatedAlso(rmd->relatedAlso()); else if (rmd->isForeign()) @@ -4238,11 +4230,11 @@ static ClassDef *findClassWithinClassContext(Definition *context,ClassDef *cd,co FileDef *fd=cd->getFileDef(); if (context && cd!=context) { - result = getResolvedClass(context,0,name,0,0,TRUE,TRUE); + result = const_cast<ClassDef*>(getResolvedClass(context,0,name,0,0,TRUE,TRUE)); } if (result==0) { - result = getResolvedClass(cd,fd,name,0,0,TRUE,TRUE); + result = const_cast<ClassDef*>(getResolvedClass(cd,fd,name,0,0,TRUE,TRUE)); } if (result==0) // try direct class, needed for namespaced classes imported via tag files (see bug624095) { @@ -4265,7 +4257,7 @@ static ClassDef *findClassWithinClassContext(Definition *context,ClassDef *cd,co } -static void findUsedClassesForClass(EntryNav *rootNav, +static void findUsedClassesForClass(Entry *root, Definition *context, ClassDef *masterCd, ClassDef *instanceCd, @@ -4274,7 +4266,7 @@ static void findUsedClassesForClass(EntryNav *rootNav, QDict<int> *templateNames=0 ) { - masterCd->visited=TRUE; + masterCd->setVisited(TRUE); ArgumentList *formalArgs = masterCd->templateArguments(); if (masterCd->memberNameInfoSDict()) { @@ -4307,10 +4299,10 @@ static void findUsedClassesForClass(EntryNav *rootNav, } //printf(" template substitution gives=%s\n",type.data()); - while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec,rootNav->lang())!=-1) + while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec,root->lang)!=-1) { // find the type (if any) that matches usedClassName - ClassDef *typeCd = getResolvedClass(masterCd, + const ClassDef *typeCd = getResolvedClass(masterCd, masterCd->getFileDef(), usedClassName, 0,0, @@ -4342,7 +4334,7 @@ static void findUsedClassesForClass(EntryNav *rootNav, delTempNames=TRUE; } BaseInfo bi(usedName,Public,Normal); - findClassRelation(rootNav,context,instanceCd,&bi,templateNames,TemplateInstances,isArtificial); + findClassRelation(root,context,instanceCd,&bi,templateNames,TemplateInstances,isArtificial); if (masterCd->templateArguments()) { @@ -4354,12 +4346,12 @@ static void findUsedClassesForClass(EntryNav *rootNav, if (arg->name==usedName) // type is a template argument { found=TRUE; - Debug::print(Debug::Classes,0," New used class `%s'\n", qPrint(usedName)); + Debug::print(Debug::Classes,0," New used class '%s'\n", qPrint(usedName)); ClassDef *usedCd = Doxygen::hiddenClasses->find(usedName); if (usedCd==0) { - usedCd = new ClassDef( + usedCd = createClassDef( masterCd->getDefFileName(),masterCd->getDefLine(), masterCd->getDefColumn(), usedName, @@ -4371,7 +4363,7 @@ static void findUsedClassesForClass(EntryNav *rootNav, Doxygen::hiddenClasses->append(usedName,usedCd); } if (isArtificial) usedCd->setArtificial(TRUE); - Debug::print(Debug::Classes,0," Adding used class `%s' (1)\n", qPrint(usedCd->name())); + Debug::print(Debug::Classes,0," Adding used class '%s' (1)\n", qPrint(usedCd->name())); instanceCd->addUsedClass(usedCd,md->name(),md->protection()); usedCd->addUsedByClass(instanceCd,md->name(),md->protection()); } @@ -4387,7 +4379,7 @@ static void findUsedClassesForClass(EntryNav *rootNav, if (usedCd) { found=TRUE; - Debug::print(Debug::Classes,0," Adding used class `%s' (2)\n", qPrint(usedCd->name())); + Debug::print(Debug::Classes,0," Adding used class '%s' (2)\n", qPrint(usedCd->name())); instanceCd->addUsedClass(usedCd,md->name(),md->protection()); // class exists usedCd->addUsedByClass(instanceCd,md->name(),md->protection()); } @@ -4407,8 +4399,8 @@ static void findUsedClassesForClass(EntryNav *rootNav, { type+=md->argsString(); } - Debug::print(Debug::Classes,0," New undocumented used class `%s'\n", qPrint(type)); - usedCd = new ClassDef( + Debug::print(Debug::Classes,0," New undocumented used class '%s'\n", qPrint(type)); + usedCd = createClassDef( masterCd->getDefFileName(),masterCd->getDefLine(), masterCd->getDefColumn(), type,ClassDef::Class); @@ -4419,7 +4411,7 @@ static void findUsedClassesForClass(EntryNav *rootNav, if (usedCd) { if (isArtificial) usedCd->setArtificial(TRUE); - Debug::print(Debug::Classes,0," Adding used class `%s' (3)\n", qPrint(usedCd->name())); + Debug::print(Debug::Classes,0," Adding used class '%s' (3)\n", qPrint(usedCd->name())); instanceCd->addUsedClass(usedCd,md->name(),md->protection()); usedCd->addUsedByClass(instanceCd,md->name(),md->protection()); } @@ -4435,7 +4427,7 @@ static void findUsedClassesForClass(EntryNav *rootNav, } static void findBaseClassesForClass( - EntryNav *rootNav, + Entry *root, Definition *context, ClassDef *masterCd, ClassDef *instanceCd, @@ -4445,9 +4437,8 @@ static void findBaseClassesForClass( QDict<int> *templateNames=0 ) { - Entry *root = rootNav->entry(); //if (masterCd->visited) return; - masterCd->visited=TRUE; + masterCd->setVisited(TRUE); // The base class could ofcouse also be a non-nested class ArgumentList *formalArgs = masterCd->templateArguments(); QListIterator<BaseInfo> bii(*root->extends); @@ -4472,7 +4463,7 @@ static void findBaseClassesForClass( if (mode==DocumentedOnly) { // find a documented base class in the correct scope - if (!findClassRelation(rootNav,context,instanceCd,&tbi,templateNames,DocumentedOnly,isArtificial)) + if (!findClassRelation(root,context,instanceCd,&tbi,templateNames,DocumentedOnly,isArtificial)) { // 1.8.2: decided to show inheritance relations even if not documented, // we do make them artificial, so they do not appear in the index @@ -4480,13 +4471,13 @@ static void findBaseClassesForClass( bool b = Config_getBool(HIDE_UNDOC_RELATIONS) ? TRUE : isArtificial; //{ // no documented base class -> try to find an undocumented one - findClassRelation(rootNav,context,instanceCd,&tbi,templateNames,Undocumented,b); + findClassRelation(root,context,instanceCd,&tbi,templateNames,Undocumented,b); //} } } else if (mode==TemplateInstances) { - findClassRelation(rootNav,context,instanceCd,&tbi,templateNames,TemplateInstances,isArtificial); + findClassRelation(root,context,instanceCd,&tbi,templateNames,TemplateInstances,isArtificial); } if (delTempNames) { @@ -4538,34 +4529,19 @@ static bool findTemplateInstanceRelation(Entry *root, // search for new template instances caused by base classes of // instanceClass - EntryNav *templateRootNav = g_classEntries.find(templateClass->name()); - if (templateRootNav) + Entry *templateRoot = g_classEntries.find(templateClass->name()); + if (templateRoot) { - bool unloadNeeded=FALSE; - Entry *templateRoot = templateRootNav->entry(); - if (templateRoot==0) // not yet loaded - { - templateRootNav->loadEntry(g_storage); - templateRoot = templateRootNav->entry(); - ASSERT(templateRoot!=0); // now it should really be loaded - unloadNeeded=TRUE; - } - Debug::print(Debug::Classes,0," template root found %s templSpec=%s!\n", qPrint(templateRoot->name),qPrint(templSpec)); ArgumentList *templArgs = new ArgumentList; stringToArgumentList(templSpec,templArgs); - findBaseClassesForClass(templateRootNav,context,templateClass,instanceClass, + findBaseClassesForClass(templateRoot,context,templateClass,instanceClass, TemplateInstances,isArtificial,templArgs,templateNames); - findUsedClassesForClass(templateRootNav,context,templateClass,instanceClass, + findUsedClassesForClass(templateRoot,context,templateClass,instanceClass, isArtificial,templArgs,templateNames); delete templArgs; - - if (unloadNeeded) // still cleanup to do - { - templateRootNav->releaseEntry(); - } } else { @@ -4675,7 +4651,7 @@ static int findEndOfTemplate(const QCString &s,int startPos) } static bool findClassRelation( - EntryNav *rootNav, + Entry *root, Definition *context, ClassDef *cd, BaseInfo *bi, @@ -4697,27 +4673,25 @@ static bool findClassRelation( //} //printf("\n"); - Entry *root = rootNav->entry(); - QCString biName=bi->name; bool explicitGlobalScope=FALSE; - //printf("findClassRelation: biName=`%s'\n",biName.data()); + //printf("findClassRelation: biName='%s'\n",biName.data()); if (biName.left(2)=="::") // explicit global scope { biName=biName.right(biName.length()-2); explicitGlobalScope=TRUE; } - EntryNav *parentNode=rootNav->parent(); + Entry *parentNode=root->parent(); bool lastParent=FALSE; do // for each parent scope, starting with the largest scope // (in case of nested classes) { - QCString scopeName= parentNode ? parentNode->name().data() : ""; + QCString scopeName= parentNode ? parentNode->name.data() : ""; int scopeOffset=explicitGlobalScope ? 0 : scopeName.length(); do // try all parent scope prefixes, starting with the largest scope { - //printf("scopePrefix=`%s' biName=`%s'\n", + //printf("scopePrefix='%s' biName='%s'\n", // scopeName.left(scopeOffset).data(),biName.data()); QCString baseClassName=biName; @@ -4729,19 +4703,20 @@ static bool findClassRelation( //baseClassName=stripTemplateSpecifiersFromScope // (removeRedundantWhiteSpace(baseClassName),TRUE, // &stripped); - MemberDef *baseClassTypeDef=0; + const MemberDef *baseClassTypeDef=0; QCString templSpec; - ClassDef *baseClass=getResolvedClass(explicitGlobalScope ? Doxygen::globalScope : context, + ClassDef *baseClass=const_cast<ClassDef*>( + getResolvedClass(explicitGlobalScope ? Doxygen::globalScope : context, cd->getFileDef(), baseClassName, &baseClassTypeDef, &templSpec, mode==Undocumented, TRUE - ); + )); //printf("baseClassName=%s baseClass=%p cd=%p explicitGlobalScope=%d\n", // baseClassName.data(),baseClass,cd,explicitGlobalScope); - //printf(" scope=`%s' baseClassName=`%s' baseClass=%s templSpec=%s\n", + //printf(" scope='%s' baseClassName='%s' baseClass=%s templSpec=%s\n", // cd ? cd->name().data():"<none>", // baseClassName.data(), // baseClass?baseClass->name().data():"<none>", @@ -4752,18 +4727,18 @@ static bool findClassRelation( // ) // Check for base class with the same name. // // If found then look in the outer scope for a match // // and prevent recursion. - if (!isRecursiveBaseClass(rootNav->name(),baseClassName) + if (!isRecursiveBaseClass(root->name,baseClassName) || explicitGlobalScope // sadly isRecursiveBaseClass always true for UNO IDL ifc/svc members // (i.e. this is needed for addInterfaceOrServiceToServiceOrSingleton) - || (rootNav->lang()==SrcLangExt_IDL && - (rootNav->section()==Entry::EXPORTED_INTERFACE_SEC || - rootNav->section()==Entry::INCLUDED_SERVICE_SEC))) + || (root->lang==SrcLangExt_IDL && + (root->section==Entry::EXPORTED_INTERFACE_SEC || + root->section==Entry::INCLUDED_SERVICE_SEC))) { Debug::print( Debug::Classes,0," class relation %s inherited/used by %s found (%s and %s) templSpec='%s'\n", qPrint(baseClassName), - qPrint(rootNav->name()), + qPrint(root->name), (bi->prot==Private)?"private":((bi->prot==Protected)?"protected":"public"), (bi->virt==Normal)?"normal":"virtual", qPrint(templSpec) @@ -4789,14 +4764,15 @@ static bool findClassRelation( { templSpec=removeRedundantWhiteSpace(baseClassName.mid(i,e-i)); baseClassName=baseClassName.left(i)+baseClassName.right(baseClassName.length()-e); - baseClass=getResolvedClass(explicitGlobalScope ? Doxygen::globalScope : context, - cd->getFileDef(), - baseClassName, - &baseClassTypeDef, - 0, //&templSpec, - mode==Undocumented, - TRUE - ); + baseClass=const_cast<ClassDef*>( + getResolvedClass(explicitGlobalScope ? Doxygen::globalScope : context, + cd->getFileDef(), + baseClassName, + &baseClassTypeDef, + 0, //&templSpec, + mode==Undocumented, + TRUE + )); //printf("baseClass=%p -> baseClass=%s templSpec=%s\n", // baseClass,baseClassName.data(),templSpec.data()); } @@ -4825,14 +4801,15 @@ static bool findClassRelation( QCString tmpTemplSpec; // replace any namespace aliases replaceNamespaceAliases(baseClassName,si); - baseClass=getResolvedClass(explicitGlobalScope ? Doxygen::globalScope : context, + baseClass=const_cast<ClassDef*>( + getResolvedClass(explicitGlobalScope ? Doxygen::globalScope : context, cd->getFileDef(), baseClassName, &baseClassTypeDef, &tmpTemplSpec, mode==Undocumented, TRUE - ); + )); found=baseClass!=0 && baseClass!=cd; if (found) templSpec = tmpTemplSpec; } @@ -4872,7 +4849,7 @@ static bool findClassRelation( //printf("3. found=%d\n",found); if (found) { - Debug::print(Debug::Classes,0," Documented base class `%s' templSpec=%s\n",qPrint(biName),qPrint(templSpec)); + Debug::print(Debug::Classes,0," Documented base class '%s' templSpec=%s\n",qPrint(biName),qPrint(templSpec)); // add base class to this class // if templSpec is not empty then we should "instantiate" @@ -4927,7 +4904,7 @@ static bool findClassRelation( else if (mode==Undocumented && (scopeOffset==0 || isATemplateArgument)) { Debug::print(Debug::Classes,0, - " New undocumented base class `%s' baseClassName=%s templSpec=%s isArtificial=%d\n", + " New undocumented base class '%s' baseClassName=%s templSpec=%s isArtificial=%d\n", qPrint(biName),qPrint(baseClassName),qPrint(templSpec),isArtificial ); baseClass=0; @@ -4936,7 +4913,7 @@ static bool findClassRelation( baseClass=Doxygen::hiddenClasses->find(baseClassName); if (baseClass==0) { - baseClass=new ClassDef(root->fileName,root->startLine,root->startColumn, + baseClass=createClassDef(root->fileName,root->startLine,root->startColumn, baseClassName, ClassDef::Class); Doxygen::hiddenClasses->append(baseClassName,baseClass); @@ -4951,7 +4928,7 @@ static bool findClassRelation( // baseClassName.data(),baseClass,biName.data(),templSpec.data()); if (baseClass==0) { - baseClass=new ClassDef(root->fileName,root->startLine,root->startColumn, + baseClass=createClassDef(root->fileName,root->startLine,root->startColumn, baseClassName, ClassDef::Class); Doxygen::classSDict->append(baseClassName,baseClass); @@ -4960,7 +4937,7 @@ static bool findClassRelation( int si = baseClassName.findRev("::"); if (si!=-1) // class is nested { - Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),0,rootNav->tagInfo()); + Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),0,root->tagInfo); if (sd==0 || sd==Doxygen::globalScope) // outer scope not found { baseClass->setArtificial(TRUE); // see bug678139 @@ -4977,7 +4954,7 @@ static bool findClassRelation( // add this class as super class to the base class baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec); // the undocumented base was found in this file - baseClass->insertUsedFile(rootNav->fileDef()); + baseClass->insertUsedFile(root->fileDef()); baseClass->setOuterScope(Doxygen::globalScope); if (baseClassName.right(2)=="-p") { @@ -4987,7 +4964,7 @@ static bool findClassRelation( } else { - Debug::print(Debug::Classes,0," Base class `%s' not found\n",qPrint(biName)); + Debug::print(Debug::Classes,0," Base class '%s' not found\n",qPrint(biName)); } } else @@ -5012,7 +4989,7 @@ static bool findClassRelation( { scopeOffset=0; } - //printf("new scopeOffset=`%d'",scopeOffset); + //printf("new scopeOffset='%d'",scopeOffset); } while (scopeOffset>=0); if (parentNode==0) @@ -5031,22 +5008,19 @@ static bool findClassRelation( //---------------------------------------------------------------------- // Computes the base and super classes for each class in the tree -static bool isClassSection(EntryNav *rootNav) +static bool isClassSection(Entry *root) { - if ( !rootNav->name().isEmpty() ) + if ( !root->name.isEmpty() ) { - if (rootNav->section() & Entry::COMPOUND_MASK) + if (root->section & Entry::COMPOUND_MASK) // is it a compound (class, struct, union, interface ...) { return TRUE; } - else if (rootNav->section() & Entry::COMPOUNDDOC_MASK) + else if (root->section & Entry::COMPOUNDDOC_MASK) // is it a documentation block with inheritance info. { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); bool extends = root->extends->count()>0; - rootNav->releaseEntry(); if (extends) return TRUE; } } @@ -5056,22 +5030,22 @@ static bool isClassSection(EntryNav *rootNav) /*! Builds a dictionary of all entry nodes in the tree starting with \a root */ -static void findClassEntries(EntryNav *rootNav) +static void findClassEntries(Entry *root) { - if (isClassSection(rootNav)) + if (isClassSection(root)) { - g_classEntries.insert(rootNav->name(),rootNav); + g_classEntries.insert(root->name,root); } - RECURSE_ENTRYTREE(findClassEntries,rootNav); + RECURSE_ENTRYTREE(findClassEntries,root); } -static QCString extractClassName(EntryNav *rootNav) +static QCString extractClassName(Entry *root) { // strip any anonymous scopes first - QCString bName=stripAnonymousNamespaceScope(rootNav->name()); + QCString bName=stripAnonymousNamespaceScope(root->name); bName=stripTemplateSpecifiersFromScope(bName); int i; - if ((rootNav->lang()==SrcLangExt_CSharp || rootNav->lang()==SrcLangExt_Java) && + if ((root->lang==SrcLangExt_CSharp || root->lang==SrcLangExt_Java) && (i=bName.find('<'))!=-1) { // a Java/C# generic class looks like a C++ specialization, so we need to strip the @@ -5089,20 +5063,18 @@ static QCString extractClassName(EntryNav *rootNav) static void findInheritedTemplateInstances() { ClassSDict::Iterator cli(*Doxygen::classSDict); - for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE; - QDictIterator<EntryNav> edi(g_classEntries); - EntryNav *rootNav; - for (;(rootNav=edi.current());++edi) + for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); + QDictIterator<Entry> edi(g_classEntries); + Entry *root; + for (;(root=edi.current());++edi) { ClassDef *cd; - QCString bName = extractClassName(rootNav); + QCString bName = extractClassName(root); Debug::print(Debug::Classes,0," Inheritance: Class %s : \n",qPrint(bName)); if ((cd=getClass(bName))) { - rootNav->loadEntry(g_storage); //printf("Class %s %d\n",cd->name().data(),root->extends->count()); - findBaseClassesForClass(rootNav,cd,cd,cd,TemplateInstances,FALSE); - rootNav->releaseEntry(); + findBaseClassesForClass(root,cd,cd,cd,TemplateInstances,FALSE); } } } @@ -5110,20 +5082,18 @@ static void findInheritedTemplateInstances() static void findUsedTemplateInstances() { ClassSDict::Iterator cli(*Doxygen::classSDict); - for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE; - QDictIterator<EntryNav> edi(g_classEntries); - EntryNav *rootNav; - for (;(rootNav=edi.current());++edi) + for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); + QDictIterator<Entry> edi(g_classEntries); + Entry *root; + for (;(root=edi.current());++edi) { ClassDef *cd; - QCString bName = extractClassName(rootNav); + QCString bName = extractClassName(root); Debug::print(Debug::Classes,0," Usage: Class %s : \n",qPrint(bName)); if ((cd=getClass(bName))) { - rootNav->loadEntry(g_storage); - findUsedClassesForClass(rootNav,cd,cd,cd,TRUE); + findUsedClassesForClass(root,cd,cd,cd,TRUE); cd->addTypeConstraints(); - rootNav->releaseEntry(); } } } @@ -5131,20 +5101,18 @@ static void findUsedTemplateInstances() static void computeClassRelations() { ClassSDict::Iterator cli(*Doxygen::classSDict); - for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE; - QDictIterator<EntryNav> edi(g_classEntries); - EntryNav *rootNav; - for (;(rootNav=edi.current());++edi) + for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); + QDictIterator<Entry> edi(g_classEntries); + Entry *root; + for (;(root=edi.current());++edi) { ClassDef *cd; - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - QCString bName = extractClassName(rootNav); + QCString bName = extractClassName(root); Debug::print(Debug::Classes,0," Relations: Class %s : \n",qPrint(bName)); if ((cd=getClass(bName))) { - findBaseClassesForClass(rootNav,cd,cd,cd,DocumentedOnly,FALSE); + findBaseClassesForClass(root,cd,cd,cd,DocumentedOnly,FALSE); } int numMembers = cd && cd->memberNameInfoSDict() ? cd->memberNameInfoSDict()->count() : 0; if ((cd==0 || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && @@ -5162,20 +5130,15 @@ static void computeClassRelations() root->name.data() ); } - - rootNav->releaseEntry(); } } static void computeTemplateClassRelations() { - QDictIterator<EntryNav> edi(g_classEntries); - EntryNav *rootNav; - for (;(rootNav=edi.current());++edi) + QDictIterator<Entry> edi(g_classEntries); + Entry *root; + for (;(root=edi.current());++edi) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - QCString bName=stripAnonymousNamespaceScope(root->name); bName=stripTemplateSpecifiersFromScope(bName); ClassDef *cd=getClass(bName); @@ -5230,10 +5193,10 @@ static void computeTemplateClassRelations() tbi.name = substituteTemplateArgumentsInString(bi->name,tl,templArgs); // find a documented base class in the correct scope - if (!findClassRelation(rootNav,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE)) + if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE)) { // no documented base class -> try to find an undocumented one - findClassRelation(rootNav,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE); + findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE); } delete actualTemplateNames; } @@ -5241,8 +5204,6 @@ static void computeTemplateClassRelations() delete templArgs; } // class has no base classes } - - rootNav->releaseEntry(); } } @@ -5286,33 +5247,14 @@ static void computeMemberReferences() static void addListReferences() { - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - MemberName *mn=0; - for (mnli.toFirst();(mn=mnli.current());++mnli) - { - MemberNameIterator mni(*mn); - MemberDef *md=0; - for (mni.toFirst();(md=mni.current());++mni) - { - md->visited=FALSE; - } - } - MemberNameSDict::Iterator fmnli(*Doxygen::functionNameSDict); - for (fmnli.toFirst();(mn=fmnli.current());++fmnli) - { - MemberNameIterator mni(*mn); - MemberDef *md=0; - for (mni.toFirst();(md=mni.current());++mni) - { - md->visited=FALSE; - } - } - ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { - cd->addListReferences(); + if (!cd->isAlias()) + { + cd->addListReferences(); + } } FileNameListIterator fnli(*Doxygen::inputNameList); @@ -5331,7 +5273,10 @@ static void addListReferences() NamespaceDef *nd=0; for (nli.toFirst();(nd=nli.current());++nli) { - nd->addListReferences(); + if (!nd->isAlias()) + { + nd->addListReferences(); + } } GroupSDict::Iterator gli(*Doxygen::groupSDict); @@ -5389,19 +5334,18 @@ static void generateXRefPages() } //---------------------------------------------------------------------- -// Copy the documentation in entry `root' to member definition `md' and -// set the function declaration of the member to `funcDecl'. If the boolean +// Copy the documentation in entry 'root' to member definition 'md' and +// set the function declaration of the member to 'funcDecl'. If the boolean // over_load is set the standard overload text is added. -static void addMemberDocs(EntryNav *rootNav, +static void addMemberDocs(Entry *root, MemberDef *md, const char *funcDecl, ArgumentList *al, bool over_load, NamespaceSDict * ) { - Entry *root = rootNav->entry(); - //printf("addMemberDocs: `%s'::`%s' `%s' funcDecl=`%s' mSpec=%d\n", + //printf("addMemberDocs: '%s'::'%s' '%s' funcDecl='%s' mSpec=%d\n", // root->parent->name.data(),md->name().data(),md->argsString(),funcDecl,root->spec); QCString fDecl=funcDecl; // strip extern specifier @@ -5411,8 +5355,8 @@ static void addMemberDocs(EntryNav *rootNav, md->enableCallerGraph(root->callerGraph); md->enableReferencedByRelation(root->referencedByRelation); md->enableReferencesRelation(root->referencesRelation); - ClassDef *cd=md->getClassDef(); - NamespaceDef *nd=md->getNamespaceDef(); + ClassDef *cd=md->getClassDef(); + const NamespaceDef *nd=md->getNamespaceDef(); QCString fullName; if (cd) fullName = cd->name(); @@ -5421,7 +5365,7 @@ static void addMemberDocs(EntryNav *rootNav, if (!fullName.isEmpty()) fullName+="::"; fullName+=md->name(); - FileDef *rfd=rootNav->fileDef(); + FileDef *rfd=root->fileDef(); // TODO determine scope based on root not md Definition *rscope = md->getOuterScope(); @@ -5468,7 +5412,7 @@ static void addMemberDocs(EntryNav *rootNav, if ( (md->inbodyDocumentation().isEmpty() || - !rootNav->parent()->name().isEmpty() + !root->parent()->name.isEmpty() ) && !root->inbodyDocs.isEmpty() ) { @@ -5537,20 +5481,20 @@ static void addMemberDocs(EntryNav *rootNav, // find a class definition given the scope name and (optionally) a // template list specifier -static ClassDef *findClassDefinition(FileDef *fd,NamespaceDef *nd, +static const ClassDef *findClassDefinition(FileDef *fd,NamespaceDef *nd, const char *scopeName) { - ClassDef *tcd = getResolvedClass(nd,fd,scopeName,0,0,TRUE,TRUE); + const ClassDef *tcd = getResolvedClass(nd,fd,scopeName,0,0,TRUE,TRUE); return tcd; } //---------------------------------------------------------------------- -// Adds the documentation contained in `root' to a global function -// with name `name' and argument list `args' (for overloading) and -// function declaration `decl' to the corresponding member definition. +// Adds the documentation contained in 'root' to a global function +// with name 'name' and argument list 'args' (for overloading) and +// function declaration 'decl' to the corresponding member definition. -static bool findGlobalMember(EntryNav *rootNav, +static bool findGlobalMember(Entry *root, const QCString &namespaceName, const char *type, const char *name, @@ -5558,7 +5502,6 @@ static bool findGlobalMember(EntryNav *rootNav, const char *, const char *decl) { - Entry *root = rootNav->entry(); Debug::print(Debug::FindMembers,0, "2. findGlobalMember(namespace=%s,type=%s,name=%s,tempArg=%s,decl=%s)\n", qPrint(namespaceName),qPrint(type),qPrint(name),qPrint(tempArg),qPrint(decl)); @@ -5579,12 +5522,20 @@ static bool findGlobalMember(EntryNav *rootNav, bool found=FALSE; for (mni.toFirst();(md=mni.current()) && !found;++mni) { - NamespaceDef *nd=md->getNamespaceDef(); - - //printf("Namespace namespaceName=%s nd=%s\n", - // namespaceName.data(),nd ? nd->name().data() : "<none>"); + const NamespaceDef *nd=0; + if (md->isAlias() && md->getOuterScope() && + md->getOuterScope()->definitionType()==Definition::TypeNamespace) + { + nd = dynamic_cast<const NamespaceDef *>(md->getOuterScope()); + } + else + { + nd = md->getNamespaceDef(); + } + //const Definition *scope=md->getOuterScope(); + //md = md->resolveAlias(); - FileDef *fd=rootNav->fileDef(); + const FileDef *fd=root->fileDef(); //printf("File %s\n",fd ? fd->name().data() : "<none>"); NamespaceSDict *nl = fd ? fd->getUsedNamespaces() : 0; //SDict<Definition> *cl = fd ? fd->getUsedClasses() : 0; @@ -5596,20 +5547,20 @@ static bool findGlobalMember(EntryNav *rootNav, if ((namespaceName.isEmpty() && nd==0) || // not in a namespace (nd && nd->name()==namespaceName) || // or in the same namespace - viaUsingDirective // member in `using' namespace + viaUsingDirective // member in 'using' namespace ) { - Debug::print(Debug::FindMembers,0,"4. Try to add member `%s' to scope `%s'\n", + Debug::print(Debug::FindMembers,0,"4. Try to add member '%s' to scope '%s'\n", qPrint(md->name()),qPrint(namespaceName)); NamespaceDef *rnd = 0; if (!namespaceName.isEmpty()) rnd = Doxygen::namespaceSDict->find(namespaceName); - ArgumentList *mdAl = md->argumentList(); + const ArgumentList *mdAl = const_cast<const MemberDef *>(md)->argumentList(); bool matching= (mdAl==0 && root->argList->count()==0) || md->isVariable() || md->isTypedef() || /* in case of function pointers */ - matchArguments2(md->getOuterScope(),md->getFileDef(),mdAl, + matchArguments2(md->getOuterScope(),const_cast<const MemberDef *>(md)->getFileDef(),mdAl, rnd ? rnd : Doxygen::globalScope,fd,root->argList, FALSE); @@ -5618,7 +5569,7 @@ static bool findGlobalMember(EntryNav *rootNav, // different functions. if (matching && root->tArgLists) { - ArgumentList *mdTempl = md->templateArguments(); + const ArgumentList *mdTempl = md->templateArguments(); if (mdTempl) { if (root->tArgLists->getLast()->count()!=mdTempl->count()) @@ -5659,7 +5610,7 @@ static bool findGlobalMember(EntryNav *rootNav, if (matching) // add docs to the member { Debug::print(Debug::FindMembers,0,"5. Match found\n"); - addMemberDocs(rootNav,md,decl,root->argList,FALSE); + addMemberDocs(root,md->resolveAlias(),decl,root->argList,FALSE); found=TRUE; } } @@ -5678,7 +5629,7 @@ static bool findGlobalMember(EntryNav *rootNav, warnMsg+=" '"; warnMsg+=substitute(md->declaration(),"%","%%"); warnMsg+="' at line "+QCString().setNum(md->getDefLine())+ - " of file"+md->getDefFileName()+"\n"; + " of file "+md->getDefFileName()+"\n"; } } warn(root->fileName,root->startLine,warnMsg); @@ -5695,7 +5646,7 @@ static bool findGlobalMember(EntryNav *rootNav, ) { warn(root->fileName,root->startLine, - "documented symbol `%s' was not declared or defined.",decl + "documented symbol '%s' was not declared or defined.",decl ); } } @@ -5718,12 +5669,12 @@ static bool isSpecialization( return FALSE; } -static bool scopeIsTemplate(Definition *d) +static bool scopeIsTemplate(const Definition *d) { bool result=FALSE; if (d && d->definitionType()==Definition::TypeClass) { - result = ((ClassDef*)d)->templateArguments() || scopeIsTemplate(d->getOuterScope()); + result = (dynamic_cast<const ClassDef*>(d))->templateArguments() || scopeIsTemplate(d->getOuterScope()); } return result; } @@ -5869,16 +5820,14 @@ static void substituteTemplatesInArgList( * The boolean \a isFunc is a hint that indicates that this is a function * instead of a variable or typedef. */ -static void findMember(EntryNav *rootNav, +static void findMember(Entry *root, QCString funcDecl, bool overloaded, bool isFunc ) { - Entry *root = rootNav->entry(); - Debug::print(Debug::FindMembers,0, - "findMember(root=%p,funcDecl=`%s',related=`%s',overload=%d," + "findMember(root=%p,funcDecl='%s',related='%s',overload=%d," "isFunc=%d mGrpId=%d tArgList=%p (#=%d) " "spec=%lld lang=%x\n", root,qPrint(funcDecl),qPrint(root->relates),overloaded,isFunc,root->mGrpId, @@ -5947,7 +5896,7 @@ static void findMember(EntryNav *rootNav, " ::","::" ).stripWhiteSpace(); - //printf("funcDecl=`%s'\n",funcDecl.data()); + //printf("funcDecl='%s'\n",funcDecl.data()); if (isFriend && funcDecl.left(6)=="class ") { //printf("friend class\n"); @@ -5962,18 +5911,18 @@ static void findMember(EntryNav *rootNav, else { // extract information from the declarations - parseFuncDecl(funcDecl,root->lang==SrcLangExt_ObjC,scopeName,funcType,funcName, + parseFuncDecl(funcDecl,root->lang,scopeName,funcType,funcName, funcArgs,funcTempList,exceptions ); } - //printf("scopeName=`%s' funcType=`%s' funcName=`%s' funcArgs=`%s'\n", + //printf("scopeName='%s' funcType='%s' funcName='%s' funcArgs='%s'\n", // scopeName.data(),funcType.data(),funcName.data(),funcArgs.data()); // the class name can also be a namespace name, we decide this later. // if a related class name is specified and the class name could // not be derived from the function declaration, then use the // related field. - //printf("scopeName=`%s' className=`%s' namespaceName=`%s'\n", + //printf("scopeName='%s' className='%s' namespaceName='%s'\n", // scopeName.data(),className.data(),namespaceName.data()); if (!root->relates.isEmpty()) { // related member, prefix user specified scope @@ -5989,14 +5938,14 @@ static void findMember(EntryNav *rootNav, } } - if (root->relates.isEmpty() && rootNav->parent() && - ((rootNav->parent()->section()&Entry::SCOPE_MASK) || - (rootNav->parent()->section()==Entry::OBJCIMPL_SEC) + if (root->relates.isEmpty() && root->parent() && + ((root->parent()->section&Entry::SCOPE_MASK) || + (root->parent()->section==Entry::OBJCIMPL_SEC) ) && - !rootNav->parent()->name().isEmpty()) // see if we can combine scopeName + !root->parent()->name.isEmpty()) // see if we can combine scopeName // with the scope in which it was found { - QCString joinedName = rootNav->parent()->name()+"::"+scopeName; + QCString joinedName = root->parent()->name+"::"+scopeName; if (!scopeName.isEmpty() && (getClass(joinedName) || Doxygen::namespaceSDict->find(joinedName))) { @@ -6004,12 +5953,12 @@ static void findMember(EntryNav *rootNav, } else { - scopeName = mergeScopes(rootNav->parent()->name(),scopeName); + scopeName = mergeScopes(root->parent()->name,scopeName); } } else // see if we can prefix a namespace or class that is used from the file { - FileDef *fd=rootNav->fileDef(); + FileDef *fd=root->fileDef(); if (fd) { NamespaceSDict *fnl = fd->getUsedNamespaces(); @@ -6049,13 +5998,13 @@ static void findMember(EntryNav *rootNav, // split scope into a namespace and a class part extractNamespaceName(scopeName,className,namespaceName,TRUE); - //printf("scopeName=`%s' className=`%s' namespaceName=`%s'\n", + //printf("scopeName='%s' className='%s' namespaceName='%s'\n", // scopeName.data(),className.data(),namespaceName.data()); //namespaceName=removeAnonymousScopes(namespaceName); if (namespaceName.find('@')!=-1) return; // skip stuff in anonymous namespace... - //printf("namespaceName=`%s' className=`%s'\n",namespaceName.data(),className.data()); + //printf("namespaceName='%s' className='%s'\n",namespaceName.data(),className.data()); // merge class and namespace scopes again scopeName.resize(0); if (!namespaceName.isEmpty()) @@ -6078,7 +6027,7 @@ static void findMember(EntryNav *rootNav, { scopeName=className; } - //printf("new scope=`%s'\n",scopeName.data()); + //printf("new scope='%s'\n",scopeName.data()); QCString tempScopeName=scopeName; ClassDef *cd=getClass(scopeName); @@ -6097,7 +6046,7 @@ static void findMember(EntryNav *rootNav, //printf("scopeName=%s cd=%p root->tArgLists=%p result=%s\n", // scopeName.data(),cd,root->tArgLists,tempScopeName.data()); - //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data()); + //printf("scopeName='%s' className='%s'\n",scopeName.data(),className.data()); // rebuild the function declaration (needed to get the scope right). if (!scopeName.isEmpty() && !isRelated && !isFriend && !Config_getBool(HIDE_SCOPE_NAMES)) { @@ -6118,7 +6067,7 @@ static void findMember(EntryNav *rootNav, { funcDecl=tempScopeName+"::"+funcName+funcTempList; } - else // variable => add `argument' list + else // variable => add 'argument' list { funcDecl=tempScopeName+"::"+funcName+funcArgs; } @@ -6132,7 +6081,7 @@ static void findMember(EntryNav *rootNav, { funcDecl=funcType+" "+funcName+funcTempList; } - else // variable => add `argument' list + else // variable => add 'argument' list { funcDecl=funcType+" "+funcName+funcArgs; } @@ -6155,16 +6104,16 @@ static void findMember(EntryNav *rootNav, Debug::print(Debug::FindMembers,0, "findMember() Parse results:\n" - " namespaceName=`%s'\n" + " namespaceName='%s'\n" " className=`%s`\n" - " funcType=`%s'\n" - " funcSpec=`%s'\n" - " funcName=`%s'\n" - " funcArgs=`%s'\n" - " funcTempList=`%s'\n" - " funcDecl=`%s'\n" - " related=`%s'\n" - " exceptions=`%s'\n" + " funcType='%s'\n" + " funcSpec='%s'\n" + " funcName='%s'\n" + " funcArgs='%s'\n" + " funcTempList='%s'\n" + " funcDecl='%s'\n" + " related='%s'\n" + " exceptions='%s'\n" " isRelated=%d\n" " isMemberOf=%d\n" " isFriend=%d\n" @@ -6179,7 +6128,7 @@ static void findMember(EntryNav *rootNav, if (!funcName.isEmpty()) // function name is valid { Debug::print(Debug::FindMembers,0, - "1. funcName=`%s'\n",funcName.data()); + "1. funcName='%s'\n",funcName.data()); if (funcName.left(9)=="operator ") // strip class scope from cast operator { funcName = substitute(funcName,className+"::",""); @@ -6210,19 +6159,19 @@ static void findMember(EntryNav *rootNav, ClassDef *cd=md->getClassDef(); Debug::print(Debug::FindMembers,0, "3. member definition found, " - "scope needed=`%s' scope=`%s' args=`%s' fileName=%s\n", + "scope needed='%s' scope='%s' args='%s' fileName=%s\n", qPrint(scopeName),cd ? qPrint(cd->name()) : "<none>", qPrint(md->argsString()), qPrint(root->fileName)); //printf("Member %s (member scopeName=%s) (this scopeName=%s) classTempList=%s\n",md->name().data(),cd->name().data(),scopeName.data(),classTempList.data()); - FileDef *fd=rootNav->fileDef(); + FileDef *fd=root->fileDef(); NamespaceDef *nd=0; if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName); //printf("scopeName %s->%s\n",scopeName.data(), // stripTemplateSpecifiersFromScope(scopeName,FALSE).data()); - ClassDef *tcd=findClassDefinition(fd,nd,scopeName); + const ClassDef *tcd=findClassDefinition(fd,nd,scopeName); if (tcd==0 && cd && stripAnonymousNamespaceScope(cd->name())==scopeName) { // don't be fooled by anonymous scopes @@ -6239,7 +6188,7 @@ static void findMember(EntryNav *rootNav, // get the template parameter lists found at the member declaration QList<ArgumentList> declTemplArgs; cd->getTemplateParameterLists(declTemplArgs); - ArgumentList *templAl = md->templateArguments(); + const ArgumentList *templAl = md->templateArguments(); if (templAl) { declTemplArgs.append(templAl); @@ -6279,7 +6228,7 @@ static void findMember(EntryNav *rootNav, } Debug::print(Debug::FindMembers,0, - "5. matching `%s'<=>`%s' className=%s namespaceName=%s\n", + "5. matching '%s'<=>'%s' className=%s namespaceName=%s\n", qPrint(argListToString(argList,TRUE)),qPrint(argListToString(root->argList,TRUE)), qPrint(className),qPrint(namespaceName) ); @@ -6357,7 +6306,9 @@ static void findMember(EntryNav *rootNav, // TODO: copy other aspects? root->protection=md->protection(); // copy protection level - addMethodToClass(rootNav,cd,md->name(),isFriend); + root->stat=md->isStatic(); + root->virt=md->virtualness(); + addMethodToClass(root,cd,md->name(),isFriend); return; } delete argList; @@ -6365,7 +6316,7 @@ static void findMember(EntryNav *rootNav, } if (matching) { - addMemberDocs(rootNav,md,funcDecl,0,overloaded,0/* TODO */); + addMemberDocs(root,md,funcDecl,0,overloaded,0/* TODO */); count++; memFound=TRUE; } @@ -6376,15 +6327,15 @@ static void findMember(EntryNav *rootNav, noMatchCount++; } } - if (count==0 && rootNav->parent() && - rootNav->parent()->section()==Entry::OBJCIMPL_SEC) + if (count==0 && root->parent() && + root->parent()->section==Entry::OBJCIMPL_SEC) { goto localObjCMethod; } if (count==0 && !(isFriend && funcType=="class")) { int candidates=0; - ClassDef *ecd = 0, *ucd = 0; + const ClassDef *ecd = 0, *ucd = 0; MemberDef *emd = 0, *umd = 0; if (mn->count()>0) { @@ -6396,11 +6347,15 @@ static void findMember(EntryNav *rootNav, //printf("ccd->name()==%s className=%s\n",ccd->name().data(),className.data()); if (ccd!=0 && rightScopeMatch(ccd->name(),className)) { - ArgumentList *templAl = md->templateArguments(); + const ArgumentList *templAl = md->templateArguments(); if (root->tArgLists && templAl!=0 && root->tArgLists->getLast()->count()<=templAl->count()) { - addMethodToClass(rootNav,ccd,md->name(),isFriend); + Debug::print(Debug::FindMembers,0,"7. add template specialization\n"); + root->protection=md->protection(); + root->stat=md->isStatic(); + root->virt=md->virtualness(); + addMethodToClass(root,ccd,md->name(),isFriend); return; } if (md->argsString()==argListToString(root->argList,TRUE,FALSE)) @@ -6430,7 +6385,7 @@ static void findMember(EntryNav *rootNav, { // we didn't find an actual match on argument lists, but there is only 1 member with this // name in the same scope, so that has to be the one. - addMemberDocs(rootNav,umd,funcDecl,0,overloaded,0); + addMemberDocs(root,umd,funcDecl,0,overloaded,0); return; } else if (candidates>1 && ecd && emd) @@ -6438,7 +6393,7 @@ static void findMember(EntryNav *rootNav, // we didn't find a unique match using type resolution, // but one of the matches has the exact same signature so // we take that one. - addMemberDocs(rootNav,emd,funcDecl,0,overloaded,0); + addMemberDocs(root,emd,funcDecl,0,overloaded,0); return; } } @@ -6470,10 +6425,10 @@ static void findMember(EntryNav *rootNav, warnMsg+="Possible candidates:\n"; for (mni.toFirst();(md=mni.current());++mni) { - ClassDef *cd=md->getClassDef(); + const ClassDef *cd=md->getClassDef(); if (cd!=0 && rightScopeMatch(cd->name(),className)) { - ArgumentList *templAl = md->templateArguments(); + const ArgumentList *templAl = md->templateArguments(); if (templAl!=0) { warnMsg+=" 'template "; @@ -6521,14 +6476,14 @@ static void findMember(EntryNav *rootNav, MemberType mtype=MemberType_Function; ArgumentList *tArgList = new ArgumentList; // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); - md=new MemberDef( + md=createMemberDef( root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, declMd ? declMd->protection() : root->protection, root->virt,root->stat,Member, mtype,tArgList,root->argList,root->metaData); - //printf("new specialized member %s args=`%s'\n",md->name().data(),funcArgs.data()); - md->setTagInfo(rootNav->tagInfo()); + //printf("new specialized member %s args='%s'\n",md->name().data(),funcArgs.data()); + md->setTagInfo(root->tagInfo); md->setLanguage(root->lang); md->setId(root->id); md->setMemberClass(cd); @@ -6543,10 +6498,10 @@ static void findMember(EntryNav *rootNav, md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); md->setDocsForDefinition(!root->proto); - md->setPrototype(root->proto); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); md->addSectionsToDefinition(root->anchors); md->setBodySegment(root->bodyLine,root->endBodyLine); - FileDef *fd=rootNav->fileDef(); + FileDef *fd=root->fileDef(); md->setBodyDef(fd); md->setMemberSpecifiers(root->spec); md->setMemberGroupId(root->mGrpId); @@ -6576,7 +6531,7 @@ static void findMember(EntryNav *rootNav, bool unique=TRUE; for (;(md=mni.current());++mni) { - ClassDef *cd=md->getClassDef(); + const ClassDef *cd=md->getClassDef(); if (className!=cd->name()) unique=FALSE; } if (unique) @@ -6590,13 +6545,13 @@ static void findMember(EntryNav *rootNav, // new overloaded member function ArgumentList *tArgList = getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); - //printf("new related member %s args=`%s'\n",md->name().data(),funcArgs.data()); - MemberDef *md=new MemberDef( + //printf("new related member %s args='%s'\n",md->name().data(),funcArgs.data()); + MemberDef *md=createMemberDef( root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,Related, mtype,tArgList,root->argList,root->metaData); - md->setTagInfo(rootNav->tagInfo()); + md->setTagInfo(root->tagInfo); md->setLanguage(root->lang); md->setId(root->id); md->setTypeConstraints(root->typeConstr); @@ -6613,10 +6568,10 @@ static void findMember(EntryNav *rootNav, md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); md->setDocsForDefinition(!root->proto); - md->setPrototype(root->proto); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); md->addSectionsToDefinition(root->anchors); md->setBodySegment(root->bodyLine,root->endBodyLine); - FileDef *fd=rootNav->fileDef(); + FileDef *fd=root->fileDef(); md->setBodyDef(fd); md->setMemberSpecifiers(root->spec); md->setMemberGroupId(root->mGrpId); @@ -6628,7 +6583,7 @@ static void findMember(EntryNav *rootNav, } else // unrelated function with the same name as a member { - if (!findGlobalMember(rootNav,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl)) + if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl)) { QCString fullFuncDecl=funcDecl.copy(); if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE); @@ -6645,7 +6600,7 @@ static void findMember(EntryNav *rootNav, " scopeName=%s className=%s\n",qPrint(scopeName),qPrint(className)); if (className.isEmpty()) className=root->relates; ClassDef *cd; - //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data()); + //printf("scopeName='%s' className='%s'\n",scopeName.data(),className.data()); if ((cd=getClass(scopeName))) { bool newMember=TRUE; // assume we have a new member @@ -6666,7 +6621,7 @@ static void findMember(EntryNav *rootNav, } } - FileDef *fd=rootNav->fileDef(); + FileDef *fd=root->fileDef(); if ((mn=Doxygen::memberNameSDict->find(funcName))==0) { @@ -6692,7 +6647,7 @@ static void findMember(EntryNav *rootNav, { //printf("addMemberDocs for related member %s\n",root->name.data()); //rmd->setMemberDefTemplateArguments(root->mtArgList); - addMemberDocs(rootNav,rmd,funcDecl,0,overloaded); + addMemberDocs(root,rmd,funcDecl,0,overloaded); } } @@ -6718,7 +6673,7 @@ static void findMember(EntryNav *rootNav, funcDecl=funcType + " " + funcName; } - //printf("New related name `%s' `%d'\n",funcName.data(), + //printf("New related name '%s' '%d'\n",funcName.data(), // root->argList ? (int)root->argList->count() : -1); // first note that we pass: @@ -6727,7 +6682,7 @@ static void findMember(EntryNav *rootNav, // this accurately reflects the template arguments of // the related function, which don't have to do with // those of the related class. - MemberDef *md=new MemberDef( + MemberDef *md=createMemberDef( root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, root->protection,root->virt, @@ -6755,11 +6710,11 @@ static void findMember(EntryNav *rootNav, // md->setDefinitionTemplateParameterLists(root->tArgLists); - md->setTagInfo(rootNav->tagInfo()); + md->setTagInfo(root->tagInfo); - //printf("Related member name=`%s' decl=`%s' bodyLine=`%d'\n", + //printf("Related member name='%s' decl='%s' bodyLine='%d'\n", // funcName.data(),funcDecl.data(),root->bodyLine); // try to find the matching line number of the body from the @@ -6771,10 +6726,10 @@ static void findMember(EntryNav *rootNav, if (rmn) { MemberNameIterator rmni(*rmn); - MemberDef *rmd; + const MemberDef *rmd; while ((rmd=rmni.current()) && !found) // see if we got another member with matching arguments { - ArgumentList *rmdAl = rmd->argumentList(); + const ArgumentList *rmdAl = rmd->argumentList(); // check for matching argument lists if ( matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmdAl, @@ -6815,7 +6770,7 @@ static void findMember(EntryNav *rootNav, md->setDocumentation(root->doc,root->docFile,root->docLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); md->setDocsForDefinition(!root->proto); - md->setPrototype(root->proto); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->addSectionsToDefinition(root->anchors); md->setMemberGroupId(root->mGrpId); @@ -6841,7 +6796,7 @@ static void findMember(EntryNav *rootNav, } if (root->relatesType == Duplicate) { - if (!findGlobalMember(rootNav,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl)) + if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl)) { QCString fullFuncDecl=funcDecl.copy(); if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE); @@ -6855,28 +6810,28 @@ static void findMember(EntryNav *rootNav, else { warn_undoc(root->fileName,root->startLine, - "class `%s' for related function `%s' is not " + "class '%s' for related function '%s' is not " "documented.", className.data(),funcName.data() ); } } - else if (rootNav->parent() && rootNav->parent()->section()==Entry::OBJCIMPL_SEC) + else if (root->parent() && root->parent()->section==Entry::OBJCIMPL_SEC) { localObjCMethod: ClassDef *cd; - //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data()); + //printf("scopeName='%s' className='%s'\n",scopeName.data(),className.data()); if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClass(scopeName))) { Debug::print(Debug::FindMembers,0,"4. Local objective C method %s\n" " scopeName=%s className=%s\n",qPrint(root->name),qPrint(scopeName),qPrint(className)); - //printf("Local objective C method `%s' of class `%s' found\n",root->name.data(),cd->name().data()); - MemberDef *md=new MemberDef( + //printf("Local objective C method '%s' of class '%s' found\n",root->name.data(),cd->name().data()); + MemberDef *md=createMemberDef( root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,Member, MemberType_Function,0,root->argList,root->metaData); - md->setTagInfo(rootNav->tagInfo()); + md->setTagInfo(root->tagInfo); md->setLanguage(root->lang); md->setId(root->id); md->makeImplementationDetail(); @@ -6890,10 +6845,10 @@ localObjCMethod: md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); md->setDocsForDefinition(!root->proto); - md->setPrototype(root->proto); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); md->addSectionsToDefinition(root->anchors); md->setBodySegment(root->bodyLine,root->endBodyLine); - FileDef *fd=rootNav->fileDef(); + FileDef *fd=root->fileDef(); md->setBodyDef(fd); md->setMemberSpecifiers(root->spec); md->setMemberGroupId(root->mGrpId); @@ -6918,18 +6873,18 @@ localObjCMethod: } else // unrelated not overloaded member found { - bool globMem = findGlobalMember(rootNav,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl); + bool globMem = findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl); if (className.isEmpty() && !globMem) { warn(root->fileName,root->startLine, - "class for member `%s' cannot " + "class for member '%s' cannot " "be found.", funcName.data() ); } else if (!className.isEmpty() && !globMem) { warn(root->fileName,root->startLine, - "member `%s' of class `%s' cannot be found", + "member '%s' of class '%s' cannot be found", funcName.data(),className.data()); } } @@ -6947,22 +6902,21 @@ localObjCMethod: // find the members corresponding to the different documentation blocks // that are extracted from the sources. -static void filterMemberDocumentation(EntryNav *rootNav) +static void filterMemberDocumentation(Entry *root) { - Entry *root = rootNav->entry(); int i=-1,l; Debug::print(Debug::FindMembers,0, - "findMemberDocumentation(): root->type=`%s' root->inside=`%s' root->name=`%s' root->args=`%s' section=%x root->spec=%lld root->mGrpId=%d\n", + "findMemberDocumentation(): root->type='%s' root->inside='%s' root->name='%s' root->args='%s' section=%x root->spec=%lld root->mGrpId=%d\n", qPrint(root->type),qPrint(root->inside),qPrint(root->name),qPrint(root->args),root->section,root->spec,root->mGrpId ); - //printf("rootNav->parent()->name()=%s\n",rootNav->parent()->name().data()); + //printf("root->parent()->name=%s\n",root->parent()->name.data()); bool isFunc=TRUE; if (root->relatesType == Duplicate && !root->relates.isEmpty()) { QCString tmp = root->relates; root->relates.resize(0); - filterMemberDocumentation(rootNav); + filterMemberDocumentation(root); root->relates = tmp; } @@ -6986,22 +6940,22 @@ static void filterMemberDocumentation(EntryNav *rootNav) //printf("Member %s isFunc=%d\n",root->name.data(),isFunc); if (root->section==Entry::MEMBERDOC_SEC) { - //printf("Documentation for inline member `%s' found args=`%s'\n", + //printf("Documentation for inline member '%s' found args='%s'\n", // root->name.data(),root->args.data()); //if (root->relates.length()) printf(" Relates %s\n",root->relates.data()); if (root->type.isEmpty()) { - findMember(rootNav,root->name+root->args+root->exception,FALSE,isFunc); + findMember(root,root->name+root->args+root->exception,FALSE,isFunc); } else { - findMember(rootNav,root->type+" "+root->name+root->args+root->exception,FALSE,isFunc); + findMember(root,root->type+" "+root->name+root->args+root->exception,FALSE,isFunc); } } else if (root->section==Entry::OVERLOADDOC_SEC) { //printf("Overloaded member %s found\n",root->name.data()); - findMember(rootNav,root->name,TRUE,isFunc); + findMember(root,root->name,TRUE,isFunc); } else if ((root->section==Entry::FUNCTION_SEC // function @@ -7014,14 +6968,14 @@ static void filterMemberDocumentation(EntryNav *rootNav) ) ) { - //printf("Documentation for member `%s' found args=`%s' excp=`%s'\n", + //printf("Documentation for member '%s' found args='%s' excp='%s'\n", // root->name.data(),root->args.data(),root->exception.data()); //if (root->relates.length()) printf(" Relates %s\n",root->relates.data()); //printf("Inside=%s\n Relates=%s\n",root->inside.data(),root->relates.data()); if (root->type=="friend class" || root->type=="friend struct" || root->type=="friend union") { - findMember(rootNav, + findMember(root, root->type+" "+ root->name, FALSE,FALSE); @@ -7029,7 +6983,7 @@ static void filterMemberDocumentation(EntryNav *rootNav) } else if (!root->type.isEmpty()) { - findMember(rootNav, + findMember(root, root->type+" "+ root->inside+ root->name+ @@ -7039,7 +6993,7 @@ static void filterMemberDocumentation(EntryNav *rootNav) } else { - findMember(rootNav, + findMember(root, root->inside+ root->name+ root->args+ @@ -7049,18 +7003,18 @@ static void filterMemberDocumentation(EntryNav *rootNav) } else if (root->section==Entry::DEFINE_SEC && !root->relates.isEmpty()) { - findMember(rootNav,root->name+root->args,FALSE,!root->args.isEmpty()); + findMember(root,root->name+root->args,FALSE,!root->args.isEmpty()); } else if (root->section==Entry::VARIABLEDOC_SEC) { //printf("Documentation for variable %s found\n",root->name.data()); //if (!root->relates.isEmpty()) printf(" Relates %s\n",root->relates.data()); - findMember(rootNav,root->name,FALSE,FALSE); + findMember(root,root->name,FALSE,FALSE); } else if (root->section==Entry::EXPORTED_INTERFACE_SEC || root->section==Entry::INCLUDED_SERVICE_SEC) { - findMember(rootNav,root->type + " " + root->name,FALSE,FALSE); + findMember(root,root->type + " " + root->name,FALSE,FALSE); } else { @@ -7069,62 +7023,53 @@ static void filterMemberDocumentation(EntryNav *rootNav) } } -static void findMemberDocumentation(EntryNav *rootNav) +static void findMemberDocumentation(Entry *root) { - if (rootNav->section()==Entry::MEMBERDOC_SEC || - rootNav->section()==Entry::OVERLOADDOC_SEC || - rootNav->section()==Entry::FUNCTION_SEC || - rootNav->section()==Entry::VARIABLE_SEC || - rootNav->section()==Entry::VARIABLEDOC_SEC || - rootNav->section()==Entry::DEFINE_SEC || - rootNav->section()==Entry::INCLUDED_SERVICE_SEC || - rootNav->section()==Entry::EXPORTED_INTERFACE_SEC + if (root->section==Entry::MEMBERDOC_SEC || + root->section==Entry::OVERLOADDOC_SEC || + root->section==Entry::FUNCTION_SEC || + root->section==Entry::VARIABLE_SEC || + root->section==Entry::VARIABLEDOC_SEC || + root->section==Entry::DEFINE_SEC || + root->section==Entry::INCLUDED_SERVICE_SEC || + root->section==Entry::EXPORTED_INTERFACE_SEC ) { - rootNav->loadEntry(g_storage); - - filterMemberDocumentation(rootNav); - - rootNav->releaseEntry(); + filterMemberDocumentation(root); } - if (rootNav->children()) + if (root->children()) { - EntryNavListIterator eli(*rootNav->children()); - EntryNav *e; + EntryListIterator eli(*root->children()); + Entry *e; for (;(e=eli.current());++eli) { - if (e->section()!=Entry::ENUM_SEC) findMemberDocumentation(e); + if (e->section!=Entry::ENUM_SEC) findMemberDocumentation(e); } } } //---------------------------------------------------------------------- -static void findObjCMethodDefinitions(EntryNav *rootNav) +static void findObjCMethodDefinitions(Entry *root) { - if (rootNav->children()) + if (root->children()) { - EntryNavListIterator eli(*rootNav->children()); - EntryNav *objCImplNav; - for (;(objCImplNav=eli.current());++eli) + EntryListIterator eli(*root->children()); + Entry *objCImpl; + for (;(objCImpl=eli.current());++eli) { - if (objCImplNav->section()==Entry::OBJCIMPL_SEC && objCImplNav->children()) + if (objCImpl->section==Entry::OBJCIMPL_SEC && objCImpl->children()) { - EntryNavListIterator seli(*objCImplNav->children()); - EntryNav *objCMethodNav; - for (;(objCMethodNav=seli.current());++seli) + EntryListIterator seli(*objCImpl->children()); + Entry *objCMethod; + for (;(objCMethod=seli.current());++seli) { - if (objCMethodNav->section()==Entry::FUNCTION_SEC) + if (objCMethod->section==Entry::FUNCTION_SEC) { - objCMethodNav->loadEntry(g_storage); - Entry *objCMethod = objCMethodNav->entry(); - //Printf(" Found ObjC method definition %s\n",objCMethod->name.data()); - findMember(objCMethodNav, objCMethod->type+" "+objCImplNav->name()+"::"+ + findMember(objCMethod, objCMethod->type+" "+objCImpl->name+"::"+ objCMethod->name+" "+objCMethod->args, FALSE,TRUE); objCMethod->section=Entry::EMPTY_SEC; - - objCMethodNav->releaseEntry(); } } } @@ -7135,13 +7080,10 @@ static void findObjCMethodDefinitions(EntryNav *rootNav) //---------------------------------------------------------------------- // find and add the enumeration to their classes, namespaces or files -static void findEnums(EntryNav *rootNav) +static void findEnums(Entry *root) { - if (rootNav->section()==Entry::ENUM_SEC) + if (root->section==Entry::ENUM_SEC) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - MemberDef *md=0; ClassDef *cd=0; FileDef *fd=0; @@ -7150,7 +7092,7 @@ static void findEnums(EntryNav *rootNav) bool isGlobal; bool isRelated=FALSE; bool isMemberOf=FALSE; - //printf("Found enum with name `%s' relates=%s\n",root->name.data(),root->relates.data()); + //printf("Found enum with name '%s' relates=%s\n",root->name.data(),root->relates.data()); int i; QCString name; @@ -7164,11 +7106,11 @@ static void findEnums(EntryNav *rootNav) } else // no scope, check the scope in which the docs where found { - if (( rootNav->parent()->section() & Entry::SCOPE_MASK ) - && !rootNav->parent()->name().isEmpty() + if (( root->parent()->section & Entry::SCOPE_MASK ) + && !root->parent()->name.isEmpty() ) // found enum docs inside a compound { - scope=rootNav->parent()->name(); + scope=root->parent()->name; if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope); } name=root->name; @@ -7187,7 +7129,7 @@ static void findEnums(EntryNav *rootNav) if (cd && !name.isEmpty()) // found a enum inside a compound { - //printf("Enum `%s'::`%s'\n",cd->name().data(),name.data()); + //printf("Enum '%s'::'%s'\n",cd->name().data(),name.data()); fd=0; mnsd=Doxygen::memberNameSDict; isGlobal=FALSE; @@ -7199,7 +7141,7 @@ static void findEnums(EntryNav *rootNav) } else // found a global enum { - fd=rootNav->fileDef(); + fd=root->fileDef(); mnsd=Doxygen::functionNameSDict; isGlobal=TRUE; } @@ -7207,19 +7149,19 @@ static void findEnums(EntryNav *rootNav) if (!name.isEmpty()) { // new enum type - md = new MemberDef( + md = createMemberDef( root->fileName,root->startLine,root->startColumn, 0,name,0,0, root->protection,Normal,FALSE, isMemberOf ? Foreign : isRelated ? Related : Member, MemberType_Enumeration, 0,0,root->metaData); - md->setTagInfo(rootNav->tagInfo()); + md->setTagInfo(root->tagInfo); md->setLanguage(root->lang); md->setId(root->id); if (!isGlobal) md->setMemberClass(cd); else md->setFileDef(fd); md->setBodySegment(root->bodyLine,root->endBodyLine); - md->setBodyDef(rootNav->fileDef()); + md->setBodyDef(root->fileDef()); md->setMemberSpecifiers(root->spec); md->setEnumBaseType(root->args); //printf("Enum %s definition at line %d of %s: protection=%d scope=%s\n", @@ -7263,9 +7205,9 @@ static void findEnums(EntryNav *rootNav) if (isGlobal) { if (!defSet) md->setDefinition(name+baseType); - if (fd==0 && rootNav->parent()) + if (fd==0 && root->parent()) { - fd=rootNav->parent()->fileDef(); + fd=root->parent()->fileDef(); } if (fd) { @@ -7308,31 +7250,27 @@ static void findEnums(EntryNav *rootNav) } addMemberToGroups(root,md); } - rootNav->releaseEntry(); } else { - RECURSE_ENTRYTREE(findEnums,rootNav); + RECURSE_ENTRYTREE(findEnums,root); } } //---------------------------------------------------------------------- -static void addEnumValuesToEnums(EntryNav *rootNav) +static void addEnumValuesToEnums(Entry *root) { - if (rootNav->section()==Entry::ENUM_SEC) + if (root->section==Entry::ENUM_SEC) // non anonymous enumeration { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - ClassDef *cd=0; FileDef *fd=0; NamespaceDef *nd=0; MemberNameSDict *mnsd=0; bool isGlobal; bool isRelated=FALSE; - //printf("Found enum with name `%s' relates=%s\n",root->name.data(),root->relates.data()); + //printf("Found enum with name '%s' relates=%s\n",root->name.data(),root->relates.data()); int i; QCString name; @@ -7346,11 +7284,11 @@ static void addEnumValuesToEnums(EntryNav *rootNav) } else // no scope, check the scope in which the docs where found { - if (( rootNav->parent()->section() & Entry::SCOPE_MASK ) - && !rootNav->parent()->name().isEmpty() + if (( root->parent()->section & Entry::SCOPE_MASK ) + && !root->parent()->name.isEmpty() ) // found enum docs inside a compound { - scope=rootNav->parent()->name(); + scope=root->parent()->name; if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope); } name=root->name; @@ -7368,21 +7306,21 @@ static void addEnumValuesToEnums(EntryNav *rootNav) if (cd && !name.isEmpty()) // found a enum inside a compound { - //printf("Enum in class `%s'::`%s'\n",cd->name().data(),name.data()); + //printf("Enum in class '%s'::'%s'\n",cd->name().data(),name.data()); fd=0; mnsd=Doxygen::memberNameSDict; isGlobal=FALSE; } else if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') // found enum inside namespace { - //printf("Enum in namespace `%s'::`%s'\n",nd->name().data(),name.data()); + //printf("Enum in namespace '%s'::'%s'\n",nd->name().data(),name.data()); mnsd=Doxygen::functionNameSDict; isGlobal=TRUE; } else // found a global enum { - fd=rootNav->fileDef(); - //printf("Enum in file `%s': `%s'\n",fd->name().data(),name.data()); + fd=root->fileDef(); + //printf("Enum in file '%s': '%s'\n",fd->name().data(),name.data()); mnsd=Doxygen::functionNameSDict; isGlobal=TRUE; } @@ -7397,16 +7335,16 @@ static void addEnumValuesToEnums(EntryNav *rootNav) MemberDef *md; for (mni.toFirst(); (md=mni.current()) ; ++mni) // for each enum in this list { - if (md->isEnumerate() && rootNav->children()) + if (!md->isAlias() && md->isEnumerate() && root->children()) { - //printf(" enum with %d children\n",rootNav->children()->count()); - EntryNavListIterator eli(*rootNav->children()); // for each enum value - EntryNav *e; + //printf(" enum with %d children\n",root->children()->count()); + EntryListIterator eli(*root->children()); // for each enum value + Entry *e; for (;(e=eli.current());++eli) { SrcLangExt sle; if ( - (sle=rootNav->lang())==SrcLangExt_CSharp || + (sle=root->lang)==SrcLangExt_CSharp || sle==SrcLangExt_Java || sle==SrcLangExt_XML || (root->spec&Entry::Strong) @@ -7415,12 +7353,10 @@ static void addEnumValuesToEnums(EntryNav *rootNav) // Unlike classic C/C++ enums, for C++11, C# & Java enum // values are only visible inside the enum scope, so we must create // them here and only add them to the enum - e->loadEntry(g_storage); - Entry *root = e->entry(); - //printf("md->qualifiedName()=%s rootNav->name()=%s tagInfo=%p name=%s\n", - // md->qualifiedName().data(),rootNav->name().data(),rootNav->tagInfo(),root->name.data()); - QCString qualifiedName = substitute(rootNav->name(),"::","."); - if (!scope.isEmpty() && rootNav->tagInfo()) + //printf("md->qualifiedName()=%s e->name=%s tagInfo=%p name=%s\n", + // md->qualifiedName().data(),e->name.data(),e->tagInfo,e->name.data()); + QCString qualifiedName = substitute(root->name,"::","."); + if (!scope.isEmpty() && root->tagInfo) { qualifiedName=substitute(scope,"::",".")+"."+qualifiedName; } @@ -7428,54 +7364,53 @@ static void addEnumValuesToEnums(EntryNav *rootNav) qualifiedName // enum value scope matches that of the enum ) { - QCString fileName = root->fileName; - if (fileName.isEmpty() && rootNav->tagInfo()) + QCString fileName = e->fileName; + if (fileName.isEmpty() && e->tagInfo) { - fileName = rootNav->tagInfo()->tagName; + fileName = e->tagInfo->tagName; } - MemberDef *fmd=new MemberDef( - fileName,root->startLine,root->startColumn, - root->type,root->name,root->args,0, - root->protection, Normal,root->stat,Member, - MemberType_EnumValue,0,0,root->metaData); + MemberDef *fmd=createMemberDef( + fileName,e->startLine,e->startColumn, + e->type,e->name,e->args,0, + e->protection, Normal,e->stat,Member, + MemberType_EnumValue,0,0,e->metaData); if (md->getClassDef()) fmd->setMemberClass(md->getClassDef()); else if (md->getNamespaceDef()) fmd->setNamespace(md->getNamespaceDef()); else if (md->getFileDef()) fmd->setFileDef(md->getFileDef()); fmd->setOuterScope(md->getOuterScope()); - fmd->setTagInfo(e->tagInfo()); - fmd->setLanguage(root->lang); - fmd->setId(root->id); - fmd->setDocumentation(root->doc,root->docFile,root->docLine); - fmd->setBriefDescription(root->brief,root->briefFile,root->briefLine); - fmd->addSectionsToDefinition(root->anchors); - fmd->setInitializer(root->initializer); - fmd->setMaxInitLines(root->initLines); - fmd->setMemberGroupId(root->mGrpId); - fmd->setExplicitExternal(root->explicitExternal); - fmd->setRefItems(root->sli); + fmd->setTagInfo(e->tagInfo); + fmd->setLanguage(e->lang); + fmd->setId(e->id); + fmd->setDocumentation(e->doc,e->docFile,e->docLine); + fmd->setBriefDescription(e->brief,e->briefFile,e->briefLine); + fmd->addSectionsToDefinition(e->anchors); + fmd->setInitializer(e->initializer); + fmd->setMaxInitLines(e->initLines); + fmd->setMemberGroupId(e->mGrpId); + fmd->setExplicitExternal(e->explicitExternal,fileName,e->startLine,e->startColumn); + fmd->setRefItems(e->sli); fmd->setAnchor(); md->insertEnumField(fmd); fmd->setEnumScope(md,TRUE); - MemberName *mn=mnsd->find(root->name); + MemberName *mn=mnsd->find(e->name); if (mn) { mn->append(fmd); } else { - mn = new MemberName(root->name); + mn = new MemberName(e->name); mn->append(fmd); - mnsd->append(root->name,mn); + mnsd->append(e->name,mn); } } - e->releaseEntry(); } else { //printf("e->name=%s isRelated=%d\n",e->name().data(),isRelated); MemberName *fmn=0; MemberNameSDict *emnsd = isRelated ? Doxygen::functionNameSDict : mnsd; - if (!e->name().isEmpty() && (fmn=(*emnsd)[e->name()])) + if (!e->name.isEmpty() && (fmn=(*emnsd)[e->name])) // get list of members with the same name as the field { MemberNameIterator fmni(*fmn); @@ -7488,7 +7423,7 @@ static void addEnumValuesToEnums(EntryNav *rootNav) // fmd->name().data(),fmd->getOuterScope()->name().data()); if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') { - NamespaceDef *fnd=fmd->getNamespaceDef(); + const NamespaceDef *fnd=fmd->getNamespaceDef(); if (fnd==nd) // enum value is inside a namespace { md->insertEnumField(fmd); @@ -7497,7 +7432,7 @@ static void addEnumValuesToEnums(EntryNav *rootNav) } else if (isGlobal) { - FileDef *ffd=fmd->getFileDef(); + const FileDef *ffd=fmd->getFileDef(); if (ffd==fd) // enum value has file scope { md->insertEnumField(fmd); @@ -7516,7 +7451,7 @@ static void addEnumValuesToEnums(EntryNav *rootNav) } else { - ClassDef *fcd=fmd->getClassDef(); + const ClassDef *fcd=fmd->getClassDef(); if (fcd==cd) // enum value is inside a class { //printf("Inserting enum field %s in enum scope %s\n", @@ -7534,12 +7469,10 @@ static void addEnumValuesToEnums(EntryNav *rootNav) } } } - - rootNav->releaseEntry(); } else { - RECURSE_ENTRYTREE(addEnumValuesToEnums,rootNav); + RECURSE_ENTRYTREE(addEnumValuesToEnums,root); } } @@ -7547,17 +7480,14 @@ static void addEnumValuesToEnums(EntryNav *rootNav) //---------------------------------------------------------------------- // find the documentation blocks for the enumerations -static void findEnumDocumentation(EntryNav *rootNav) +static void findEnumDocumentation(Entry *root) { - if (rootNav->section()==Entry::ENUMDOC_SEC - && !rootNav->name().isEmpty() - && rootNav->name().at(0)!='@' // skip anonymous enums + if (root->section==Entry::ENUMDOC_SEC + && !root->name.isEmpty() + && root->name.at(0)!='@' // skip anonymous enums ) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - - //printf("Found docs for enum with name `%s' in context %s\n", + //printf("Found docs for enum with name '%s' in context %s\n", // root->name.data(),root->parent->name.data()); int i; QCString name; @@ -7566,18 +7496,18 @@ static void findEnumDocumentation(EntryNav *rootNav) { name=root->name.right(root->name.length()-i-2); // extract name scope=root->name.left(i); // extract scope - //printf("Scope=`%s' Name=`%s'\n",scope.data(),name.data()); + //printf("Scope='%s' Name='%s'\n",scope.data(),name.data()); } else // just the name { name=root->name; } - if (( rootNav->parent()->section() & Entry::SCOPE_MASK ) - && !rootNav->parent()->name().isEmpty() + if (( root->parent()->section & Entry::SCOPE_MASK ) + && !root->parent()->name.isEmpty() ) // found enum docs inside a compound { if (!scope.isEmpty()) scope.prepend("::"); - scope.prepend(rootNav->parent()->name()); + scope.prepend(root->parent()->name); } ClassDef *cd=getClass(scope); @@ -7586,7 +7516,7 @@ static void findEnumDocumentation(EntryNav *rootNav) bool found=FALSE; if (cd) { - //printf("Enum: scope=`%s' name=`%s'\n",cd->name(),name.data()); + //printf("Enum: scope='%s' name='%s'\n",cd->name(),name.data()); QCString className=cd->name().copy(); MemberName *mn=Doxygen::memberNameSDict->find(name); if (mn) @@ -7595,12 +7525,12 @@ static void findEnumDocumentation(EntryNav *rootNav) MemberDef *md; for (mni.toFirst();(md=mni.current()) && !found;++mni) { - ClassDef *cd=md->getClassDef(); + const ClassDef *cd=md->getClassDef(); if (cd && cd->name()==className && md->isEnumerate()) { // documentation outside a compound overrides the documentation inside it #if 0 - if (!md->documentation() || rootNav->parent()->name().isEmpty()) + if (!md->documentation() || root->parent()->name.isEmpty()) #endif { md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -7610,13 +7540,13 @@ static void findEnumDocumentation(EntryNav *rootNav) // brief descriptions inside a compound override the documentation // outside it #if 0 - if (!md->briefDescription() || !rootNav->parent()->name().isEmpty()) + if (!md->briefDescription() || !root->parent()->name.isEmpty()) #endif { md->setBriefDescription(root->brief,root->briefFile,root->briefLine); } - if (!md->inbodyDocumentation() || !rootNav->parent()->name().isEmpty()) + if (!md->inbodyDocumentation() || !root->parent()->name.isEmpty()) { md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); } @@ -7629,7 +7559,7 @@ static void findEnumDocumentation(EntryNav *rootNav) md->addSectionsToDefinition(root->anchors); md->setRefItems(root->sli); - GroupDef *gd=md->getGroupDef(); + const GroupDef *gd=md->getGroupDef(); if (gd==0 &&root->groups->getFirst()!=0) // member not grouped but out-of-line documentation is { addMemberToGroups(root,md); @@ -7663,7 +7593,7 @@ static void findEnumDocumentation(EntryNav *rootNav) md->addSectionsToDefinition(root->anchors); md->setMemberGroupId(root->mGrpId); - GroupDef *gd=md->getGroupDef(); + const GroupDef *gd=md->getGroupDef(); if (gd==0 && root->groups->getFirst()!=0) // member not grouped but out-of-line documentation is { addMemberToGroups(root,md); @@ -7677,15 +7607,13 @@ static void findEnumDocumentation(EntryNav *rootNav) if (!found) { warn(root->fileName,root->startLine, - "Documentation for undefined enum `%s' found.", + "Documentation for undefined enum '%s' found.", name.data() ); } } - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(findEnumDocumentation,rootNav); + RECURSE_ENTRYTREE(findEnumDocumentation,root); } // search for each enum (member or function) in mnl if it has documented @@ -7704,7 +7632,7 @@ static void findDEV(const MemberNameSDict &mnsd) { if (md->isEnumerate()) // member is an enum { - MemberList *fmdl = md->enumFieldList(); + const MemberList *fmdl = md->enumFieldList(); int documentedEnumValues=0; if (fmdl) // enum has values { @@ -7757,22 +7685,57 @@ static void addMembersToIndex() // for each member definition for (mni.toFirst();(md=mni.current());++mni) { - if (md->getNamespaceDef()) + if (!md->isAlias()) { - addNamespaceMemberNameToIndex(md); - } - else - { - addFileMemberNameToIndex(md); + if (md->getNamespaceDef()) + { + addNamespaceMemberNameToIndex(md); + } + else + { + addFileMemberNameToIndex(md); + } } } } } //---------------------------------------------------------------------- -// computes the relation between all members. For each member `m' -// the members that override the implementation of `m' are searched and -// the member that `m' overrides is searched. + +static void vhdlCorrectMemberProperties() +{ + MemberName *mn; + MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); + // for each member name + for (mnli.toFirst();(mn=mnli.current());++mnli) + { + MemberDef *md; + MemberNameIterator mni(*mn); + // for each member definition + for (mni.toFirst();(md=mni.current());++mni) + { + VhdlDocGen::correctMemberProperties(md); + } + } + MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); + // for each member name + for (fnli.toFirst();(mn=fnli.current());++fnli) + { + MemberDef *md; + MemberNameIterator mni(*mn); + // for each member definition + for (mni.toFirst();(md=mni.current());++mni) + { + VhdlDocGen::correctMemberProperties(md); + } + } +} + + +//---------------------------------------------------------------------- +// computes the relation between all members. For each member 'm' +// the members that override the implementation of 'm' are searched and +// the member that 'm' overrides is searched. static void computeMemberRelations() { @@ -7788,16 +7751,17 @@ static void computeMemberRelations() { for ( bmdi.toFirst() ; (bmd=bmdi.current()); ++bmdi ) // for each other member with the same name { - ClassDef *mcd = md->getClassDef(); + const ClassDef *mcd = md->getClassDef(); if (mcd && mcd->baseClasses()) { - ClassDef *bmcd = bmd->getClassDef(); - //printf("Check relation between `%s'::`%s' (%p) and `%s'::`%s' (%p)\n", + 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 // ); if (md!=bmd && 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 ) && @@ -7809,7 +7773,7 @@ static void computeMemberRelations() //printf(" derived scope\n"); ArgumentList *bmdAl = bmd->argumentList(); ArgumentList *mdAl = md->argumentList(); - //printf(" Base argList=`%s'\n Super argList=`%s'\n", + //printf(" Base argList='%s'\n Super argList='%s'\n", // argListToString(bmdAl.pointer()).data(), // argListToString(mdAl.pointer()).data() // ); @@ -8015,7 +7979,7 @@ static void generateFileSources() { QStrList filesInSameTu; fd->startParsing(); - if (fd->generateSourceFile() && !g_useOutputTemplate) // sources need to be shown in the output + if (fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate) // sources need to be shown in the output { msg("Generating code for file %s...\n",fd->docName().data()); fd->writeSource(*g_outputList,FALSE,filesInSameTu); @@ -8045,7 +8009,7 @@ static void generateFileSources() { QStrList filesInSameTu; fd->startParsing(); - if (fd->generateSourceFile() && !g_useOutputTemplate) // sources need to be shown in the output + if (fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate) // sources need to be shown in the output { msg("Generating code for file %s...\n",fd->docName().data()); fd->writeSource(*g_outputList,FALSE,filesInSameTu); @@ -8138,7 +8102,7 @@ static void addSourceReferences() (fd->generateSourceFile() || Doxygen::parseSourcesNeeded) ) { - //printf("Found member `%s' in file `%s' at line `%d' def=%s\n", + //printf("Found member '%s' in file '%s' at line '%d' def=%s\n", // md->name().data(),fd->name().data(),md->getStartBodyLine(),md->getOuterScope()->name().data()); fd->addSourceRef(md->getStartBodyLine(),md->getOuterScope(),md); } @@ -8163,7 +8127,7 @@ static void addSourceReferences() (fd->generateSourceFile() || Doxygen::parseSourcesNeeded) ) { - //printf("Found member `%s' in file `%s' at line `%d' def=%s\n", + //printf("Found member '%s' in file '%s' at line '%d' def=%s\n", // md->name().data(),fd->name().data(),md->getStartBodyLine(),md->getOuterScope()->name().data()); fd->addSourceRef(md->getStartBodyLine(),md->getOuterScope(),md); } @@ -8214,6 +8178,85 @@ static void sortMemberLists() } //---------------------------------------------------------------------------- + +static void setAnonymousEnumType() +{ + ClassSDict::Iterator cli(*Doxygen::classSDict); + ClassDef *cd=0; + for (cli.toFirst();(cd=cli.current());++cli) + { + cd->setAnonymousEnumType(); + } + +#if 0 + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); + NamespaceDef *nd=0; + for (nli.toFirst();(nd=nli.current());++nli) + { + nd->setAnonymousEnumType(); + } + + FileNameListIterator fnli(*Doxygen::inputNameList); + FileName *fn; + for (;(fn=fnli.current());++fnli) + { + FileNameIterator fni(*fn); + FileDef *fd; + for (;(fd=fni.current());++fni) + { + fd->setAnonymousEnumType(); + } + } + + GroupSDict::Iterator gli(*Doxygen::groupSDict); + GroupDef *gd; + for (gli.toFirst();(gd=gli.current());++gli) + { + gd->setAnonymousEnumType(); + } +#endif +} + +//---------------------------------------------------------------------------- + +static void countMembers() +{ + ClassSDict::Iterator cli(*Doxygen::classSDict); + ClassDef *cd=0; + for (cli.toFirst();(cd=cli.current());++cli) + { + cd->countMembers(); + } + + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); + NamespaceDef *nd=0; + for (nli.toFirst();(nd=nli.current());++nli) + { + nd->countMembers(); + } + + FileNameListIterator fnli(*Doxygen::inputNameList); + FileName *fn; + for (;(fn=fnli.current());++fnli) + { + FileNameIterator fni(*fn); + FileDef *fd; + for (;(fd=fni.current());++fni) + { + fd->countMembers(); + } + } + + GroupSDict::Iterator gli(*Doxygen::groupSDict); + GroupDef *gd; + for (gli.toFirst();(gd=gli.current());++gli) + { + gd->countMembers(); + } +} + + +//---------------------------------------------------------------------------- // generate the documentation of all classes static void generateClassList(ClassSDict &classSDict) @@ -8264,7 +8307,7 @@ static void inheritDocumentation() MemberDef *md; for (;(md=mni.current());++mni) { - //printf("%04d Member `%s'\n",count++,md->name().data()); + //printf("%04d Member '%s'\n",count++,md->name().data()); if (md->documentation().isEmpty() && md->briefDescription().isEmpty()) { // no documentation yet MemberDef *bmd = md->reimplements(); @@ -8302,7 +8345,7 @@ static void combineUsingRelations() FileDef *fd; for (fni.toFirst();(fd=fni.current());++fni) { - fd->visited=FALSE; + fd->setVisited(FALSE); } } for (fnli.toFirst();(fn=fnli.current());++fnli) @@ -8320,7 +8363,7 @@ static void combineUsingRelations() NamespaceDef *nd; for (nli.toFirst() ; (nd=nli.current()) ; ++nli ) { - nd->visited=FALSE; + nd->setVisited(FALSE); } for (nli.toFirst() ; (nd=nli.current()) ; ++nli ) { @@ -8480,7 +8523,7 @@ static void flushCachedTemplateRelations() { if (fmd->isTypedefValCached()) { - ClassDef *cd = fmd->getCachedTypedefVal(); + const ClassDef *cd = fmd->getCachedTypedefVal(); if (cd->isTemplate()) fmd->invalidateTypedefValCache(); } } @@ -8494,7 +8537,7 @@ static void flushCachedTemplateRelations() { if (fmd->isTypedefValCached()) { - ClassDef *cd = fmd->getCachedTypedefVal(); + const ClassDef *cd = fmd->getCachedTypedefVal(); if (cd->isTemplate()) fmd->invalidateTypedefValCache(); } } @@ -8551,27 +8594,24 @@ static void flushUnresolvedRelations() //---------------------------------------------------------------------------- -static void findDefineDocumentation(EntryNav *rootNav) +static void findDefineDocumentation(Entry *root) { - if ((rootNav->section()==Entry::DEFINEDOC_SEC || - rootNav->section()==Entry::DEFINE_SEC) && !rootNav->name().isEmpty() + if ((root->section==Entry::DEFINEDOC_SEC || + root->section==Entry::DEFINE_SEC) && !root->name.isEmpty() ) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - - //printf("found define `%s' `%s' brief=`%s' doc=`%s'\n", + //printf("found define '%s' '%s' brief='%s' doc='%s'\n", // root->name.data(),root->args.data(),root->brief.data(),root->doc.data()); - if (rootNav->tagInfo() && !root->name.isEmpty()) // define read from a tag file + if (root->tagInfo && !root->name.isEmpty()) // define read from a tag file { - MemberDef *md=new MemberDef(rootNav->tagInfo()->tagName,1,1, + MemberDef *md=createMemberDef(root->tagInfo->tagName,1,1, "#define",root->name,root->args,0, Public,Normal,FALSE,Member,MemberType_Define,0,0,""); - md->setTagInfo(rootNav->tagInfo()); + md->setTagInfo(root->tagInfo); md->setLanguage(root->lang); - //printf("Searching for `%s' fd=%p\n",filePathName.data(),fd); - md->setFileDef(rootNav->parent()->fileDef()); + //printf("Searching for '%s' fd=%p\n",filePathName.data(),fd); + md->setFileDef(root->parent()->fileDef()); //printf("Adding member=%s\n",md->name().data()); MemberName *mn; if ((mn=Doxygen::functionNameSDict->find(root->name))) @@ -8609,7 +8649,7 @@ static void findDefineDocumentation(EntryNav *rootNav) md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); } md->setBodySegment(root->bodyLine,root->endBodyLine); - md->setBodyDef(rootNav->fileDef()); + md->setBodyDef(root->fileDef()); md->addSectionsToDefinition(root->anchors); md->setMaxInitLines(root->initLines); md->setRefItems(root->sli); @@ -8631,7 +8671,7 @@ static void findDefineDocumentation(EntryNav *rootNav) { if (md->memberType()==MemberType_Define) { - FileDef *fd=md->getFileDef(); + const FileDef *fd=md->getFileDef(); if (fd && fd->absFilePath()==root->fileName) // doc and define in the same file assume they belong together. { @@ -8653,7 +8693,7 @@ static void findDefineDocumentation(EntryNav *rootNav) md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); } md->setBodySegment(root->bodyLine,root->endBodyLine); - md->setBodyDef(rootNav->fileDef()); + md->setBodyDef(root->fileDef()); md->addSectionsToDefinition(root->anchors); md->setRefItems(root->sli); md->setLanguage(root->lang); @@ -8687,21 +8727,16 @@ static void findDefineDocumentation(EntryNav *rootNav) ); } } - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(findDefineDocumentation,rootNav); + RECURSE_ENTRYTREE(findDefineDocumentation,root); } //---------------------------------------------------------------------------- -static void findDirDocumentation(EntryNav *rootNav) +static void findDirDocumentation(Entry *root) { - if (rootNav->section() == Entry::DIRDOC_SEC) + if (root->section == Entry::DIRDOC_SEC) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - QCString normalizedName = root->name; normalizedName = substitute(normalizedName,"\\","/"); //printf("root->docFile=%s normalizedName=%s\n", @@ -8753,34 +8788,25 @@ static void findDirDocumentation(EntryNav *rootNav) warn(root->fileName,root->startLine,"No matching " "directory found for command \\dir %s\n",normalizedName.data()); } - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(findDirDocumentation,rootNav); + RECURSE_ENTRYTREE(findDirDocumentation,root); } //---------------------------------------------------------------------------- // create a (sorted) list of separate documentation pages -static void buildPageList(EntryNav *rootNav) +static void buildPageList(Entry *root) { - if (rootNav->section() == Entry::PAGEDOC_SEC) + if (root->section == Entry::PAGEDOC_SEC) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - if (!root->name.isEmpty()) { - addRelatedPage(rootNav); + addRelatedPage(root); } - - rootNav->releaseEntry(); } - else if (rootNav->section() == Entry::MAINPAGEDOC_SEC) + else if (root->section == Entry::MAINPAGEDOC_SEC) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - QCString title=root->args.stripWhiteSpace(); if (title.isEmpty()) title=theTranslator->trMainPage(); //QCString name = Config_getBool(GENERATE_TREEVIEW)?"main":"index"; @@ -8792,33 +8818,28 @@ static void buildPageList(EntryNav *rootNav) title, 0,0 ); - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(buildPageList,rootNav); + RECURSE_ENTRYTREE(buildPageList,root); } // search for the main page defined in this project -static void findMainPage(EntryNav *rootNav) +static void findMainPage(Entry *root) { - if (rootNav->section() == Entry::MAINPAGEDOC_SEC) + if (root->section == Entry::MAINPAGEDOC_SEC) { - rootNav->loadEntry(g_storage); - - if (Doxygen::mainPage==0 && rootNav->tagInfo()==0) + if (Doxygen::mainPage==0 && root->tagInfo==0) { - Entry *root = rootNav->entry(); //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"; QCString indexName="index"; - Doxygen::mainPage = new PageDef(root->docFile,root->docLine, + Doxygen::mainPage = createPageDef(root->docFile,root->docLine, 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->setFileName(indexName); Doxygen::mainPage->setLocalToc(root->localToc); - addPageToContext(Doxygen::mainPage,rootNav); + addPageToContext(Doxygen::mainPage,root); SectionInfo *si = Doxygen::sectionDict->find(Doxygen::mainPage->name()); if (si) @@ -8845,46 +8866,37 @@ static void findMainPage(EntryNav *rootNav) Doxygen::mainPage->addSectionsToDefinition(root->anchors); } } - else if (rootNav->tagInfo()==0) + else if (root->tagInfo==0) { - Entry *root = rootNav->entry(); 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()); } - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(findMainPage,rootNav); + RECURSE_ENTRYTREE(findMainPage,root); } // search for the main page imported via tag files and add only the section labels -static void findMainPageTagFiles(EntryNav *rootNav) +static void findMainPageTagFiles(Entry *root) { - if (rootNav->section() == Entry::MAINPAGEDOC_SEC) + if (root->section == Entry::MAINPAGEDOC_SEC) { - rootNav->loadEntry(g_storage); - - if (Doxygen::mainPage && rootNav->tagInfo()) + if (Doxygen::mainPage && root->tagInfo) { - Entry *root = rootNav->entry(); Doxygen::mainPage->addSectionsToDefinition(root->anchors); } } - RECURSE_ENTRYTREE(findMainPageTagFiles,rootNav); + RECURSE_ENTRYTREE(findMainPageTagFiles,root); } -static void computePageRelations(EntryNav *rootNav) +static void computePageRelations(Entry *root) { - if ((rootNav->section()==Entry::PAGEDOC_SEC || - rootNav->section()==Entry::MAINPAGEDOC_SEC + if ((root->section==Entry::PAGEDOC_SEC || + root->section==Entry::MAINPAGEDOC_SEC ) - && !rootNav->name().isEmpty() + && !root->name.isEmpty() ) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - PageDef *pd = root->section==Entry::PAGEDOC_SEC ? Doxygen::pageSDict->find(root->name) : Doxygen::mainPage; @@ -8895,7 +8907,14 @@ static void computePageRelations(EntryNav *rootNav) for (bii.toFirst();(bi=bii.current());++bii) { PageDef *subPd = Doxygen::pageSDict->find(bi->name); - if (subPd) + if (pd==subPd) + { + err("page defined at line %d of file %s with label %s is a direct " + "subpage of itself! Please remove this cyclic dependency.\n", + pd->docLine(),pd->docFile().data(),pd->name().data()); + exit(1); + } + else if (subPd) { pd->addInnerCompound(subPd); //printf("*** Added subpage relation: %s->%s\n", @@ -8903,10 +8922,8 @@ static void computePageRelations(EntryNav *rootNav) } } } - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(computePageRelations,rootNav); + RECURSE_ENTRYTREE(computePageRelations,root); } static void checkPageRelations() @@ -8938,7 +8955,7 @@ static void resolveUserReferences() SectionInfo *si; for (;(si=sdi.current());++sdi) { - //printf("si->label=`%s' si->definition=%s si->fileName=`%s'\n", + //printf("si->label='%s' si->definition=%s si->fileName='%s'\n", // si->label.data(),si->definition?si->definition->name().data():"<none>", // si->fileName.data()); PageDef *pd=0; @@ -8977,10 +8994,10 @@ static void resolveUserReferences() { // TODO: there should be one function in Definition that returns // the file to link to, so we can avoid the following tests. - GroupDef *gd=0; + const GroupDef *gd=0; if (si->definition->definitionType()==Definition::TypeMember) { - gd = ((MemberDef *)si->definition)->getGroupDef(); + gd = (dynamic_cast<MemberDef *>(si->definition))->getGroupDef(); } if (gd) @@ -9025,13 +9042,10 @@ static void generatePageDocs() //---------------------------------------------------------------------------- // create a (sorted) list & dictionary of example pages -static void buildExampleList(EntryNav *rootNav) +static void buildExampleList(Entry *root) { - if ((rootNav->section()==Entry::EXAMPLE_SEC || rootNav->section()==Entry::EXAMPLE_LINENO_SEC) && !rootNav->name().isEmpty()) + if ((root->section==Entry::EXAMPLE_SEC || root->section==Entry::EXAMPLE_LINENO_SEC) && !root->name.isEmpty()) { - rootNav->loadEntry(g_storage); - Entry *root = rootNav->entry(); - if (Doxygen::exampleSDict->find(root->name)) { warn(root->fileName,root->startLine, @@ -9042,38 +9056,36 @@ static void buildExampleList(EntryNav *rootNav) } else { - PageDef *pd=new PageDef(root->fileName,root->startLine, + PageDef *pd=createPageDef(root->fileName,root->startLine, root->name,root->brief+root->doc+root->inbodyDocs,root->args); pd->setBriefDescription(root->brief,root->briefFile,root->briefLine); pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE)); pd->addSectionsToDefinition(root->anchors); pd->setLanguage(root->lang); - pd->setShowLineNo(rootNav->section()==Entry::EXAMPLE_LINENO_SEC); + pd->setShowLineNo(root->section==Entry::EXAMPLE_LINENO_SEC); Doxygen::exampleSDict->inSort(root->name,pd); //we don't add example to groups //addExampleToGroups(root,pd); } - - rootNav->releaseEntry(); } - RECURSE_ENTRYTREE(buildExampleList,rootNav); + RECURSE_ENTRYTREE(buildExampleList,root); } //---------------------------------------------------------------------------- // prints the Entry tree (for debugging) -void printNavTree(EntryNav *rootNav,int indent) +void printNavTree(Entry *root,int indent) { QCString indentStr; indentStr.fill(' ',indent); msg("%s%s (sec=0x%x)\n", indentStr.isEmpty()?"":indentStr.data(), - rootNav->name().isEmpty()?"<empty>":rootNav->name().data(), - rootNav->section()); - if (rootNav->children()) + root->name.isEmpty()?"<empty>":root->name.data(), + root->section); + if (root->children()) { - EntryNavListIterator eli(*rootNav->children()); + EntryListIterator eli(*root->children()); for (;eli.current();++eli) printNavTree(eli.current(),indent+2); } } @@ -9245,7 +9257,7 @@ static void generateConfigFile(const char *configFile,bool shortList, { if (!updateOnly) { - msg("\n\nConfiguration file `%s' created.\n\n",configFile); + msg("\n\nConfiguration file '%s' created.\n\n",configFile); msg("Now edit the configuration file and enter\n\n"); if (qstrcmp(configFile,"Doxyfile") || qstrcmp(configFile,"doxyfile")) msg(" doxygen %s\n\n",configFile); @@ -9255,7 +9267,7 @@ static void generateConfigFile(const char *configFile,bool shortList, } else { - msg("\n\nConfiguration file `%s' updated.\n\n",configFile); + msg("\n\nConfiguration file '%s' updated.\n\n",configFile); } } } @@ -9318,15 +9330,15 @@ static void readTagFile(Entry *root,const char *tl) QFileInfo fi(fileName); if (!fi.exists() || !fi.isFile()) { - err("Tag file `%s' does not exist or is not a file. Skipping it...\n", + err("Tag file '%s' does not exist or is not a file. Skipping it...\n", fileName.data()); return; } if (!destName.isEmpty()) - msg("Reading tag file `%s', location `%s'...\n",fileName.data(),destName.data()); + msg("Reading tag file '%s', location '%s'...\n",fileName.data(),destName.data()); else - msg("Reading tag file `%s'...\n",fileName.data()); + msg("Reading tag file '%s'...\n",fileName.data()); parseTagFile(root,fi.absFilePath().utf8()); } @@ -9465,7 +9477,7 @@ static ParserInterface *getParserForFile(const char *fn) } static void parseFile(ParserInterface *parser, - Entry *root,EntryNav *rootNav,FileDef *fd,const char *fn, + Entry *root,FileDef *fd,const char *fn, bool sameTu,QStrList &filesInSameTu) { #if USE_LIBCLANG @@ -9518,17 +9530,15 @@ static void parseFile(ParserInterface *parser, fd->getAllIncludeFilesRecursively(filesInSameTu); } + Entry *fileRoot = new Entry; // use language parse to parse the file - parser->parseInput(fileName,convBuf.data(),root,sameTu,filesInSameTu); - - // store the Entry tree in a file and create an index to - // navigate/load entries - //printf("root->createNavigationIndex for %s\n",fd->name().data()); - root->createNavigationIndex(rootNav,g_storage,fd); + parser->parseInput(fileName,convBuf.data(),fileRoot,sameTu,filesInSameTu); + fileRoot->setFileDef(fd); + root->addSubEntry(fileRoot); } //! parse the list of input files -static void parseFiles(Entry *root,EntryNav *rootNav) +static void parseFiles(Entry *root) { #if USE_LIBCLANG static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); @@ -9556,7 +9566,7 @@ static void parseFiles(Entry *root,EntryNav *rootNav) QStrList filesInSameTu; ParserInterface * parser = getParserForFile(s->data()); parser->startTranslationUnit(s->data()); - parseFile(parser,root,rootNav,fd,s->data(),FALSE,filesInSameTu); + parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); //printf(" got %d extra files in tu\n",filesInSameTu.count()); // Now process any include files in the same translation unit @@ -9571,7 +9581,7 @@ static void parseFiles(Entry *root,EntryNav *rootNav) { QStrList moreFiles; //printf(" Processing %s in same translation unit as %s\n",incFile,s->data()); - parseFile(parser,root,rootNav,ifd,incFile,TRUE,moreFiles); + parseFile(parser,root,ifd,incFile,TRUE,moreFiles); g_processedFiles.insert(incFile,(void*)0x8); } } @@ -9592,7 +9602,7 @@ static void parseFiles(Entry *root,EntryNav *rootNav) ASSERT(fd!=0); ParserInterface * parser = getParserForFile(s->data()); parser->startTranslationUnit(s->data()); - parseFile(parser,root,rootNav,fd,s->data(),FALSE,filesInSameTu); + parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); parser->finishTranslationUnit(); g_processedFiles.insert(*s,(void*)0x8); } @@ -9611,7 +9621,7 @@ static void parseFiles(Entry *root,EntryNav *rootNav) ASSERT(fd!=0); ParserInterface * parser = getParserForFile(s->data()); parser->startTranslationUnit(s->data()); - parseFile(parser,root,rootNav,fd,s->data(),FALSE,filesInSameTu); + parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); } } } @@ -9687,8 +9697,8 @@ static QCString resolveSymlink(QCString path) static QDict<void> g_pathsVisited(1009); //---------------------------------------------------------------------------- -// Read all files matching at least one pattern in `patList' in the -// directory represented by `fi'. +// Read all files matching at least one pattern in 'patList' in the +// directory represented by 'fi'. // The directory is read iff the recusiveFlag is set. // The contents of all files is append to the input string @@ -9754,7 +9764,7 @@ int readDir(QFileInfo *fi, //printf("New file %s\n",name.data()); if (fnDict) { - FileDef *fd=new FileDef(cfi->dirPath().utf8()+"/",name); + FileDef *fd=createFileDef(cfi->dirPath().utf8()+"/",name); FileName *fn=0; if (!name.isEmpty() && (fn=(*fnDict)[name])) { @@ -9798,7 +9808,7 @@ int readDir(QFileInfo *fi, //---------------------------------------------------------------------------- // read a file or all files in a directory and append their contents to the -// input string. The names of the files are appended to the `fiList' list. +// input string. The names of the files are appended to the 'fiList' list. int readFileOrDirectory(const char *s, FileNameList *fnList, @@ -9853,7 +9863,7 @@ int readFileOrDirectory(const char *s, //printf("New file %s\n",name.data()); if (fnDict) { - FileDef *fd=new FileDef(dirPath+"/",name); + FileDef *fd=createFileDef(dirPath+"/",name); FileName *fn=0; if (!name.isEmpty() && (fn=(*fnDict)[name])) { @@ -10001,7 +10011,7 @@ static void escapeAliases() while ((in=value.find("^^",p))!=-1) { newValue+=value.mid(p,in-p); - newValue+="@_linebr"; + newValue+="\\\\_linebr "; p=in+2; } newValue+=value.mid(p,value.length()-p); @@ -10028,7 +10038,7 @@ void readAliases() { QCString name=alias.left(i).stripWhiteSpace(); QCString value=alias.right(alias.length()-i-1); - //printf("Alias: found name=`%s' value=`%s'\n",name.data(),value.data()); + //printf("Alias: found name='%s' value='%s'\n",name.data(),value.data()); if (!name.isEmpty()) { QCString *dn=Doxygen::aliasDict[name]; @@ -10056,7 +10066,7 @@ static void dumpSymbol(FTextStream &t,Definition *d) QCString anchor; if (d->definitionType()==Definition::TypeMember) { - MemberDef *md = (MemberDef *)d; + MemberDef *md = dynamic_cast<MemberDef *>(d); anchor=":"+md->anchor(); } QCString scope; @@ -10117,9 +10127,9 @@ static void devUsage() //---------------------------------------------------------------------------- // print the usage of doxygen -static void usage(const char *name) +static void usage(const char *name,const char *versionString) { - msg("Doxygen version %s\nCopyright Dimitri van Heesch 1997-2015\n\n",versionString); + msg("Doxygen version %s\nCopyright Dimitri van Heesch 1997-2019\n\n",versionString); msg("You can use doxygen in a number of ways:\n\n"); msg("1) Use doxygen to generate a template configuration file:\n"); msg(" %s [-s] -g [configName]\n\n",name); @@ -10141,17 +10151,17 @@ static void usage(const char *name) msg(" RTF: %s -e rtf extensionsFile\n\n",name); msg("7) Use doxygen to compare the used configuration file with the template configuration file\n"); msg(" %s -x [configFile]\n\n",name); - msg("8) Use doxygen to show a list of build in emoji.\n"); + msg("8) Use doxygen to show a list of built-in emojis.\n"); msg(" %s -f emoji outputFileName\n\n",name); msg(" If - is used for outputFileName doxygen will write to standard output.\n\n"); msg("If -s is specified the comments of the configuration items in the config file will be omitted.\n"); - msg("If configName is omitted `Doxyfile' will be used as a default.\n\n"); + msg("If configName is omitted 'Doxyfile' will be used as a default.\n\n"); msg("-v print version string\n"); } //---------------------------------------------------------------------------- -// read the argument of option `c' from the comment argument list and -// update the option index `optind'. +// read the argument of option 'c' from the comment argument list and +// update the option index 'optind'. static const char *getArg(int argc,char **argv,int &optind) { @@ -10336,6 +10346,16 @@ static int computeIdealCacheParam(uint v) void readConfiguration(int argc, char **argv) { + QCString versionString; + if (strlen(getGitVersion())>0) + { + versionString = QCString(getVersion())+" ("+getGitVersion()+")"; + } + else + { + versionString = getVersion(); + } + /************************************************************************** * Handle arguments * **************************************************************************/ @@ -10579,26 +10599,26 @@ void readConfiguration(int argc, char **argv) g_dumpSymbolMap = TRUE; break; case 'v': - msg("%s\n",versionString); + msg("%s\n",versionString.data()); cleanUpDoxygen(); exit(0); break; case '-': if (qstrcmp(&argv[optind][2],"help")==0) { - usage(argv[0]); + usage(argv[0],versionString); exit(0); } else if (qstrcmp(&argv[optind][2],"version")==0) { - msg("%s\n",versionString); + msg("%s\n",versionString.data()); cleanUpDoxygen(); exit(0); } else { err("Unknown option \"-%s\"\n",&argv[optind][1]); - usage(argv[0]); + usage(argv[0],versionString); exit(1); } break; @@ -10614,12 +10634,12 @@ void readConfiguration(int argc, char **argv) break; case 'h': case '?': - usage(argv[0]); + usage(argv[0],versionString); exit(0); break; default: err("Unknown option \"-%c\"\n",argv[optind][1]); - usage(argv[0]); + usage(argv[0],versionString); exit(1); } optind++; @@ -10649,7 +10669,7 @@ void readConfiguration(int argc, char **argv) else { err("Doxyfile not found and no input file specified!\n"); - usage(argv[0]); + usage(argv[0],versionString); exit(1); } } @@ -10663,7 +10683,7 @@ void readConfiguration(int argc, char **argv) else { err("configuration file %s not found!\n",argv[optind]); - usage(argv[0]); + usage(argv[0],versionString); exit(1); } } @@ -10721,7 +10741,7 @@ void checkConfiguration() /** adjust globals that depend on configuration settings. */ void adjustConfiguration() { - Doxygen::globalScope = new NamespaceDef("<globalScope>",1,1,"<globalScope>"); + Doxygen::globalScope = createNamespaceDef("<globalScope>",1,1,"<globalScope>"); Doxygen::inputNameDict = new FileNameDict(10007); Doxygen::includeNameDict = new FileNameDict(10007); Doxygen::exampleNameDict = new FileNameDict(1009); @@ -11138,14 +11158,14 @@ void parseInput() dir.setPath(QDir::currentDirPath()); if (!dir.mkdir(outputDirectory)) { - err("tag OUTPUT_DIRECTORY: Output directory `%s' does not " + err("tag OUTPUT_DIRECTORY: Output directory '%s' does not " "exist and cannot be created\n",outputDirectory.data()); cleanUpDoxygen(); exit(1); } else { - msg("Notice: Output directory `%s' does not exist. " + msg("Notice: Output directory '%s' does not exist. " "I have created it for you.\n", outputDirectory.data()); } dir.cd(outputDirectory); @@ -11157,7 +11177,7 @@ void parseInput() * Initialize global lists and dictionaries **************************************************************************/ - Doxygen::symbolStorage = new Store; + //Doxygen::symbolStorage = new Store; // also scale lookup cache with SYMBOL_CACHE_SIZE int cacheSize = Config_getInt(LOOKUP_CACHE_SIZE); @@ -11179,11 +11199,11 @@ void parseInput() Doxygen::filterDBFileName.sprintf("doxygen_filterdb_%d.tmp",pid); Doxygen::filterDBFileName.prepend(outputDirectory+"/"); - if (Doxygen::symbolStorage->open(Doxygen::objDBFileName)==-1) - { - err("Failed to open temporary file %s\n",Doxygen::objDBFileName.data()); - exit(1); - } +// if (Doxygen::symbolStorage->open(Doxygen::objDBFileName)==-1) +// { +// err("Failed to open temporary file %s\n",Doxygen::objDBFileName.data()); +// exit(1); +// } @@ -11265,9 +11285,7 @@ void parseInput() if (layoutFile.open(IO_ReadOnly)) { msg("Parsing layout file %s...\n",layoutFileName.data()); - QTextStream t(&layoutFile); - t.setEncoding(QTextStream::Latin1); - LayoutDocManager::instance().parse(t,layoutFileName); + LayoutDocManager::instance().parse(layoutFileName); } else if (!defaultLayoutUsed) { @@ -11311,17 +11329,7 @@ void parseInput() * Handle Tag Files * **************************************************************************/ - g_storage = new FileStorage; - g_storage->setName(Doxygen::entryDBFileName); - if (!g_storage->open(IO_WriteOnly)) - { - err("Failed to create temporary storage file %s\n", - Doxygen::entryDBFileName.data()); - exit(1); - } Entry *root=new Entry; - EntryNav *rootNav = new EntryNav(0,root); - rootNav->setEntry(root); msg("Reading and parsing tag files\n"); QStrList &tagFileList = Config_getList(TAGFILES); @@ -11329,7 +11337,6 @@ void parseInput() while (s) { readTagFile(root,s); - root->createNavigationIndex(rootNav,g_storage,0); s=tagFileList.next(); } @@ -11339,12 +11346,11 @@ void parseInput() if (Config_getBool(BUILTIN_STL_SUPPORT)) { - addSTLClasses(rootNav); + addSTLClasses(root); } g_s.begin("Parsing files\n"); - parseFiles(root,rootNav); - g_storage->close(); + parseFiles(root); g_s.end(); // we are done with input scanning now, so free up the buffers used by flex @@ -11353,46 +11359,36 @@ void parseInput() scanFreeScanner(); pyscanFreeScanner(); - if (!g_storage->open(IO_ReadOnly)) - { - err("Failed to open temporary storage file %s for reading", - Doxygen::entryDBFileName.data()); - exit(1); - } - /************************************************************************** * Gather information * **************************************************************************/ g_s.begin("Building group list...\n"); - buildGroupList(rootNav); - organizeSubGroups(rootNav); + buildGroupList(root); + organizeSubGroups(root); g_s.end(); g_s.begin("Building directory list...\n"); buildDirectories(); - findDirDocumentation(rootNav); + findDirDocumentation(root); g_s.end(); g_s.begin("Building namespace list...\n"); - buildNamespaceList(rootNav); - findUsingDirectives(rootNav); + buildNamespaceList(root); + findUsingDirectives(root); g_s.end(); g_s.begin("Building file list...\n"); - buildFileList(rootNav); + buildFileList(root); g_s.end(); //generateFileTree(); g_s.begin("Building class list...\n"); - buildClassList(rootNav); + buildClassList(root); g_s.end(); - g_s.begin("Associating documentation with classes...\n"); - buildClassDocList(rootNav); - // build list of using declarations here (global list) - buildListOfUsingDecls(rootNav); + buildListOfUsingDecls(root); g_s.end(); g_s.begin("Computing nesting relations for classes...\n"); @@ -11408,12 +11404,15 @@ void parseInput() // we don't need the list of using declaration anymore g_usingDeclarations.clear(); + g_s.begin("Associating documentation with classes...\n"); + buildClassDocList(root); + g_s.begin("Building example list...\n"); - buildExampleList(rootNav); + buildExampleList(root); g_s.end(); g_s.begin("Searching for enumerations...\n"); - findEnums(rootNav); + findEnums(root); g_s.end(); // Since buildVarList calls isVarWithConstructor @@ -11421,24 +11420,24 @@ void parseInput() // typedefs first so the relations between classes via typedefs // are properly resolved. See bug 536385 for an example. g_s.begin("Searching for documented typedefs...\n"); - buildTypedefList(rootNav); + buildTypedefList(root); g_s.end(); if (Config_getBool(OPTIMIZE_OUTPUT_SLICE)) { g_s.begin("Searching for documented sequences...\n"); - buildSequenceList(rootNav); + buildSequenceList(root); g_s.end(); g_s.begin("Searching for documented dictionaries...\n"); - buildDictionaryList(rootNav); + buildDictionaryList(root); g_s.end(); } g_s.begin("Searching for members imported via using declarations...\n"); // this should be after buildTypedefList in order to properly import // used typedefs - findUsingDeclarations(rootNav); + findUsingDeclarations(root); g_s.end(); g_s.begin("Searching for included using directives...\n"); @@ -11446,14 +11445,14 @@ void parseInput() g_s.end(); g_s.begin("Searching for documented variables...\n"); - buildVarList(rootNav); + buildVarList(root); g_s.end(); g_s.begin("Building interface member list...\n"); - buildInterfaceAndServiceList(rootNav); // UNO IDL + buildInterfaceAndServiceList(root); // UNO IDL g_s.begin("Building member list...\n"); // using class info only ! - buildFunctionList(rootNav); + buildFunctionList(root); g_s.end(); g_s.begin("Searching for friends...\n"); @@ -11461,11 +11460,11 @@ void parseInput() g_s.end(); g_s.begin("Searching for documented defines...\n"); - findDefineDocumentation(rootNav); + findDefineDocumentation(root); g_s.end(); g_s.begin("Computing class inheritance relations...\n"); - findClassEntries(rootNav); + findClassEntries(root); findInheritedTemplateInstances(); g_s.end(); @@ -11496,14 +11495,14 @@ void parseInput() g_s.end(); g_s.begin("Add enum values to enums...\n"); - addEnumValuesToEnums(rootNav); - findEnumDocumentation(rootNav); + addEnumValuesToEnums(root); + findEnumDocumentation(root); g_s.end(); g_s.begin("Searching for member function documentation...\n"); - findObjCMethodDefinitions(rootNav); - findMemberDocumentation(rootNav); // may introduce new members ! - findUsingDeclImports(rootNav); // may introduce new members ! + findObjCMethodDefinitions(root); + findMemberDocumentation(root); // may introduce new members ! + findUsingDeclImports(root); // may introduce new members ! transferRelatedFunctionDocumentation(); transferFunctionDocumentation(); @@ -11516,21 +11515,21 @@ void parseInput() g_s.end(); g_s.begin("Building page list...\n"); - buildPageList(rootNav); + buildPageList(root); g_s.end(); g_s.begin("Search for main page...\n"); - findMainPage(rootNav); - findMainPageTagFiles(rootNav); + findMainPage(root); + findMainPageTagFiles(root); g_s.end(); g_s.begin("Computing page relations...\n"); - computePageRelations(rootNav); + computePageRelations(root); checkPageRelations(); g_s.end(); g_s.begin("Determining the scope of groups...\n"); - findGroupScope(rootNav); + findGroupScope(root); g_s.end(); g_s.begin("Sorting lists...\n"); @@ -11540,12 +11539,6 @@ void parseInput() Doxygen::classSDict->sort(); g_s.end(); - msg("Freeing entry tree\n"); - delete rootNav; - g_storage->close(); - delete g_storage; - g_storage=0; - QDir thisDir; thisDir.remove(Doxygen::entryDBFileName); @@ -11603,6 +11596,10 @@ void parseInput() sortMemberLists(); g_s.end(); + g_s.begin("Setting anonymous enum type...\n"); + setAnonymousEnumType(); + g_s.end(); + if (Config_getBool(DIRECTORY_GRAPH)) { g_s.begin("Computing dependencies between directories...\n"); @@ -11617,6 +11614,10 @@ void parseInput() Doxygen::citeDict->generatePage(); g_s.end(); + g_s.begin("Counting members...\n"); + countMembers(); + g_s.end(); + g_s.begin("Counting data structures...\n"); countDataStructures(); g_s.end(); @@ -11640,6 +11641,11 @@ void parseInput() g_s.begin("Adding members to index pages...\n"); addMembersToIndex(); g_s.end(); + + g_s.begin("Correcting members for VHDL...\n"); + vhdlCorrectMemberProperties(); + g_s.end(); + } void generateOutput() @@ -11659,6 +11665,7 @@ void generateOutput() } initSearchIndexer(); + initDot(); bool generateHtml = Config_getBool(GENERATE_HTML); bool generateLatex = Config_getBool(GENERATE_LATEX); @@ -11713,7 +11720,7 @@ void generateOutput() QCString htmldir = Config_getString(HTML_OUTPUT); if (!Htags::execute(htmldir)) err("USE_HTAGS is YES but htags(1) failed. \n"); - if (!Htags::loadFilemap(htmldir)) + else if (!Htags::loadFilemap(htmldir)) err("htags(1) ended normally but failed to load the filemap. \n"); } @@ -11721,11 +11728,6 @@ void generateOutput() * Generate documentation * **************************************************************************/ - if (generateHtml) writeDoxFont(Config_getString(HTML_OUTPUT)); - if (generateLatex) writeDoxFont(Config_getString(LATEX_OUTPUT)); - if (generateDocbook) writeDoxFont(Config_getString(DOCBOOK_OUTPUT)); - if (generateRtf) writeDoxFont(Config_getString(RTF_OUTPUT)); - g_s.begin("Generating style sheet...\n"); //printf("writing style info\n"); g_outputList->writeStyleInfo(0); // write first part @@ -11765,12 +11767,9 @@ void generateOutput() generateExampleDocs(); g_s.end(); - if (!Htags::useHtags) - { - g_s.begin("Generating file sources...\n"); - generateFileSources(); - g_s.end(); - } + g_s.begin("Generating file sources...\n"); + generateFileSources(); + g_s.end(); g_s.begin("Generating file documentation...\n"); generateFileDocs(); @@ -11848,18 +11847,6 @@ void generateOutput() writeTagFile(); g_s.end(); - if (Config_getBool(DOT_CLEANUP)) - { - if (generateHtml) - removeDoxFont(Config_getString(HTML_OUTPUT)); - if (generateRtf) - removeDoxFont(Config_getString(RTF_OUTPUT)); - if (generateLatex) - removeDoxFont(Config_getString(LATEX_OUTPUT)); - if (generateDocbook) - removeDoxFont(Config_getString(DOCBOOK_OUTPUT)); - } - if (Config_getBool(GENERATE_XML)) { g_s.begin("Generating XML output...\n"); @@ -11924,6 +11911,10 @@ void generateOutput() g_s.end(); } + g_s.begin("Running plantuml with JAVA...\n"); + PlantumlManager::instance()->run(); + g_s.end(); + if (Config_getBool(HAVE_DOT)) { g_s.begin("Running dot...\n"); @@ -12024,7 +12015,7 @@ void generateOutput() cleanUpDoxygen(); finializeSearchIndexer(); - Doxygen::symbolStorage->close(); +// Doxygen::symbolStorage->close(); QDir thisDir; thisDir.remove(Doxygen::objDBFileName); thisDir.remove(Doxygen::filterDBFileName); @@ -12032,7 +12023,7 @@ void generateOutput() QTextCodec::deleteAllCodecs(); delete Doxygen::symbolMap; delete Doxygen::clangUsrMap; - delete Doxygen::symbolStorage; +// delete Doxygen::symbolStorage; g_successfulRun=TRUE; } diff --git a/src/doxygen.h b/src/doxygen.h index 4ff8a56..c8eee7c 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -27,6 +27,7 @@ #include "membergroup.h" #include "dirdef.h" #include "memberlist.h" +#include "docgroup.h" class RefList; class PageSList; @@ -76,10 +77,10 @@ class StringDict : public QDict<QCString> struct LookupInfo { LookupInfo() : classDef(0), typeDef(0) {} - LookupInfo(ClassDef *cd,MemberDef *td,QCString ts,QCString rt) + LookupInfo(const ClassDef *cd,const MemberDef *td,QCString ts,QCString rt) : classDef(cd), typeDef(td), templSpec(ts),resolvedType(rt) {} - ClassDef *classDef; - MemberDef *typeDef; + const ClassDef *classDef; + const MemberDef *typeDef; QCString templSpec; QCString resolvedType; }; @@ -150,6 +151,7 @@ class Doxygen static bool generatingXmlOutput; static bool markdownSupport; static GenericsSDict *genericsDict; + static DocGroup docGroup; }; void initDoxygen(); diff --git a/src/doxygen.md b/src/doxygen.md index 17144ec..7680a94 100644 --- a/src/doxygen.md +++ b/src/doxygen.md @@ -2,17 +2,17 @@ Doxygen Internals {#mainpage} ================= Introduction ------------- +============ This page provides a high-level overview of the internals of doxygen, with links to the relevant parts of the code. This document is intended for developers who want to work on doxygen. Users of doxygen are referred to the -[User Manual](http://www.doxygen.org/manual.html). +[User Manual](http://www.doxygen.nl/manual/index.html). The generic starting point of the application is of course the main() function. Configuration options ---------------------- +===================== Configuration file data is stored in singleton class Config and can be accessed using wrapper macros @@ -22,20 +22,20 @@ option. The format of the configuration file (options and types) is defined by the file `config.xml`. As part of the build process, -the python script `configgen.py` will create a file configoptions.cpp +the python script `configgen.py` will create a file `configoptions.cpp` from this, which serves as the input for the configuration file parser that is invoked using Config::parse(). The script `configgen.py` will also create the documentation for the configuration items, creating the file `config.doc`. Gathering Input files ---------------------- +===================== After the configuration is known, the input files are searched using searchInputFiles() and any tag files are read using readTagFile() Parsing Input files -------------------- +=================== The function parseFiles() takes care of parsing all files. It uses the ParserManager singleton factory to create a suitable parser object @@ -71,7 +71,7 @@ extracted like section labels, xref items, and formulas. Also Markdown markup is processed using processMarkdown() during this pass. Resolving relations -------------------- +=================== The Entry objects created and filled during parsing are stored on disk (to keep memory needs low). The name, parent/child relation, and @@ -98,7 +98,7 @@ Finally the data for members of classes, namespaces, and files is stored in the subclass MemberDef. Producing debug output ----------------------- +====================== Within doxygen there are a number of ways to obtain debug output. Besides the invasive method of putting print statements in the code there are a number of @@ -174,12 +174,12 @@ easy ways to get debug information. problem occurs. This makes it easier to select the file to be compiled in `lex` debug mode. Producing output ----------------- +================ TODO Topics TODO ------------ +=========== - Grouping of files in Model / Parser / Generator categories - Index files based on IndexIntf - HTML navigation diff --git a/src/eclipsehelp.cpp b/src/eclipsehelp.cpp index bf150b4..dab001a 100644 --- a/src/eclipsehelp.cpp +++ b/src/eclipsehelp.cpp @@ -174,7 +174,7 @@ void EclipseHelp::addContentsItem( const char *anchor, bool /* separateIndex */, bool /* addToNavIndex */, - Definition * /*def*/) + const Definition * /*def*/) { // -- write the topic tag closedTag(); @@ -216,8 +216,8 @@ void EclipseHelp::addContentsItem( } void EclipseHelp::addIndexItem( - Definition * /* context */, - MemberDef * /* md */, + const Definition * /* context */, + const MemberDef * /* md */, const char * /* sectionAnchor */, const char * /* title */) { diff --git a/src/eclipsehelp.h b/src/eclipsehelp.h index a7cde1e..5d63768 100644 --- a/src/eclipsehelp.h +++ b/src/eclipsehelp.h @@ -50,8 +50,8 @@ class EclipseHelp : public IndexIntf virtual void decContentsDepth(); virtual void addContentsItem(bool isDir, const char *name, const char *ref, const char *file, const char *anchor,bool separateIndex,bool addToNavIndex, - Definition *def); - virtual void addIndexItem(Definition *context,MemberDef *md, + const Definition *def); + virtual void addIndexItem(const Definition *context,const MemberDef *md, const char *sectionAnchor,const char *title); virtual void addIndexFile(const char *name); virtual void addImageFile(const char *name); diff --git a/src/emoji.cpp b/src/emoji.cpp index c332083..311f748 100644 --- a/src/emoji.cpp +++ b/src/emoji.cpp @@ -1578,7 +1578,7 @@ void EmojiEntityMapper::writeEmojiFile(QFile &file) /*! @brief Access routine to the unicode sequence for the Emoji entity * - * @param symb code of the requested Emoji entity returned by symbol2index() + * @param index code of the requested Emoji entity returned by symbol2index() * @return the unicode sequence of the Emoji entity, */ const char *EmojiEntityMapper::unicode(int index) const @@ -1588,7 +1588,7 @@ const char *EmojiEntityMapper::unicode(int index) const /*! @brief Access routine to the name of the Emoji entity * - * @param symb code of the requested Emoji entity returned by symbol2index() + * @param index code of the requested Emoji entity returned by symbol2index() * @return the name of the Emoji entity in GitHub format (i.e. :smile:) */ const char *EmojiEntityMapper::name(int index) const diff --git a/src/entry.cpp b/src/entry.cpp index b3693cd..e2a21c6 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -18,11 +18,9 @@ #include <stdlib.h> #include <qfile.h> #include "entry.h" -#include "marshal.h" #include "util.h" #include "section.h" #include "doxygen.h" -#include "filestorage.h" #include "arguments.h" #include "config.h" //------------------------------------------------------------------ @@ -185,6 +183,8 @@ Entry::Entry(const Entry &e) tArgLists = copyArgumentLists(e.tArgLists); } + m_fileDef = e.m_fileDef; + } Entry::~Entry() @@ -281,6 +281,7 @@ void Entry::reset() if (sli) { delete sli; sli=0; } if (typeConstr) { delete typeConstr; typeConstr=0; } //if (mtArgList) { delete mtArgList; mtArgList=0; } + m_fileDef = 0; } @@ -289,31 +290,20 @@ int Entry::getSize() return sizeof(Entry); } -void Entry::createSubtreeIndex(EntryNav *nav,FileStorage *storage,FileDef *fd) +void Entry::setFileDef(FileDef *fd) { - EntryNav *childNav = new EntryNav(nav,this); - nav->addChild(childNav); - childNav->setFileDef(fd); - childNav->saveEntry(this,storage); + m_fileDef = fd; if (m_sublist) { - //printf("saveEntry: %d children\n",node->sublist->count()); QListIterator<Entry> eli(*m_sublist); Entry *childNode; for (eli.toFirst();(childNode=eli.current());++eli) { - childNode->createSubtreeIndex(childNav,storage,fd); + childNode->setFileDef(fd); } - //m_sublist->setAutoDelete(FALSE); - m_sublist->clear(); } } -void Entry::createNavigationIndex(EntryNav *rootNav,FileStorage *storage,FileDef *fd) -{ - createSubtreeIndex(rootNav,storage,fd); -} - void Entry::addSpecialListItem(const char *listName,int itemId) { if (sli==0) @@ -334,107 +324,3 @@ Entry *Entry::removeSubEntry(Entry *e) } //------------------------------------------------------------------ - - -EntryNav::EntryNav(EntryNav *parent, Entry *e) - : m_parent(parent), m_subList(0), m_section(e->section), m_type(e->type), - m_name(e->name), m_fileDef(0), m_lang(e->lang), - m_info(0), m_offset(-1), m_noLoad(FALSE) -{ - if (e->tagInfo) - { - m_tagInfo = new TagInfo; - m_tagInfo->tagName = e->tagInfo->tagName; - m_tagInfo->fileName = e->tagInfo->fileName; - m_tagInfo->anchor = e->tagInfo->anchor; - if (e->tagInfo) - { - //printf("tagInfo %p: tagName=%s fileName=%s anchor=%s\n", - // e->tagInfo, - // e->tagInfo->tagName.data(), - // e->tagInfo->fileName.data(), - // e->tagInfo->anchor.data()); - } - } - else - { - m_tagInfo = 0; - } -} - -EntryNav::~EntryNav() -{ - delete m_subList; - delete m_info; - delete m_tagInfo; -} - -void EntryNav::addChild(EntryNav *e) -{ - if (m_subList==0) - { - m_subList = new QList<EntryNav>; - m_subList->setAutoDelete(TRUE); - } - m_subList->append(e); -} - -bool EntryNav::loadEntry(FileStorage *storage) -{ - if (m_noLoad) - { - return TRUE; - } - if (m_offset==-1) - { - //printf("offset not set!\n"); - return FALSE; - } - //delete m_info; - //printf("EntryNav::loadEntry: new entry %p: %s\n",m_info,m_name.data()); - //m_info->tagInfo = m_tagInfo; - //if (m_parent) - //{ - // m_info->parent = m_parent->m_info; - //} - //m_info->parent = 0; - //printf("load entry: seek to %llx\n",m_offset); - if (!storage->seek(m_offset)) - { - //printf("seek failed!\n"); - return FALSE; - } - if (m_info) delete m_info; - m_info = unmarshalEntry(storage); - m_info->name = m_name; - m_info->type = m_type; - m_info->section = m_section; - return TRUE; -} - -bool EntryNav::saveEntry(Entry *e,FileStorage *storage) -{ - m_offset = storage->pos(); - //printf("EntryNav::saveEntry offset=%llx\n",m_offset); - marshalEntry(storage,e); - return TRUE; -} - -void EntryNav::releaseEntry() -{ - if (!m_noLoad) - { - //printf("EntryNav::releaseEntry %p\n",m_info); - delete m_info; - m_info=0; - } -} - -void EntryNav::setEntry(Entry *e) -{ - delete m_info; - m_info = e; - //printf("EntryNav::setEntry %p\n",e); - m_noLoad=TRUE; -} - diff --git a/src/entry.h b/src/entry.h index 44e47da..6dfa0c6 100644 --- a/src/entry.h +++ b/src/entry.h @@ -25,7 +25,6 @@ struct SectionInfo; class QFile; -class EntryNav; class FileDef; class FileStorage; class StorageIntf; @@ -138,6 +137,7 @@ class Entry static const uint64 Local = (1ULL<<16); // for Slice types // member specifiers (add new items to the beginning) + static const uint64 ConstExpr = (1ULL<<19); // C++11 constexpr static const uint64 PrivateGettable = (1ULL<<20); // C# private getter static const uint64 ProtectedGettable = (1ULL<<21); // C# protected getter static const uint64 PrivateSettable = (1ULL<<22); // C# private setter @@ -186,7 +186,7 @@ class Entry enum GroupDocType { GROUPDOC_NORMAL, //!< defgroup - GROUPDOC_ADD, //!< addgroup + GROUPDOC_ADD, //!< addtogroup GROUPDOC_WEAK //!< weakgroup }; //!< kind of group @@ -198,7 +198,6 @@ class Entry int getSize(); void addSpecialListItem(const char *listName,int index); - void createNavigationIndex(EntryNav *rootNav,FileStorage *storage,FileDef *fd); // while parsing a file these function can be used to navigate/build the tree void setParent(Entry *parent) { m_parent = parent; } @@ -225,11 +224,9 @@ class Entry */ void reset(); - /*! Serialize this entry to a persistent storage stream. */ - void marshall(StorageIntf *); - - /*! Reinitialize this entry from a persistent storage stream. */ - void unmarshall(StorageIntf *); + void changeSection(int sec) { section = sec; } + void setFileDef(FileDef *fd); + FileDef *fileDef() const { return m_fileDef; } public: @@ -304,7 +301,7 @@ class Entry switch( groupDocType ) { case GROUPDOC_NORMAL: return "\\defgroup"; - case GROUPDOC_ADD: return "\\addgroup"; + case GROUPDOC_ADD: return "\\addtogroup"; case GROUPDOC_WEAK: return "\\weakgroup"; default: return "unknown group command"; } @@ -325,64 +322,13 @@ class Entry } private: - void createSubtreeIndex(EntryNav *nav,FileStorage *storage,FileDef *fd); Entry *m_parent; //!< parent node in the tree QList<Entry> *m_sublist; //!< entries that are children of this one Entry &operator=(const Entry &); + FileDef *m_fileDef; }; -/** Wrapper for a node in the Entry tree. - * - * Allows navigating through the Entry tree and load and storing Entry - * objects persistently to disk. - */ -class EntryNav -{ - public: - EntryNav(EntryNav *parent,Entry *e); - ~EntryNav(); - void addChild(EntryNav *); - bool loadEntry(FileStorage *storage); - bool saveEntry(Entry *e,FileStorage *storage); - void setEntry(Entry *e); - void releaseEntry(); - void changeSection(int section) { m_section = section; } - void setFileDef(FileDef *fd) { m_fileDef = fd; } - - Entry *entry() const { return m_info; } - int section() const { return m_section; } - SrcLangExt lang() const { return m_lang; } - const QCString &type() const { return m_type; } - const QCString &name() const { return m_name; } - TagInfo *tagInfo() const { return m_tagInfo; } - const QList<EntryNav> *children() const { return m_subList; } - EntryNav *parent() const { return m_parent; } - FileDef *fileDef() const { return m_fileDef; } - - private: - - // navigation - EntryNav *m_parent; //!< parent node in the tree - QList<EntryNav> *m_subList; //!< entries that are children of this one - - // identification - int m_section; //!< entry type (see Sections); - QCString m_type; //!< member type - QCString m_name; //!< member name - TagInfo *m_tagInfo; //!< tag file info - FileDef *m_fileDef; - SrcLangExt m_lang; //!< programming language in which this entry was found - - Entry *m_info; - int64 m_offset; - bool m_noLoad; -}; - - typedef QList<Entry> EntryList; typedef QListIterator<Entry> EntryListIterator; -typedef QList<EntryNav> EntryNavList; -typedef QListIterator<EntryNav> EntryNavListIterator; - #endif diff --git a/src/filedef.cpp b/src/filedef.cpp index f9f68d1..9a82c8a 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -26,6 +26,7 @@ #include "language.h" #include "outputlist.h" #include "dot.h" +#include "dotincldepgraph.h" #include "message.h" #include "docparser.h" #include "searchindex.h" @@ -43,6 +44,147 @@ #include "config.h" #include "clangparser.h" #include "settings.h" +#include "definitionimpl.h" + +//--------------------------------------------------------------------------- + +class FileDefImpl : public DefinitionImpl, public FileDef +{ + public: + FileDefImpl(const char *p,const char *n,const char *ref=0,const char *dn=0); + virtual ~FileDefImpl(); + + virtual DefType definitionType() const { return TypeFile; } + virtual QCString name() const; + virtual QCString displayName(bool=TRUE) const { return name(); } + virtual QCString fileName() const { return m_fileName; } + virtual QCString getOutputFileBase() const; + virtual QCString anchor() const { return QCString(); } + virtual QCString getSourceFileBase() const; + virtual QCString includeName() const; + virtual QCString includeDependencyGraphFileName() const; + virtual QCString includedByDependencyGraphFileName() const; + virtual QCString absFilePath() const { return m_filePath; } + virtual const QCString &docName() const { return m_docname; } + virtual bool isSource() const { return m_isSource; } + virtual bool isDocumentationFile() const; + virtual Definition *getSourceDefinition(int lineNr) const; + virtual MemberDef *getSourceMember(int lineNr) const; + virtual QCString getPath() const { return m_path; } + virtual QCString getVersion() const { return m_fileVersion; } + virtual bool isLinkableInProject() const; + virtual bool isLinkable() const { return isLinkableInProject() || isReference(); } + virtual bool isIncluded(const QCString &name) const; + virtual PackageDef *packageDef() const { return m_package; } + virtual DirDef *getDirDef() const { return m_dir; } + virtual NamespaceSDict *getUsedNamespaces() const; + virtual SDict<Definition> *getUsedClasses() const { return m_usingDeclList; } + virtual QList<IncludeInfo> *includeFileList() const { return m_includeList; } + virtual QList<IncludeInfo> *includedByFileList() const { return m_includedByList; } + virtual void getAllIncludeFilesRecursively(QStrList &incFiles) const; + virtual MemberList *getMemberList(MemberListType lt) const; + virtual const QList<MemberList> &getMemberLists() const { return m_memberLists; } + virtual MemberGroupSDict *getMemberGroupSDict() const { return m_memberGroupSDict; } + virtual NamespaceSDict *getNamespaceSDict() const { return m_namespaceSDict; } + virtual ClassSDict *getClassSDict() const { return m_classSDict; } + virtual QCString title() const; + virtual bool hasDetailedDescription() const; + virtual QCString fileVersion() const; + virtual bool subGrouping() const { return m_subGrouping; } + virtual void countMembers(); + virtual int numDocMembers() const; + virtual int numDecMembers() const; + virtual void addSourceRef(int line,Definition *d,MemberDef *md); + virtual void writeDocumentation(OutputList &ol); + virtual void writeMemberPages(OutputList &ol); + virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const; + virtual void writeSummaryLinks(OutputList &ol) const; + virtual void writeTagFile(FTextStream &t); + virtual void startParsing(); + virtual void writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu); + virtual void parseSource(bool sameTu,QStrList &filesInSameTu); + virtual void finishParsing(); + virtual void setDiskName(const QCString &name); + virtual void insertMember(MemberDef *md); + virtual void insertClass(ClassDef *cd); + virtual void insertNamespace(NamespaceDef *nd); + virtual void computeAnchors(); + virtual void setPackageDef(PackageDef *pd) { m_package=pd; } + virtual void setDirDef(DirDef *dd) { m_dir=dd; } + virtual void addUsingDirective(const NamespaceDef *nd); + virtual void addUsingDeclaration(Definition *def); + virtual void combineUsingRelations(); + virtual bool generateSourceFile() const; + virtual void sortMemberLists(); + virtual void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported,bool indirect); + virtual void addIncludedByDependency(FileDef *fd,const char *incName,bool local,bool imported); + virtual void addMembersToMemberGroup(); + virtual void distributeMemberGroupDocumentation(); + virtual void findSectionsInDocumentation(); + virtual void addIncludedUsingDirectives(); + virtual void addListReferences(); + virtual void setVisited(bool v) { m_visited = v; } + virtual bool isVisited() const { return m_visited; } + + private: + bool m_visited; + void acquireFileVersion(); + MemberList *createMemberList(MemberListType lt); + void addMemberToList(MemberListType lt,MemberDef *md); + void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title); + void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title); + void writeIncludeFiles(OutputList &ol); + void writeIncludeGraph(OutputList &ol); + void writeIncludedByGraph(OutputList &ol); + void writeMemberGroups(OutputList &ol); + void writeAuthorSection(OutputList &ol); + void writeSourceLink(OutputList &ol); + void writeNamespaceDeclarations(OutputList &ol,const QCString &title, + bool isConstantGroup); + void writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d); + void writeInlineClasses(OutputList &ol); + void startMemberDeclarations(OutputList &ol); + void endMemberDeclarations(OutputList &ol); + void startMemberDocumentation(OutputList &ol); + void endMemberDocumentation(OutputList &ol); + void writeDetailedDescription(OutputList &ol,const QCString &title); + void writeBriefDescription(OutputList &ol); + void writeClassesToTagFile(FTextStream &t,ClassSDict *d); + + QDict<IncludeInfo> *m_includeDict; + QList<IncludeInfo> *m_includeList; + QDict<IncludeInfo> *m_includedByDict; + QList<IncludeInfo> *m_includedByList; + NamespaceSDict *m_usingDirList; + SDict<Definition> *m_usingDeclList; + QCString m_path; + QCString m_filePath; + QCString m_inclDepFileName; + QCString m_inclByDepFileName; + QCString m_outputDiskName; + QCString m_fileName; + QCString m_docname; + QIntDict<Definition> *m_srcDefDict; + QIntDict<MemberDef> *m_srcMemberDict; + bool m_isSource; + QCString m_fileVersion; + PackageDef *m_package; + DirDef *m_dir; + QList<MemberList> m_memberLists; + MemberGroupSDict *m_memberGroupSDict; + NamespaceSDict *m_namespaceSDict; + ClassSDict *m_classSDict; + ClassSDict *m_interfaceSDict; + ClassSDict *m_structSDict; + ClassSDict *m_exceptionSDict; + bool m_subGrouping; +}; + +FileDef *createFileDef(const char *p,const char *n,const char *ref,const char *dn) +{ + return new FileDefImpl(p,n,ref,dn); +} + //--------------------------------------------------------------------------- @@ -65,7 +207,7 @@ class DevNullCodeDocInterface : public CodeOutputInterface virtual void endFontClass() {} virtual void writeCodeAnchor(const char *) {} virtual void linkableSymbol(int, const char *,Definition *,Definition *) {} - virtual void setCurrentDoc(Definition *,const char *,bool) {} + virtual void setCurrentDoc(const Definition *,const char *,bool) {} virtual void addWord(const char *,bool) {} }; @@ -75,9 +217,9 @@ class DevNullCodeDocInterface : public CodeOutputInterface \a nm the file name, and \a lref is an HTML anchor name if the file was read from a tag file or 0 otherwise */ -FileDef::FileDef(const char *p,const char *nm, +FileDefImpl::FileDefImpl(const char *p,const char *nm, const char *lref,const char *dn) - : Definition((QCString)p+nm,1,1,nm) + : DefinitionImpl((QCString)p+nm,1,1,nm) { m_path=p; m_filePath=m_path+nm; @@ -101,6 +243,7 @@ FileDef::FileDef(const char *p,const char *nm, m_isSource = guessSection(nm)==Entry::SOURCE_SEC; m_docname = nm; m_dir = 0; + m_visited = FALSE; if (Config_getBool(FULL_PATH_NAMES)) { m_docname.prepend(stripFromPath(m_path.copy())); @@ -112,7 +255,7 @@ FileDef::FileDef(const char *p,const char *nm, } /*! destroy the file definition */ -FileDef::~FileDef() +FileDefImpl::~FileDefImpl() { delete m_classSDict; delete m_interfaceSDict; @@ -130,7 +273,7 @@ FileDef::~FileDef() delete m_memberGroupSDict; } -void FileDef::setDiskName(const QCString &name) +void FileDefImpl::setDiskName(const QCString &name) { if (isReference()) { @@ -147,15 +290,15 @@ void FileDef::setDiskName(const QCString &name) } /*! Compute the HTML anchor names for all members in the class */ -void FileDef::computeAnchors() +void FileDefImpl::computeAnchors() { MemberList *ml = getMemberList(MemberListType_allMembersList); if (ml) setAnchors(ml); } -void FileDef::distributeMemberGroupDocumentation() +void FileDefImpl::distributeMemberGroupDocumentation() { - //printf("FileDef::distributeMemberGroupDocumentation()\n"); + //printf("FileDefImpl::distributeMemberGroupDocumentation()\n"); if (m_memberGroupSDict) { MemberGroupSDict::Iterator mgli(*m_memberGroupSDict); @@ -167,7 +310,7 @@ void FileDef::distributeMemberGroupDocumentation() } } -void FileDef::findSectionsInDocumentation() +void FileDefImpl::findSectionsInDocumentation() { docFindSections(documentation(),this,0,docFile()); if (m_memberGroupSDict) @@ -191,7 +334,7 @@ void FileDef::findSectionsInDocumentation() } } -bool FileDef::hasDetailedDescription() const +bool FileDefImpl::hasDetailedDescription() const { static bool repeatBrief = Config_getBool(REPEAT_BRIEF); static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); @@ -201,7 +344,7 @@ bool FileDef::hasDetailedDescription() const ); } -void FileDef::writeTagFile(FTextStream &tagFile) +void FileDefImpl::writeTagFile(FTextStream &tagFile) { tagFile << " <compound kind=\"file\">" << endl; tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; @@ -314,7 +457,7 @@ void FileDef::writeTagFile(FTextStream &tagFile) tagFile << " </compound>" << endl; } -void FileDef::writeDetailedDescription(OutputList &ol,const QCString &title) +void FileDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title) { if (hasDetailedDescription()) { @@ -393,7 +536,7 @@ void FileDef::writeDetailedDescription(OutputList &ol,const QCString &title) } } -void FileDef::writeBriefDescription(OutputList &ol) +void FileDefImpl::writeBriefDescription(OutputList &ol) { if (hasBriefDescription()) { @@ -430,7 +573,7 @@ void FileDef::writeBriefDescription(OutputList &ol) ol.writeSynopsis(); } -void FileDef::writeClassesToTagFile(FTextStream &tagFile, ClassSDict *d) +void FileDefImpl::writeClassesToTagFile(FTextStream &tagFile, ClassSDict *d) { SDict<ClassDef>::Iterator ci(*d); ClassDef *cd; @@ -444,7 +587,7 @@ void FileDef::writeClassesToTagFile(FTextStream &tagFile, ClassSDict *d) } } -void FileDef::writeIncludeFiles(OutputList &ol) +void FileDefImpl::writeIncludeFiles(OutputList &ol) { if (m_includeList && m_includeList->count()>0) { @@ -513,7 +656,7 @@ void FileDef::writeIncludeFiles(OutputList &ol) } } -void FileDef::writeIncludeGraph(OutputList &ol) +void FileDefImpl::writeIncludeGraph(OutputList &ol) { if (Config_getBool(HAVE_DOT) /*&& Config_getBool(INCLUDE_GRAPH)*/) { @@ -537,7 +680,7 @@ void FileDef::writeIncludeGraph(OutputList &ol) } } -void FileDef::writeIncludedByGraph(OutputList &ol) +void FileDefImpl::writeIncludedByGraph(OutputList &ol) { if (Config_getBool(HAVE_DOT) /*&& Config_getBool(INCLUDED_BY_GRAPH)*/) { @@ -562,7 +705,7 @@ void FileDef::writeIncludedByGraph(OutputList &ol) } -void FileDef::writeSourceLink(OutputList &ol) +void FileDefImpl::writeSourceLink(OutputList &ol) { //printf("%s: generateSourceFile()=%d\n",name().data(),generateSourceFile()); if (generateSourceFile()) @@ -577,20 +720,20 @@ void FileDef::writeSourceLink(OutputList &ol) } } -void FileDef::writeNamespaceDeclarations(OutputList &ol,const QCString &title, +void FileDefImpl::writeNamespaceDeclarations(OutputList &ol,const QCString &title, bool const isConstantGroup) { // write list of namespaces if (m_namespaceSDict) m_namespaceSDict->writeDeclaration(ol,title,isConstantGroup); } -void FileDef::writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d) +void FileDefImpl::writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d) { // write list of classes if (d) d->writeDeclaration(ol,0,title,FALSE); } -void FileDef::writeInlineClasses(OutputList &ol) +void FileDefImpl::writeInlineClasses(OutputList &ol) { // temporarily undo the disbling could be done by startMemberDocumentation() // as a result of setting SEPARATE_MEMBER_PAGES to YES; see bug730512 @@ -603,17 +746,17 @@ void FileDef::writeInlineClasses(OutputList &ol) if (!isEnabled) ol.disable(OutputGenerator::Html); } -void FileDef::startMemberDeclarations(OutputList &ol) +void FileDefImpl::startMemberDeclarations(OutputList &ol) { ol.startMemberSections(); } -void FileDef::endMemberDeclarations(OutputList &ol) +void FileDefImpl::endMemberDeclarations(OutputList &ol) { ol.endMemberSections(); } -void FileDef::startMemberDocumentation(OutputList &ol) +void FileDefImpl::startMemberDocumentation(OutputList &ol) { if (Config_getBool(SEPARATE_MEMBER_PAGES)) { @@ -622,7 +765,7 @@ void FileDef::startMemberDocumentation(OutputList &ol) } } -void FileDef::endMemberDocumentation(OutputList &ol) +void FileDefImpl::endMemberDocumentation(OutputList &ol) { if (Config_getBool(SEPARATE_MEMBER_PAGES)) { @@ -631,7 +774,7 @@ void FileDef::endMemberDocumentation(OutputList &ol) } } -void FileDef::writeMemberGroups(OutputList &ol) +void FileDefImpl::writeMemberGroups(OutputList &ol) { /* write user defined member groups */ if (m_memberGroupSDict) @@ -650,7 +793,7 @@ void FileDef::writeMemberGroups(OutputList &ol) } } -void FileDef::writeAuthorSection(OutputList &ol) +void FileDefImpl::writeAuthorSection(OutputList &ol) { // write Author section (Man only) ol.pushGeneratorState(); @@ -662,7 +805,7 @@ void FileDef::writeAuthorSection(OutputList &ol) ol.popGeneratorState(); } -void FileDef::writeSummaryLinks(OutputList &ol) +void FileDefImpl::writeSummaryLinks(OutputList &ol) const { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -729,7 +872,7 @@ void FileDef::writeSummaryLinks(OutputList &ol) /*! Write the documentation page for this file to the file of output generators \a ol. */ -void FileDef::writeDocumentation(OutputList &ol) +void FileDefImpl::writeDocumentation(OutputList &ol) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); //funcList->countDecMembers(); @@ -946,7 +1089,7 @@ void FileDef::writeDocumentation(OutputList &ol) } } -void FileDef::writeMemberPages(OutputList &ol) +void FileDefImpl::writeMemberPages(OutputList &ol) { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -964,7 +1107,7 @@ void FileDef::writeMemberPages(OutputList &ol) ol.popGeneratorState(); } -void FileDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const +void FileDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const { static bool createSubDirs=Config_getBool(CREATE_SUBDIRS); @@ -1008,7 +1151,7 @@ void FileDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const } /*! Write a source listing of this file to the output */ -void FileDef::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu) +void FileDefImpl::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); @@ -1126,7 +1269,7 @@ void FileDef::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu) ol.enableAll(); } -void FileDef::parseSource(bool sameTu,QStrList &filesInSameTu) +void FileDefImpl::parseSource(bool sameTu,QStrList &filesInSameTu) { static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); DevNullCodeDocInterface devNullIntf; @@ -1161,16 +1304,16 @@ void FileDef::parseSource(bool sameTu,QStrList &filesInSameTu) } } -void FileDef::startParsing() +void FileDefImpl::startParsing() { } -void FileDef::finishParsing() +void FileDefImpl::finishParsing() { ClangParser::instance()->finish(); } -void FileDef::addMembersToMemberGroup() +void FileDefImpl::addMembersToMemberGroup() { QListIterator<MemberList> mli(m_memberLists); MemberList *ml; @@ -1199,10 +1342,10 @@ void FileDef::addMembersToMemberGroup() } /*! Adds member definition \a md to the list of all members of this file */ -void FileDef::insertMember(MemberDef *md) +void FileDefImpl::insertMember(MemberDef *md) { if (md->isHidden()) return; - //printf("%s:FileDef::insertMember(%s (=%p) list has %d elements)\n", + //printf("%s:FileDefImpl::insertMember(%s (=%p) list has %d elements)\n", // name().data(),md->name().data(),md,allMemberList.count()); MemberList *allMemberList = getMemberList(MemberListType_allMembersList); if (allMemberList && allMemberList->findRef(md)!=-1) // TODO optimize the findRef! @@ -1251,8 +1394,8 @@ void FileDef::insertMember(MemberDef *md) addMemberToList(MemberListType_docDefineMembers,md); break; default: - err("FileDef::insertMembers(): " - "member `%s' with class scope `%s' inserted in file scope `%s'!\n", + err("FileDefImpl::insertMembers(): " + "member '%s' with class scope '%s' inserted in file scope '%s'!\n", md->name().data(), md->getClassDef() ? md->getClassDef()->name().data() : "<global>", name().data()); @@ -1261,7 +1404,7 @@ void FileDef::insertMember(MemberDef *md) } /*! Adds compound definition \a cd to the list of all compounds of this file */ -void FileDef::insertClass(ClassDef *cd) +void FileDefImpl::insertClass(ClassDef *cd) { if (cd->isHidden()) return; @@ -1298,7 +1441,7 @@ void FileDef::insertClass(ClassDef *cd) } /*! Adds namespace definition \a nd to the list of all compounds of this file */ -void FileDef::insertNamespace(NamespaceDef *nd) +void FileDefImpl::insertNamespace(NamespaceDef *nd) { if (nd->isHidden()) return; if (!nd->name().isEmpty() && @@ -1319,17 +1462,17 @@ void FileDef::insertNamespace(NamespaceDef *nd) } } -QCString FileDef::name() const +QCString FileDefImpl::name() const { if (Config_getBool(FULL_PATH_NAMES)) return m_fileName; else - return Definition::name(); + return DefinitionImpl::name(); } -void FileDef::addSourceRef(int line,Definition *d,MemberDef *md) +void FileDefImpl::addSourceRef(int line,Definition *d,MemberDef *md) { - //printf("FileDef::addSourceDef(%d,%p,%p)\n",line,d,md); + //printf("FileDefImpl::addSourceDef(%d,%p,%p)\n",line,d,md); if (d) { if (m_srcDefDict==0) m_srcDefDict = new QIntDict<Definition>(257); @@ -1341,7 +1484,7 @@ void FileDef::addSourceRef(int line,Definition *d,MemberDef *md) } } -Definition *FileDef::getSourceDefinition(int lineNr) const +Definition *FileDefImpl::getSourceDefinition(int lineNr) const { Definition *result=0; if (m_srcDefDict) @@ -1352,7 +1495,7 @@ Definition *FileDef::getSourceDefinition(int lineNr) const return result; } -MemberDef *FileDef::getSourceMember(int lineNr) const +MemberDef *FileDefImpl::getSourceMember(int lineNr) const { MemberDef *result=0; if (m_srcMemberDict) @@ -1364,7 +1507,7 @@ MemberDef *FileDef::getSourceMember(int lineNr) const } -void FileDef::addUsingDirective(NamespaceDef *nd) +void FileDefImpl::addUsingDirective(const NamespaceDef *nd) { if (m_usingDirList==0) { @@ -1374,16 +1517,16 @@ void FileDef::addUsingDirective(NamespaceDef *nd) { m_usingDirList->append(nd->qualifiedName(),nd); } - //printf("%p: FileDef::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count()); + //printf("%p: FileDefImpl::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count()); } -NamespaceSDict *FileDef::getUsedNamespaces() const +NamespaceSDict *FileDefImpl::getUsedNamespaces() const { - //printf("%p: FileDef::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0); + //printf("%p: FileDefImpl::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0); return m_usingDirList; } -void FileDef::addUsingDeclaration(Definition *d) +void FileDefImpl::addUsingDeclaration(Definition *d) { if (m_usingDeclList==0) { @@ -1395,10 +1538,10 @@ void FileDef::addUsingDeclaration(Definition *d) } } -void FileDef::addIncludeDependency(FileDef *fd,const char *incName,bool local, +void FileDefImpl::addIncludeDependency(FileDef *fd,const char *incName,bool local, bool imported,bool indirect) { - //printf("FileDef::addIncludeDependency(%p,%s,%d)\n",fd,incName,local); + //printf("FileDefImpl::addIncludeDependency(%p,%s,%d)\n",fd,incName,local); QCString iName = fd ? fd->absFilePath().data() : incName; if (!iName.isEmpty() && (!m_includeDict || m_includeDict->find(iName)==0)) { @@ -1419,11 +1562,11 @@ void FileDef::addIncludeDependency(FileDef *fd,const char *incName,bool local, } } -void FileDef::addIncludedUsingDirectives() +void FileDefImpl::addIncludedUsingDirectives() { - if (visited) return; - visited=TRUE; - //printf("( FileDef::addIncludedUsingDirectives for file %s\n",name().data()); + if (m_visited) return; + m_visited=TRUE; + //printf("( FileDefImpl::addIncludedUsingDirectives for file %s\n",name().data()); if (m_includeList) // file contains #includes { @@ -1432,7 +1575,7 @@ void FileDef::addIncludedUsingDirectives() IncludeInfo *ii; for (iii.toFirst();(ii=iii.current());++iii) // foreach #include... { - if (ii->fileDef && !ii->fileDef->visited) // ...that is a known file + if (ii->fileDef && !ii->fileDef->isVisited()) // ...that is a known file { // recurse into this file ii->fileDef->addIncludedUsingDirectives(); @@ -1448,7 +1591,7 @@ void FileDef::addIncludedUsingDirectives() if (ii->fileDef && ii->fileDef!=this) { // add using directives - NamespaceSDict *unl = ii->fileDef->m_usingDirList; + NamespaceSDict *unl = ii->fileDef->getUsedNamespaces(); if (unl) { NamespaceSDict::Iterator nli(*unl); @@ -1466,7 +1609,7 @@ void FileDef::addIncludedUsingDirectives() } } // add using declarations - SDict<Definition> *udl = ii->fileDef->m_usingDeclList; + SDict<Definition> *udl = ii->fileDef->getUsedClasses(); if (udl) { SDict<Definition>::Iterator udi(*udl); @@ -1488,14 +1631,14 @@ void FileDef::addIncludedUsingDirectives() } } } - //printf(") end FileDef::addIncludedUsingDirectives for file %s\n",name().data()); + //printf(") end FileDefImpl::addIncludedUsingDirectives for file %s\n",name().data()); } -void FileDef::addIncludedByDependency(FileDef *fd,const char *incName, +void FileDefImpl::addIncludedByDependency(FileDef *fd,const char *incName, bool local,bool imported) { - //printf("FileDef::addIncludedByDependency(%p,%s,%d)\n",fd,incName,local); + //printf("FileDefImpl::addIncludedByDependency(%p,%s,%d)\n",fd,incName,local); QCString iName = fd ? fd->absFilePath().data() : incName; if (!iName.isEmpty() && (m_includedByDict==0 || m_includedByDict->find(iName)==0)) { @@ -1516,13 +1659,13 @@ void FileDef::addIncludedByDependency(FileDef *fd,const char *incName, } } -bool FileDef::isIncluded(const QCString &name) const +bool FileDefImpl::isIncluded(const QCString &name) const { if (name.isEmpty()) return FALSE; return m_includeDict!=0 && m_includeDict->find(name)!=0; } -bool FileDef::generateSourceFile() const +bool FileDefImpl::generateSourceFile() const { static bool sourceBrowser = Config_getBool(SOURCE_BROWSER); static bool verbatimHeaders = Config_getBool(VERBATIM_HEADERS); @@ -1534,7 +1677,7 @@ bool FileDef::generateSourceFile() const } -void FileDef::addListReferences() +void FileDefImpl::addListReferences() { { QList<ListItemInfo> *xrefItems = xrefListItems(); @@ -1762,7 +1905,7 @@ static void addDirsAsGroups(Directory *root,GroupDef *parent,int level) GroupDef *gd=0; if (root->kind()==DirEntry::Dir) { - gd = new GroupDef("[generated]", + gd = createGroupDef("[generated]", 1, root->path(), // name root->name() // title @@ -1812,10 +1955,10 @@ void generateFileTree() //------------------------------------------------------------------- -void FileDef::combineUsingRelations() +void FileDefImpl::combineUsingRelations() { - if (visited) return; // already done - visited=TRUE; + if (m_visited) return; // already done + m_visited=TRUE; if (m_usingDirList) { NamespaceSDict::Iterator nli(*m_usingDirList); @@ -1852,7 +1995,7 @@ void FileDef::combineUsingRelations() } } -bool FileDef::isDocumentationFile() const +bool FileDefImpl::isDocumentationFile() const { return name().right(4)==".doc" || name().right(4)==".txt" || @@ -1861,7 +2004,7 @@ bool FileDef::isDocumentationFile() const name().right(9)==".markdown"; } -void FileDef::acquireFileVersion() +void FileDefImpl::acquireFileVersion() { QCString vercmd = Config_getString(FILE_VERSION_FILTER); if (!vercmd.isEmpty() && !m_filePath.isEmpty() && @@ -1895,7 +2038,7 @@ void FileDef::acquireFileVersion() } -QCString FileDef::getSourceFileBase() const +QCString FileDefImpl::getSourceFileBase() const { if (Htags::useHtags) { @@ -1907,18 +2050,18 @@ QCString FileDef::getSourceFileBase() const } } -QCString FileDef::getOutputFileBase() const +QCString FileDefImpl::getOutputFileBase() const { return m_outputDiskName; } /*! Returns the name of the verbatim copy of this file (if any). */ -QCString FileDef::includeName() const +QCString FileDefImpl::includeName() const { return getSourceFileBase(); } -MemberList *FileDef::createMemberList(MemberListType lt) +MemberList *FileDefImpl::createMemberList(MemberListType lt) { m_memberLists.setAutoDelete(TRUE); QListIterator<MemberList> mli(m_memberLists); @@ -1936,7 +2079,7 @@ MemberList *FileDef::createMemberList(MemberListType lt) return ml; } -void FileDef::addMemberToList(MemberListType lt,MemberDef *md) +void FileDefImpl::addMemberToList(MemberListType lt,MemberDef *md) { static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); @@ -1958,7 +2101,7 @@ void FileDef::addMemberToList(MemberListType lt,MemberDef *md) if (ml->listType()&MemberListType_declarationLists) md->setSectionList(this,ml); } -void FileDef::sortMemberLists() +void FileDefImpl::sortMemberLists() { QListIterator<MemberList> mli(m_memberLists); MemberList *ml; @@ -1966,9 +2109,21 @@ void FileDef::sortMemberLists() { if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); } } + + if (m_memberGroupSDict) + { + MemberGroupSDict::Iterator mgli(*m_memberGroupSDict); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + MemberList *mlg = mg->members(); + if (mlg->needsSorting()) { mlg->sort(); mlg->setNeedsSorting(FALSE); } + } + } + } -MemberList *FileDef::getMemberList(MemberListType lt) const +MemberList *FileDefImpl::getMemberList(MemberListType lt) const { QListIterator<MemberList> mli(m_memberLists); MemberList *ml; @@ -1982,7 +2137,7 @@ MemberList *FileDef::getMemberList(MemberListType lt) const return 0; } -void FileDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title) +void FileDefImpl::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title) { static bool optVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL); MemberList * ml = getMemberList(lt); @@ -2000,13 +2155,13 @@ void FileDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCS } } -void FileDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title) +void FileDefImpl::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title) { MemberList * ml = getMemberList(lt); if (ml) ml->writeDocumentation(ol,name(),this,title); } -bool FileDef::isLinkableInProject() const +bool FileDefImpl::isLinkableInProject() const { static bool showFiles = Config_getBool(SHOW_FILES); return hasDocumentation() && !isReference() && (showFiles || isLinkableViaGroup()); @@ -2024,7 +2179,7 @@ static void getAllIncludeFilesRecursively( if (ii->fileDef && !ii->fileDef->isReference() && !filesVisited->find(ii->fileDef->absFilePath())) { - //printf("FileDef::addIncludeDependency(%s)\n",ii->fileDef->absFilePath().data()); + //printf("FileDefImpl::addIncludeDependency(%s)\n",ii->fileDef->absFilePath().data()); incFiles.append(ii->fileDef->absFilePath()); filesVisited->insert(ii->fileDef->absFilePath(),(void*)0x8); getAllIncludeFilesRecursively(filesVisited,ii->fileDef,incFiles); @@ -2033,29 +2188,62 @@ static void getAllIncludeFilesRecursively( } } -void FileDef::getAllIncludeFilesRecursively(QStrList &incFiles) const +void FileDefImpl::getAllIncludeFilesRecursively(QStrList &incFiles) const { QDict<void> includes(257); ::getAllIncludeFilesRecursively(&includes,this,incFiles); } -QCString FileDef::title() const +QCString FileDefImpl::title() const { return theTranslator->trFileReference(name()); } -QCString FileDef::fileVersion() const +QCString FileDefImpl::fileVersion() const { return m_fileVersion; } -QCString FileDef::includeDependencyGraphFileName() const +QCString FileDefImpl::includeDependencyGraphFileName() const { return m_inclDepFileName; } -QCString FileDef::includedByDependencyGraphFileName() const +QCString FileDefImpl::includedByDependencyGraphFileName() const { return m_inclByDepFileName; } +void FileDefImpl::countMembers() +{ + QListIterator<MemberList> mli(m_memberLists); + MemberList *ml; + for (mli.toFirst();(ml=mli.current());++mli) + { + ml->countDecMembers(); + ml->countDocMembers(); + } + if (m_memberGroupSDict) + { + MemberGroupSDict::Iterator mgli(*m_memberGroupSDict); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + mg->countDecMembers(); + mg->countDocMembers(); + } + } +} + +int FileDefImpl::numDocMembers() const +{ + MemberList *ml = getMemberList(MemberListType_allMembersList); + return ml ? ml->numDocMembers() : 0; +} + +int FileDefImpl::numDecMembers() const +{ + MemberList *ml = getMemberList(MemberListType_allMembersList); + return ml ? ml->numDecMembers() : 0; +} + diff --git a/src/filedef.h b/src/filedef.h index fe3c81d..b66d7be 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -61,185 +61,131 @@ struct IncludeInfo * The member writeDocumentation() can be used to generate the page of * documentation to HTML and LaTeX. */ -class FileDef : public Definition +class FileDef : virtual public Definition { public: - //enum FileType { Source, Header, Unknown }; - - FileDef(const char *p,const char *n,const char *ref=0,const char *dn=0); - ~FileDef(); + ~FileDef() {} // ---------------------------------------------------------------------- - DefType definitionType() const { return TypeFile; } + virtual DefType definitionType() const = 0; /*! Returns the unique file name (this may include part of the path). */ - QCString name() const; - QCString displayName(bool=TRUE) const { return name(); } - QCString fileName() const { return m_fileName; } - - QCString getOutputFileBase() const; + virtual QCString name() const = 0; + virtual QCString displayName(bool=TRUE) const = 0; + virtual QCString fileName() const = 0; + + virtual QCString getOutputFileBase() const = 0; + + virtual QCString anchor() const = 0; - QCString anchor() const { return QCString(); } + virtual QCString getSourceFileBase() const = 0; - QCString getSourceFileBase() const; - /*! Returns the name of the verbatim copy of this file (if any). */ - QCString includeName() const; + virtual QCString includeName() const = 0; - QCString includeDependencyGraphFileName() const; + virtual QCString includeDependencyGraphFileName() const = 0; + + virtual QCString includedByDependencyGraphFileName() const = 0; - QCString includedByDependencyGraphFileName() const; - /*! Returns the absolute path including the file name. */ - QCString absFilePath() const { return m_filePath; } - + virtual QCString absFilePath() const = 0; + /*! Returns the name as it is used in the documentation */ - const QCString &docName() const { return m_docname; } + virtual const QCString &docName() const = 0; /*! Returns TRUE if this file is a source file. */ - bool isSource() const { return m_isSource; } + virtual bool isSource() const = 0; + + virtual bool isDocumentationFile() const = 0; - bool isDocumentationFile() const; - - Definition *getSourceDefinition(int lineNr) const; - MemberDef *getSourceMember(int lineNr) const; + virtual Definition *getSourceDefinition(int lineNr) const = 0; + virtual MemberDef *getSourceMember(int lineNr) const = 0; - /*! Returns the absolute path of this file. */ - QCString getPath() const { return m_path; } + /*! Returns the absolute path of this file. */ + virtual QCString getPath() const = 0; /*! Returns version of this file. */ - QCString getVersion() const { return m_fileVersion; } - - bool isLinkableInProject() const; + virtual QCString getVersion() const = 0; - bool isLinkable() const { return isLinkableInProject() || isReference(); } - bool isIncluded(const QCString &name) const; + virtual bool isLinkableInProject() const = 0; - PackageDef *packageDef() const { return m_package; } - DirDef *getDirDef() const { return m_dir; } - NamespaceSDict *getUsedNamespaces() const; - SDict<Definition> *getUsedClasses() const { return m_usingDeclList; } - QList<IncludeInfo> *includeFileList() const { return m_includeList; } - QList<IncludeInfo> *includedByFileList() const { return m_includedByList; } - void getAllIncludeFilesRecursively(QStrList &incFiles) const; + virtual bool isLinkable() const = 0; + virtual bool isIncluded(const QCString &name) const = 0; - MemberList *getMemberList(MemberListType lt) const; - const QList<MemberList> &getMemberLists() const { return m_memberLists; } + virtual PackageDef *packageDef() const = 0; + virtual DirDef *getDirDef() const = 0; + virtual NamespaceSDict *getUsedNamespaces() const = 0; + virtual SDict<Definition> *getUsedClasses() const = 0; + virtual QList<IncludeInfo> *includeFileList() const = 0; + virtual QList<IncludeInfo> *includedByFileList() const = 0; + virtual void getAllIncludeFilesRecursively(QStrList &incFiles) const = 0; + + virtual MemberList *getMemberList(MemberListType lt) const = 0; + virtual const QList<MemberList> &getMemberLists() const = 0; /* user defined member groups */ - MemberGroupSDict *getMemberGroupSDict() const { return m_memberGroupSDict; } - NamespaceSDict *getNamespaceSDict() const { return m_namespaceSDict; } - ClassSDict *getClassSDict() const { return m_classSDict; } + virtual MemberGroupSDict *getMemberGroupSDict() const = 0; + virtual NamespaceSDict *getNamespaceSDict() const = 0; + virtual ClassSDict *getClassSDict() const = 0; + + virtual QCString title() const = 0; + virtual bool hasDetailedDescription() const = 0; + virtual QCString fileVersion() const = 0; + + virtual bool subGrouping() const = 0; - QCString title() const; - bool hasDetailedDescription() const; - QCString fileVersion() const; + virtual void countMembers() = 0; + virtual int numDocMembers() const = 0; + virtual int numDecMembers() const = 0; - bool subGrouping() const { return m_subGrouping; } - //--------------------------------- - void addSourceRef(int line,Definition *d,MemberDef *md); + virtual void addSourceRef(int line,Definition *d,MemberDef *md) = 0; - void writeDocumentation(OutputList &ol); - void writeMemberPages(OutputList &ol); - void writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const; - void writeSummaryLinks(OutputList &ol); - void writeTagFile(FTextStream &t); + virtual void writeDocumentation(OutputList &ol) = 0; + virtual void writeMemberPages(OutputList &ol) = 0; + virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const = 0; + virtual void writeSummaryLinks(OutputList &ol) const = 0; + virtual void writeTagFile(FTextStream &t) = 0; - void startParsing(); - void writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu); - void parseSource(bool sameTu,QStrList &filesInSameTu); - void finishParsing(); - void setDiskName(const QCString &name); + virtual void startParsing() = 0; + virtual void writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu) = 0; + virtual void parseSource(bool sameTu,QStrList &filesInSameTu) = 0; + virtual void finishParsing() = 0; + virtual void setDiskName(const QCString &name) = 0; - void insertMember(MemberDef *md); - void insertClass(ClassDef *cd); - void insertNamespace(NamespaceDef *nd); - void computeAnchors(); + virtual void insertMember(MemberDef *md) = 0; + virtual void insertClass(ClassDef *cd) = 0; + virtual void insertNamespace(NamespaceDef *nd) = 0; + virtual void computeAnchors() = 0; - void setPackageDef(PackageDef *pd) { m_package=pd; } - void setDirDef(DirDef *dd) { m_dir=dd; } + virtual void setPackageDef(PackageDef *pd) = 0; + virtual void setDirDef(DirDef *dd) = 0; - void addUsingDirective(NamespaceDef *nd); - void addUsingDeclaration(Definition *def); - void combineUsingRelations(); + virtual void addUsingDirective(const NamespaceDef *nd) = 0; + virtual void addUsingDeclaration(Definition *def) = 0; + virtual void combineUsingRelations() = 0; - bool generateSourceFile() const; - void sortMemberLists(); + virtual bool generateSourceFile() const = 0; + virtual void sortMemberLists() = 0; - void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported,bool indirect); - void addIncludedByDependency(FileDef *fd,const char *incName,bool local,bool imported); + virtual void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported,bool indirect) = 0; + virtual void addIncludedByDependency(FileDef *fd,const char *incName,bool local,bool imported) = 0; - void addMembersToMemberGroup(); - void distributeMemberGroupDocumentation(); - void findSectionsInDocumentation(); - void addIncludedUsingDirectives(); + virtual void addMembersToMemberGroup() = 0; + virtual void distributeMemberGroupDocumentation() = 0; + virtual void findSectionsInDocumentation() = 0; + virtual void addIncludedUsingDirectives() = 0; - void addListReferences(); - //bool includes(FileDef *incFile,QDict<FileDef> *includedFiles) const; - //bool includesByName(const QCString &name) const; - bool visited; + virtual void addListReferences() = 0; - protected: - /** - * Retrieves the file version from version control system. - */ - void acquireFileVersion(); - - private: - MemberList *createMemberList(MemberListType lt); - void addMemberToList(MemberListType lt,MemberDef *md); - void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title); - void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title); - void writeIncludeFiles(OutputList &ol); - void writeIncludeGraph(OutputList &ol); - void writeIncludedByGraph(OutputList &ol); - void writeMemberGroups(OutputList &ol); - void writeAuthorSection(OutputList &ol); - void writeSourceLink(OutputList &ol); - void writeNamespaceDeclarations(OutputList &ol,const QCString &title, - bool isConstantGroup); - void writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d); - void writeInlineClasses(OutputList &ol); - void startMemberDeclarations(OutputList &ol); - void endMemberDeclarations(OutputList &ol); - void startMemberDocumentation(OutputList &ol); - void endMemberDocumentation(OutputList &ol); - void writeDetailedDescription(OutputList &ol,const QCString &title); - void writeBriefDescription(OutputList &ol); - void writeClassesToTagFile(FTextStream &t,ClassSDict *d); - - QDict<IncludeInfo> *m_includeDict; - QList<IncludeInfo> *m_includeList; - QDict<IncludeInfo> *m_includedByDict; - QList<IncludeInfo> *m_includedByList; - NamespaceSDict *m_usingDirList; - SDict<Definition> *m_usingDeclList; - QCString m_path; - QCString m_filePath; - QCString m_inclDepFileName; - QCString m_inclByDepFileName; - QCString m_outputDiskName; - QCString m_fileName; - QCString m_docname; - QIntDict<Definition> *m_srcDefDict; - QIntDict<MemberDef> *m_srcMemberDict; - bool m_isSource; - QCString m_fileVersion; - PackageDef *m_package; - DirDef *m_dir; - QList<MemberList> m_memberLists; - MemberGroupSDict *m_memberGroupSDict; - NamespaceSDict *m_namespaceSDict; - ClassSDict *m_classSDict; - ClassSDict *m_interfaceSDict; - ClassSDict *m_structSDict; - ClassSDict *m_exceptionSDict; - bool m_subGrouping; + virtual void setVisited(bool v) = 0; + virtual bool isVisited() const = 0; }; +FileDef *createFileDef(const char *p,const char *n,const char *ref=0,const char *dn=0); + /** Class representing a list of FileDef objects. */ class FileList : public QList<FileDef> { diff --git a/src/filename.cpp b/src/filename.cpp index ae3b596..637fe33 100644 --- a/src/filename.cpp +++ b/src/filename.cpp @@ -70,7 +70,7 @@ void FileName::generateDiskNames() QCString path = fd->getPath(); if (!fd->isReference()) { - //printf("i=%d j=%d fd->path=`%s' fd->name=`%s'\n",i,j,fd->path.left(i).data(),fd->name().data()); + //printf("i=%d j=%d fd->path='%s' fd->name='%s'\n",i,j,fd->path.left(i).data(),fd->name().data()); if (i==(int)path.length()) { //warning("Input file %s found multiple times!\n" diff --git a/src/fileparser.cpp b/src/fileparser.cpp index 6883622..45bdc81 100644 --- a/src/fileparser.cpp +++ b/src/fileparser.cpp @@ -26,9 +26,9 @@ void FileParser::parseCode(CodeOutputInterface &codeOutIntf, int startLine, int endLine, bool, // inlineFragment - MemberDef *, // memberDef + const MemberDef *, // memberDef bool showLineNumbers, - Definition *, // searchCtx, + const Definition *, // searchCtx, bool // collectXRefs ) { diff --git a/src/fileparser.h b/src/fileparser.h index 4568a39..4b311e6 100644 --- a/src/fileparser.h +++ b/src/fileparser.h @@ -37,9 +37,9 @@ class FileParser : public ParserInterface int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, - MemberDef *memberDef=0, + const MemberDef *memberDef=0, bool showLineNumbers=TRUE, - Definition *searchCtx=0, + const Definition *searchCtx=0, bool collectXRefs=TRUE ); void resetCodeParserState() {} diff --git a/src/filestorage.h b/src/filestorage.h deleted file mode 100644 index 5c2a92d..0000000 --- a/src/filestorage.h +++ /dev/null @@ -1,135 +0,0 @@ -/****************************************************************************** - * - * 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 - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ - -#include <qfile.h> -#include <assert.h> -#include "store.h" - - -#ifndef FILESTORAGE_H -#define FILESTORAGE_H - -/** @brief Store implementation based on a file. - Writing is linear, after that the file is re-opened for reading. - Reading is random (seek+read). - */ -class FileStorage : public StorageIntf -{ - public: - FileStorage() : m_readOnly(FALSE) {} - FileStorage( const QString &name) : - m_readOnly(FALSE) { m_file.setName(name); } - int read(char *buf,uint size) { return m_file.readBlock(buf,size); } - int write(const char *buf,uint size) { assert(m_readOnly==FALSE); return m_file.writeBlock(buf,size); } - bool open( int m ) { m_readOnly = m==IO_ReadOnly; return m_file.open(m); } - bool seek(int64 pos) { return m_file.seek(pos); } - int64 pos() const { return m_file.pos(); } - void close() { m_file.close(); } - void setName( const char *name ) { m_file.setName(name); } - private: - bool m_readOnly; - QFile m_file; -}; - -#if 0 // experimental version using mmap after opening the file as read only. -#include <sys/mman.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <stdio.h> - -class FileStorage : public StorageIntf -{ - public: - FileStorage() : m_readOnly(FALSE), m_map(0), m_off(0), m_size(0) {} - FileStorage( const QString &name) : - m_readOnly(FALSE) { m_file.setName(name); } - void setName( const char *name ) { m_file.setName(name); } - bool open( int m ) - { - if (m==IO_ReadOnly) - { - m_readOnly=TRUE; - QString name = m_file.name(); - m_file.close(); - m_fd = ::open(name.data(),O_RDONLY); - struct stat stat; - fstat(m_fd,&stat); - m_size = stat.st_size; - m_map = mmap(NULL,m_size,PROT_READ,MAP_SHARED,m_fd,0); - if (m_map==MAP_FAILED) perror("mmap failed"); - assert(m_map!=MAP_FAILED); - m_off = 0; - return TRUE; - } - else - { - m_readOnly = FALSE; - return m_file.open(m); - } - } - int write(const char *buf,uint size) - { - assert(m_map==0); - return m_file.writeBlock(buf,size); - } - int read(char *buf,uint size) - { - assert(m_map!=0); - memcpy(buf,((char *)m_map)+m_off,size); - m_off+=size; - return size; - } - bool seek(int64 pos) - { - m_off=pos; - return TRUE; - } - int64 pos() const - { - if (m_readOnly) - { - return m_off; - } - else - { - return m_file.pos(); - } - } - void close() - { - if (m_readOnly) - { - munmap(m_map,m_size); - ::close(m_fd); - exit(1); - } - else - { - m_file.close(); - } - } - private: - bool m_readOnly; - QFile m_file; - int m_fd; - void *m_map; - off_t m_off; - off_t m_size; -}; -#endif - -#endif diff --git a/src/formula.cpp b/src/formula.cpp index c252e07..1c5042e 100644 --- a/src/formula.cpp +++ b/src/formula.cpp @@ -71,6 +71,7 @@ void FormulaList::generateBitmaps(const char *path) t << "\\documentclass{article}" << endl; t << "\\usepackage{ifthen}" << endl; t << "\\usepackage{epsfig}" << endl; // for those who want to include images + t << "\\usepackage[utf8]{inputenc}" << endl; // looks like some older distributions with newunicode package 1.1 need this option. writeExtraLatexPackages(t); writeLatexSpecialFormulaChars(t); t << "\\pagestyle{empty}" << endl; diff --git a/src/fortrancode.h b/src/fortrancode.h index c110852..4df20a9 100644 --- a/src/fortrancode.h +++ b/src/fortrancode.h @@ -29,7 +29,7 @@ class Definition; void parseFortranCode(CodeOutputInterface &,const char *,const QCString &, bool ,const char *,FileDef *fd, int startLine,int endLine,bool inlineFragment, - MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx, + const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, bool collectRefs, FortranFormat format); void resetFortranCodeParserState(); void codeFreeScanner(); diff --git a/src/fortrancode.l b/src/fortrancode.l index 0e610fd..3e443b5 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -140,7 +140,7 @@ static int g_yyLineNr; //!< current line number static int g_contLineNr; //!< current, local, line number for continuation determination static int *g_hasContLine = NULL; //!< signals whether or not a line has a continuation line (fixed source form) static bool g_needsTermination; -static Definition *g_searchCtx; +static const Definition *g_searchCtx; static bool g_collectXRefs; static bool g_isFixedForm; @@ -269,7 +269,7 @@ static void endCodeLine() g_code->endCodeLine(); } -/*! write a code fragment `text' that may span multiple lines, inserting +/*! write a code fragment 'text' that may span multiple lines, inserting * line numbers for each line. */ static void codifyLines(char *text) @@ -452,16 +452,16 @@ static bool getFortranDefs(const QCString &memberName, const QCString &moduleNam MemberNameIterator mli(*mn); for (mli.toFirst();(md=mli.current());++mli) // all found functions with given name { - FileDef *fd=md->getFileDef(); - GroupDef *gd=md->getGroupDef(); - ClassDef *cd=md->getClassDef(); + const FileDef *fd=md->getFileDef(); + const GroupDef *gd=md->getGroupDef(); + const ClassDef *cd=md->getClassDef(); //cout << "found link with same name: " << fd->fileName() << " " << memberName; //if (md->getNamespaceDef() != 0) cout << " in namespace " << md->getNamespaceDef()->name();cout << endl; if ((gd && gd->isLinkable()) || (fd && fd->isLinkable())) { - NamespaceDef *nspace= md->getNamespaceDef(); + const NamespaceDef *nspace= md->getNamespaceDef(); if (nspace == 0) { // found function in global scope @@ -532,8 +532,8 @@ static bool getLink(UseSDict *usedict, // dictonary with used modules if (md->isVariable() && (md->getLanguage()!=SrcLangExt_Fortran)) return FALSE; // Non Fortran variables aren't handled yet, // see also linkifyText in util.cpp - Definition *d = md->getOuterScope()==Doxygen::globalScope ? - md->getBodyDef() : md->getOuterScope(); + const Definition *d = md->getOuterScope()==Doxygen::globalScope ? + md->getBodyDef() : md->getOuterScope(); if (md->getGroupDef()) d = md->getGroupDef(); if (d && d->isLinkable()) { @@ -750,6 +750,10 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") { if ((yy_my_start == 1) && ((yytext[0] == 'c') || (yytext[0] == 'C'))) YY_FTN_REJECT; } + if (g_currentMemberDef && g_currentMemberDef->isFunction()) + { + g_currentMemberDef->incrementFlowKeyWordCount(); + } /* font class is defined e.g. in doxygen.css */ startFontClass("keywordflow"); codifyLines(yytext); @@ -934,7 +938,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") yy_pop_state(); YY_FTN_RESET } -<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface")?{BS} { // Fortran subroutine or function ends +<Start>"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface")?{BS} { // Fortran subroutine or function ends //cout << "===> end function " << yytext << endl; endScope(); startFontClass("keyword"); @@ -943,11 +947,11 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") yy_push_state(YY_START); BEGIN(Subprogend); } -<Subprogend>{ID}/{BS}(\n|!) { +<Subprogend>{ID}/{BS}(\n|!|;) { generateLink(*g_code,yytext); yy_pop_state(); } -<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface"){BS}/(\n|!) { // Fortran subroutine or function ends +<Start>"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface"){BS}/(\n|!|;) { // Fortran subroutine or function ends //cout << "===> end function " << yytext << endl; endScope(); startFontClass("keyword"); @@ -1313,21 +1317,16 @@ static void checkContLines(const char *s) g_hasContLine[0] = 0; } -void parseFortranCode(CodeOutputInterface &od,const char *className,const QCString &s, +void parseFortranCode(CodeOutputInterface &od,const char *,const QCString &s, bool exBlock, const char *exName,FileDef *fd, int startLine,int endLine,bool inlineFragment, - MemberDef *memberDef,bool,Definition *searchCtx, + const MemberDef *,bool,const Definition *searchCtx, bool collectXRefs, FortranFormat format) { //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd); - // used parameters - (void)memberDef; - (void)className; - if (s.isEmpty()) return; printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL); - TooltipManager::instance()->clearTooltips(); g_code = &od; g_inputString = s; g_inputPosition = 0; @@ -1358,7 +1357,7 @@ void parseFortranCode(CodeOutputInterface &od,const char *className,const QCStri if (exBlock && fd==0) { // create a dummy filedef for the example - g_sourceFileDef = new FileDef("",exName); + g_sourceFileDef = createFileDef("",exName); } if (g_sourceFileDef) { @@ -1382,10 +1381,6 @@ void parseFortranCode(CodeOutputInterface &od,const char *className,const QCStri endFontClass(); g_code->endCodeLine(); } - if (fd) - { - TooltipManager::instance()->writeTooltips(*g_code); - } if (exBlock && g_sourceFileDef) { // delete the temporary file definition used for this example diff --git a/src/fortranscanner.h b/src/fortranscanner.h index bc8071b..15a9bf0 100644 --- a/src/fortranscanner.h +++ b/src/fortranscanner.h @@ -47,9 +47,9 @@ class FortranLanguageScanner : public ParserInterface int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, - MemberDef *memberDef=0, + const MemberDef *memberDef=0, bool showLineNumbers=TRUE, - Definition *searchCtx=0, + const Definition *searchCtx=0, bool collectXRefs=TRUE ); void resetCodeParserState(); diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 5f10669..ea75836 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -32,7 +32,7 @@ * * - Do not like constructs like aa{BS} or {BS}bb. Should try to handle blank space * with separate rule?: It seems it is often necessary, because we may parse something like - * "functionA" or "MyInterface". So constructs like `(^|[ \t])interface({BS_}{ID})?/[ \t\n]' + * "functionA" or "MyInterface". So constructs like '(^|[ \t])interface({BS_}{ID})?/[ \t\n]' * are desired. * * - Must track yyLineNr when using REJECT, unput() or similar commands. @@ -66,6 +66,7 @@ #include "fortrancode.h" #include "pre.h" #include "arguments.h" +#include "debug.h" // Toggle for some debugging info //#define DBG_CTX(x) fprintf x @@ -522,16 +523,16 @@ SCOPENAME ({ID}{BS}"::"{BS})* <InterfaceBody>. {} /*-- Contains handling --*/ -<Start>^{BS}{CONTAINS}/({BS}|\n|!) { +<Start>^{BS}{CONTAINS}/({BS}|\n|!|;) { if(YY_START == Start) { addModule(NULL); yy_push_state(ModuleBodyContains); //anon program } } -<ModuleBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(ModuleBodyContains); } -<SubprogBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(SubprogBodyContains); } -<TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(TypedefBodyContains); } +<ModuleBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(ModuleBodyContains); } +<SubprogBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(SubprogBodyContains); } +<TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(TypedefBodyContains); } /*------ module handling ------------------------------------------------------------*/ <Start>block{BS}data{BS}{ID_} { // @@ -547,13 +548,13 @@ SCOPENAME ({ID}{BS}"::"{BS})* yy_push_state(Program); defaultProtection = Public; } -<BlockData>^{BS}"end"({BS}(block{BS}data)({BS_}{ID})?)?{BS}/(\n|!) { // end block data +<BlockData>^{BS}"end"({BS}(block{BS}data)({BS_}{ID})?)?{BS}/(\n|!|;) { // end block data //if (!endScope(current_root)) // yyterminate(); defaultProtection = Public; yy_pop_state(); } -<Start,ModuleBody,ModuleBodyContains>^{BS}"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!) { // end module +<Start,ModuleBody,ModuleBodyContains>"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!|;) { // end module resolveModuleProcedures(moduleProcedures, current_root); if (!endScope(current_root)) yyterminate(); @@ -690,7 +691,15 @@ private { <TypedefBody,TypedefBodyContains>{ -^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!) { /* end type definition */ +^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!|;) { /* end type definition */ + last_entry->parent()->endBodyLine = yyLineNr; + if (!endScope(current_root)) + yyterminate(); + typeMode = false; + yy_pop_state(); + } +^{BS}"end"{BS}/(\n|!|;) { /* incorrect end type definition */ + warn(yyFileName,yyLineNr, "Found 'END' instead of 'END TYPE'"); last_entry->parent()->endBodyLine = yyLineNr; if (!endScope(current_root)) yyterminate(); @@ -701,7 +710,7 @@ private { /*------- module/global/typedef variable ---------------------------------------------------*/ -<SubprogBody,SubprogBodyContains>^{BS}[0-9]*{BS}"end"({BS}{SUBPROG}({BS_}{ID})?)?{BS}/(\n|!) { +<SubprogBody,SubprogBodyContains>^{BS}[0-9]*{BS}"end"({BS}{SUBPROG}({BS_}{ID})?)?{BS}/(\n|!|;) { // // ABSTRACT and specific interfaces are stored // in a scope of their own, even if multiple @@ -1513,6 +1522,7 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) int column=0; int prevLineLength=0; int prevLineAmpOrExclIndex=-1; + int skipped = 0; char prevQuote = '\0'; char thisQuote = '\0'; bool emptyLabel=TRUE; @@ -1521,18 +1531,41 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) bool inDouble=FALSE; bool inBackslash=FALSE; bool fullCommentLine=TRUE; + bool artificialComment=FALSE; + bool spaces=TRUE; int newContentsSize = strlen(contents)+3; // \000, \n (when necessary) and one spare character (to avoid reallocation) char* newContents = (char*)malloc(newContentsSize); int curLine = 1; - for(int i=0, j=0;;i++,j++) { + int j = -1; + for(int i=0;;i++) { + column++; + char c = contents[i]; + if (artificialComment && c != '\n') + { + if (c == '!' && spaces) + { + newContents[j++] = c; + artificialComment = FALSE; + spaces = FALSE; + skipped = 0; + continue; + } + else if (c == ' ' || c == '\t') continue; + else + { + spaces = FALSE; + skipped++; + continue; + } + } + + j++; if(j>=newContentsSize-3) { // check for spare characters, which may be eventually used below (by & and '! ') newContents = (char*)realloc(newContents, newContentsSize+1000); newContentsSize = newContentsSize+1000; } - column++; - char c = contents[i]; switch(c) { case '\n': if (!fullCommentLine) @@ -1540,6 +1573,11 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) prevLineLength=column; prevLineAmpOrExclIndex=getAmpOrExclAtTheEnd(&contents[i-prevLineLength+1], prevLineLength,prevQuote); if (prevLineAmpOrExclIndex == -1) prevLineAmpOrExclIndex = column - 1; + if (skipped) + { + prevLineAmpOrExclIndex = -1; + skipped = 0; + } } else { @@ -1550,6 +1588,8 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) hasContLine[curLine - 1] = 1; } } + artificialComment=FALSE; + spaces=TRUE; fullCommentLine=TRUE; column=0; emptyLabel=TRUE; @@ -1654,7 +1694,8 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) j++; } else { // add & just before end of previous line comment /* first line is not a continuation line in code, just in snippets etc. */ - if (curLine != 1) insertCharacter(newContents, j+1, (j+1)-6-prevLineLength+prevLineAmpOrExclIndex, '&'); + if (curLine != 1) insertCharacter(newContents, j+1, (j+1)-6-prevLineLength+prevLineAmpOrExclIndex+skipped, '&'); + skipped = 0; j++; } if (hasContLine) hasContLine[curLine - 1] = 1; @@ -1664,13 +1705,20 @@ const char* prepassFixedForm(const char* contents, int *hasContLine) prevLineLength=0; } else if ((column > fixedCommentAfter) && !commented) { // first non commented non blank character after position fixedCommentAfter - if (c != '!') { + if (c == '&') { + newContents[j]=' '; + } + else if (c != '!') { // I'm not a possible start of doxygen comment - newContents[j++]='!'; - newContents[j++]=' '; // so that '<' and '>' as first character are not converted to doxygen comment + newContents[j]=' '; + artificialComment = TRUE; + spaces=TRUE; + skipped = 0; + } + else { + newContents[j]=c; + commented = TRUE; } - newContents[j]=c; - commented = TRUE; } else { if (!commented) fullCommentLine=FALSE; newContents[j]=c; @@ -2256,7 +2304,7 @@ static void initEntry() current->virt = virt; current->stat = gstat; current->lang = SrcLangExt_Fortran; - initGroupInfo(current); + Doxygen::docGroup.initGroupInfo(current); } /** @@ -2411,9 +2459,7 @@ static void startCommentBlock(bool brief) static void handleCommentBlock(const QCString &doc,bool brief) { - bool needsEntry = FALSE; static bool hideInBodyDocs = Config_getBool(HIDE_IN_BODY_DOCS); - int position=0; if (docBlockInBody && hideInBodyDocs) { docBlockInBody = FALSE; @@ -2421,10 +2467,13 @@ static void handleCommentBlock(const QCString &doc,bool brief) } DBG_CTX((stderr,"call parseCommentBlock [%s]\n",doc.data())); int lineNr = brief ? current->briefLine : current->docLine; + int position=0; + bool needsEntry = FALSE; + QCString processedDoc = preprocessCommentBlock(doc,yyFileName,lineNr); while (parseCommentBlock( g_thisParser, docBlockInBody ? subrCurrent.getFirst() : current, - doc, // text + processedDoc, // text yyFileName, // file lineNr, docBlockInBody ? FALSE : brief, @@ -2639,6 +2688,8 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra //printf("Input fixed form string:\n%s\n", fileBuf); //printf("===========================\n"); inputString = prepassFixedForm(fileBuf, NULL); + Debug::print(Debug::FortranFixed2Free,0,"======== Fixed to Free format =========\n---- Input fixed form string ------- \n%s\n", fileBuf); + Debug::print(Debug::FortranFixed2Free,0,"---- Resulting free form string ------- \n%s\n", inputString); //printf("Resulting free form string:\n%s\n", inputString); //printf("===========================\n"); @@ -2661,7 +2712,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra global_scope = rt; startScope(rt); // implies current_root = rt initParser(); - groupEnterFile(yyFileName,yyLineNr); + Doxygen::docGroup.enterFile(yyFileName,yyLineNr); current = new Entry; current->lang = SrcLangExt_Fortran; @@ -2678,7 +2729,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, Fortra } fortranscannerYYlex(); - groupLeaveFile(yyFileName,yyLineNr); + Doxygen::docGroup.leaveFile(yyFileName,yyLineNr); if (global_scope && global_scope != (Entry *) -1) endScope(current_root, TRUE); // TRUE - global root @@ -2727,9 +2778,9 @@ void FortranLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf, int startLine, int endLine, bool inlineFragment, - MemberDef *memberDef, + const MemberDef *memberDef, bool showLineNumbers, - Definition *searchCtx, + const Definition *searchCtx, bool collectXRefs ) { @@ -2776,7 +2827,7 @@ static void scanner_abort() // dummy call to avoid compiler warning (void)yy_top_state(); - + return; //exit(-1); } diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp index ea57eb7..149f43c 100644 --- a/src/ftvhelp.cpp +++ b/src/ftvhelp.cpp @@ -46,7 +46,7 @@ static int folderId=1; struct FTVNode { FTVNode(bool dir,const char *r,const char *f,const char *a, - const char *n,bool sepIndex,bool navIndex,Definition *df) + const char *n,bool sepIndex,bool navIndex,const Definition *df) : isLast(TRUE), isDir(dir),ref(r),file(f),anchor(a),name(n), index(0), parent(0), separateIndex(sepIndex), addToNavIndex(navIndex), def(df) { children.setAutoDelete(TRUE); } @@ -63,7 +63,7 @@ struct FTVNode FTVNode *parent; bool separateIndex; bool addToNavIndex; - Definition *def; + const Definition *def; }; int FTVNode::computeTreeDepth(int level) const @@ -187,7 +187,7 @@ void FTVHelp::addContentsItem(bool isDir, const char *anchor, bool separateIndex, bool addToNavIndex, - Definition *def + const Definition *def ) { //printf("%p: m_indent=%d addContentsItem(%s,%s,%s,%s)\n",this,m_indent,name,ref,file,anchor); @@ -207,7 +207,7 @@ void FTVHelp::addContentsItem(bool isDir, } -static QCString node2URL(FTVNode *n,bool overruleFile=FALSE,bool srcLink=FALSE) +static QCString node2URL(const FTVNode *n,bool overruleFile=FALSE,bool srcLink=FALSE) { QCString url = n->file; if (!url.isEmpty() && url.at(0)=='!') // relative URL @@ -223,7 +223,7 @@ static QCString node2URL(FTVNode *n,bool overruleFile=FALSE,bool srcLink=FALSE) { if (overruleFile && n->def && n->def->definitionType()==Definition::TypeFile) { - FileDef *fd = (FileDef*)n->def; + const FileDef *fd = dynamic_cast<const FileDef*>(n->def); if (srcLink) { url = fd->getSourceFileBase(); @@ -286,7 +286,7 @@ void FTVHelp::generateLink(FTextStream &t,FTVNode *n) t << "<a class=\"elRef\" "; QCString result = externalLinkTarget(); if (result != "") setTarget = TRUE; - t << result << externalRef("",n->ref,FALSE); + t << result; } else // local link { @@ -315,7 +315,7 @@ void FTVHelp::generateLink(FTextStream &t,FTVNode *n) } } -static void generateBriefDoc(FTextStream &t,Definition *def) +static void generateBriefDoc(FTextStream &t,const Definition *def) { QCString brief = def->briefDescription(TRUE); //printf("*** %p: generateBriefDoc(%s)='%s'\n",def,def->name().data(),brief.data()); @@ -332,7 +332,7 @@ static void generateBriefDoc(FTextStream &t,Definition *def) } } -static char compoundIcon(ClassDef *cd) +static char compoundIcon(const ClassDef *cd) { char icon='C'; if (cd->getLanguage() == SrcLangExt_Slice) @@ -392,7 +392,7 @@ void FTVHelp::generateTree(FTextStream &t, const QList<FTVNode> &nl,int level,in } else if (n->def && n->def->definitionType()==Definition::TypeClass) { - char icon=compoundIcon(dynamic_cast<ClassDef*>(n->def)); + char icon=compoundIcon(dynamic_cast<const ClassDef*>(n->def)); t << "<span class=\"icona\"><span class=\"icon\">" << icon << "</span></span>"; } else @@ -415,11 +415,11 @@ void FTVHelp::generateTree(FTextStream &t, const QList<FTVNode> &nl,int level,in } else // leaf node { - FileDef *srcRef=0; + const FileDef *srcRef=0; if (n->def && n->def->definitionType()==Definition::TypeFile && - ((FileDef*)n->def)->generateSourceFile()) + (dynamic_cast<const FileDef*>(n->def))->generateSourceFile()) { - srcRef = (FileDef*)n->def; + srcRef = dynamic_cast<const FileDef*>(n->def); } if (srcRef) { @@ -448,7 +448,7 @@ void FTVHelp::generateTree(FTextStream &t, const QList<FTVNode> &nl,int level,in } else if (n->def && n->def->definitionType()==Definition::TypeClass) { - char icon=compoundIcon(dynamic_cast<ClassDef*>(n->def)); + char icon=compoundIcon(dynamic_cast<const ClassDef*>(n->def)); t << "<span class=\"icona\"><span class=\"icon\">" << icon << "</span></span>"; } else @@ -492,7 +492,7 @@ class NavIndexEntryList : public QList<NavIndexEntry> } }; -static QCString pathToNode(FTVNode *leaf,FTVNode *n) +static QCString pathToNode(const FTVNode *leaf,const FTVNode *n) { QCString result; if (n->parent) @@ -511,7 +511,7 @@ static bool dupOfParent(const FTVNode *n) return FALSE; } -static void generateJSLink(FTextStream &t,FTVNode *n) +static void generateJSLink(FTextStream &t,const FTVNode *n) { if (n->file.isEmpty()) // no link { @@ -542,7 +542,7 @@ static bool generateJSTree(NavIndexEntryList &navIndex,FTextStream &t, indentStr.fill(' ',level*2); bool found=FALSE; QListIterator<FTVNode> nli(nl); - FTVNode *n; + const FTVNode *n; for (nli.toFirst();(n=nli.current());++nli) { // terminate previous entry @@ -560,7 +560,7 @@ static bool generateJSTree(NavIndexEntryList &navIndex,FTextStream &t, { if (n->def && n->def->definitionType()==Definition::TypeFile) { - FileDef *fd = (FileDef*)n->def; + const FileDef *fd = dynamic_cast<const FileDef*>(n->def); bool doc,src; doc = fileVisibleInIndex(fd,src); if (doc) @@ -635,29 +635,14 @@ static void generateJSNavTree(const QList<FTVNode> &nodeList) //tidx << "var NAVTREEINDEX =" << endl; //tidx << "{" << endl; FTextStream t(&f); - t << "/*\n@ @licstart The following is the entire license notice for the\n" - "JavaScript code in this file.\n\nCopyright (C) 1997-2017 by Dimitri van Heesch\n\n" - "This program is free software; you can redistribute it and/or modify\n" - "it under the terms of the GNU General Public License as published by\n" - "the Free Software Foundation; either version 2 of the License, or\n" - "(at your option) any later version.\n\n" - "This program is distributed in the hope that it will be useful,\n" - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - " GNU General Public License for more details.\n\n" - "You should have received a copy of the GNU General Public License along\n" - "with this program; if not, write to the Free Software Foundation, Inc.,\n" - "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\n" - "@licend The above is the entire license notice\n" - "for the JavaScript code in this file\n" - "*/\n"; + t << JAVASCRIPT_LICENSE_TEXT; t << "var NAVTREE =" << endl; t << "[" << endl; t << " [ "; QCString &projName = Config_getString(PROJECT_NAME); if (projName.isEmpty()) { - if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty()) // Use title of main page as root + if (mainPageHasTitle()) // Use title of main page as root { t << "\"" << convertToJSString(Doxygen::mainPage->title()) << "\", "; } diff --git a/src/ftvhelp.h b/src/ftvhelp.h index bacf9a5..9bcaa5b 100644 --- a/src/ftvhelp.h +++ b/src/ftvhelp.h @@ -50,8 +50,8 @@ class FTVHelp : public IndexIntf const char *anchor, bool separateIndex, bool addToNavIndex, - Definition *def); - void addIndexItem(Definition *,MemberDef *,const char *,const char *) {} + const Definition *def); + void addIndexItem(const Definition *,const MemberDef *,const char *,const char *) {} void addIndexFile(const char *) {} void addImageFile(const char *) {} void addStyleSheetFile(const char *) {} @@ -72,6 +72,22 @@ class FTVHelp : public IndexIntf bool m_topLevelIndex; }; +#define JAVASCRIPT_LICENSE_TEXT \ + "/*\n@licstart The following is the entire license notice for the\n" \ + "JavaScript code in this file.\n\nCopyright (C) 1997-2019 by Dimitri van Heesch\n\n" \ + "This program is free software; you can redistribute it and/or modify\n" \ + "it under the terms of version 2 of the GNU General Public License as published by\n" \ + "the Free Software Foundation\n\n" \ + "This program is distributed in the hope that it will be useful,\n" \ + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \ + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" \ + "GNU General Public License for more details.\n\n" \ + "You should have received a copy of the GNU General Public License along\n" \ + "with this program; if not, write to the Free Software Foundation, Inc.,\n" \ + "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\n" \ + "@licend The above is the entire license notice\n" \ + "for the JavaScript code in this file\n" \ + "*/\n" #endif /* FTVHELP_H */ diff --git a/src/groupdef.cpp b/src/groupdef.cpp index e543d16..9baf0aa 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -33,6 +33,7 @@ #include "docparser.h" #include "searchindex.h" #include "dot.h" +#include "dotgroupcollaboration.h" #include "vhdldocgen.h" #include "layout.h" #include "arguments.h" @@ -40,11 +41,130 @@ #include "membername.h" #include "dirdef.h" #include "config.h" +#include "definitionimpl.h" //--------------------------------------------------------------------------- -GroupDef::GroupDef(const char *df,int dl,const char *na,const char *t, - const char *refFileName) : Definition(df,dl,1,na) +class GroupDefImpl : public DefinitionImpl, public GroupDef +{ + public: + GroupDefImpl(const char *fileName,int line,const char *name,const char *title,const char *refFileName=0); + virtual ~GroupDefImpl(); + + virtual DefType definitionType() const { return TypeGroup; } + virtual QCString getOutputFileBase() const; + virtual QCString anchor() const { return QCString(); } + virtual QCString displayName(bool=TRUE) const { return hasGroupTitle() ? title : DefinitionImpl::name(); } + virtual const char *groupTitle() const { return title; } + virtual void setGroupTitle( const char *newtitle ); + virtual bool hasGroupTitle( ) const { return titleSet; } + virtual void addFile(const FileDef *def); + virtual bool addClass(const ClassDef *def); + virtual bool addNamespace(const NamespaceDef *def); + virtual void addGroup(const GroupDef *def); + virtual void addPage(PageDef *def); + virtual void addExample(const PageDef *def); + virtual void addDir(const DirDef *dd); + virtual bool insertMember(MemberDef *def,bool docOnly=FALSE); + virtual void removeMember(MemberDef *md); + virtual bool findGroup(const GroupDef *def) const; // true if def is a subgroup of this group + virtual void writeDocumentation(OutputList &ol); + virtual void writeMemberPages(OutputList &ol); + virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const; + virtual void writeTagFile(FTextStream &); + virtual int numDocMembers() const; + virtual bool isLinkableInProject() const; + virtual bool isLinkable() const; + virtual bool isASubGroup() const; + virtual void computeAnchors(); + virtual void countMembers(); + + virtual void addMembersToMemberGroup(); + virtual void distributeMemberGroupDocumentation(); + virtual void findSectionsInDocumentation(); + + virtual void addListReferences(); + virtual void sortMemberLists(); + virtual bool subGrouping() const { return m_subGrouping; } + + virtual void setGroupScope(Definition *d) { groupScope = d; } + virtual Definition *getGroupScope() const { return groupScope; } + + virtual MemberList *getMemberList(MemberListType lt) const; + virtual const QList<MemberList> &getMemberLists() const { return m_memberLists; } + + /* user defined member groups */ + virtual MemberGroupSDict *getMemberGroupSDict() const { return memberGroupSDict; } + + virtual FileList * getFiles() const { return fileList; } + virtual ClassSDict * getClasses() const { return classSDict; } + virtual NamespaceSDict * getNamespaces() const { return namespaceSDict; } + virtual GroupList * getSubGroups() const { return groupList; } + virtual PageSDict * getPages() const { return pageDict; } + virtual DirList * getDirs() const { return dirList; } + virtual PageSDict * getExamples() const { return exampleDict; } + virtual bool hasDetailedDescription() const; + virtual void sortSubGroups(); + + private: + void addMemberListToGroup(MemberList *,bool (MemberDef::*)() const); + MemberList *createMemberList(MemberListType lt); + void addMemberToList(MemberListType lt,MemberDef *md); + void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title); + void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title); + void removeMemberFromList(MemberListType lt,MemberDef *md); + void writeGroupGraph(OutputList &ol); + void writeFiles(OutputList &ol,const QCString &title); + void writeNamespaces(OutputList &ol,const QCString &title); + void writeNestedGroups(OutputList &ol,const QCString &title); + void writeDirs(OutputList &ol,const QCString &title); + void writeClasses(OutputList &ol,const QCString &title); + void writeInlineClasses(OutputList &ol); + void writePageDocumentation(OutputList &ol); + void writeDetailedDescription(OutputList &ol,const QCString &title); + void writeBriefDescription(OutputList &ol); + void writeMemberGroups(OutputList &ol); + void startMemberDeclarations(OutputList &ol); + void endMemberDeclarations(OutputList &ol); + void startMemberDocumentation(OutputList &ol); + void endMemberDocumentation(OutputList &ol); + void writeAuthorSection(OutputList &ol); + void writeSummaryLinks(OutputList &ol) const; + void updateLanguage(const Definition *); + + QCString title; // title of the group + bool titleSet; // true if title is not the same as the name + QCString fileName; // base name of the generated file + FileList *fileList; // list of files in the group + ClassSDict *classSDict; // list of classes in the group + NamespaceSDict *namespaceSDict; // list of namespaces in the group + GroupList *groupList; // list of sub groups. + PageSDict *pageDict; // list of pages in the group + PageSDict *exampleDict; // list of examples in the group + DirList *dirList; // list of directories in the group + + MemberList *allMemberList; + MemberNameInfoSDict *allMemberNameInfoSDict; + + Definition *groupScope; + + QList<MemberList> m_memberLists; + MemberGroupSDict *memberGroupSDict; + bool m_subGrouping; + +}; + +GroupDef *createGroupDef(const char *fileName,int line,const char *name, + const char *title,const char *refFileName) +{ + return new GroupDefImpl(fileName,line,name,title,refFileName); +} + + +//--------------------------------------------------------------------------- + +GroupDefImpl::GroupDefImpl(const char *df,int dl,const char *na,const char *t, + const char *refFileName) : DefinitionImpl(df,dl,1,na) { fileList = new FileList; classSDict = new ClassSDict(17); @@ -69,12 +189,12 @@ GroupDef::GroupDef(const char *df,int dl,const char *na,const char *t, allMemberList = new MemberList(MemberListType_allMembersList); - visited = 0; + //visited = 0; groupScope = 0; m_subGrouping=Config_getBool(SUBGROUPING); } -GroupDef::~GroupDef() +GroupDefImpl::~GroupDefImpl() { delete fileList; delete classSDict; @@ -88,7 +208,7 @@ GroupDef::~GroupDef() delete dirList; } -void GroupDef::setGroupTitle( const char *t ) +void GroupDefImpl::setGroupTitle( const char *t ) { if ( t && qstrlen(t) ) { @@ -104,7 +224,7 @@ void GroupDef::setGroupTitle( const char *t ) } -void GroupDef::distributeMemberGroupDocumentation() +void GroupDefImpl::distributeMemberGroupDocumentation() { MemberGroupSDict::Iterator mgli(*memberGroupSDict); MemberGroup *mg; @@ -114,7 +234,7 @@ void GroupDef::distributeMemberGroupDocumentation() } } -void GroupDef::findSectionsInDocumentation() +void GroupDefImpl::findSectionsInDocumentation() { docFindSections(documentation(),this,0,docFile()); MemberGroupSDict::Iterator mgli(*memberGroupSDict); @@ -135,7 +255,7 @@ void GroupDef::findSectionsInDocumentation() } } -void GroupDef::addFile(const FileDef *def) +void GroupDefImpl::addFile(const FileDef *def) { static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); if (def->isHidden()) return; @@ -146,7 +266,7 @@ void GroupDef::addFile(const FileDef *def) fileList->append(def); } -bool GroupDef::addClass(const ClassDef *cd) +bool GroupDefImpl::addClass(const ClassDef *cd) { static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); if (cd->isHidden()) return FALSE; @@ -194,7 +314,7 @@ bool GroupDef::addClass(const ClassDef *cd) return FALSE; } -bool GroupDef::addNamespace(const NamespaceDef *def) +bool GroupDefImpl::addNamespace(const NamespaceDef *def) { static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); if (def->isHidden()) return FALSE; @@ -210,7 +330,7 @@ bool GroupDef::addNamespace(const NamespaceDef *def) return FALSE; } -void GroupDef::addDir(const DirDef *def) +void GroupDefImpl::addDir(const DirDef *def) { if (def->isHidden()) return; if (Config_getBool(SORT_BRIEF_DOCS)) @@ -219,7 +339,7 @@ void GroupDef::addDir(const DirDef *def) dirList->append(def); } -void GroupDef::addPage(PageDef *def) +void GroupDefImpl::addPage(PageDef *def) { if (def->isHidden()) return; //printf("Making page %s part of a group\n",def->name.data()); @@ -227,14 +347,14 @@ void GroupDef::addPage(PageDef *def) def->makePartOfGroup(this); } -void GroupDef::addExample(const PageDef *def) +void GroupDefImpl::addExample(const PageDef *def) { if (def->isHidden()) return; exampleDict->append(def->name(),def); } -void GroupDef::addMembersToMemberGroup() +void GroupDefImpl::addMembersToMemberGroup() { QListIterator<MemberList> mli(m_memberLists); MemberList *ml; @@ -246,7 +366,7 @@ void GroupDef::addMembersToMemberGroup() } } - //printf("GroupDef::addMembersToMemberGroup() memberGroupList=%d\n",memberGroupList->count()); + //printf("GroupDefImpl::addMembersToMemberGroup() memberGroupList=%d\n",memberGroupList->count()); MemberGroupSDict::Iterator mgli(*memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) @@ -256,7 +376,7 @@ void GroupDef::addMembersToMemberGroup() } -bool GroupDef::insertMember(MemberDef *md,bool docOnly) +bool GroupDefImpl::insertMember(MemberDef *md,bool docOnly) { if (md->isHidden()) return FALSE; updateLanguage(md); @@ -265,10 +385,10 @@ bool GroupDef::insertMember(MemberDef *md,bool docOnly) if ((mni=(*allMemberNameInfoSDict)[md->name()])) { // member with this name already found MemberNameInfoIterator srcMnii(*mni); - MemberInfo *srcMi; + const MemberInfo *srcMi; for ( ; (srcMi=srcMnii.current()) ; ++srcMnii ) { - MemberDef *srcMd = srcMi->memberDef; + const MemberDef *srcMd = srcMi->memberDef; if (srcMd==md) return FALSE; // already added before! bool sameScope = srcMd->getOuterScope()==md->getOuterScope() || // same class or namespace @@ -276,10 +396,10 @@ bool GroupDef::insertMember(MemberDef *md,bool docOnly) (srcMd->getOuterScope()->definitionType()==Definition::TypeFile && md->getOuterScope()->definitionType()==Definition::TypeFile); - ArgumentList *srcMdAl = srcMd->argumentList(); - ArgumentList *mdAl = md->argumentList(); - ArgumentList *tSrcMdAl = srcMd->templateArguments(); - ArgumentList *tMdAl = md->templateArguments(); + const ArgumentList *srcMdAl = srcMd->argumentList(); + const ArgumentList *mdAl = md->argumentList(); + const ArgumentList *tSrcMdAl = srcMd->templateArguments(); + const ArgumentList *tMdAl = md->templateArguments(); if (srcMd->isFunction() && md->isFunction() && // both are a function ((tSrcMdAl==0 && tMdAl==0) || @@ -412,8 +532,8 @@ bool GroupDef::insertMember(MemberDef *md,bool docOnly) addMemberToList(MemberListType_docFriendMembers,md); break; default: - err("GroupDef::insertMembers(): " - "member `%s' (typeid=%d) with scope `%s' inserted in group scope `%s'!\n", + err("GroupDefImpl::insertMembers(): " + "member '%s' (typeid=%d) with scope '%s' inserted in group scope '%s'!\n", md->name().data(),md->memberType(), md->getClassDef() ? md->getClassDef()->name().data() : "", name().data()); @@ -421,7 +541,7 @@ bool GroupDef::insertMember(MemberDef *md,bool docOnly) return TRUE; } -void GroupDef::removeMember(MemberDef *md) +void GroupDefImpl::removeMember(MemberDef *md) { // fprintf(stderr, "GroupDef(%s)::removeMember( %s )\n", title.data(), md->name().data()); MemberNameInfo *mni = allMemberNameInfoSDict->find(md->name()); @@ -503,12 +623,12 @@ void GroupDef::removeMember(MemberDef *md) removeMemberFromList(MemberListType_docFriendMembers,md); break; default: - err("GroupDef::removeMember(): unexpected member remove in file!\n"); + err("GroupDefImpl::removeMember(): unexpected member remove in file!\n"); } } } -bool GroupDef::findGroup(const GroupDef *def) const +bool GroupDefImpl::findGroup(const GroupDef *def) const { if (this==def) { @@ -529,22 +649,43 @@ bool GroupDef::findGroup(const GroupDef *def) const return FALSE; } -void GroupDef::addGroup(const GroupDef *def) +void GroupDefImpl::addGroup(const GroupDef *def) { - //printf("adding group `%s' to group `%s'\n",def->name().data(),name().data()); + //printf("adding group '%s' to group '%s'\n",def->name().data(),name().data()); //if (Config_getBool(SORT_MEMBER_DOCS)) // groupList->inSort(def); //else groupList->append(def); } -bool GroupDef::isASubGroup() const +bool GroupDefImpl::isASubGroup() const { GroupList *groups = partOfGroups(); return groups!=0 && groups->count()!=0; } -int GroupDef::countMembers() const +void GroupDefImpl::countMembers() +{ + QListIterator<MemberList> mli(m_memberLists); + MemberList *ml; + for (;(ml=mli.current());++mli) + { + ml->countDecMembers(); + ml->countDocMembers(); + } + if (memberGroupSDict) + { + MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + mg->countDecMembers(); + mg->countDocMembers(); + } + } +} + +int GroupDefImpl::numDocMembers() const { return fileList->count()+ classSDict->count()+ @@ -556,13 +697,13 @@ int GroupDef::countMembers() const } /*! Compute the HTML anchor names for all members in the group */ -void GroupDef::computeAnchors() +void GroupDefImpl::computeAnchors() { - //printf("GroupDef::computeAnchors()\n"); + //printf("GroupDefImpl::computeAnchors()\n"); setAnchors(allMemberList); } -void GroupDef::writeTagFile(FTextStream &tagFile) +void GroupDefImpl::writeTagFile(FTextStream &tagFile) { tagFile << " <compound kind=\"group\">" << endl; tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; @@ -705,14 +846,14 @@ void GroupDef::writeTagFile(FTextStream &tagFile) tagFile << " </compound>" << endl; } -void GroupDef::writeDetailedDescription(OutputList &ol,const QCString &title) +void GroupDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title) { if ((!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF)) || !documentation().isEmpty() || !inbodyDocumentation().isEmpty() ) { ol.pushGeneratorState(); - if (pageDict->count()!=countMembers()) // not only pages -> classical layout + if (pageDict->count()!=numDocMembers()) // not only pages -> classical layout { ol.pushGeneratorState(); ol.disable(OutputGenerator::Html); @@ -766,7 +907,7 @@ void GroupDef::writeDetailedDescription(OutputList &ol,const QCString &title) } } -void GroupDef::writeBriefDescription(OutputList &ol) +void GroupDefImpl::writeBriefDescription(OutputList &ol) { if (hasBriefDescription()) { @@ -802,7 +943,7 @@ void GroupDef::writeBriefDescription(OutputList &ol) ol.writeSynopsis(); } -void GroupDef::writeGroupGraph(OutputList &ol) +void GroupDefImpl::writeGroupGraph(OutputList &ol) { if (Config_getBool(HAVE_DOT) /*&& Config_getBool(GROUP_GRAPHS)*/ ) { @@ -822,7 +963,7 @@ void GroupDef::writeGroupGraph(OutputList &ol) } } -void GroupDef::writeFiles(OutputList &ol,const QCString &title) +void GroupDefImpl::writeFiles(OutputList &ol,const QCString &title) { // write list of files if (fileList->count()>0) @@ -854,13 +995,13 @@ void GroupDef::writeFiles(OutputList &ol,const QCString &title) } } -void GroupDef::writeNamespaces(OutputList &ol,const QCString &title) +void GroupDefImpl::writeNamespaces(OutputList &ol,const QCString &title) { // write list of namespaces namespaceSDict->writeDeclaration(ol,title); } -void GroupDef::writeNestedGroups(OutputList &ol,const QCString &title) +void GroupDefImpl::writeNestedGroups(OutputList &ol,const QCString &title) { // write list of groups int count=0; @@ -910,7 +1051,7 @@ void GroupDef::writeNestedGroups(OutputList &ol,const QCString &title) } } -void GroupDef::writeDirs(OutputList &ol,const QCString &title) +void GroupDefImpl::writeDirs(OutputList &ol,const QCString &title) { // write list of directories if (dirList->count()>0) @@ -943,18 +1084,18 @@ void GroupDef::writeDirs(OutputList &ol,const QCString &title) } } -void GroupDef::writeClasses(OutputList &ol,const QCString &title) +void GroupDefImpl::writeClasses(OutputList &ol,const QCString &title) { // write list of classes classSDict->writeDeclaration(ol,0,title,FALSE); } -void GroupDef::writeInlineClasses(OutputList &ol) +void GroupDefImpl::writeInlineClasses(OutputList &ol) { classSDict->writeDocumentation(ol); } -void GroupDef::writePageDocumentation(OutputList &ol) +void GroupDefImpl::writePageDocumentation(OutputList &ol) { PageDef *pd=0; PageSDict::Iterator pdi(*pageDict); @@ -963,7 +1104,7 @@ void GroupDef::writePageDocumentation(OutputList &ol) if (!pd->isReference()) { SectionInfo *si=0; - if (!pd->title().isEmpty() && !pd->name().isEmpty() && + if (pd->hasTitle() && !pd->name().isEmpty() && (si=Doxygen::sectionDict->find(pd->name()))!=0) { ol.startSection(si->label,si->title,SectionInfo::Subsection); @@ -977,7 +1118,7 @@ void GroupDef::writePageDocumentation(OutputList &ol) } } -void GroupDef::writeMemberGroups(OutputList &ol) +void GroupDefImpl::writeMemberGroups(OutputList &ol) { /* write user defined member groups */ if (memberGroupSDict) @@ -993,19 +1134,19 @@ void GroupDef::writeMemberGroups(OutputList &ol) } } -void GroupDef::startMemberDeclarations(OutputList &ol) +void GroupDefImpl::startMemberDeclarations(OutputList &ol) { ol.startMemberSections(); } -void GroupDef::endMemberDeclarations(OutputList &ol) +void GroupDefImpl::endMemberDeclarations(OutputList &ol) { ol.endMemberSections(); } -void GroupDef::startMemberDocumentation(OutputList &ol) +void GroupDefImpl::startMemberDocumentation(OutputList &ol) { - //printf("** GroupDef::startMemberDocumentation()\n"); + //printf("** GroupDefImpl::startMemberDocumentation()\n"); if (Config_getBool(SEPARATE_MEMBER_PAGES)) { ol.pushGeneratorState(); @@ -1014,9 +1155,9 @@ void GroupDef::startMemberDocumentation(OutputList &ol) } } -void GroupDef::endMemberDocumentation(OutputList &ol) +void GroupDefImpl::endMemberDocumentation(OutputList &ol) { - //printf("** GroupDef::endMemberDocumentation()\n"); + //printf("** GroupDefImpl::endMemberDocumentation()\n"); if (Config_getBool(SEPARATE_MEMBER_PAGES)) { ol.popGeneratorState(); @@ -1024,7 +1165,7 @@ void GroupDef::endMemberDocumentation(OutputList &ol) } } -void GroupDef::writeAuthorSection(OutputList &ol) +void GroupDefImpl::writeAuthorSection(OutputList &ol) { // write Author section (Man only) ol.pushGeneratorState(); @@ -1036,7 +1177,7 @@ void GroupDef::writeAuthorSection(OutputList &ol) ol.popGeneratorState(); } -void GroupDef::writeSummaryLinks(OutputList &ol) +void GroupDefImpl::writeSummaryLinks(OutputList &ol) const { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -1081,7 +1222,7 @@ void GroupDef::writeSummaryLinks(OutputList &ol) ol.popGeneratorState(); } -void GroupDef::writeDocumentation(OutputList &ol) +void GroupDefImpl::writeDocumentation(OutputList &ol) { //static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); ol.pushGeneratorState(); @@ -1258,7 +1399,7 @@ void GroupDef::writeDocumentation(OutputList &ol) } -void GroupDef::writeMemberPages(OutputList &ol) +void GroupDefImpl::writeMemberPages(OutputList &ol) { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -1276,7 +1417,7 @@ void GroupDef::writeMemberPages(OutputList &ol) ol.popGeneratorState(); } -void GroupDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const +void GroupDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const { static bool createSubDirs=Config_getBool(CREATE_SUBDIRS); @@ -1345,7 +1486,7 @@ void addNamespaceToGroups(Entry *root,NamespaceDef *nd) for (;(g=gli.current());++gli) { GroupDef *gd=0; - //printf("group `%s'\n",s->data()); + //printf("group '%s'\n",s->data()); if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) { if (gd->addNamespace(nd)) nd->makePartOfGroup(gd); @@ -1362,7 +1503,7 @@ void addDirToGroups(Entry *root,DirDef *dd) for (;(g=gli.current());++gli) { GroupDef *gd=0; - //printf("group `%s'\n",g->groupname.data()); + //printf("group '%s'\n",g->groupname.data()); if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) { gd->addDir(dd); @@ -1439,7 +1580,7 @@ void addMemberToGroups(Entry *root,MemberDef *md) // put member into group defined by this entry? if (fgd) { - GroupDef *mgd = md->getGroupDef(); + GroupDef *mgd = const_cast<GroupDef*>(md->getGroupDef()); //printf("mgd=%p\n",mgd); bool insertit = FALSE; if (mgd==0) @@ -1525,12 +1666,12 @@ void addExampleToGroups(Entry *root,PageDef *eg) } } -QCString GroupDef::getOutputFileBase() const +QCString GroupDefImpl::getOutputFileBase() const { return fileName; } -void GroupDef::addListReferences() +void GroupDefImpl::addListReferences() { { QList<ListItemInfo> *xrefItems = xrefListItems(); @@ -1559,7 +1700,7 @@ void GroupDef::addListReferences() } } -MemberList *GroupDef::createMemberList(MemberListType lt) +MemberList *GroupDefImpl::createMemberList(MemberListType lt) { m_memberLists.setAutoDelete(TRUE); QListIterator<MemberList> mli(m_memberLists); @@ -1578,7 +1719,7 @@ MemberList *GroupDef::createMemberList(MemberListType lt) return ml; } -void GroupDef::addMemberToList(MemberListType lt,MemberDef *md) +void GroupDefImpl::addMemberToList(MemberListType lt,MemberDef *md) { static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); @@ -1589,7 +1730,7 @@ void GroupDef::addMemberToList(MemberListType lt,MemberDef *md) ml->append(md); } -void GroupDef::sortMemberLists() +void GroupDefImpl::sortMemberLists() { QListIterator<MemberList> mli(m_memberLists); MemberList *ml; @@ -1599,7 +1740,7 @@ void GroupDef::sortMemberLists() } } -MemberList *GroupDef::getMemberList(MemberListType lt) const +MemberList *GroupDefImpl::getMemberList(MemberListType lt) const { QListIterator<MemberList> mli(m_memberLists); MemberList *ml; @@ -1613,7 +1754,7 @@ MemberList *GroupDef::getMemberList(MemberListType lt) const return 0; } -void GroupDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title) +void GroupDefImpl::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title) { static bool optimizeVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL); @@ -1629,36 +1770,36 @@ void GroupDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QC } } -void GroupDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title) +void GroupDefImpl::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title) { MemberList * ml = getMemberList(lt); if (ml) ml->writeDocumentation(ol,name(),this,title); } -void GroupDef::removeMemberFromList(MemberListType lt,MemberDef *md) +void GroupDefImpl::removeMemberFromList(MemberListType lt,MemberDef *md) { MemberList *ml = getMemberList(lt); if (ml) ml->remove(md); } -void GroupDef::sortSubGroups() +void GroupDefImpl::sortSubGroups() { groupList->sort(); } -bool GroupDef::isLinkableInProject() const +bool GroupDefImpl::isLinkableInProject() const { return !isReference() && isLinkable(); } -bool GroupDef::isLinkable() const +bool GroupDefImpl::isLinkable() const { return hasUserDocumentation(); } // let the "programming language" for a group depend on what is inserted into it. // First item that has an associated languages determines the language for the whole group. -void GroupDef::updateLanguage(const Definition *d) +void GroupDefImpl::updateLanguage(const Definition *d) { if (getLanguage()==SrcLangExt_Unknown && d->getLanguage()!=SrcLangExt_Unknown) { @@ -1666,7 +1807,7 @@ void GroupDef::updateLanguage(const Definition *d) } } -bool GroupDef::hasDetailedDescription() const +bool GroupDefImpl::hasDetailedDescription() const { static bool repeatBrief = Config_getBool(REPEAT_BRIEF); return ((!briefDescription().isEmpty() && repeatBrief) || diff --git a/src/groupdef.h b/src/groupdef.h index be4475f..92d524f 100644 --- a/src/groupdef.h +++ b/src/groupdef.h @@ -42,122 +42,71 @@ class MemberDef; class FTextStream; /** A model of a group of symbols. */ -class GroupDef : public Definition +class GroupDef : virtual public Definition { public: - GroupDef(const char *fileName,int line,const char *name,const char *title,const char *refFileName=0); - ~GroupDef(); - DefType definitionType() const { return TypeGroup; } - QCString getOutputFileBase() const; - QCString anchor() const { return QCString(); } - QCString displayName(bool=TRUE) const { return hasGroupTitle() ? title : Definition::name(); } - const char *groupTitle() const { return title; } - void setGroupTitle( const char *newtitle ); - bool hasGroupTitle( ) const { return titleSet; } - void addFile(const FileDef *def); - bool addClass(const ClassDef *def); - bool addNamespace(const NamespaceDef *def); - void addGroup(const GroupDef *def); - void addParentGroup(const GroupDef *def); - void addPage(PageDef *def); - void addExample(const PageDef *def); - void addDir(const DirDef *dd); - bool insertMember(MemberDef *def,bool docOnly=FALSE); - void removeMember(MemberDef *md); - bool findGroup(const GroupDef *def) const; // true if def is a subgroup of this group - void writeDocumentation(OutputList &ol); - void writeMemberPages(OutputList &ol); - void writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const; - void writeTagFile(FTextStream &); - int countMembers() const; - bool isLinkableInProject() const; - bool isLinkable() const; - bool isASubGroup() const; - void computeAnchors(); - - void addMembersToMemberGroup(); - void distributeMemberGroupDocumentation(); - void findSectionsInDocumentation(); - - void addListReferences(); - void sortMemberLists(); - bool subGrouping() const { return m_subGrouping; } - - bool visited; // number of times accessed for output - KPW - - //friend void writeGroupTreeNode(OutputList&, GroupDef*, int, FTVHelp*); - // make accessible for writing tree view of group in index.cpp - KPW - - void setGroupScope(Definition *d) { groupScope = d; } - Definition *getGroupScope() const { return groupScope; } - - MemberList *getMemberList(MemberListType lt) const; - const QList<MemberList> &getMemberLists() const { return m_memberLists; } + ~GroupDef() {} + + virtual DefType definitionType() const = 0; + virtual QCString getOutputFileBase() const = 0; + virtual QCString anchor() const = 0; + virtual QCString displayName(bool=TRUE) const = 0; + virtual const char *groupTitle() const = 0; + virtual void setGroupTitle( const char *newtitle ) = 0; + virtual bool hasGroupTitle( ) const = 0; + virtual void addFile(const FileDef *def) = 0; + virtual bool addClass(const ClassDef *def) = 0; + virtual bool addNamespace(const NamespaceDef *def) = 0; + virtual void addGroup(const GroupDef *def) = 0; + virtual void addPage(PageDef *def) = 0; + virtual void addExample(const PageDef *def) = 0; + virtual void addDir(const DirDef *dd) = 0; + virtual bool insertMember(MemberDef *def,bool docOnly=FALSE) = 0; + virtual void removeMember(MemberDef *md) = 0; + virtual bool findGroup(const GroupDef *def) const = 0; + virtual void writeDocumentation(OutputList &ol) = 0; + virtual void writeMemberPages(OutputList &ol) = 0; + virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const = 0; + virtual void writeTagFile(FTextStream &) = 0; + virtual int numDocMembers() const = 0; + virtual bool isLinkableInProject() const = 0; + virtual bool isLinkable() const = 0; + virtual bool isASubGroup() const = 0; + virtual void computeAnchors() = 0; + virtual void countMembers() = 0; + + virtual void addMembersToMemberGroup() = 0; + virtual void distributeMemberGroupDocumentation() = 0; + virtual void findSectionsInDocumentation() = 0; + + virtual void addListReferences() = 0; + virtual void sortMemberLists() = 0; + virtual bool subGrouping() const = 0; + + virtual void setGroupScope(Definition *d) = 0; + virtual Definition *getGroupScope() const = 0; + + virtual MemberList *getMemberList(MemberListType lt) const = 0; + virtual const QList<MemberList> &getMemberLists() const = 0; /* user defined member groups */ - MemberGroupSDict *getMemberGroupSDict() const { return memberGroupSDict; } - - FileList * getFiles() const { return fileList; } - ClassSDict * getClasses() const { return classSDict; } - NamespaceSDict * getNamespaces() const { return namespaceSDict; } - GroupList * getSubGroups() const { return groupList; } - PageSDict * getPages() const { return pageDict; } - DirList * getDirs() const { return dirList; } - PageSDict * getExamples() const { return exampleDict; } - bool hasDetailedDescription() const; - //MemberList* getMembers() const { return allMemberList; } - void sortSubGroups(); - - protected: - void addMemberListToGroup(MemberList *,bool (MemberDef::*)() const); - - private: - MemberList *createMemberList(MemberListType lt); - void addMemberToList(MemberListType lt,MemberDef *md); - void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title); - void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title); - void removeMemberFromList(MemberListType lt,MemberDef *md); - void writeGroupGraph(OutputList &ol); - void writeFiles(OutputList &ol,const QCString &title); - void writeNamespaces(OutputList &ol,const QCString &title); - void writeNestedGroups(OutputList &ol,const QCString &title); - void writeDirs(OutputList &ol,const QCString &title); - void writeClasses(OutputList &ol,const QCString &title); - void writeInlineClasses(OutputList &ol); - void writePageDocumentation(OutputList &ol); - void writeDetailedDescription(OutputList &ol,const QCString &title); - void writeBriefDescription(OutputList &ol); - void writeMemberGroups(OutputList &ol); - void startMemberDeclarations(OutputList &ol); - void endMemberDeclarations(OutputList &ol); - void startMemberDocumentation(OutputList &ol); - void endMemberDocumentation(OutputList &ol); - void writeAuthorSection(OutputList &ol); - void writeSummaryLinks(OutputList &ol); - void updateLanguage(const Definition *); - - QCString title; // title of the group - bool titleSet; // true if title is not the same as the name - QCString fileName; // base name of the generated file - FileList *fileList; // list of files in the group - ClassSDict *classSDict; // list of classes in the group - NamespaceSDict *namespaceSDict; // list of namespaces in the group - GroupList *groupList; // list of sub groups. - PageSDict *pageDict; // list of pages in the group - PageSDict *exampleDict; // list of examples in the group - DirList *dirList; // list of directories in the group - - MemberList *allMemberList; - MemberNameInfoSDict *allMemberNameInfoSDict; - - Definition *groupScope; - - QList<MemberList> m_memberLists; - MemberGroupSDict *memberGroupSDict; - bool m_subGrouping; + virtual MemberGroupSDict *getMemberGroupSDict() const = 0; + + virtual FileList * getFiles() const = 0; + virtual ClassSDict * getClasses() const = 0; + virtual NamespaceSDict * getNamespaces() const = 0; + virtual GroupList * getSubGroups() const = 0; + virtual PageSDict * getPages() const = 0; + virtual DirList * getDirs() const = 0; + virtual PageSDict * getExamples() const = 0; + virtual bool hasDetailedDescription() const = 0; + virtual void sortSubGroups() = 0; }; +GroupDef *createGroupDef(const char *fileName,int line,const char *name, + const char *title,const char *refFileName=0); + /** A sorted dictionary of GroupDef objects. */ class GroupSDict : public SDict<GroupDef> { diff --git a/src/growbuf.h b/src/growbuf.h index bc8e4b5..4c49dce 100644 --- a/src/growbuf.h +++ b/src/growbuf.h @@ -11,11 +11,21 @@ class GrowBuf { public: GrowBuf() : str(0), pos(0), len(0) {} + GrowBuf(int initialSize) : pos(0), len(initialSize) { str=(char*)malloc(len); } ~GrowBuf() { free(str); str=0; pos=0; len=0; } void clear() { pos=0; } void addChar(char c) { if (pos>=len) { len+=GROW_AMOUNT; str = (char*)realloc(str,len); } str[pos++]=c; } + void addStr(const QCString &s) { + if (!s.isEmpty()) + { + int l=s.length(); + if (pos+l>=len) { len+=l+GROW_AMOUNT; str = (char*)realloc(str,len); } + strcpy(&str[pos],s.data()); + pos+=l; + } + } void addStr(const char *s) { if (s) { diff --git a/src/htags.cpp b/src/htags.cpp index 77b1f8d..51cd6d9 100644 --- a/src/htags.cpp +++ b/src/htags.cpp @@ -91,6 +91,10 @@ bool Htags::execute(const QCString &htmldir) //printf("CommandLine=[%s]\n",commandLine.data()); portable_sysTimerStart(); bool result=portable_system("htags",commandLine,FALSE)==0; + if (!result) + { + err("Problems running %s. Check your installation\n", "htags"); + } portable_sysTimerStop(); QDir::setCurrent(oldDir); return result; @@ -128,7 +132,7 @@ bool Htags::loadFilemap(const QCString &htmlDir) int len; while ((len=f.readLine(line.rawData(),maxlen))>0) { - line.resize(len+1); + line.at(len)='\0'; //printf("Read line: %s",line.data()); int sep = line.find('\t'); if (sep!=-1) diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 6386cb8..e1ff3e9 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -126,7 +126,6 @@ static bool mustBeOutsideParagraph(DocNode *n) case DocNode::Kind_Internal: /* <div> */ case DocNode::Kind_Include: - case DocNode::Kind_Image: case DocNode::Kind_SecRefList: /* <hr> */ case DocNode::Kind_HorRuler: @@ -152,6 +151,8 @@ static bool mustBeOutsideParagraph(DocNode *n) ((DocStyleChange*)n)->style()==DocStyleChange::Center; case DocNode::Kind_Formula: return !((DocFormula*)n)->isInline(); + case DocNode::Kind_Image: + return !((DocImage*)n)->isInlineImage(); default: break; } @@ -210,36 +211,66 @@ static bool isInvisibleNode(DocNode *node) ; } -static QString htmlAttribsToString(const HtmlAttribList &attribs, bool img_tag = FALSE) +static void mergeHtmlAttributes(const HtmlAttribList &attribs, HtmlAttribList *mergeInto) { - QString result; HtmlAttribListIterator li(attribs); HtmlAttrib *att; - bool alt_set = FALSE; + for (li.toFirst();(att=li.current());++li) + { + HtmlAttribListIterator ml(*mergeInto); + HtmlAttrib *opt; + bool found = false; + for (ml.toFirst();(opt=ml.current());++ml) + { + if (opt->name == att -> name) + { + found = true; + break; + } + } + if (found) + { + opt->value = opt->value + " " + att->value; + } + else + { + mergeInto->append(att); + } + } +} +static QCString htmlAttribsToString(const HtmlAttribList &attribs, QCString *pAltValue = 0) +{ + QCString result; + HtmlAttribListIterator li(attribs); + HtmlAttrib *att; for (li.toFirst();(att=li.current());++li) { if (!att->value.isEmpty()) // ignore attribute without values as they // are not XHTML compliant, with the exception // of the alt attribute with the img tag { - result+=" "; - result+=att->name; - result+="=\""+convertToXML(att->value)+"\""; - if (att->name == "alt") alt_set = TRUE; + if (att->name=="alt" && pAltValue) // optionally return the value of alt separately + // need to convert <img> to <object> for SVG images, + // which do not support the alt attribute + { + *pAltValue = att->value; + } + else + { + result+=" "; + result+=att->name; + result+="=\""+convertToXML(att->value)+"\""; + } } } - if (!alt_set && img_tag) - { - result+=" alt=\"\""; - } return result; } //------------------------------------------------------------------------- HtmlDocVisitor::HtmlDocVisitor(FTextStream &t,CodeOutputInterface &ci, - Definition *ctx) + const Definition *ctx) : DocVisitor(DocVisitor_Html), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_ctx(ctx) { @@ -347,17 +378,17 @@ void HtmlDocVisitor::visit(DocURL *u) } } -void HtmlDocVisitor::visit(DocLineBreak *) +void HtmlDocVisitor::visit(DocLineBreak *br) { if (m_hide) return; - m_t << "<br />\n"; + m_t << "<br "<< htmlAttribsToString(br->attribs()) << " />\n"; } void HtmlDocVisitor::visit(DocHorRuler *hr) { if (m_hide) return; forceEndParagraph(hr); - m_t << "<hr/>\n"; + m_t << "<hr "<< htmlAttribsToString(hr->attribs()) << " />\n"; forceStartParagraph(hr); } @@ -372,9 +403,15 @@ void HtmlDocVisitor::visit(DocStyleChange *s) case DocStyleChange::Strike: if (s->enable()) m_t << "<strike" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</strike>"; break; + case DocStyleChange::Del: + if (s->enable()) m_t << "<del" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</del>"; + break; case DocStyleChange::Underline: if (s->enable()) m_t << "<u" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</u>"; break; + case DocStyleChange::Ins: + if (s->enable()) m_t << "<ins" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</ins>"; + break; case DocStyleChange::Italic: if (s->enable()) m_t << "<em" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</em>"; break; @@ -588,9 +625,14 @@ void HtmlDocVisitor::visit(DocVerbatim *s) case DocVerbatim::PlantUML: { forceEndParagraph(s); - static QCString htmlOutput = Config_getString(HTML_OUTPUT); - QCString baseName = writePlantUMLSource(htmlOutput,s->exampleFile(),s->text()); + QCString imgExt = getDotImageExtension(); + PlantumlManager::OutputFormat format = PlantumlManager::PUML_BITMAP; // default : PUML_BITMAP + if (imgExt=="svg") + { + format = PlantumlManager::PUML_SVG; + } + QCString baseName = PlantumlManager::instance()->writePlantUMLSource(htmlOutput,s->exampleFile(),s->text(),format); m_t << "<div class=\"plantumlgraph\">" << endl; writePlantUMLFile(baseName,s->relPath(),s->context()); visitPreCaption(m_t, s); @@ -606,7 +648,7 @@ void HtmlDocVisitor::visit(DocVerbatim *s) void HtmlDocVisitor::visit(DocAnchor *anc) { if (m_hide) return; - m_t << "<a class=\"anchor\" id=\"" << anc->anchor() << "\"></a>"; + m_t << "<a class=\"anchor\" id=\"" << anc->anchor() << "\"" << htmlAttribsToString(anc->attribs()) << "></a>"; } void HtmlDocVisitor::visit(DocInclude *inc) @@ -641,7 +683,7 @@ void HtmlDocVisitor::visit(DocInclude *inc) forceEndParagraph(inc); m_t << PREFRAG_START; QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci, inc->context(), @@ -649,7 +691,7 @@ void HtmlDocVisitor::visit(DocInclude *inc) langExt, inc->isExample(), inc->exampleFile(), - &fd, // fileDef, + fd, // fileDef, -1, // start line -1, // end line FALSE, // inline fragment @@ -657,11 +699,14 @@ void HtmlDocVisitor::visit(DocInclude *inc) TRUE, // show line numbers m_ctx // search context ); + delete fd; m_t << PREFRAG_END; forceStartParagraph(inc); } break; - case DocInclude::DontInclude: + case DocInclude::DontInclude: + case DocInclude::LatexInclude: + case DocInclude::DontIncWithLines: break; case DocInclude::HtmlInclude: { @@ -670,8 +715,6 @@ void HtmlDocVisitor::visit(DocInclude *inc) if (inc->isBlock()) forceStartParagraph(inc); } break; - case DocInclude::LatexInclude: - break; case DocInclude::VerbInclude: forceEndParagraph(inc); m_t << /*PREFRAG_START <<*/ "<pre class=\"fragment\">"; @@ -707,7 +750,7 @@ void HtmlDocVisitor::visit(DocInclude *inc) forceEndParagraph(inc); m_t << PREFRAG_START; QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci, inc->context(), @@ -715,7 +758,7 @@ void HtmlDocVisitor::visit(DocInclude *inc) langExt, inc->isExample(), inc->exampleFile(), - &fd, + fd, lineBlock(inc->text(),inc->blockId()), -1, // endLine FALSE, // inlineFragment @@ -723,6 +766,7 @@ void HtmlDocVisitor::visit(DocInclude *inc) TRUE, // show line number m_ctx // search context ); + delete fd; m_t << PREFRAG_END; forceStartParagraph(inc); } @@ -737,7 +781,7 @@ void HtmlDocVisitor::visit(DocInclude *inc) void HtmlDocVisitor::visit(DocIncOperator *op) { - //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n", + //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", // op->type(),op->isFirst(),op->isLast(),op->text().data()); if (op->isFirst()) { @@ -746,13 +790,21 @@ void HtmlDocVisitor::visit(DocIncOperator *op) pushEnabled(); m_hide=TRUE; } - SrcLangExt langExt = getLanguageFromFileName(m_langExt); + QCString locLangExt = getFileNameExtension(op->includeFileName()); + if (locLangExt.isEmpty()) locLangExt = m_langExt; + SrcLangExt langExt = getLanguageFromFileName(locLangExt); if (op->type()!=DocIncOperator::Skip) { popEnabled(); if (!m_hide) { - Doxygen::parserManager->getParser(m_langExt) + FileDef *fd = 0; + if (!op->includeFileName().isEmpty()) + { + QFileInfo cfi( op->includeFileName() ); + fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + } + Doxygen::parserManager->getParser(locLangExt) ->parseCode( m_ci, op->context(), @@ -760,14 +812,15 @@ void HtmlDocVisitor::visit(DocIncOperator *op) langExt, op->isExample(), op->exampleFile(), - 0, // fileDef - -1, // startLine + fd, // fileDef + op->line(), // startLine -1, // endLine FALSE, // inline fragment 0, // memberDef - TRUE, // show line numbers + op->showLineNo(), // show line numbers m_ctx // search context ); + if (fd) delete fd; } pushEnabled(); m_hide=TRUE; @@ -1198,13 +1251,17 @@ void HtmlDocVisitor::visitPre(DocPara *p) //printf(" needsTag=%d\n",needsTag); // write the paragraph tag (if needed) if (needsTag) - m_t << "<p" << getDirHtmlClassOfNode(getTextDirByConfig(p), contexts[t]) << ">"; + m_t << "<p" << getDirHtmlClassOfNode(getTextDirByConfig(p), contexts[t]) << htmlAttribsToString(p->attribs()) << ">"; else if(!paragraphAlreadyStarted) - m_t << getHtmlDirEmbedingChar(getTextDirByConfig(p)); + m_t << getHtmlDirEmbedingChar(getTextDirByConfig(p)) << htmlAttribsToString(p->attribs()); } void HtmlDocVisitor::visitPost(DocPara *p) { + + //printf("DocPara::visitPost: parent of kind %d ", + // p->parent() ? p->parent()->kind() : -1); + bool needsTag = FALSE; if (p->parent()) { @@ -1480,7 +1537,11 @@ void HtmlDocVisitor::visitPre(DocHtmlTable *t) if (t->hasCaption()) { - m_t << "<a class=\"anchor\" id=\"" << t->caption()->anchor() << "\"></a>\n"; + QCString anc = t->caption()->anchor(); + if (!anc.isEmpty()) + { + m_t << "<a class=\"anchor\" id=\"" << anc << "\"></a>\n"; + } } QString attrs = htmlAttribsToString(t->attribs()); @@ -1577,7 +1638,7 @@ void HtmlDocVisitor::visitPre(DocHRef *href) else { QCString url = correctURL(href->url(),href->relPath()); - m_t << "<a href=\"" << convertToXML(url) << "\"" + m_t << "<a href=\"" << convertToHtml(url) << "\"" << htmlAttribsToString(href->attribs()) << ">"; } } @@ -1610,17 +1671,9 @@ void HtmlDocVisitor::visitPre(DocImage *img) if (img->type()==DocImage::Html) { bool inlineImage = img->isInlineImage(); - bool typeSVG = FALSE; - + bool typeSVG = img->isSVG(); QCString url = img->url(); - if (url.isEmpty()) - { - typeSVG = (img->name().right(4)==".svg"); - } - else - { - typeSVG = (url.right(4)==".svg"); - } + if (!inlineImage) { forceEndParagraph(img); @@ -1642,41 +1695,58 @@ void HtmlDocVisitor::visitPre(DocImage *img) { sizeAttribs+=" height=\""+img->height()+"\""; } + // 16 cases: url.isEmpty() | typeSVG | inlineImage | img->hasCaption() + + HtmlAttribList extraAttribs; + if (typeSVG) + { + HtmlAttrib opt; + opt.name = "style"; + opt.value = "pointer-events: none;"; + extraAttribs.append(&opt); + } + QCString alt; + mergeHtmlAttributes(img->attribs(),&extraAttribs); + QCString attrs = htmlAttribsToString(extraAttribs,&alt); + QCString src; if (url.isEmpty()) { - if (typeSVG) + src = img->relPath()+img->name(); + } + else + { + src = correctURL(url,img->relPath()); + } + if (typeSVG) + { + m_t << "<object type=\"image/svg+xml\" data=\"" << src + << "\"" << sizeAttribs << attrs; + if (inlineImage) { - m_t << "<object type=\"image/svg+xml\" data=\"" << img->relPath() << img->name() - << "\"" << sizeAttribs << htmlAttribsToString(img->attribs()) << ">" << baseName - << "</object>" << endl; + // skip closing tag } else { - m_t << "<img src=\"" << img->relPath() << img->name() << "\" alt=\"" - << baseName << "\"" << sizeAttribs << htmlAttribsToString(img->attribs()) - << (inlineImage ? " class=\"inline\"" : "/>\n"); + m_t << ">" << alt << "</object>" << endl; } } - else // link to URL + else { - if (typeSVG) + m_t << "<img src=\"" << convertToHtml(src) << "\" alt=\"" << alt << "\"" << sizeAttribs << attrs; + if (inlineImage) { - m_t << "<object type=\"image/svg+xml\" data=\"" << correctURL(url,img->relPath()) - << "\"" << sizeAttribs << htmlAttribsToString(img->attribs()) - << "></object>" << endl; + m_t << " class=\"inline\""; } else { - m_t << "<img src=\"" << correctURL(url,img->relPath()) << "\"" - << sizeAttribs << htmlAttribsToString(img->attribs(), TRUE) - << (inlineImage ? " class=\"inline\"" : "/>\n"); + m_t << "/>\n"; } } if (img->hasCaption()) { if (inlineImage) { - m_t << " title=\""; + m_t << " title=\""; } else { @@ -1686,7 +1756,14 @@ void HtmlDocVisitor::visitPre(DocImage *img) } else if (inlineImage) { - m_t << "/>" << endl; + if (typeSVG) + { + m_t << ">" << alt << "</object>"; + } + else + { + m_t << "/>"; + } } } else // other format -> skip @@ -1705,11 +1782,24 @@ void HtmlDocVisitor::visitPost(DocImage *img) if (img->hasCaption()) { if (inlineImage) - m_t << "\"/>\n "; - else + { + if (img->isSVG()) + { + QCString alt; + QCString attrs = htmlAttribsToString(img->attribs(),&alt); + m_t << "\">" << alt << "</object>"; + } + else + { + m_t << "\"/>"; + } + } + else // end <div class="caption"> + { m_t << "</div>"; + } } - if (!inlineImage) + if (!inlineImage) // end <div class="image"> { m_t << "</div>" << endl; forceStartParagraph(img); @@ -1836,8 +1926,8 @@ void HtmlDocVisitor::visitPre(DocSecRefList *s) { if (m_hide) return; forceEndParagraph(s); - m_t << "<div class=\"multicol\">" << endl; - m_t << "<ul>" << endl; + m_t << "<div>" << endl; + m_t << "<ul class=\"multicol\">" << endl; } void HtmlDocVisitor::visitPost(DocSecRefList *s) @@ -1946,10 +2036,8 @@ void HtmlDocVisitor::visitPre(DocParamList *pl) m_t << "<td class=\"paramtype\">"; QListIterator<DocNode> li(pl->paramTypes()); DocNode *type; - bool first=TRUE; for (li.toFirst();(type=li.current());++li) { - if (!first) m_t << " | "; else first=FALSE; if (type->kind()==DocNode::Kind_Word) { visit((DocWord*)type); @@ -1958,6 +2046,10 @@ void HtmlDocVisitor::visitPre(DocParamList *pl) { visit((DocLinkedWord*)type); } + else if (type->kind()==DocNode::Kind_Sep) + { + m_t << " " << ((DocSeparator *)type)->chars() << " "; + } } m_t << "</td>"; } @@ -2034,14 +2126,6 @@ void HtmlDocVisitor::visitPost(DocInternalRef *) m_t << " "; } -void HtmlDocVisitor::visitPre(DocCopy *) -{ -} - -void HtmlDocVisitor::visitPost(DocCopy *) -{ -} - void HtmlDocVisitor::visitPre(DocText *) { } @@ -2164,7 +2248,7 @@ void HtmlDocVisitor::startLink(const QCString &ref,const QCString &file, if (!ref.isEmpty()) // link to entity imported via tag file { m_t << "<a class=\"elRef\" "; - m_t << externalLinkTarget() << externalRef(relPath,ref,FALSE); + m_t << externalLinkTarget(); } else // local link { @@ -2279,7 +2363,7 @@ void HtmlDocVisitor::writePlantUMLFile(const QCString &fileName, QCString imgExt = getDotImageExtension(); if (imgExt=="svg") { - generatePlantUMLOutput(fileName,outDir,PUML_SVG); + PlantumlManager::instance()->generatePlantUMLOutput(fileName,outDir,PlantumlManager::PUML_SVG); //m_t << "<iframe scrolling=\"no\" frameborder=\"0\" src=\"" << relPath << baseName << ".svg" << "\" />" << endl; //m_t << "<p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p>"; //m_t << "</iframe>" << endl; @@ -2287,7 +2371,7 @@ void HtmlDocVisitor::writePlantUMLFile(const QCString &fileName, } else { - generatePlantUMLOutput(fileName,outDir,PUML_BITMAP); + PlantumlManager::instance()->generatePlantUMLOutput(fileName,outDir,PlantumlManager::PUML_BITMAP); m_t << "<img src=\"" << relPath << baseName << ".png" << "\" />" << endl; } } @@ -2340,16 +2424,14 @@ void HtmlDocVisitor::forceEndParagraph(DocNode *n) DocPara *para = (DocPara*)n->parent(); int nodeIndex = para->children().findRef(n); nodeIndex--; - if (nodeIndex<0) return; // first node + if (nodeIndex<0) return; // first node in paragraph while (nodeIndex>=0 && isInvisibleNode(para->children().at(nodeIndex))) { nodeIndex--; } - if (nodeIndex>=0) - { - DocNode *n = para->children().at(nodeIndex); - if (mustBeOutsideParagraph(n)) return; - } + if (nodeIndex<0) return; // first visible node in paragraph + DocNode *n = para->children().at(nodeIndex); + if (mustBeOutsideParagraph(n)) return; // previous node already outside paragraph context nodeIndex--; bool styleOutsideParagraph=insideStyleChangeThatIsOutsideParagraph(para,nodeIndex); bool isFirst; diff --git a/src/htmldocvisitor.h b/src/htmldocvisitor.h index 7184f0f..c994bac 100644 --- a/src/htmldocvisitor.h +++ b/src/htmldocvisitor.h @@ -33,7 +33,7 @@ class CodeOutputInterface; class HtmlDocVisitor : public DocVisitor { public: - HtmlDocVisitor(FTextStream &t,CodeOutputInterface &ci,Definition *ctx); + HtmlDocVisitor(FTextStream &t,CodeOutputInterface &ci,const Definition *ctx); //-------------------------------------- // visitor functions for leaf nodes @@ -127,8 +127,6 @@ class HtmlDocVisitor : public DocVisitor void visitPost(DocXRefItem *); void visitPre(DocInternalRef *); void visitPost(DocInternalRef *); - void visitPre(DocCopy *); - void visitPost(DocCopy *); void visitPre(DocText *); void visitPost(DocText *); void visitPre(DocHtmlBlockQuote *); @@ -171,7 +169,7 @@ class HtmlDocVisitor : public DocVisitor bool m_insidePre; bool m_hide; QStack<bool> m_enabled; - Definition *m_ctx; + const Definition *m_ctx; QCString m_langExt; }; diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index efd2108..402b4e4 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -25,10 +25,15 @@ #include "config.h" #include "util.h" #include "doxygen.h" -#include "logos.h" #include "diagram.h" #include "version.h" #include "dot.h" +#include "dotcallgraph.h" +#include "dotclassgraph.h" +#include "dotdirdeps.h" +#include "dotgfxhierarchytable.h" +#include "dotgroupcollaboration.h" +#include "dotincldepgraph.h" #include "language.h" #include "htmlhelp.h" #include "docparser.h" @@ -43,7 +48,7 @@ #include "ftvhelp.h" #include "bufstr.h" #include "resourcemgr.h" - +#include "tooltip.h" //#define DBG_HTML(x) x; #define DBG_HTML(x) @@ -52,6 +57,7 @@ static QCString g_header; static QCString g_footer; static QCString g_mathjax_code; +static bool DoxyCodeLineOpen = FALSE; // note: this is only active if DISABLE_INDEX=YES, if DISABLE_INDEX is disabled, this // part will be rendered inside menu.js @@ -525,7 +531,12 @@ void HtmlCodeGenerator::writeLineNumber(const char *ref,const char *filename, qsnprintf(lineNumber,maxLineNrStr,"%5d",l); qsnprintf(lineAnchor,maxLineNrStr,"l%05d",l); - m_t << "<div class=\"line\">"; + if (!DoxyCodeLineOpen) + { + m_t << "<div class=\"line\">"; + DoxyCodeLineOpen = TRUE; + } + m_t << "<a name=\"" << lineAnchor << "\"></a><span class=\"lineno\">"; if (filename) { @@ -556,7 +567,7 @@ void HtmlCodeGenerator::_writeCodeLink(const char *className, if (ref) { m_t << "<a class=\"" << className << "Ref\" "; - m_t << externalLinkTarget() << externalRef(m_relPath,ref,FALSE); + m_t << externalLinkTarget(); } else { @@ -656,18 +667,34 @@ void HtmlCodeGenerator::writeTooltip(const char *id, const DocLinkInfo &docInfo, } -void HtmlCodeGenerator::startCodeLine(bool hasLineNumbers) +void HtmlCodeGenerator::startCodeLine(bool) { if (m_streamSet) { - if (!hasLineNumbers) m_t << "<div class=\"line\">"; m_col=0; + if (!DoxyCodeLineOpen) + { + m_t << "<div class=\"line\">"; + DoxyCodeLineOpen = TRUE; + } } } void HtmlCodeGenerator::endCodeLine() { - if (m_streamSet) m_t << "</div>"; + if (m_streamSet) + { + if (m_col == 0) + { + m_t << " "; + m_col++; + } + if (DoxyCodeLineOpen) + { + m_t << "</div>\n"; + DoxyCodeLineOpen = FALSE; + } + } } void HtmlCodeGenerator::startFontClass(const char *s) @@ -769,7 +796,7 @@ void HtmlGenerator::init() t << endl << "$(document).ready(function() {\n" " $('.code,.codeRef').each(function() {\n" - " $(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html());\n" + " $(this).data('powertip',$('#a'+$(this).attr('href').replace(/.*\\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html());\n" " $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true });\n" " });\n" "});\n"; @@ -851,7 +878,7 @@ void HtmlGenerator::writeSearchData(const char *dir) { searchCss = mgr.getAsString("search.css"); } - searchCss = substitute(replaceColorMarkers(searchCss),"$doxygenversion",versionString); + searchCss = substitute(replaceColorMarkers(searchCss),"$doxygenversion",getVersion()); t << searchCss; Doxygen::indexList->addStyleSheetFile("search/search.css"); } @@ -860,20 +887,20 @@ void HtmlGenerator::writeSearchData(const char *dir) void HtmlGenerator::writeStyleSheetFile(QFile &file) { FTextStream t(&file); - t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",versionString)); + t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",getVersion())); } void HtmlGenerator::writeHeaderFile(QFile &file, const char * /*cssname*/) { FTextStream t(&file); - t << "<!-- HTML header for doxygen " << versionString << "-->" << endl; + t << "<!-- HTML header for doxygen " << getVersion() << "-->" << endl; t << ResourceMgr::instance().getAsString("header.html"); } void HtmlGenerator::writeFooterFile(QFile &file) { FTextStream t(&file); - t << "<!-- HTML footer for doxygen " << versionString << "-->" << endl; + t << "<!-- HTML footer for doxygen " << getVersion() << "-->" << endl; t << ResourceMgr::instance().getAsString("footer.html"); } @@ -898,7 +925,7 @@ void HtmlGenerator::startFile(const char *name,const char *, t << substituteHtmlKeywords(g_header,convertToHtml(filterTitle(title)),relPath); t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " - << versionString << " -->" << endl; + << getVersion() << " -->" << endl; //static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); static bool searchEngine = Config_getBool(SEARCHENGINE); if (searchEngine /*&& !generateTreeView*/) @@ -963,7 +990,7 @@ QCString HtmlGenerator::writeLogoAsString(const char *path) "<img class=\"footer\" src=\""; result += path; result += "doxygen.png\" alt=\"doxygen\"/></a> "; - result += versionString; + result += getVersion(); result += " "; return result; } @@ -981,6 +1008,9 @@ 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,lastTitle,relPath,navPath); } @@ -1013,7 +1043,7 @@ void HtmlGenerator::writeStyleInfo(int part) //t << "H1 { text-align: center; border-width: thin none thin none;" << endl; //t << " border-style : double; border-color : blue; padding-left : 1em; padding-right : 1em }" << endl; - t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",versionString)); + t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",getVersion())); endPlainFile(); Doxygen::indexList->addStyleSheetFile("doxygen.css"); } @@ -1111,7 +1141,7 @@ void HtmlGenerator::startIndexItem(const char *ref,const char *f) if (ref) { t << "<a class=\"elRef\" "; - t << externalLinkTarget() << externalRef(relPath,ref,FALSE); + t << externalLinkTarget(); } else { @@ -1157,7 +1187,7 @@ void HtmlGenerator::writeObjectLink(const char *ref,const char *f, if (ref) { t << "<a class=\"elRef\" "; - t << externalLinkTarget() << externalRef(relPath,ref,FALSE); + t << externalLinkTarget(); } else { @@ -1765,7 +1795,7 @@ void HtmlGenerator::startDotGraph() startSectionHeader(t,relPath,m_sectionCount); } -void HtmlGenerator::endDotGraph(const DotClassGraph &g) +void HtmlGenerator::endDotGraph(DotClassGraph &g) { bool generateLegend = Config_getBool(GENERATE_LEGEND); bool umlLook = Config_getBool(UML_LOOK); @@ -1793,7 +1823,7 @@ void HtmlGenerator::startInclDepGraph() startSectionHeader(t,relPath,m_sectionCount); } -void HtmlGenerator::endInclDepGraph(const DotInclDepGraph &g) +void HtmlGenerator::endInclDepGraph(DotInclDepGraph &g) { endSectionHeader(t); startSectionSummary(t,m_sectionCount); @@ -1811,7 +1841,7 @@ void HtmlGenerator::startGroupCollaboration() startSectionHeader(t,relPath,m_sectionCount); } -void HtmlGenerator::endGroupCollaboration(const DotGroupCollaboration &g) +void HtmlGenerator::endGroupCollaboration(DotGroupCollaboration &g) { endSectionHeader(t); startSectionSummary(t,m_sectionCount); @@ -1829,7 +1859,7 @@ void HtmlGenerator::startCallGraph() startSectionHeader(t,relPath,m_sectionCount); } -void HtmlGenerator::endCallGraph(const DotCallGraph &g) +void HtmlGenerator::endCallGraph(DotCallGraph &g) { endSectionHeader(t); startSectionSummary(t,m_sectionCount); @@ -1847,7 +1877,7 @@ void HtmlGenerator::startDirDepGraph() startSectionHeader(t,relPath,m_sectionCount); } -void HtmlGenerator::endDirDepGraph(const DotDirDeps &g) +void HtmlGenerator::endDirDepGraph(DotDirDeps &g) { endSectionHeader(t); startSectionSummary(t,m_sectionCount); @@ -1860,7 +1890,7 @@ void HtmlGenerator::endDirDepGraph(const DotDirDeps &g) m_sectionCount++; } -void HtmlGenerator::writeGraphicalHierarchy(const DotGfxHierarchyTable &g) +void HtmlGenerator::writeGraphicalHierarchy(DotGfxHierarchyTable &g) { g.writeGraph(t,dir,fileName); } @@ -1984,7 +2014,7 @@ void HtmlGenerator::endParamList() t << "</dl>"; } -void HtmlGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *) +void HtmlGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *) { HtmlDocVisitor *visitor = new HtmlDocVisitor(t,m_codeGen,ctx); n->accept(visitor); @@ -2431,7 +2461,7 @@ void HtmlGenerator::writeSearchPage() t << substituteHtmlKeywords(g_header,"Search",""); t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " - << versionString << " -->" << endl; + << getVersion() << " -->" << endl; t << "<script type=\"text/javascript\">\n"; t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"; t << "var searchBox = new SearchBox(\"searchBox\", \"" @@ -2485,7 +2515,7 @@ void HtmlGenerator::writeExternalSearchPage() t << substituteHtmlKeywords(g_header,"Search",""); t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " - << versionString << " -->" << endl; + << getVersion() << " -->" << endl; t << "<script type=\"text/javascript\">\n"; t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"; t << "var searchBox = new SearchBox(\"searchBox\", \"" @@ -2624,6 +2654,19 @@ void HtmlGenerator::endConstraintList() t << "</div>" << endl; } +void HtmlGenerator::startCodeFragment() +{ + t << PREFRAG_START; +} + +void HtmlGenerator::endCodeFragment() +{ + //endCodeLine checks is there is still an open code line, if so closes it. + endCodeLine(); + + t << PREFRAG_END; +} + void HtmlGenerator::lineBreak(const char *style) { if (style) @@ -2809,7 +2852,7 @@ void HtmlGenerator::endMemberDeclaration(const char *anchor,const char *inheritI t << "\"><td class=\"memSeparator\" colspan=\"2\"> </td></tr>\n"; } -void HtmlGenerator::setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile) +void HtmlGenerator::setCurrentDoc(const Definition *context,const char *anchor,bool isSourceFile) { if (Doxygen::searchIndex) { diff --git a/src/htmlgen.h b/src/htmlgen.h index 221269f..2db5b74 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -52,7 +52,7 @@ class HtmlCodeGenerator : public CodeOutputInterface void startFontClass(const char *s); void endFontClass(); void writeCodeAnchor(const char *anchor); - void setCurrentDoc(Definition *,const char *,bool) {} + void setCurrentDoc(const Definition *,const char *,bool) {} void addWord(const char *,bool) {} private: @@ -119,9 +119,9 @@ class HtmlGenerator : public OutputGenerator { m_codeGen.writeCodeAnchor(anchor); } // --------------------------- - void setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile); + void setCurrentDoc(const Definition *context,const char *anchor,bool isSourceFile); void addWord(const char *word,bool hiPriority); - void writeDoc(DocNode *,Definition *,MemberDef *); + void writeDoc(DocNode *,const Definition *,const MemberDef *); void startFile(const char *name,const char *manName,const char *title); void writeFooter(const char *navPath); @@ -212,8 +212,8 @@ class HtmlGenerator : public OutputGenerator void writeRuler() { t << "<hr/>"; } void writeAnchor(const char *,const char *name) { t << "<a name=\"" << name <<"\" id=\"" << name << "\"></a>"; } - void startCodeFragment() { t << PREFRAG_START; } - void endCodeFragment() { t << PREFRAG_END; } + void startCodeFragment(); + void endCodeFragment(); void startEmphasis() { t << "<em>"; } void endEmphasis() { t << "</em>"; } void startBold() { t << "<b>"; } @@ -283,16 +283,16 @@ class HtmlGenerator : public OutputGenerator void endDescTableData(); void startDotGraph(); - void endDotGraph(const DotClassGraph &g); + void endDotGraph(DotClassGraph &g); void startInclDepGraph(); - void endInclDepGraph(const DotInclDepGraph &g); + void endInclDepGraph(DotInclDepGraph &g); void startGroupCollaboration(); - void endGroupCollaboration(const DotGroupCollaboration &g); + void endGroupCollaboration(DotGroupCollaboration &g); void startCallGraph(); - void endCallGraph(const DotCallGraph &g); + void endCallGraph(DotCallGraph &g); void startDirDepGraph(); - void endDirDepGraph(const DotDirDeps &g); - void writeGraphicalHierarchy(const DotGfxHierarchyTable &g); + void endDirDepGraph(DotDirDeps &g); + void writeGraphicalHierarchy(DotGfxHierarchyTable &g); void startTextBlock(bool) { t << "<div class=\"textblock\">"; } diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp index 3ed3d64..20cb6ca 100644 --- a/src/htmlhelp.cpp +++ b/src/htmlhelp.cpp @@ -632,7 +632,7 @@ void HtmlHelp::addContentsItem(bool isDir, const char *anchor, bool /* separateIndex */, bool /* addToNavIndex */, - Definition * /* def */) + const Definition * /* def */) { // If we're using a binary toc then folders cannot have links. // Tried this and I didn't see any problems, when not using @@ -677,7 +677,7 @@ void HtmlHelp::addContentsItem(bool isDir, } -void HtmlHelp::addIndexItem(Definition *context,MemberDef *md, +void HtmlHelp::addIndexItem(const Definition *context,const MemberDef *md, const char *sectionAnchor,const char *word) { if (md) diff --git a/src/htmlhelp.h b/src/htmlhelp.h index 9c3fa04..184b929 100644 --- a/src/htmlhelp.h +++ b/src/htmlhelp.h @@ -78,8 +78,8 @@ class HtmlHelp : public IndexIntf const char *anchor, bool separateIndex, bool addToNavIndex, - Definition *def); - void addIndexItem(Definition *context,MemberDef *md, + const Definition *def); + void addIndexItem(const Definition *context,const MemberDef *md, const char *sectionAnchor, const char *title); void addIndexFile(const char *name); void addImageFile(const char *); diff --git a/src/index.cpp b/src/index.cpp index 7bb9574..0631ee4 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -40,6 +40,7 @@ #include "htmlhelp.h" #include "ftvhelp.h" #include "dot.h" +#include "dotgfxhierarchytable.h" #include "pagedef.h" #include "dirdef.h" #include "vhdldocgen.h" @@ -48,6 +49,7 @@ #include "classlist.h" #include "namespacedef.h" #include "filename.h" +#include "tooltip.h" #define MAX_ITEMS_BEFORE_MULTIPAGE_INDEX 200 #define MAX_ITEMS_BEFORE_QUICK_INDEX 30 @@ -145,7 +147,7 @@ static void endIndexHierarchy(OutputList &ol,int level) class MemberIndexList : public QList<MemberDef> { public: - typedef MemberDef ElementType; + typedef const MemberDef ElementType; MemberIndexList(uint letter) : QList<MemberDef>(), m_letter(letter) {} ~MemberIndexList() {} int compareValues(const MemberDef *md1, const MemberDef *md2) const @@ -251,7 +253,7 @@ QCString fixSpaces(const QCString &s) return substitute(s," "," "); } -void startTitle(OutputList &ol,const char *fileName,Definition *def) +void startTitle(OutputList &ol,const char *fileName,const Definition *def) { ol.startHeaderSection(); if (def) def->writeSummaryLinks(ol); @@ -284,7 +286,6 @@ void startFile(OutputList &ol,const char *name,const char *manName, } ol.writeSplitBar(altSidebarName ? altSidebarName : name); ol.writeSearchInfo(); - resetDotNodeNumbering(); } void endFile(OutputList &ol,bool skipNavIndex,bool skipEndContents, @@ -301,12 +302,14 @@ void endFile(OutputList &ol,bool skipNavIndex,bool skipEndContents, ol.writeString("</div><!-- doc-content -->\n"); } } + ol.writeFooter(navPath); // write the footer ol.popGeneratorState(); ol.endFile(); + TooltipManager::instance()->clearTooltips(); // Only clear after the last is written } -void endFileWithNavPath(Definition *d,OutputList &ol) +void endFileWithNavPath(const Definition *d,OutputList &ol) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); QCString navPath; @@ -362,7 +365,7 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, MemberDef *md; for (mi.toFirst();(md=mi.current());++mi) { - MemberList *enumList = md->enumFieldList(); + const MemberList *enumList = md->enumFieldList(); bool isDir = enumList!=0 && md->isEnumerate(); bool isAnonymous = md->name().find('@')!=-1; static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); @@ -487,7 +490,7 @@ static void writeClassTree(OutputList &ol,const BaseClassList *bcl,bool hideSupe } ol.startIndexListItem(); //printf("Passed...\n"); - bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd); + bool hasChildren = !cd->isVisited() && !hideSuper && classHasVisibleChildren(cd); //printf("tree4: Has children %s: %d\n",cd->name().data(),hasChildren); if (cd->isLinkable()) { @@ -534,8 +537,8 @@ static void writeClassTree(OutputList &ol,const BaseClassList *bcl,bool hideSupe if (hasChildren) { //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited); - bool wasVisited=cd->visited; - cd->visited=TRUE; + bool wasVisited=cd->isVisited(); + cd->setVisited(TRUE); if (cd->getLanguage()==SrcLangExt_VHDL) { writeClassTree(ol,cd->baseClasses(),wasVisited,level+1,ftv,addToIndex); @@ -617,7 +620,7 @@ static void writeDirTreeNode(OutputList &ol, DirDef *dd, int level, FTVHelp* ftv (tocExpand && // or toc expand and dd->getFiles() && dd->getFiles()->count()>0 // there are files ); - //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count()); + //printf("gd='%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count()); if (addToIndex) { Doxygen::indexList->addContentsItem(isDir,dd->shortName(),dd->getReference(),dd->getOutputFileBase(),0,TRUE,TRUE); @@ -869,7 +872,7 @@ static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FT started=TRUE; } ol.startIndexListItem(); - bool hasChildren = !cd->visited && classHasVisibleChildren(cd); + bool hasChildren = !cd->isVisited() && classHasVisibleChildren(cd); //printf("list: Has children %s: %d\n",cd->name().data(),hasChildren); if (cd->isLinkable()) { @@ -910,13 +913,13 @@ static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FT } if (cd->getLanguage()==SrcLangExt_VHDL && hasChildren) { - writeClassTree(ol,cd->baseClasses(),cd->visited,1,ftv,addToIndex); - cd->visited=TRUE; + writeClassTree(ol,cd->baseClasses(),cd->isVisited(),1,ftv,addToIndex); + cd->setVisited(TRUE); } else if (hasChildren) { - writeClassTree(ol,cd->subClasses(),cd->visited,1,ftv,addToIndex); - cd->visited=TRUE; + writeClassTree(ol,cd->subClasses(),cd->isVisited(),1,ftv,addToIndex); + cd->setVisited(TRUE); } ol.endIndexListItem(); } @@ -1646,14 +1649,14 @@ void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalO } } -static void writeNamespaceTree(NamespaceSDict *nsDict,FTVHelp *ftv, +static void writeNamespaceTree(const NamespaceSDict *nsDict,FTVHelp *ftv, bool rootOnly,bool showClasses,bool addToIndex,ClassDef::CompoundType ct) { static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE); if (nsDict) { NamespaceSDict::Iterator nli(*nsDict); - NamespaceDef *nd; + const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { if (nd->localName().find('@')==-1 && @@ -1982,7 +1985,7 @@ static QCString letterToLabel(uint startLetter) class PrefixIgnoreClassList : public ClassList { public: - typedef ClassDef ElementType; + typedef const ClassDef ElementType; PrefixIgnoreClassList(uint letter) : m_letter(letter) {} uint letter() const { return m_letter; } private: @@ -2068,7 +2071,7 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct // first count the number of headers ClassSDict::Iterator cli(*Doxygen::classSDict); - ClassDef *cd; + const ClassDef *cd; uint startLetter=0; int headerItems=0; for (;(cd=cli.current());++cli) @@ -2219,6 +2222,7 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct // the last column may contain less items then the others //int colsInRow = (i<rows-1) ? columns : itemsInLastRow; //printf("row [%d]\n",i); + bool cellCont = false; for (j=0;j<columns;j++) // foreach table column { if (colIterators[j]) @@ -2230,6 +2234,7 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct { if (cell->letter()!=0) { + cellCont = true; QCString s = letterToLabel(cell->letter()); ol.writeString("<td rowspan=\"2\" valign=\"bottom\">"); ol.writeString("<a name=\"letter_"); @@ -2246,6 +2251,7 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct } else if (cell->classDef()!=(ClassDef*)0x8) { + cellCont = true; cd = cell->classDef(); ol.writeString("<td valign=\"top\">"); QCString namesp,cname; @@ -2284,20 +2290,21 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct } ol.writeNonBreakableSpace(3); } - else + ++(*colIterators[j]); + if (cell->letter()!=0 || cell->classDef()!=(ClassDef*)0x8) { - ol.writeString("<td>"); + ol.writeString("</td>\n"); } - ++(*colIterators[j]); - ol.writeString("</td>"); } } else { + cellCont = true; ol.writeString("<td></td>"); } } } + if (!cellCont) ol.writeString("<td></td>"); // we need at least one cell in case of xhtml ol.writeString("</tr>\n"); } ol.writeString("</table>\n"); @@ -2741,7 +2748,7 @@ static void writeAnnotatedExceptionIndex(OutputList &ol) static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *separator, QCString &prevClassName) { - ClassDef *cd=md->getClassDef(); + const ClassDef *cd=md->getClassDef(); if ( cd && prevClassName!=cd->displayName()) { ol.docify(separator); @@ -2755,7 +2762,7 @@ static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *sep static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *separator, QCString &prevFileName) { - FileDef *fd=md->getFileDef(); + const FileDef *fd=md->getFileDef(); if (fd && prevFileName!=fd->name()) { ol.docify(separator); @@ -2769,7 +2776,7 @@ static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *sepa static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char *separator, QCString &prevNamespaceName) { - NamespaceDef *nd=md->getNamespaceDef(); + const NamespaceDef *nd=md->getNamespaceDef(); if (nd && prevNamespaceName!=nd->displayName()) { ol.docify(separator); @@ -2891,9 +2898,7 @@ void initClassMemberIndices() void addClassMemberNameToIndex(MemberDef *md) { static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS); - ClassDef *cd=0; - - + const ClassDef *cd=0; if (md->isLinkableInProject() && (cd=md->getClassDef()) && @@ -2975,7 +2980,7 @@ void initNamespaceMemberIndices() void addNamespaceMemberNameToIndex(MemberDef *md) { - NamespaceDef *nd=md->getNamespaceDef(); + const NamespaceDef *nd=md->getNamespaceDef(); if (nd && nd->isLinkableInProject() && md->isLinkableInProject()) { QCString n = md->name(); @@ -3042,7 +3047,7 @@ void initFileMemberIndices() void addFileMemberNameToIndex(MemberDef *md) { - FileDef *fd=md->getFileDef(); + const FileDef *fd=md->getFileDef(); if (fd && fd->isLinkableInProject() && md->isLinkableInProject()) { QCString n = md->name(); @@ -3882,7 +3887,7 @@ static int countGroups() { if (!gd->isReference()) { - gd->visited=FALSE; + //gd->visited=FALSE; count++; } } @@ -3900,7 +3905,6 @@ static int countDirs() { if (dd->isLinkableInProject()) { - dd->visited=FALSE; count++; } } @@ -3940,8 +3944,9 @@ void writeGraphInfo(OutputList &ol) legendDocs = legendDocs.left(s+8) + "[!-- SVG 0 --]\n" + legendDocs.mid(e); //printf("legendDocs=%s\n",legendDocs.data()); } - FileDef fd("","graph_legend"); - ol.generateDoc("graph_legend",1,&fd,0,legendDocs,FALSE,FALSE); + FileDef *fd = createFileDef("","graph_legend"); + ol.generateDoc("graph_legend",1,fd,0,legendDocs,FALSE,FALSE); + delete fd; // restore config settings stripCommentsStateRef = oldStripCommentsState; @@ -4001,7 +4006,7 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* } bool isDir = hasSubGroups || hasSubPages || numSubItems>0; - //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count()); + //printf("gd='%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count()); if (addToIndex) { Doxygen::indexList->addContentsItem(isDir,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0,isDir,TRUE); @@ -4045,7 +4050,7 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* MemberDef *md; for (mi.toFirst();(md=mi.current());++mi) { - MemberList *enumList = md->enumFieldList(); + const MemberList *enumList = md->enumFieldList(); bool isDir = enumList!=0 && md->isEnumerate(); if (md->isVisible() && md->name().find('@')==-1) { @@ -4670,7 +4675,7 @@ static void writeIndex(OutputList &ol) ol.parseText(/*projPrefix+*/ theTranslator->trModuleIndex()); ol.endIndexSection(isModuleIndex); } - if (documentedNamespaces>0) + if (Config_getBool(SHOW_NAMESPACES) && (documentedNamespaces>0)) { ol.startIndexSection(isNamespaceIndex); ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModulesIndex():theTranslator->trNamespaceIndex())); @@ -4726,7 +4731,7 @@ static void writeIndex(OutputList &ol) ol.parseText(/*projPrefix+*/theTranslator->trExceptionIndex()); ol.endIndexSection(isCompoundIndex); } - if (documentedFiles>0) + if (Config_getBool(SHOW_FILES) && (documentedFiles>0)) { ol.startIndexSection(isFileIndex); ol.parseText(/*projPrefix+*/theTranslator->trFileIndex()); @@ -5275,22 +5280,7 @@ static void writeMenuData() if (f.open(IO_WriteOnly)) { FTextStream t(&f); - t << "/*\n@ @licstart The following is the entire license notice for the\n" - "JavaScript code in this file.\n\nCopyright (C) 1997-2017 by Dimitri van Heesch\n\n" - "This program is free software; you can redistribute it and/or modify\n" - "it under the terms of the GNU General Public License as published by\n" - "the Free Software Foundation; either version 2 of the License, or\n" - "(at your option) any later version.\n\n" - "This program is distributed in the hope that it will be useful,\n" - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - " GNU General Public License for more details.\n\n" - "You should have received a copy of the GNU General Public License along\n" - "with this program; if not, write to the Free Software Foundation, Inc.,\n" - "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\n" - "@licend The above is the entire license notice\n" - "for the JavaScript code in this file\n" - "*/\n"; + t << JAVASCRIPT_LICENSE_TEXT; t << "var menudata={"; bool hasChildren = renderQuickLinksAsJs(t,root,TRUE); if (hasChildren) t << "]"; diff --git a/src/index.h b/src/index.h index f3e0241..c6baba5 100644 --- a/src/index.h +++ b/src/index.h @@ -37,8 +37,8 @@ class IndexIntf virtual void decContentsDepth() = 0; virtual void addContentsItem(bool isDir, const char *name, const char *ref, const char *file, const char *anchor, bool separateIndex, - bool addToNavIndex,Definition *def) = 0; - virtual void addIndexItem(Definition *context,MemberDef *md, + bool addToNavIndex,const Definition *def) = 0; + virtual void addIndexItem(const Definition *context,const MemberDef *md, const char *sectionAnchor,const char *title) = 0; virtual void addIndexFile(const char *name) = 0; virtual void addImageFile(const char *name) = 0; @@ -136,11 +136,11 @@ class IndexList : public IndexIntf { if (m_enabled) foreach(&IndexIntf::decContentsDepth); } void addContentsItem(bool isDir, const char *name, const char *ref, const char *file, const char *anchor,bool separateIndex=FALSE,bool addToNavIndex=FALSE, - Definition *def=0) - { if (m_enabled) foreach<bool,const char *,const char *,const char *,const char*,bool,bool,Definition *> + const Definition *def=0) + { if (m_enabled) foreach<bool,const char *,const char *,const char *,const char*,bool,bool,const Definition *> (&IndexIntf::addContentsItem,isDir,name,ref,file,anchor,separateIndex,addToNavIndex,def); } - void addIndexItem(Definition *context,MemberDef *md,const char *sectionAnchor=0,const char *title=0) - { if (m_enabled) foreach<Definition *,MemberDef *,const char *,const char *> + void addIndexItem(const Definition *context,const MemberDef *md,const char *sectionAnchor=0,const char *title=0) + { if (m_enabled) foreach<const Definition *,const MemberDef *,const char *,const char *> (&IndexIntf::addIndexItem,context,md,sectionAnchor,title); } void addIndexFile(const char *name) { if (m_enabled) foreach<const char *>(&IndexIntf::addIndexFile,name); } @@ -289,14 +289,14 @@ extern int documentedDirs; extern int documentedHtmlFiles; extern int documentedPages; -void startTitle(OutputList &ol,const char *fileName,Definition *def=0); +void startTitle(OutputList &ol,const char *fileName,const Definition *def=0); void endTitle(OutputList &ol,const char *fileName,const char *name); void startFile(OutputList &ol,const char *name,const char *manName, const char *title,HighlightedItem hli=HLI_None, bool additionalIndices=FALSE,const char *altSidebarName=0); void endFile(OutputList &ol,bool skipNavIndex=FALSE,bool skipEndContents=FALSE, const QCString &navPath=QCString()); -void endFileWithNavPath(Definition *d,OutputList &ol); +void endFileWithNavPath(const Definition *d,OutputList &ol); void initClassMemberIndices(); void initFileMemberIndices(); diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 5be3fc9..a0bbf73 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -38,7 +38,7 @@ const int maxLevels=5; static const char *secLabels[maxLevels] = - { "section","subsection","subsubsection","paragraph","subparagraph" }; + { "doxysection","doxysubsection","doxysubsubsection","doxyparagraph","doxysubparagraph" }; static const char *getSectionName(int level) { @@ -280,7 +280,7 @@ void LatexDocVisitor::visit(DocLineBreak *) void LatexDocVisitor::visit(DocHorRuler *) { if (m_hide) return; - m_t << "\n\n"; + m_t << "\\DoxyHorRuler\n"; } void LatexDocVisitor::visit(DocStyleChange *s) @@ -292,9 +292,11 @@ void LatexDocVisitor::visit(DocStyleChange *s) if (s->enable()) m_t << "{\\bfseries{"; else m_t << "}}"; break; case DocStyleChange::Strike: + case DocStyleChange::Del: if (s->enable()) m_t << "\\sout{"; else m_t << "}"; break; case DocStyleChange::Underline: + case DocStyleChange::Ins: if (s->enable()) m_t << "\\uline{"; else m_t << "}"; break; case DocStyleChange::Italic: @@ -428,7 +430,7 @@ void LatexDocVisitor::visit(DocVerbatim *s) case DocVerbatim::PlantUML: { QCString latexOutput = Config_getString(LATEX_OUTPUT); - QCString baseName = writePlantUMLSource(latexOutput,s->exampleFile(),s->text()); + QCString baseName = PlantumlManager::instance()->writePlantUMLSource(latexOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_EPS); writePlantUMLFile(baseName, s); } @@ -458,20 +460,21 @@ void LatexDocVisitor::visit(DocInclude *inc) m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; LatexCodeGenerator::setDoxyCodeOpen(TRUE); QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), inc->exampleFile(), - &fd, // fileDef, + fd, // fileDef, -1, // start line -1, // end line FALSE, // inline fragment 0, // memberDef TRUE // show line numbers ); + delete fd; LatexCodeGenerator::setDoxyCodeOpen(FALSE); m_t << "\\end{DoxyCodeInclude}" << endl; } @@ -493,9 +496,9 @@ void LatexDocVisitor::visit(DocInclude *inc) LatexCodeGenerator::setDoxyCodeOpen(FALSE); m_t << "\\end{DoxyCodeInclude}\n"; break; - case DocInclude::DontInclude: - break; - case DocInclude::HtmlInclude: + case DocInclude::DontInclude: + case DocInclude::DontIncWithLines: + case DocInclude::HtmlInclude: break; case DocInclude::LatexInclude: m_t << inc->text(); @@ -524,7 +527,7 @@ void LatexDocVisitor::visit(DocInclude *inc) case DocInclude::SnipWithLines: { QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; LatexCodeGenerator::setDoxyCodeOpen(TRUE); Doxygen::parserManager->getParser(inc->extension()) @@ -534,13 +537,14 @@ void LatexDocVisitor::visit(DocInclude *inc) langExt, inc->isExample(), inc->exampleFile(), - &fd, + fd, lineBlock(inc->text(),inc->blockId()), -1, // endLine FALSE, // inlineFragment 0, // memberDef TRUE // show line number ); + delete fd; LatexCodeGenerator::setDoxyCodeOpen(FALSE); m_t << "\\end{DoxyCodeInclude}" << endl; } @@ -555,7 +559,7 @@ void LatexDocVisitor::visit(DocInclude *inc) void LatexDocVisitor::visit(DocIncOperator *op) { - //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n", + //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", // op->type(),op->isFirst(),op->isLast(),op->text().data()); if (op->isFirst()) { @@ -564,15 +568,32 @@ void LatexDocVisitor::visit(DocIncOperator *op) pushEnabled(); m_hide = TRUE; } - SrcLangExt langExt = getLanguageFromFileName(m_langExt); + QCString locLangExt = getFileNameExtension(op->includeFileName()); + if (locLangExt.isEmpty()) locLangExt = m_langExt; + SrcLangExt langExt = getLanguageFromFileName(locLangExt); if (op->type()!=DocIncOperator::Skip) { popEnabled(); if (!m_hide) { - Doxygen::parserManager->getParser(m_langExt) + FileDef *fd = 0; + if (!op->includeFileName().isEmpty()) + { + QFileInfo cfi( op->includeFileName() ); + fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + } + + Doxygen::parserManager->getParser(locLangExt) ->parseCode(m_ci,op->context(),op->text(),langExt, - op->isExample(),op->exampleFile()); + op->isExample(),op->exampleFile(), + fd, // fileDef + op->line(), // startLine + -1, // endLine + FALSE, // inline fragment + 0, // memberDef + op->showLineNo() // show line numbers + ); + if (fd) delete fd; } pushEnabled(); m_hide=TRUE; @@ -1567,10 +1588,8 @@ void LatexDocVisitor::visitPre(DocParamList *pl) { QListIterator<DocNode> li(pl->paramTypes()); DocNode *type; - bool first=TRUE; for (li.toFirst();(type=li.current());++li) { - if (!first) m_t << " | "; else first=FALSE; if (type->kind()==DocNode::Kind_Word) { visit((DocWord*)type); @@ -1579,6 +1598,10 @@ void LatexDocVisitor::visitPre(DocParamList *pl) { visit((DocLinkedWord*)type); } + else if (type->kind()==DocNode::Kind_Sep) + { + m_t << " " << ((DocSeparator *)type)->chars() << " "; + } } if (useTable) m_t << " & "; } @@ -1679,14 +1702,6 @@ void LatexDocVisitor::visitPost(DocInternalRef *ref) endLink(0,ref->file(),ref->anchor()); } -void LatexDocVisitor::visitPre(DocCopy *) -{ -} - -void LatexDocVisitor::visitPost(DocCopy *) -{ -} - void LatexDocVisitor::visitPre(DocText *) { } @@ -1927,7 +1942,7 @@ void LatexDocVisitor::writePlantUMLFile(const QCString &baseName, DocVerbatim *s shortName=shortName.right(shortName.length()-i-1); } QCString outDir = Config_getString(LATEX_OUTPUT); - generatePlantUMLOutput(baseName,outDir,PUML_EPS); + PlantumlManager::instance()->generatePlantUMLOutput(baseName,outDir,PlantumlManager::PUML_EPS); visitPreStart(m_t, s->hasCaption(), shortName, s->width(), s->height()); visitCaption(this, s->children()); visitPostEnd(m_t, s->hasCaption()); diff --git a/src/latexdocvisitor.h b/src/latexdocvisitor.h index 7ea8ae1..71fb5be 100644 --- a/src/latexdocvisitor.h +++ b/src/latexdocvisitor.h @@ -128,8 +128,6 @@ class LatexDocVisitor : public DocVisitor void visitPost(DocXRefItem *); void visitPre(DocInternalRef *); void visitPost(DocInternalRef *); - void visitPre(DocCopy *); - void visitPost(DocCopy *); void visitPre(DocText *); void visitPost(DocText *); void visitPre(DocHtmlBlockQuote *); diff --git a/src/latexgen.cpp b/src/latexgen.cpp index b860195..e6c6861 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -27,6 +27,11 @@ #include "language.h" #include "version.h" #include "dot.h" +#include "dotcallgraph.h" +#include "dotclassgraph.h" +#include "dotdirdeps.h" +#include "dotgroupcollaboration.h" +#include "dotincldepgraph.h" #include "pagedef.h" #include "docparser.h" #include "latexdocvisitor.h" @@ -480,7 +485,7 @@ static void writeDefaultHeaderPart1(FTextStream &t) if (Config_getBool(LATEX_BATCHMODE)) t << "\\batchmode\n"; - // to overcome problems wit too many open files + // to overcome problems with too many open files t << "\\let\\mypdfximage\\pdfximage" "\\def\\pdfximage{\\immediate\\mypdfximage}"; @@ -492,6 +497,14 @@ static void writeDefaultHeaderPart1(FTextStream &t) documentClass = "book"; t << "\\documentclass[twoside]{" << documentClass << "}\n" "\n"; + t << "%% moved from doxygen.sty due to workaround for LaTex 2019 version and unmaintained tabu package\n" + "\\usepackage{ifthen}\n" + "\\ifx\\requestedLaTeXdate\\undefined\n" + "\\usepackage{array}\n" + "\\else\n" + "\\usepackage{array}[=2016-10-06]\n" + "\\fi\n" + "%%\n"; // Load required packages t << "% Packages required by doxygen\n" @@ -763,7 +776,7 @@ static void writeDefaultHeaderPart3(FTextStream &t) { // part 3 // Finalize project number - t << " Doxygen " << versionString << "}\\\\\n"; + t << " Doxygen " << getVersion() << "}\\\\\n"; if (Config_getBool(LATEX_TIMESTAMP)) t << "\\vspace*{0.5cm}\n" "{\\small " << dateToString(TRUE) << "}\\\\\n"; @@ -832,7 +845,7 @@ static void writeDefaultFooter(FTextStream &t) void LatexGenerator::writeHeaderFile(QFile &f) { FTextStream t(&f); - t << "% Latex header for doxygen " << versionString << endl; + t << "% Latex header for doxygen " << getVersion() << endl; writeDefaultHeaderPart1(t); t << "Your title here"; writeDefaultHeaderPart2(t); @@ -843,14 +856,14 @@ void LatexGenerator::writeHeaderFile(QFile &f) void LatexGenerator::writeFooterFile(QFile &f) { FTextStream t(&f); - t << "% Latex footer for doxygen " << versionString << endl; + t << "% Latex footer for doxygen " << getVersion() << endl; writeDefaultFooter(t); } void LatexGenerator::writeStyleSheetFile(QFile &f) { FTextStream t(&f); - t << "% stylesheet for doxygen " << versionString << endl; + t << "% stylesheet for doxygen " << getVersion() << endl; writeDefaultStyleSheet(t); } @@ -913,39 +926,39 @@ void LatexGenerator::startIndexSection(IndexSections is) } break; case isMainPage: - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Introduction}\n" break; //case isPackageIndex: - // if (compactLatex) t << "\\section"; else t << "\\chapter"; + // if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; // t << "{"; //Package Index}\n" // break; case isModuleIndex: - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Module Index}\n" break; case isDirIndex: - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Directory Index}\n" break; case isNamespaceIndex: - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Namespace Index}\" break; case isClassHierarchyIndex: - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Hierarchical Index}\n" break; case isCompoundIndex: - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Annotated Compound Index}\n" break; case isFileIndex: - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Annotated File Index}\n" break; case isPageIndex: - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Annotated Page Index}\n" break; case isModuleDocumentation: @@ -957,7 +970,7 @@ void LatexGenerator::startIndexSection(IndexSections is) { if (!gd->isReference()) { - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Module Documentation}\n"; found=TRUE; } @@ -973,7 +986,7 @@ void LatexGenerator::startIndexSection(IndexSections is) { if (dd->isLinkableInProject()) { - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Module Documentation}\n"; found=TRUE; } @@ -989,7 +1002,7 @@ void LatexGenerator::startIndexSection(IndexSections is) { if (nd->isLinkableInProject()) { - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; // Namespace Documentation}\n": found=TRUE; } @@ -1008,7 +1021,7 @@ void LatexGenerator::startIndexSection(IndexSections is) !cd->isEmbeddedInOuterScope() ) { - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Compound Documentation}\n"; found=TRUE; } @@ -1030,7 +1043,7 @@ void LatexGenerator::startIndexSection(IndexSections is) { if (isFirst) { - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //File Documentation}\n"; isFirst=FALSE; break; @@ -1042,13 +1055,13 @@ void LatexGenerator::startIndexSection(IndexSections is) break; case isExampleDocumentation: { - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Example Documentation}\n"; } break; case isPageDocumentation: { - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{"; //Page Documentation}\n"; } break; @@ -1275,7 +1288,7 @@ void LatexGenerator::endIndexSection(IndexSections is) { if (!pd->getGroupDef() && !pd->isReference()) { - if (compactLatex) t << "\\section"; else t << "\\chapter"; + if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; t << "{" << pd->title(); t << "}\n"; @@ -1324,6 +1337,15 @@ void LatexGenerator::writeStyleInfo(int part) startPlainFile("doxygen.sty"); writeDefaultStyleSheet(t); endPlainFile(); + + // workaround for the problem caused by change in LaTeX in version 2019 + // in the unmaintained tabu package + startPlainFile("tabu_doxygen.sty"); + t << ResourceMgr::instance().getAsString("tabu_doxygen.sty"); + endPlainFile(); + startPlainFile("longtable_doxygen.sty"); + t << ResourceMgr::instance().getAsString("longtable_doxygen.sty"); + endPlainFile(); } void LatexGenerator::newParagraph() @@ -1376,7 +1398,7 @@ void LatexGenerator::startHtmlLink(const char *url) if (Config_getBool(PDF_HYPERLINKS)) { t << "\\href{"; - t << url; + t << latexFilterURL(url); t << "}"; } t << "{\\texttt{ "; @@ -1515,11 +1537,11 @@ void LatexGenerator::startTitleHead(const char *fileName) } if (Config_getBool(COMPACT_LATEX)) { - t << "\\subsection{"; + t << "\\doxysubsection{"; } else { - t << "\\section{"; + t << "\\doxysection{"; } } @@ -1540,11 +1562,11 @@ void LatexGenerator::startTitle() { if (Config_getBool(COMPACT_LATEX)) { - t << "\\subsection{"; + t << "\\doxysubsection{"; } else { - t << "\\section{"; + t << "\\doxysection{"; } } @@ -1557,19 +1579,19 @@ void LatexGenerator::startGroupHeader(int extraIndentLevel) if (extraIndentLevel==3) { - t << "\\subparagraph*{"; + t << "\\doxysubparagraph*{"; } else if (extraIndentLevel==2) { - t << "\\paragraph{"; + t << "\\doxyparagraph{"; } else if (extraIndentLevel==1) { - t << "\\subsubsection{"; + t << "\\doxysubsubsection{"; } else // extraIndentLevel==0 { - t << "\\subsection{"; + t << "\\doxysubsection{"; } disableLinks=TRUE; } @@ -1584,11 +1606,11 @@ void LatexGenerator::startMemberHeader(const char *,int) { if (Config_getBool(COMPACT_LATEX)) { - t << "\\subsubsection*{"; + t << "\\doxysubsubsection*{"; } else { - t << "\\subsection*{"; + t << "\\doxysubsection*{"; } disableLinks=TRUE; } @@ -1637,7 +1659,7 @@ void LatexGenerator::startMemberDoc(const char *clname, } t << "}" << endl; } - static const char *levelLab[] = { "subsubsection","paragraph","subparagraph", "subparagraph" }; + static const char *levelLab[] = { "doxysubsubsection","doxyparagraph","doxysubparagraph", "doxysubparagraph" }; static bool compactLatex = Config_getBool(COMPACT_LATEX); static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); int level=0; @@ -1755,11 +1777,11 @@ void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::Sect { switch(type) { - case SectionInfo::Page: t << "subsection"; break; - case SectionInfo::Section: t << "subsubsection"; break; - case SectionInfo::Subsection: t << "paragraph"; break; - case SectionInfo::Subsubsection: t << "subparagraph"; break; - case SectionInfo::Paragraph: t << "subparagraph"; break; + case SectionInfo::Page: t << "doxysubsection"; break; + case SectionInfo::Section: t << "doxysubsubsection"; break; + case SectionInfo::Subsection: t << "doxyparagraph"; break; + case SectionInfo::Subsubsection: t << "doxysubparagraph"; break; + case SectionInfo::Paragraph: t << "doxysubparagraph"; break; default: ASSERT(0); break; } t << "{"; @@ -1768,11 +1790,11 @@ void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::Sect { switch(type) { - case SectionInfo::Page: t << "section"; break; - case SectionInfo::Section: t << "subsection"; break; - case SectionInfo::Subsection: t << "subsubsection"; break; - case SectionInfo::Subsubsection: t << "paragraph"; break; - case SectionInfo::Paragraph: t << "subparagraph"; break; + case SectionInfo::Page: t << "doxysection"; break; + case SectionInfo::Section: t << "doxysubsection"; break; + case SectionInfo::Subsection: t << "doxysubsubsection"; break; + case SectionInfo::Subsubsection: t << "doxyparagraph"; break; + case SectionInfo::Paragraph: t << "doxysubparagraph"; break; default: ASSERT(0); break; } t << "{"; @@ -1800,7 +1822,7 @@ void LatexGenerator::writeChar(char c) void LatexGenerator::startClassDiagram() { - //if (Config_getBool(COMPACT_LATEX)) t << "\\subsubsection"; else t << "\\subsection"; + //if (Config_getBool(COMPACT_LATEX)) t << "\\doxysubsubsection"; else t << "\\doxysubsection"; //t << "{"; } @@ -1994,11 +2016,11 @@ void LatexGenerator::startMemberGroupHeader(bool hasHeader) // changed back to rev 756 due to bug 660501 //if (Config_getBool(COMPACT_LATEX)) //{ - // t << "\\subparagraph*{"; + // t << "\\doxysubparagraph*{"; //} //else //{ - // t << "\\paragraph*{"; + // t << "\\doxyparagraph*{"; //} } @@ -2034,7 +2056,7 @@ void LatexGenerator::startDotGraph() newParagraph(); } -void LatexGenerator::endDotGraph(const DotClassGraph &g) +void LatexGenerator::endDotGraph(DotClassGraph &g) { g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),fileName,relPath); } @@ -2043,7 +2065,7 @@ void LatexGenerator::startInclDepGraph() { } -void LatexGenerator::endInclDepGraph(const DotInclDepGraph &g) +void LatexGenerator::endInclDepGraph(DotInclDepGraph &g) { g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),fileName,relPath); } @@ -2052,7 +2074,7 @@ void LatexGenerator::startGroupCollaboration() { } -void LatexGenerator::endGroupCollaboration(const DotGroupCollaboration &g) +void LatexGenerator::endGroupCollaboration(DotGroupCollaboration &g) { g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),fileName,relPath); } @@ -2061,7 +2083,7 @@ void LatexGenerator::startCallGraph() { } -void LatexGenerator::endCallGraph(const DotCallGraph &g) +void LatexGenerator::endCallGraph(DotCallGraph &g) { g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),fileName,relPath); } @@ -2070,7 +2092,7 @@ void LatexGenerator::startDirDepGraph() { } -void LatexGenerator::endDirDepGraph(const DotDirDeps &g) +void LatexGenerator::endDirDepGraph(DotDirDeps &g) { g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),fileName,relPath); } @@ -2175,7 +2197,7 @@ void LatexGenerator::exceptionEntry(const char* prefix,bool closeBracket) t << " "; } -void LatexGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *) +void LatexGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *) { LatexDocVisitor *visitor = new LatexDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString(""),insideTabbing); @@ -2243,11 +2265,11 @@ void LatexGenerator::startInlineHeader() { if (Config_getBool(COMPACT_LATEX)) { - t << "\\paragraph*{"; + t << "\\doxyparagraph*{"; } else { - t << "\\subsubsection*{"; + t << "\\doxysubsubsection*{"; } } diff --git a/src/latexgen.h b/src/latexgen.h index 1460000..6430dbc 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -49,7 +49,7 @@ class LatexCodeGenerator : public CodeOutputInterface void startFontClass(const char *); void endFontClass(); void writeCodeAnchor(const char *) {} - void setCurrentDoc(Definition *,const char *,bool) {} + void setCurrentDoc(const Definition *,const char *,bool) {} void addWord(const char *,bool) {} static void setDoxyCodeOpen(bool val); @@ -116,7 +116,7 @@ class LatexGenerator : public OutputGenerator // --------------------------- - void writeDoc(DocNode *,Definition *ctx,MemberDef *); + void writeDoc(DocNode *,const Definition *ctx,const MemberDef *); void startFile(const char *name,const char *manName,const char *title); void writeSearchInfo() {} @@ -273,16 +273,16 @@ class LatexGenerator : public OutputGenerator void lastIndexPage(); void startDotGraph(); - void endDotGraph(const DotClassGraph &); + void endDotGraph(DotClassGraph &); void startInclDepGraph(); - void endInclDepGraph(const DotInclDepGraph &); + void endInclDepGraph(DotInclDepGraph &); void startCallGraph(); void startGroupCollaboration(); - void endGroupCollaboration(const DotGroupCollaboration &g); - void endCallGraph(const DotCallGraph &); + void endGroupCollaboration(DotGroupCollaboration &g); + void endCallGraph(DotCallGraph &); void startDirDepGraph(); - void endDirDepGraph(const DotDirDeps &g); - void writeGraphicalHierarchy(const DotGfxHierarchyTable &) {} + void endDirDepGraph(DotDirDeps &g); + void writeGraphicalHierarchy(DotGfxHierarchyTable &) {} void startTextBlock(bool) {} void endTextBlock(bool) {} @@ -321,7 +321,7 @@ class LatexGenerator : public OutputGenerator void writeLabel(const char *l,bool isLast); void endLabels(); - void setCurrentDoc(Definition *,const char *,bool) {} + void setCurrentDoc(const Definition *,const char *,bool) {} void addWord(const char *,bool) {} diff --git a/src/layout.cpp b/src/layout.cpp index 393e05d..38a55f4 100644 --- a/src/layout.cpp +++ b/src/layout.cpp @@ -106,7 +106,7 @@ QCString LayoutNavEntry::url() const } else if (url.left(5)=="@ref " || url.left(5)=="\\ref ") { - Definition *d; + const Definition *d = 0; QCString anchor; bool found=FALSE; if (resolveLink(0,url.mid(5).stripWhiteSpace(),TRUE,&d,anchor)) @@ -1395,7 +1395,7 @@ class LayoutParser : public QXmlDefaultHandler } else { - err("Unexpected start tag `%s' found in scope='%s'!\n", + err("Unexpected start tag '%s' found in scope='%s'!\n", name.data(),m_scope.data()); } return TRUE; @@ -1538,10 +1538,11 @@ void LayoutDocManager::clear(LayoutDocManager::LayoutPart p) d->docEntries[(int)p].clear(); } -void LayoutDocManager::parse(QTextStream &t,const char *fileName) +void LayoutDocManager::parse(const char *fileName) { LayoutErrorHandler errorHandler(fileName); - QXmlInputSource source( t ); + QXmlInputSource source; + source.setData(fileToString(fileName)); QXmlSimpleReader reader; reader.setContentHandler( &LayoutParser::instance() ); reader.setErrorHandler( &errorHandler ); @@ -1560,7 +1561,7 @@ void writeDefaultLayoutFile(const char *fileName) return; } QTextStream t(&f); - t << substitute(layout_default,"$doxygenversion",versionString); + t << substitute(layout_default,"$doxygenversion",getVersion()); } //---------------------------------------------------------------------------------- diff --git a/src/layout.h b/src/layout.h index b25aa4e..b1facf5 100644 --- a/src/layout.h +++ b/src/layout.h @@ -201,7 +201,7 @@ class LayoutDocManager LayoutNavEntry *rootNavEntry() const; /** Parses a user provided layout */ - void parse(QTextStream &t,const char *fileName); + void parse(const char *fileName); void init(); private: void addEntry(LayoutPart p,LayoutDocEntry*e); diff --git a/src/lodepng.cpp b/src/lodepng.cpp deleted file mode 100644 index 1906f09..0000000 --- a/src/lodepng.cpp +++ /dev/null @@ -1,2445 +0,0 @@ -/* -LodePNG version 20080927 - -Copyright (c) 2005-2008 Lode Vandevenne - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -/* -The manual and changelog can be found in the header file "lodepng.h" -You are free to name this file lodepng.cpp or lodepng.c depending on your usage. -*/ - -#include "lodepng.h" -#include "portable.h" - -#define USE_BRUTE_FORCE_ENCODING 1 - -#define VERSION_STRING "20080927" - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Tools For C / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/* -About these tools (vector, uivector, ucvector and string): --LodePNG was originally written in C++. The vectors replace the std::vectors that were used in the C++ version. --The string tools are made to avoid problems with compilers that declare things like strncat as deprecated. --They're not used in the interface, only internally in this file, so all their functions are made static. -*/ - -//-------------------------------------------------------------------------------------------- - - -/*LodePNG_chunk functions: These functions need as input a large enough amount of allocated memory.*/ - -static unsigned LodePNG_chunk_length(const unsigned char* chunk); /*get the length of the data of the chunk. Total chunk length has 12 bytes more.*/ - -static void LodePNG_chunk_generate_crc(unsigned char* chunk); /*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/ - -/*add chunks to out buffer. It reallocs the buffer to append the data. returns error code*/ -static unsigned LodePNG_create_chunk(unsigned char** out, size_t* outlength, unsigned length, const char* type, const unsigned char* data); /*appends new chunk to out. Returns pointer to start of appended chunk, or NULL if error happened; may change memory address of out buffer*/ - -static void LodePNG_InfoColor_init(LodePNG_InfoColor* info); -static void LodePNG_InfoColor_cleanup(LodePNG_InfoColor* info); -static unsigned LodePNG_InfoColor_copy(LodePNG_InfoColor* dest, const LodePNG_InfoColor* source); - -/*Use these functions instead of allocating palette manually*/ -static void LodePNG_InfoColor_clearPalette(LodePNG_InfoColor* info); - -/*additional color info*/ -static unsigned LodePNG_InfoColor_getBpp(const LodePNG_InfoColor* info); /*bits per pixel*/ -static unsigned LodePNG_InfoColor_isGreyscaleType(const LodePNG_InfoColor* info); /*is it a greyscale type? (colorType 0 or 4)*/ -static unsigned LodePNG_InfoColor_isAlphaType(const LodePNG_InfoColor* info); /*has it an alpha channel? (colorType 2 or 6)*/ - -static void LodePNG_InfoPng_init(LodePNG_InfoPng* info); -static void LodePNG_InfoPng_cleanup(LodePNG_InfoPng* info); -static unsigned LodePNG_InfoPng_copy(LodePNG_InfoPng* dest, const LodePNG_InfoPng* source); - -static void LodePNG_InfoRaw_init(LodePNG_InfoRaw* info); -static void LodePNG_InfoRaw_cleanup(LodePNG_InfoRaw* info); -static unsigned LodePNG_InfoRaw_copy(LodePNG_InfoRaw* dest, const LodePNG_InfoRaw* source); - -/* -LodePNG_convert: Converts from any color type to 24-bit or 32-bit (later maybe more supported). return value = LodePNG error code -The out buffer must have (w * h * bpp + 7) / 8, where bpp is the bits per pixel of the output color type (LodePNG_InfoColor_getBpp) -*/ -static unsigned LodePNG_convert(unsigned char* out, const unsigned char* in, LodePNG_InfoColor* infoOut, LodePNG_InfoColor* infoIn, unsigned w, unsigned h); - -static void LodeZlib_DeflateSettings_init(LodeZlib_DeflateSettings* settings); - -/* ////////////////////////////////////////////////////////////////////////// */ -/* LodeFlate & LodeZlib */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/*This function reallocates the out buffer and appends the data. -Either, *out must be NULL and *outsize must be 0, or, *out must be a valid buffer and *outsize its size in bytes.*/ -//unsigned LodeZlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DeflateSettings* settings); - -//-------------------------------------------------------------------------------------------- - -typedef struct vector /*this one is used only by the deflate compressor*/ -{ - void* data; - size_t size; /*in groups of bytes depending on type*/ - size_t allocsize; /*in bytes*/ - unsigned typesize; /*sizeof the type you store in data*/ -} vector; - -static unsigned vector_resize(vector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/ -{ - if(size * p->typesize > p->allocsize) - { - size_t newsize = size * p->typesize * 2; - void* data = realloc(p->data, newsize); - if(data) - { - p->allocsize = newsize; - p->data = data; - p->size = size; - } - else return 0; - } - else p->size = size; - return 1; -} - -static unsigned vector_resized(vector* p, size_t size, void dtor(void*)) /*resize and use destructor on elements if it gets smaller*/ -{ - size_t i; - if(size < p->size) for(i = size; i < p->size; i++) dtor(&((char*)(p->data))[i * p->typesize]); - return vector_resize(p, size); -} - -static void vector_cleanup(void* p) -{ - ((vector*)p)->size = ((vector*)p)->allocsize = 0; - free(((vector*)p)->data); - ((vector*)p)->data = NULL; -} - -static void vector_cleanupd(vector* p, void dtor(void*)) /*clear and use destructor on elements*/ -{ - vector_resized(p, 0, dtor); - vector_cleanup(p); -} - -static void vector_init(vector* p, unsigned typesize) -{ - p->data = NULL; - p->size = p->allocsize = 0; - p->typesize = typesize; -} - -static void vector_swap(vector* p, vector* q) /*they're supposed to have the same typesize*/ -{ - size_t tmp; - void* tmpp; - tmp = p->size; p->size = q->size; q->size = tmp; - tmp = p->allocsize; p->allocsize = q->allocsize; q->allocsize = tmp; - tmpp = p->data; p->data = q->data; q->data = tmpp; -} - -static void* vector_get(vector* p, size_t index) -{ - return &((char*)p->data)[index * p->typesize]; -} - -/* /////////////////////////////////////////////////////////////////////////// */ - -typedef struct uivector -{ - unsigned* data; - size_t size; /*size in number of unsigned longs*/ - size_t allocsize; /*allocated size in bytes*/ -} uivector; - -static void uivector_cleanup(void* p) -{ - ((uivector*)p)->size = ((uivector*)p)->allocsize = 0; - free(((uivector*)p)->data); - ((uivector*)p)->data = NULL; -} - -static unsigned uivector_resize(uivector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/ -{ - if(size * sizeof(unsigned) > p->allocsize) - { - size_t newsize = size * sizeof(unsigned) * 2; - void* data = realloc(p->data, newsize); - if(data) - { - p->allocsize = newsize; - p->data = (unsigned*)data; - p->size = size; - } - else return 0; - } - else p->size = size; - return 1; -} - -static unsigned uivector_resizev(uivector* p, size_t size, unsigned value) /*resize and give all new elements the value*/ -{ - size_t oldsize = p->size, i; - if(!uivector_resize(p, size)) return 0; - for(i = oldsize; i < size; i++) p->data[i] = value; - return 1; -} - -static void uivector_init(uivector* p) -{ - p->data = NULL; - p->size = p->allocsize = 0; -} - -static unsigned uivector_push_back(uivector* p, unsigned c) /*returns 1 if success, 0 if failure ==> nothing done*/ -{ - if(!uivector_resize(p, p->size + 1)) return 0; - p->data[p->size - 1] = c; - return 1; -} - -static unsigned uivector_copy(uivector* p, const uivector* q) /*copy q to p, returns 1 if success, 0 if failure ==> nothing done*/ -{ - size_t i; - if(!uivector_resize(p, q->size)) return 0; - for(i = 0; i < q->size; i++) p->data[i] = q->data[i]; - return 1; -} - -static void uivector_swap(uivector* p, uivector* q) -{ - size_t tmp; - unsigned* tmpp; - tmp = p->size; p->size = q->size; q->size = tmp; - tmp = p->allocsize; p->allocsize = q->allocsize; q->allocsize = tmp; - tmpp = p->data; p->data = q->data; q->data = tmpp; -} - -/* /////////////////////////////////////////////////////////////////////////// */ - -typedef struct ucvector -{ - unsigned char* data; - size_t size; /*used size*/ - size_t allocsize; /*allocated size*/ -} ucvector; - -static void ucvector_cleanup(void* p) -{ - ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0; - free(((ucvector*)p)->data); - ((ucvector*)p)->data = NULL; -} - -static unsigned ucvector_resize(ucvector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/ -{ - if(size * sizeof(unsigned) > p->allocsize) - { - size_t newsize = size * sizeof(unsigned) * 2; - void* data = realloc(p->data, newsize); - if(data) - { - p->allocsize = newsize; - p->data = (unsigned char*)data; - p->size = size; - } - else return 0; /*error: not enough memory*/ - } - else p->size = size; - return 1; -} - - -static void ucvector_init(ucvector* p) -{ - p->data = NULL; - p->size = p->allocsize = 0; -} - -/*you can both convert from vector to buffer&size and vica versa*/ -static void ucvector_init_buffer(ucvector* p, unsigned char* buffer, size_t size) -{ - p->data = buffer; - p->allocsize = p->size = size; -} - -static unsigned ucvector_push_back(ucvector* p, unsigned char c) /*returns 1 if success, 0 if failure ==> nothing done*/ -{ - if(!ucvector_resize(p, p->size + 1)) return 0; - p->data[p->size - 1] = c; - return 1; -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Reading and writing single bits and bytes from/to stream for Deflate / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -static void addBitToStream(size_t* bitpointer, ucvector* bitstream, unsigned char bit) -{ - if((*bitpointer) % 8 == 0) ucvector_push_back(bitstream, 0); /*add a new byte at the end*/ - (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7)); /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/ - (*bitpointer)++; -} - -static void addBitsToStream(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) -{ - size_t i; - for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1)); -} - -static void addBitsToStreamReversed(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) -{ - size_t i; - for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1)); -} - - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Deflate - Huffman / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -#define FIRST_LENGTH_CODE_INDEX 257 -#define LAST_LENGTH_CODE_INDEX 285 -#define NUM_DEFLATE_CODE_SYMBOLS 288 /*256 literals, the end code, some length codes, and 2 unused codes*/ -#define NUM_DISTANCE_SYMBOLS 32 /*the distance codes have their own symbols, 30 used, 2 unused*/ -#define NUM_CODE_LENGTH_CODES 19 /*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/ - -static const unsigned LENGTHBASE[29] /*the base lengths represented by codes 257-285*/ - = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}; -static const unsigned LENGTHEXTRA[29] /*the extra bits used by codes 257-285 (added to base length)*/ - = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; -static const unsigned DISTANCEBASE[30] /*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/ - = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; -static const unsigned DISTANCEEXTRA[30] /*the extra bits of backwards distances (added to base)*/ - = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; -static const unsigned CLCL[NUM_CODE_LENGTH_CODES] /*the order in which "code length alphabet code lengths" are stored, out of this the huffman tree of the dynamic huffman tree lengths is generated*/ - = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* /////////////////////////////////////////////////////////////////////////// */ - -/*terminology used for the package-merge algorithm and the coin collector's problem*/ -typedef struct Coin /*a coin can be multiple coins (when they're merged)*/ -{ - uivector symbols; - float weight; /*the sum of all weights in this coin*/ -} Coin; - -static void Coin_init(Coin* c) -{ - uivector_init(&c->symbols); -} - -static void Coin_cleanup(void* c) /*void* so that this dtor can be given as function pointer to the vector resize function*/ -{ - uivector_cleanup(&((Coin*)c)->symbols); -} - -static void Coin_copy(Coin* c1, const Coin* c2) -{ - c1->weight = c2->weight; - uivector_copy(&c1->symbols, &c2->symbols); -} - -static void addCoins(Coin* c1, const Coin* c2) -{ - unsigned i; - for(i = 0; i < c2->symbols.size; i++) uivector_push_back(&c1->symbols, c2->symbols.data[i]); - c1->weight += c2->weight; -} - -static void Coin_sort(Coin* data, size_t amount) /*combsort*/ -{ - size_t gap = amount; - unsigned char swapped = 0; - while(gap > 1 || swapped) - { - size_t i; - gap = (gap * 10) / 13; /*shrink factor 1.3*/ - if(gap == 9 || gap == 10) gap = 11; /*combsort11*/ - if(gap < 1) gap = 1; - swapped = 0; - for(i = 0; i < amount - gap; i++) - { - size_t j = i + gap; - if(data[j].weight < data[i].weight) - { - float temp = data[j].weight; data[j].weight = data[i].weight; data[i].weight = temp; - uivector_swap(&data[i].symbols, &data[j].symbols); - swapped = 1; - } - } - } -} - -typedef struct HuffmanTree -{ - uivector tree2d; - uivector tree1d; - uivector lengths; /*the lengths of the codes of the 1d-tree*/ - unsigned maxbitlen; /*maximum number of bits a single code can get*/ - unsigned numcodes; /*number of symbols in the alphabet = number of codes*/ -} HuffmanTree; - -/*function used for debug purposes*/ -/*#include <iostream> -static void HuffmanTree_draw(HuffmanTree* tree) -{ - std::cout << "tree. length: " << tree->numcodes << " maxbitlen: " << tree->maxbitlen << std::endl; - for(size_t i = 0; i < tree->tree1d.size; i++) - { - if(tree->lengths.data[i]) - std::cout << i << " " << tree->tree1d.data[i] << " " << tree->lengths.data[i] << std::endl; - } - std::cout << std::endl; -}*/ - -static void HuffmanTree_init(HuffmanTree* tree) -{ - uivector_init(&tree->tree2d); - uivector_init(&tree->tree1d); - uivector_init(&tree->lengths); -} - -static void HuffmanTree_cleanup(HuffmanTree* tree) -{ - uivector_cleanup(&tree->tree2d); - uivector_cleanup(&tree->tree1d); - uivector_cleanup(&tree->lengths); -} - -/*the tree representation used by the decoder. return value is error*/ -static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) -{ - unsigned nodefilled = 0; /*up to which node it is filled*/ - unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/ - unsigned n, i; - - if(!uivector_resize(&tree->tree2d, tree->numcodes * 2)) return 9901; /*if failed return not enough memory error*/ - /*convert tree1d[] to tree2d[][]. In the 2D array, a value of 32767 means uninited, a value >= numcodes is an address to another bit, a value < numcodes is a code. The 2 rows are the 2 possible bit values (0 or 1), there are as many columns as codes - 1 - a good huffmann tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. Here, the internal nodes are stored (what their 0 and 1 option point to). There is only memory for such good tree currently, if there are more nodes (due to too long length codes), error 55 will happen*/ - for(n = 0; n < tree->numcodes * 2; n++) tree->tree2d.data[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/ - - for(n = 0; n < tree->numcodes; n++) /*the codes*/ - for(i = 0; i < tree->lengths.data[n]; i++) /*the bits for this code*/ - { - unsigned char bit = (unsigned char)((tree->tree1d.data[n] >> (tree->lengths.data[n] - i - 1)) & 1); - if(treepos > tree->numcodes - 2) return 55; /*error 55: oversubscribed; see description in header*/ - if(tree->tree2d.data[2 * treepos + bit] == 32767) /*not yet filled in*/ - { - if(i + 1 == tree->lengths.data[n]) /*last bit*/ - { - tree->tree2d.data[2 * treepos + bit] = n; /*put the current code in it*/ - treepos = 0; - } - else /*put address of the next step in here, first that address has to be found of course (it's just nodefilled + 1)...*/ - { - nodefilled++; - tree->tree2d.data[2 * treepos + bit] = nodefilled + tree->numcodes; /*addresses encoded with numcodes added to it*/ - treepos = nodefilled; - } - } - else treepos = tree->tree2d.data[2 * treepos + bit] - tree->numcodes; - } - for(n = 0; n < tree->numcodes * 2; n++) if(tree->tree2d.data[n] == 32767) tree->tree2d.data[n] = 0; /*remove possible remaining 32767's*/ - - return 0; -} - -static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) /*given that numcodes, lengths and maxbitlen are already filled in correctly. return value is error.*/ -{ - uivector blcount; - uivector nextcode; - unsigned bits, n, error = 0; - - uivector_init(&blcount); - uivector_init(&nextcode); - if(!uivector_resize(&tree->tree1d, tree->numcodes) - || !uivector_resizev(&blcount, tree->maxbitlen + 1, 0) - || !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0)) - error = 9902; - - if(!error) - { - /*step 1: count number of instances of each code length*/ - for(bits = 0; bits < tree->numcodes; bits++) blcount.data[tree->lengths.data[bits]]++; - /*step 2: generate the nextcode values*/ - for(bits = 1; bits <= tree->maxbitlen; bits++) nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1; - /*step 3: generate all the codes*/ - for(n = 0; n < tree->numcodes; n++) if(tree->lengths.data[n] != 0) tree->tree1d.data[n] = nextcode.data[tree->lengths.data[n]]++; - } - - uivector_cleanup(&blcount); - uivector_cleanup(&nextcode); - - if(!error) return HuffmanTree_make2DTree(tree); - else return error; -} - -/*given the code lengths (as stored in the PNG file), generate the tree as defined by Deflate. maxbitlen is the maximum bits that a code in the tree can have. return value is error.*/ -static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen, size_t numcodes, unsigned maxbitlen) -{ - unsigned i; - if(!uivector_resize(&tree->lengths, numcodes)) return 9903; - for(i = 0; i < numcodes; i++) tree->lengths.data[i] = bitlen[i]; - tree->numcodes = (unsigned)numcodes; /*number of symbols*/ - tree->maxbitlen = maxbitlen; - return HuffmanTree_makeFromLengths2(tree); -} - -static unsigned HuffmanTree_fillInCoins(vector* coins, const unsigned* frequencies, unsigned numcodes, size_t sum) -{ - unsigned i; - for(i = 0; i < numcodes; i++) - { - Coin* coin; - if(frequencies[i] == 0) continue; /*it's important to exclude symbols that aren't present*/ - if(!vector_resize(coins, coins->size + 1)) { vector_cleanup(coins); return 9904; } - coin = (Coin*)(vector_get(coins, coins->size - 1)); - Coin_init(coin); - coin->weight = frequencies[i] / (float)sum; - uivector_push_back(&coin->symbols, i); - } - if(coins->size) Coin_sort((Coin*)coins->data, coins->size); - return 0; -} - -static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies, size_t numcodes, unsigned maxbitlen) -{ - unsigned i, j; - size_t sum = 0, numpresent = 0; - unsigned error = 0; - - vector prev_row; /*type Coin, the previous row of coins*/ - vector coins; /*type Coin, the coins of the currently calculated row*/ - - tree->maxbitlen = maxbitlen; - - for(i = 0; i < numcodes; i++) - { - if(frequencies[i] > 0) - { - numpresent++; - sum += frequencies[i]; - } - } - - if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/ - tree->numcodes = (unsigned)numcodes; /*number of symbols*/ - uivector_resize(&tree->lengths, 0); - if(!uivector_resizev(&tree->lengths, tree->numcodes, 0)) return 9905; - - if(numpresent == 0) /*there are no symbols at all, in that case add one symbol of value 0 to the tree (see RFC 1951 section 3.2.7) */ - { - tree->lengths.data[0] = 1; - return HuffmanTree_makeFromLengths2(tree); - } - else if(numpresent == 1) /*the package merge algorithm gives wrong results if there's only one symbol (theoretically 0 bits would then suffice, but we need a proper symbol for zlib)*/ - { - for(i = 0; i < numcodes; i++) if(frequencies[i]) tree->lengths.data[i] = 1; - return HuffmanTree_makeFromLengths2(tree); - } - - vector_init(&coins, sizeof(Coin)); - vector_init(&prev_row, sizeof(Coin)); - - /*Package-Merge algorithm represented by coin collector's problem - For every symbol, maxbitlen coins will be created*/ - - /*first row, lowest denominator*/ - error = HuffmanTree_fillInCoins(&coins, frequencies, tree->numcodes, sum); - if(!error) - { - for(j = 1; j <= maxbitlen && !error; j++) /*each of the remaining rows*/ - { - vector_swap(&coins, &prev_row); /*swap instead of copying*/ - if(!vector_resized(&coins, 0, Coin_cleanup)) { error = 9906; break; } - - for(i = 0; i + 1 < prev_row.size; i += 2) - { - if(!vector_resize(&coins, coins.size + 1)) { error = 9907; break; } - Coin_init((Coin*)vector_get(&coins, coins.size - 1)); - Coin_copy((Coin*)vector_get(&coins, coins.size - 1), (Coin*)vector_get(&prev_row, i)); - addCoins((Coin*)vector_get(&coins, coins.size - 1), (Coin*)vector_get(&prev_row, i + 1)); /*merge the coins into packages*/ - } - if(j < maxbitlen) - { - error = HuffmanTree_fillInCoins(&coins, frequencies, tree->numcodes, sum); - } - } - } - - if(!error) - { - /*keep the coins with lowest weight, so that they add up to the amount of symbols - 1*/ - vector_resized(&coins, numpresent - 1, Coin_cleanup); - - /*calculate the lengths of each symbol, as the amount of times a coin of each symbol is used*/ - for(i = 0; i < coins.size; i++) - { - Coin* coin = (Coin*)vector_get(&coins, i); - for(j = 0; j < coin->symbols.size; j++) tree->lengths.data[coin->symbols.data[j]]++; - } - - error = HuffmanTree_makeFromLengths2(tree); - } - - vector_cleanupd(&coins, Coin_cleanup); - vector_cleanupd(&prev_row, Coin_cleanup); - - return error; -} - -static unsigned HuffmanTree_getCode(const HuffmanTree* tree, unsigned index) { return tree->tree1d.data[index]; } -static unsigned HuffmanTree_getLength(const HuffmanTree* tree, unsigned index) { return tree->lengths.data[index]; } - -/*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/ -static unsigned generateFixedTree(HuffmanTree* tree) -{ - unsigned i, error = 0; - uivector bitlen; - uivector_init(&bitlen); - if(!uivector_resize(&bitlen, NUM_DEFLATE_CODE_SYMBOLS)) error = 9909; - - if(!error) - { - /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ - for(i = 0; i <= 143; i++) bitlen.data[i] = 8; - for(i = 144; i <= 255; i++) bitlen.data[i] = 9; - for(i = 256; i <= 279; i++) bitlen.data[i] = 7; - for(i = 280; i <= 287; i++) bitlen.data[i] = 8; - - error = HuffmanTree_makeFromLengths(tree, bitlen.data, NUM_DEFLATE_CODE_SYMBOLS, 15); - } - - uivector_cleanup(&bitlen); - return error; -} - -static unsigned generateDistanceTree(HuffmanTree* tree) -{ - unsigned i, error = 0; - uivector bitlen; - uivector_init(&bitlen); - if(!uivector_resize(&bitlen, NUM_DISTANCE_SYMBOLS)) error = 9910; - - /*there are 32 distance codes, but 30-31 are unused*/ - if(!error) - { - for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen.data[i] = 5; - error = HuffmanTree_makeFromLengths(tree, bitlen.data, NUM_DISTANCE_SYMBOLS, 15); - } - uivector_cleanup(&bitlen); - return error; -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Deflator / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258; - -/*bitlen is the size in bits of the code*/ -static void addHuffmanSymbol(size_t* bp, ucvector* compressed, unsigned code, unsigned bitlen) -{ - addBitsToStreamReversed(bp, compressed, code, bitlen); -} - -/*search the index in the array, that has the largest value smaller than or equal to the given value, given array must be sorted (if no value is smaller, it returns the size of the given array)*/ -static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value) -{ - /*linear search implementation*/ - /*for(size_t i = 1; i < array_size; i++) if(array[i] > value) return i - 1; - return array_size - 1;*/ - - /*binary search implementation (not that much faster) (precondition: array_size > 0)*/ - size_t left = 1; - size_t right = array_size - 1; - while(left <= right) - { - size_t mid = (left + right) / 2; - if(array[mid] <= value) left = mid + 1; /*the value to find is more to the right*/ - else if(array[mid - 1] > value) right = mid - 1; /*the value to find is more to the left*/ - else return mid - 1; - } - return array_size - 1; -} - -static void addLengthDistance(uivector* values, size_t length, size_t distance) -{ - /*values in encoded vector are those used by deflate: - 0-255: literal bytes - 256: end - 257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits) - 286-287: invalid*/ - - unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length); - unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]); - unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance); - unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]); - - uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX); - uivector_push_back(values, extra_length); - uivector_push_back(values, dist_code); - uivector_push_back(values, extra_distance); -} - -#if USE_BRUTE_FORCE_ENCODING -#define encodeLZ77 encodeLZ77_brute -/*the "brute force" version of the encodeLZ7 algorithm, not used anymore, kept here for reference*/ -static unsigned encodeLZ77_brute(uivector* out, const unsigned char* in, size_t size, unsigned windowSize) -{ - size_t pos; - /*using pointer instead of vector for input makes it faster when NOT using optimization when compiling; no influence if optimization is used*/ - for(pos = 0; pos < size; pos++) - { - /*Phase 1: doxygen images often have long runs of the same color, try to find them*/ - const int minLength = 4; // Minimum length for a run to make sense - - if(pos < size - minLength * 4) - { - size_t p, fp; - size_t current_length; - - /*RGBA pixel run?*/ - p = pos; - fp = pos + 4; - current_length = 0; - - while(fp < size && in[p] == in[fp] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH) - { - ++p; - ++fp; - ++current_length; - } - - if (current_length > (minLength - 1 ) * 4) /*worth using?*/ - { - uivector_push_back(out, in[pos ]); - uivector_push_back(out, in[pos + 1]); - uivector_push_back(out, in[pos + 2]); - uivector_push_back(out, in[pos + 3]); - addLengthDistance(out, current_length, 4); - - pos += current_length + 4 - 1; /*-1 for loop's pos++*/ - continue; - } - - /*RGB pixel run?*/ - p = pos; - fp = pos + 3; - current_length = 0; - - while(fp < size && in[p] == in[fp] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH) - { - ++p; - ++fp; - ++current_length; - } - - if (current_length > (minLength - 1 ) * 3) /*worth using?*/ - { - uivector_push_back(out, in[pos ]); - uivector_push_back(out, in[pos + 1]); - uivector_push_back(out, in[pos + 2]); - addLengthDistance(out, current_length, 3); - - pos += current_length + 3 - 1; /*-1 for loop's pos++*/ - continue; - } - } - - size_t length = 0, offset = 0; /*the length and offset found for the current position*/ - size_t max_offset = pos < windowSize ? pos : windowSize; /*how far back to test*/ - size_t current_offset; - - /**search for the longest string**/ - for(current_offset = 1; current_offset < max_offset; current_offset++) /*search backwards through all possible distances (=offsets)*/ - { - size_t backpos = pos - current_offset; - if(in[backpos] == in[pos]) - { - /*test the next characters*/ - size_t current_length = 1; - size_t backtest = backpos + 1; - size_t foretest = pos + 1; - while(foretest < size && in[backtest] == in[foretest] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH) /*maximum support length by deflate is max length*/ - { - if(backpos >= pos) backpos -= current_offset; /*continue as if we work on the decoded bytes after pos by jumping back before pos*/ - current_length++; - backtest++; - foretest++; - } - if(current_length > length) - { - length = current_length; /*the longest length*/ - offset = current_offset; /*the offset that is related to this longest length*/ - if(current_length == MAX_SUPPORTED_DEFLATE_LENGTH) break; /*you can jump out of this for loop once a length of max length is found (gives significant speed gain)*/ - } - } - } - - /**encode it as length/distance pair or literal value**/ - if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/ - { - uivector_push_back(out, in[pos]); - } - else - { - addLengthDistance(out, length, offset); - pos += (length - 1); - } - } /*end of the loop through each character of input*/ - - return 0; -} -#endif - -/* -static const unsigned HASH_NUM_VALUES = 65536; -static const unsigned HASH_NUM_CHARACTERS = 6; -static const unsigned HASH_SHIFT = 2; -Good and fast values: HASH_NUM_VALUES=65536, HASH_NUM_CHARACTERS=6, HASH_SHIFT=2 -making HASH_NUM_CHARACTERS larger (like 8), makes the file size larger but is a bit faster -making HASH_NUM_CHARACTERS smaller (like 3), makes the file size smaller but is slower -*/ - -#if !defined(USE_BRUTE_FORCE_ENCODING) -static unsigned getHash(const unsigned char* data, size_t size, size_t pos) -{ - unsigned result = 0; - size_t amount, i; - if(pos >= size) return 0; - amount = HASH_NUM_CHARACTERS; if(pos + amount >= size) amount = size - pos; - for(i = 0; i < amount; i++) result ^= (data[pos + i] << (i * HASH_SHIFT)); - return result % HASH_NUM_VALUES; -} - -/*LZ77-encode the data using a hash table technique to let it encode faster. Return value is error code*/ -static unsigned encodeLZ77(uivector* out, const unsigned char* in, size_t size, unsigned windowSize) -{ - /**generate hash table**/ - vector table; /*HASH_NUM_VALUES uivectors; this represents what would be an std::vector<std::vector<unsigned> > in C++*/ - uivector tablepos1, tablepos2; - unsigned pos, i, error = 0; - - vector_init(&table, sizeof(uivector)); - if(!vector_resize(&table, HASH_NUM_VALUES)) return 9917; - for(i = 0; i < HASH_NUM_VALUES; i++) - { - uivector* v = (uivector*)vector_get(&table, i); - uivector_init(v); - } - - /*remember start and end positions in the tables to searching in*/ - uivector_init(&tablepos1); - uivector_init(&tablepos2); - if(!uivector_resizev(&tablepos1, HASH_NUM_VALUES, 0)) error = 9918; - if(!uivector_resizev(&tablepos2, HASH_NUM_VALUES, 0)) error = 9919; - - if(!error) - { - for(pos = 0; pos < size; pos++) - { - unsigned length = 0, offset = 0; /*the length and offset found for the current position*/ - unsigned max_offset = pos < windowSize ? pos : windowSize; /*how far back to test*/ - unsigned tablepos; - - /*/search for the longest string*/ - /*first find out where in the table to start (the first value that is in the range from "pos - max_offset" to "pos")*/ - unsigned hash = getHash(in, size, pos); - if(!uivector_push_back((uivector*)vector_get(&table, hash), pos)) { error = 9920; break; } - - while(((uivector*)vector_get(&table, hash))->data[tablepos1.data[hash]] < pos - max_offset) tablepos1.data[hash]++; /*it now points to the first value in the table for which the index is larger than or equal to pos - max_offset*/ - while(((uivector*)vector_get(&table, hash))->data[tablepos2.data[hash]] < pos) tablepos2.data[hash]++; /*it now points to the first value in the table for which the index is larger than or equal to pos*/ - - for(tablepos = tablepos2.data[hash] - 1; tablepos >= tablepos1.data[hash] && tablepos < tablepos2.data[hash]; tablepos--) - { - unsigned backpos = ((uivector*)vector_get(&table, hash))->data[tablepos]; - unsigned current_offset = pos - backpos; - - /*test the next characters*/ - unsigned current_length = 0; - unsigned backtest = backpos; - unsigned foretest = pos; - while(foretest < size && in[backtest] == in[foretest] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH) /*maximum support length by deflate is max length*/ - { - if(backpos >= pos) backpos -= current_offset; /*continue as if we work on the decoded bytes after pos by jumping back before pos*/ - current_length++; - backtest++; - foretest++; - } - if(current_length > length) - { - length = current_length; /*the longest length*/ - offset = current_offset; /*the offset that is related to this longest length*/ - if(current_length == MAX_SUPPORTED_DEFLATE_LENGTH) break; /*you can jump out of this for loop once a length of max length is found (gives significant speed gain)*/ - } - } - - /**encode it as length/distance pair or literal value**/ - if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/ - { - if(!uivector_push_back(out, in[pos])) { error = 9921; break; } - } - else - { - unsigned j; - addLengthDistance(out, length, offset); - for(j = 0; j < length - 1; j++) - { - pos++; - if(!uivector_push_back((uivector*)vector_get(&table, getHash(in, size, pos)), pos)) { error = 9922; break; } - } - } - } /*end of the loop through each character of input*/ - } /*end of "if(!error)"*/ - - /*cleanup*/ - for(i = 0; i < table.size; i++) - { - uivector* v = (uivector*)vector_get(&table, i); - uivector_cleanup(v); - } - vector_cleanup(&table); - uivector_cleanup(&tablepos1); - uivector_cleanup(&tablepos2); - return error; -} -#endif - -/* /////////////////////////////////////////////////////////////////////////// */ - -static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize) -{ - /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/ - - size_t i, j, numdeflateblocks = datasize / 65536 + 1; - unsigned datapos = 0; - for(i = 0; i < numdeflateblocks; i++) - { - unsigned BFINAL, BTYPE, LEN, NLEN; - unsigned char firstbyte; - - BFINAL = (i == numdeflateblocks - 1); - BTYPE = 0; - - firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1)); - ucvector_push_back(out, firstbyte); - - LEN = 65535; - if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos; - NLEN = 65535 - LEN; - - ucvector_push_back(out, (unsigned char)(LEN % 256)); - ucvector_push_back(out, (unsigned char)(LEN / 256)); - ucvector_push_back(out, (unsigned char)(NLEN % 256)); - ucvector_push_back(out, (unsigned char)(NLEN / 256)); - - /*Decompressed data*/ - for(j = 0; j < 65535 && datapos < datasize; j++) - { - ucvector_push_back(out, data[datapos++]); - } - } - - return 0; -} - -/*write the encoded data, using lit/len as well as distance codes*/ -static void writeLZ77data(size_t* bp, ucvector* out, const uivector* lz77_encoded, const HuffmanTree* codes, const HuffmanTree* codesD) -{ - size_t i = 0; - for(i = 0; i < lz77_encoded->size; i++) - { - unsigned val = lz77_encoded->data[i]; - addHuffmanSymbol(bp, out, HuffmanTree_getCode(codes, val), HuffmanTree_getLength(codes, val)); - if(val > 256) /*for a length code, 3 more things have to be added*/ - { - unsigned length_index = val - FIRST_LENGTH_CODE_INDEX; - unsigned n_length_extra_bits = LENGTHEXTRA[length_index]; - unsigned length_extra_bits = lz77_encoded->data[++i]; - - unsigned distance_code = lz77_encoded->data[++i]; - - unsigned distance_index = distance_code; - unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index]; - unsigned distance_extra_bits = lz77_encoded->data[++i]; - - addBitsToStream(bp, out, length_extra_bits, n_length_extra_bits); - addHuffmanSymbol(bp, out, HuffmanTree_getCode(codesD, distance_code), HuffmanTree_getLength(codesD, distance_code)); - addBitsToStream(bp, out, distance_extra_bits, n_distance_extra_bits); - } - } -} - -static unsigned deflateDynamic(ucvector* out, const unsigned char* data, size_t datasize, const LodeZlib_DeflateSettings* settings) -{ - /* - after the BFINAL and BTYPE, the dynamic block consists out of the following: - - 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN - - (HCLEN+4)*3 bits code lengths of code length alphabet - - HLIT + 257 code lengths of lit/length alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18) - - HDIST + 1 code lengths of distance alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18) - - compressed data - - 256 (end code) - */ - - unsigned error = 0; - - uivector lz77_encoded; - HuffmanTree codes; /*tree for literal values and length codes*/ - HuffmanTree codesD; /*tree for distance codes*/ - HuffmanTree codelengthcodes; - uivector frequencies; - uivector frequenciesD; - uivector amounts; /*the amounts in the "normal" order*/ - uivector lldl; - uivector lldll; /*lit/len & dist code lengths*/ - uivector clcls; - - unsigned BFINAL = 1; /*make only one block... the first and final one*/ - size_t numcodes, numcodesD, i, bp = 0; /*the bit pointer*/ - unsigned HLIT, HDIST, HCLEN; - - uivector_init(&lz77_encoded); - HuffmanTree_init(&codes); - HuffmanTree_init(&codesD); - HuffmanTree_init(&codelengthcodes); - uivector_init(&frequencies); - uivector_init(&frequenciesD); - uivector_init(&amounts); - uivector_init(&lldl); - uivector_init(&lldll); - uivector_init(&clcls); - - while(!error) /*the goto-avoiding while construct: break out to go to the cleanup phase, a break at the end makes sure the while is never repeated*/ - { - if(settings->useLZ77) - { - error = encodeLZ77(&lz77_encoded, data, datasize, settings->windowSize); /*LZ77 encoded*/ - if(error) break; - } - else - { - if(!uivector_resize(&lz77_encoded, datasize)) { error = 9923; break; } - for(i = 0; i < datasize; i++) lz77_encoded.data[i] = data[i]; /*no LZ77, but still will be Huffman compressed*/ - } - - if(!uivector_resizev(&frequencies, 286, 0)) { error = 9924; break; } - if(!uivector_resizev(&frequenciesD, 30, 0)) { error = 9925; break; } - for(i = 0; i < lz77_encoded.size; i++) - { - unsigned symbol = lz77_encoded.data[i]; - frequencies.data[symbol]++; - if(symbol > 256) - { - unsigned dist = lz77_encoded.data[i + 2]; - frequenciesD.data[dist]++; - i += 3; - } - } - frequencies.data[256] = 1; /*there will be exactly 1 end code, at the end of the block*/ - - error = HuffmanTree_makeFromFrequencies(&codes, frequencies.data, frequencies.size, 15); - if(error) break; - error = HuffmanTree_makeFromFrequencies(&codesD, frequenciesD.data, frequenciesD.size, 15); - if(error) break; - - addBitToStream(&bp, out, BFINAL); - addBitToStream(&bp, out, 0); /*first bit of BTYPE "dynamic"*/ - addBitToStream(&bp, out, 1); /*second bit of BTYPE "dynamic"*/ - - numcodes = codes.numcodes; if(numcodes > 286) numcodes = 286; - numcodesD = codesD.numcodes; if(numcodesD > 30) numcodesD = 30; - for(i = 0; i < numcodes; i++) uivector_push_back(&lldll, HuffmanTree_getLength(&codes, (unsigned)i)); - for(i = 0; i < numcodesD; i++) uivector_push_back(&lldll, HuffmanTree_getLength(&codesD, (unsigned)i)); - - /*make lldl smaller by using repeat codes 16 (copy length 3-6 times), 17 (3-10 zeros), 18 (11-138 zeros)*/ - for(i = 0; i < (unsigned)lldll.size; i++) - { - unsigned j = 0; - while(i + j + 1 < (unsigned)lldll.size && lldll.data[i + j + 1] == lldll.data[i]) j++; - - if(lldll.data[i] == 0 && j >= 2) - { - j++; /*include the first zero*/ - if(j <= 10) { uivector_push_back(&lldl, 17); uivector_push_back(&lldl, j - 3); } - else - { - if(j > 138) j = 138; - uivector_push_back(&lldl, 18); uivector_push_back(&lldl, j - 11); - } - i += (j - 1); - } - else if(j >= 3) - { - size_t k; - unsigned num = j / 6, rest = j % 6; - uivector_push_back(&lldl, lldll.data[i]); - for(k = 0; k < num; k++) { uivector_push_back(&lldl, 16); uivector_push_back(&lldl, 6 - 3); } - if(rest >= 3) { uivector_push_back(&lldl, 16); uivector_push_back(&lldl, rest - 3); } - else j -= rest; - i += j; - } - else uivector_push_back(&lldl, lldll.data[i]); - } - - /*generate huffmantree for the length codes of lit/len and dist codes*/ - if(!uivector_resizev(&amounts, 19, 0)) { error = 9926; break; } /*16 possible lengths (0-15) and 3 repeat codes (16, 17 and 18)*/ - for(i = 0; i < lldl.size; i++) - { - amounts.data[lldl.data[i]]++; - if(lldl.data[i] >= 16) i++; /*after a repeat code come the bits that specify the amount, those don't need to be in the amounts calculation*/ - } - - error = HuffmanTree_makeFromFrequencies(&codelengthcodes, amounts.data, amounts.size, 7); - if(error) break; - - if(!uivector_resize(&clcls, 19)) { error = 9927; break; } - for(i = 0; i < 19; i++) clcls.data[i] = HuffmanTree_getLength(&codelengthcodes, CLCL[i]); /*lengths of code length tree is in the order as specified by deflate*/ - while(clcls.data[clcls.size - 1] == 0 && clcls.size > 4) - { - if(!uivector_resize(&clcls, clcls.size - 1)) { error = 9928; break; } /*remove zeros at the end, but minimum size must be 4*/ - } - if(error) break; - - /*write the HLIT, HDIST and HCLEN values*/ - HLIT = (unsigned)(numcodes - 257); - HDIST = (unsigned)(numcodesD - 1); - HCLEN = (unsigned)clcls.size - 4; - addBitsToStream(&bp, out, HLIT, 5); - addBitsToStream(&bp, out, HDIST, 5); - addBitsToStream(&bp, out, HCLEN, 4); - - /*write the code lengths of the code length alphabet*/ - for(i = 0; i < HCLEN + 4; i++) addBitsToStream(&bp, out, clcls.data[i], 3); - - /*write the lengths of the lit/len AND the dist alphabet*/ - for(i = 0; i < lldl.size; i++) - { - addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codelengthcodes, lldl.data[i]), HuffmanTree_getLength(&codelengthcodes, lldl.data[i])); - /*extra bits of repeat codes*/ - if(lldl.data[i] == 16) addBitsToStream(&bp, out, lldl.data[++i], 2); - else if(lldl.data[i] == 17) addBitsToStream(&bp, out, lldl.data[++i], 3); - else if(lldl.data[i] == 18) addBitsToStream(&bp, out, lldl.data[++i], 7); - } - - /*write the compressed data symbols*/ - writeLZ77data(&bp, out, &lz77_encoded, &codes, &codesD); - if(HuffmanTree_getLength(&codes, 256) == 0) { error = 64; break; } /*the length of the end code 256 must be larger than 0*/ - addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, 256), HuffmanTree_getLength(&codes, 256)); /*end code*/ - - break; /*end of error-while*/ - } - - /*cleanup*/ - uivector_cleanup(&lz77_encoded); - HuffmanTree_cleanup(&codes); - HuffmanTree_cleanup(&codesD); - HuffmanTree_cleanup(&codelengthcodes); - uivector_cleanup(&frequencies); - uivector_cleanup(&frequenciesD); - uivector_cleanup(&amounts); - uivector_cleanup(&lldl); - uivector_cleanup(&lldll); - uivector_cleanup(&clcls); - - return error; -} - -static unsigned deflateFixed(ucvector* out, const unsigned char* data, size_t datasize, const LodeZlib_DeflateSettings* settings) -{ - HuffmanTree codes; /*tree for literal values and length codes*/ - HuffmanTree codesD; /*tree for distance codes*/ - - unsigned BFINAL = 1; /*make only one block... the first and final one*/ - unsigned error = 0; - size_t i, bp = 0; /*the bit pointer*/ - - HuffmanTree_init(&codes); - HuffmanTree_init(&codesD); - - generateFixedTree(&codes); - generateDistanceTree(&codesD); - - addBitToStream(&bp, out, BFINAL); - addBitToStream(&bp, out, 1); /*first bit of BTYPE*/ - addBitToStream(&bp, out, 0); /*second bit of BTYPE*/ - - if(settings->useLZ77) /*LZ77 encoded*/ - { - uivector lz77_encoded; - uivector_init(&lz77_encoded); - error = encodeLZ77(&lz77_encoded, data, datasize, settings->windowSize); - if(!error) writeLZ77data(&bp, out, &lz77_encoded, &codes, &codesD); - uivector_cleanup(&lz77_encoded); - } - else /*no LZ77, but still will be Huffman compressed*/ - { - for(i = 0; i < datasize; i++) addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, data[i]), HuffmanTree_getLength(&codes, data[i])); - } - if(!error) addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, 256), HuffmanTree_getLength(&codes, 256)); /*"end" code*/ - - /*cleanup*/ - HuffmanTree_cleanup(&codes); - HuffmanTree_cleanup(&codesD); - - return error; -} - -unsigned LodeFlate_deflate(ucvector* out, const unsigned char* data, size_t datasize, const LodeZlib_DeflateSettings* settings) -{ - unsigned error = 0; - if(settings->btype == 0) error = deflateNoCompression(out, data, datasize); - else if(settings->btype == 1) error = deflateFixed(out, data, datasize, settings); - else if(settings->btype == 2) error = deflateDynamic(out, data, datasize, settings); - else error = 61; - return error; -} - - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Adler32 */ -/* ////////////////////////////////////////////////////////////////////////// */ - -static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len) -{ - unsigned s1 = adler & 0xffff; - unsigned s2 = (adler >> 16) & 0xffff; - - while(len > 0) - { - /*at least 5550 sums can be done before the sums overflow, saving us from a lot of module divisions*/ - unsigned amount = len > 5550 ? 5550 : len; - len -= amount; - while(amount > 0) - { - s1 = (s1 + *data++); - s2 = (s2 + s1); - amount--; - } - s1 %= 65521; - s2 %= 65521; - } - - return (s2 << 16) | s1; -} - -/*Return the adler32 of the bytes data[0..len-1]*/ -static unsigned adler32(const unsigned char* data, unsigned len) -{ - return update_adler32(1L, data, len); -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Reading and writing single bits and bytes from/to stream for Zlib / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -static void LodeZlib_add32bitInt(ucvector* buffer, unsigned value) -{ - ucvector_push_back(buffer, (unsigned char)((value >> 24) & 0xff)); - ucvector_push_back(buffer, (unsigned char)((value >> 16) & 0xff)); - ucvector_push_back(buffer, (unsigned char)((value >> 8) & 0xff)); - ucvector_push_back(buffer, (unsigned char)((value ) & 0xff)); -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Zlib / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -static unsigned LodeZlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DeflateSettings* settings) -{ - /*initially, *out must be NULL and outsize 0, if you just give some random *out that's pointing to a non allocated buffer, this'll crash*/ - ucvector deflatedata, outv; - size_t i; - unsigned error; - - unsigned ADLER32; - /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/ - unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/ - unsigned FLEVEL = 0; - unsigned FDICT = 0; - unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64; - unsigned FCHECK = 31 - CMFFLG % 31; - CMFFLG += FCHECK; - - ucvector_init_buffer(&outv, *out, *outsize); /*ucvector-controlled version of the output buffer, for dynamic array*/ - - ucvector_push_back(&outv, (unsigned char)(CMFFLG / 256)); - ucvector_push_back(&outv, (unsigned char)(CMFFLG % 256)); - - ucvector_init(&deflatedata); - error = LodeFlate_deflate(&deflatedata, in, insize, settings); - - if(!error) - { - ADLER32 = adler32(in, (unsigned)insize); - for(i = 0; i < deflatedata.size; i++) ucvector_push_back(&outv, deflatedata.data[i]); - ucvector_cleanup(&deflatedata); - LodeZlib_add32bitInt(&outv, ADLER32); - } - - *out = outv.data; - *outsize = outv.size; - - return error; -} - -/* ////////////////////////////////////////////////////////////////////////// */ - -void LodeZlib_DeflateSettings_init(LodeZlib_DeflateSettings* settings) -{ - settings->btype = 2; /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/ - settings->useLZ77 = 1; - settings->windowSize = 2048; /*this is a good tradeoff between speed and compression ratio*/ -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* // End of Zlib related code, now comes the PNG related code that uses it// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/* -The two functions below (LodePNG_decompress and LodePNG_compress) directly call the -LodeZlib_decompress and LodeZlib_compress functions. The only purpose of the functions -below, is to provide the ability to let LodePNG use a different Zlib encoder by only -changing the two functions below, instead of changing it inside the various places -in the other LodePNG functions. - -*out must be NULL and *outsize must be 0 initially, and after the function is done, -*out must point to the decompressed data, *outsize must be the size of it, and must -be the size of the useful data in bytes, not the alloc size. -*/ - -static unsigned LodePNG_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DeflateSettings* settings) -{ - return LodeZlib_compress(out, outsize, in, insize, settings); -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / CRC32 / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -static unsigned Crc32_crc_table_computed = 0; -static unsigned Crc32_crc_table[256]; - -/*Make the table for a fast CRC.*/ -static void Crc32_make_crc_table(void) -{ - unsigned int c, k, n; - for(n = 0; n < 256; n++) - { - c = n; - for(k = 0; k < 8; k++) - { - if(c & 1) c = (unsigned int)(0xedb88320L ^ (c >> 1)); - else c = c >> 1; - } - Crc32_crc_table[n] = c; - } - Crc32_crc_table_computed = 1; -} - -/*Update a running CRC with the bytes buf[0..len-1]--the CRC should be -initialized to all 1's, and the transmitted value is the 1's complement of the -final running CRC (see the crc() routine below).*/ -static unsigned Crc32_update_crc(const unsigned char* buf, unsigned int crc, size_t len) -{ - unsigned int c = crc; - size_t n; - - if(!Crc32_crc_table_computed) Crc32_make_crc_table(); - for(n = 0; n < len; n++) - { - c = Crc32_crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); - } - return c; -} - -/*Return the CRC of the bytes buf[0..len-1].*/ -static unsigned Crc32_crc(const unsigned char* buf, size_t len) -{ - return Crc32_update_crc(buf, 0xffffffffu, len) ^ 0xffffffffu; -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Reading and writing single bits and bytes from/to stream for LodePNG / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream) -{ - unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1); - (*bitpointer)++; - return result; -} - -static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) -{ - unsigned result = 0; - size_t i; - for(i = nbits - 1; i < nbits; i--) result += (unsigned)readBitFromReversedStream(bitpointer, bitstream) << i; - return result; -} - -static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) -{ - /*the current bit in bitstream may be 0 or 1 for this to work*/ - if(bit == 0) bitstream[(*bitpointer) >> 3] &= (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7)))); - else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7))); - (*bitpointer)++; -} - -static unsigned LodePNG_read32bitInt(const unsigned char* buffer) -{ - return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; -} - -static void LodePNG_set32bitInt(unsigned char* buffer, unsigned value) /*buffer must have at least 4 allocated bytes available*/ -{ - buffer[0] = (unsigned char)((value >> 24) & 0xff); - buffer[1] = (unsigned char)((value >> 16) & 0xff); - buffer[2] = (unsigned char)((value >> 8) & 0xff); - buffer[3] = (unsigned char)((value ) & 0xff); -} - -static void LodePNG_add32bitInt(ucvector* buffer, unsigned value) -{ - ucvector_resize(buffer, buffer->size + 4); - LodePNG_set32bitInt(&buffer->data[buffer->size - 4], value); -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / PNG chunks / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -static unsigned LodePNG_chunk_length(const unsigned char* chunk) /*get the length of the data of the chunk. Total chunk length has 12 bytes more.*/ -{ - return LodePNG_read32bitInt(&chunk[0]); -} - -static void LodePNG_chunk_generate_crc(unsigned char* chunk) /*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/ -{ - unsigned length = LodePNG_chunk_length(chunk); - unsigned CRC = Crc32_crc(&chunk[4], length + 4); - LodePNG_set32bitInt(chunk + 8 + length, CRC); -} - -static unsigned LodePNG_create_chunk(unsigned char** out, size_t* outlength, unsigned length, const char* type, const unsigned char* data) /*appends new chunk to out. Returns error code; may change memory address of out buffer*/ -{ - unsigned i; - unsigned char *chunk, *new_buffer; - size_t new_length = (*outlength) + length + 12; - if(new_length < length + 12 || new_length < (*outlength)) return 77; /*integer overflow happened*/ - new_buffer = (unsigned char*)realloc(*out, new_length); - if(!new_buffer) return 9930; - (*out) = new_buffer; - (*outlength) = new_length; - chunk = &(*out)[(*outlength) - length - 12]; - - /*1: length*/ - LodePNG_set32bitInt(chunk, (unsigned)length); - - /*2: chunk name (4 letters)*/ - chunk[4] = type[0]; - chunk[5] = type[1]; - chunk[6] = type[2]; - chunk[7] = type[3]; - - /*3: the data*/ - for(i = 0; i < length; i++) chunk[8 + i] = data[i]; - - /*4: CRC (of the chunkname characters and the data)*/ - LodePNG_chunk_generate_crc(chunk); - - return 0; -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / Color types and such / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/*return type is a LodePNG error code*/ -static unsigned checkColorValidity(unsigned colorType, unsigned bd) /*bd = bitDepth*/ -{ - switch(colorType) - { - case 0: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; /*grey*/ - case 2: if(!( bd == 8 || bd == 16)) return 37; break; /*RGB*/ - case 3: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break; /*palette*/ - case 4: if(!( bd == 8 || bd == 16)) return 37; break; /*grey + alpha*/ - case 6: if(!( bd == 8 || bd == 16)) return 37; break; /*RGBA*/ - default: return 31; - } - return 0; /*allowed color type / bits combination*/ -} - -static unsigned getNumColorChannels(unsigned colorType) -{ - switch(colorType) - { - case 0: return 1; /*grey*/ - case 2: return 3; /*RGB*/ - case 3: return 1; /*palette*/ - case 4: return 2; /*grey + alpha*/ - case 6: return 4; /*RGBA*/ - } - return 0; /*unexisting color type*/ -} - -static unsigned getBpp(unsigned colorType, unsigned bitDepth) -{ - return getNumColorChannels(colorType) * bitDepth; /*bits per pixel is amount of channels * bits per channel*/ -} - -/* ////////////////////////////////////////////////////////////////////////// */ - -static void LodePNG_InfoColor_init(LodePNG_InfoColor* info) -{ - info->key_defined = 0; - info->key_r = info->key_g = info->key_b = 0; - info->colorType = 6; - info->bitDepth = 8; - info->palette = 0; - info->palettesize = 0; -} - -static void LodePNG_InfoColor_cleanup(LodePNG_InfoColor* info) -{ - LodePNG_InfoColor_clearPalette(info); -} - -static void LodePNG_InfoColor_clearPalette(LodePNG_InfoColor* info) -{ - if(info->palette) free(info->palette); - info->palettesize = 0; -} - -unsigned LodePNG_InfoColor_addPalette(LodePNG_InfoColor* info, unsigned char r, unsigned char g, unsigned char b, unsigned char a) -{ - unsigned char* data; - /*the same resize technique as C++ std::vectors is used, and here it's made so that for a palette with the max of 256 colors, it'll have the exact alloc size*/ - if(!(info->palettesize & (info->palettesize - 1))) /*if palettesize is 0 or a power of two*/ - { - /*allocated data must be at least 4* palettesize (for 4 color bytes)*/ - size_t alloc_size = info->palettesize == 0 ? 4 : info->palettesize * 4 * 2; - data = (unsigned char*)realloc(info->palette, alloc_size); - if(!data) return 9931; - else info->palette = data; - } - info->palette[4 * info->palettesize + 0] = r; - info->palette[4 * info->palettesize + 1] = g; - info->palette[4 * info->palettesize + 2] = b; - info->palette[4 * info->palettesize + 3] = a; - info->palettesize++; - return 0; -} - -static unsigned LodePNG_InfoColor_getBpp(const LodePNG_InfoColor* info) { return getBpp(info->colorType, info->bitDepth); } /*calculate bits per pixel out of colorType and bitDepth*/ -static unsigned LodePNG_InfoColor_isGreyscaleType(const LodePNG_InfoColor* info) { return info->colorType == 0 || info->colorType == 4; } -static unsigned LodePNG_InfoColor_isAlphaType(const LodePNG_InfoColor* info) { return (info->colorType & 4) != 0; } - -static unsigned LodePNG_InfoColor_equal(const LodePNG_InfoColor* info1, const LodePNG_InfoColor* info2) -{ - return info1->colorType == info2->colorType - && info1->bitDepth == info2->bitDepth; /*palette and color key not compared*/ -} - - -static void LodePNG_InfoPng_init(LodePNG_InfoPng* info) -{ - info->width = info->height = 0; - LodePNG_InfoColor_init(&info->color); - info->interlaceMethod = 0; - info->compressionMethod = 0; - info->filterMethod = 0; -} - -static void LodePNG_InfoPng_cleanup(LodePNG_InfoPng* info) -{ - LodePNG_InfoColor_cleanup(&info->color); -} - -static unsigned LodePNG_InfoPng_copy(LodePNG_InfoPng* dest, const LodePNG_InfoPng* source) -{ - unsigned error = 0; - LodePNG_InfoPng_cleanup(dest); - *dest = *source; - LodePNG_InfoColor_init(&dest->color); - error = LodePNG_InfoColor_copy(&dest->color, &source->color); if(error) return error; - return error; -} - -static unsigned LodePNG_InfoColor_copy(LodePNG_InfoColor* dest, const LodePNG_InfoColor* source) -{ - size_t i; - LodePNG_InfoColor_cleanup(dest); - *dest = *source; - dest->palette = (unsigned char*)malloc(source->palettesize * 4); - if(!dest->palette && source->palettesize) return 9935; - for(i = 0; i < source->palettesize * 4; i++) dest->palette[i] = source->palette[i]; - return 0; -} - -static void LodePNG_InfoRaw_init(LodePNG_InfoRaw* info) -{ - LodePNG_InfoColor_init(&info->color); -} - -static void LodePNG_InfoRaw_cleanup(LodePNG_InfoRaw* info) -{ - LodePNG_InfoColor_cleanup(&info->color); -} - -static unsigned LodePNG_InfoRaw_copy(LodePNG_InfoRaw* dest, const LodePNG_InfoRaw* source) -{ - unsigned error = 0; - LodePNG_InfoRaw_cleanup(dest); - *dest = *source; - LodePNG_InfoColor_init(&dest->color); - error = LodePNG_InfoColor_copy(&dest->color, &source->color); - return error; -} - -/* ////////////////////////////////////////////////////////////////////////// */ - -/* -converts from any color type to 24-bit or 32-bit (later maybe more supported). return value = LodePNG error code -the out buffer must have (w * h * bpp + 7) / 8 bytes, where bpp is the bits per pixel of the output color type (LodePNG_InfoColor_getBpp) -for < 8 bpp images, there may _not_ be padding bits at the end of scanlines. -*/ -static unsigned LodePNG_convert(unsigned char* out, const unsigned char* in, LodePNG_InfoColor* infoOut, LodePNG_InfoColor* infoIn, unsigned w, unsigned h) -{ - const size_t numpixels = w * h; /*amount of pixels*/ - const unsigned OUT_BYTES = LodePNG_InfoColor_getBpp(infoOut) / 8; /*bytes per pixel in the output image*/ - const unsigned OUT_ALPHA = LodePNG_InfoColor_isAlphaType(infoOut); /*use 8-bit alpha channel*/ - size_t i, c, bp = 0; /*bitpointer, used by less-than-8-bit color types*/ - - /*cases where in and out already have the same format*/ - if(LodePNG_InfoColor_equal(infoIn, infoOut)) - { - size_t i, size = (w * h * LodePNG_InfoColor_getBpp(infoIn) + 7) / 8; - for(i = 0; i < size; i++) out[i] = in[i]; - return 0; - } - - if((infoOut->colorType == 2 || infoOut->colorType == 6) && infoOut->bitDepth == 8) - { - if(infoIn->bitDepth == 8) - { - switch(infoIn->colorType) - { - case 0: /*greyscale color*/ - for(i = 0; i < numpixels; i++) - { - if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255; - out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[i]; - if(OUT_ALPHA && infoIn->key_defined && in[i] == infoIn->key_r) out[OUT_BYTES * i + 3] = 0; - } - break; - case 2: /*RGB color*/ - for(i = 0; i < numpixels; i++) - { - if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255; - for(c = 0; c < 3; c++) out[OUT_BYTES * i + c] = in[3 * i + c]; - if(OUT_ALPHA && infoIn->key_defined == 1 && in[3 * i + 0] == infoIn->key_r && in[3 * i + 1] == infoIn->key_g && in[3 * i + 2] == infoIn->key_b) out[OUT_BYTES * i + 3] = 0; - } - break; - case 3: /*indexed color (palette)*/ - for(i = 0; i < numpixels; i++) - { - if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255; - if(in[i] >= infoIn->palettesize) return 46; - for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = infoIn->palette[4 * in[i] + c]; /*get rgb colors from the palette*/ - } - break; - case 4: /*greyscale with alpha*/ - for(i = 0; i < numpixels; i++) - { - out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[2 * i + 0]; - if(OUT_ALPHA) out[OUT_BYTES * i + 3] = in[2 * i + 1]; - } - break; - case 6: /*RGB with alpha*/ - for(i = 0; i < numpixels; i++) - { - for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = in[4 * i + c]; - } - break; - default: break; - } - } - else if(infoIn->bitDepth == 16) - { - switch(infoIn->colorType) - { - case 0: /*greyscale color*/ - for(i = 0; i < numpixels; i++) - { - if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255; - out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[2 * i]; - if(OUT_ALPHA && infoIn->key_defined && 256U * in[i] + in[i + 1] == infoIn->key_r) out[OUT_BYTES * i + 3] = 0; - } - break; - case 2: /*RGB color*/ - for(i = 0; i < numpixels; i++) - { - if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255; - for(c = 0; c < 3; c++) out[OUT_BYTES * i + c] = in[6 * i + 2 * c]; - if(OUT_ALPHA && infoIn->key_defined && 256U * in[6 * i + 0] + in[6 * i + 1] == infoIn->key_r && 256U * in[6 * i + 2] + in[6 * i + 3] == infoIn->key_g && 256U * in[6 * i + 4] + in[6 * i + 5] == infoIn->key_b) out[OUT_BYTES * i + 3] = 0; - } - break; - case 4: /*greyscale with alpha*/ - for(i = 0; i < numpixels; i++) - { - out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[4 * i]; /*most significant byte*/ - if(OUT_ALPHA) out[OUT_BYTES * i + 3] = in[4 * i + 2]; - } - break; - case 6: /*RGB with alpha*/ - for(i = 0; i < numpixels; i++) - { - for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = in[8 * i + 2 * c]; - } - break; - default: break; - } - } - else /*infoIn->bitDepth is less than 8 bit per channel*/ - { - switch(infoIn->colorType) - { - case 0: /*greyscale color*/ - for(i = 0; i < numpixels; i++) - { - unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth); - if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255; - if(OUT_ALPHA && infoIn->key_defined && value && ((1U << infoIn->bitDepth) - 1U) == infoIn->key_r && ((1U << infoIn->bitDepth) - 1U)) out[OUT_BYTES * i + 3] = 0; - value = (value * 255) / ((1 << infoIn->bitDepth) - 1); /*scale value from 0 to 255*/ - out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = (unsigned char)(value); - } - break; - case 3: /*indexed color (palette)*/ - for(i = 0; i < numpixels; i++) - { - unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth); - if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255; - if(value >= infoIn->palettesize) return 47; - for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = infoIn->palette[4 * value + c]; /*get rgb colors from the palette*/ - } - break; - default: break; - } - } - } - else if(LodePNG_InfoColor_isGreyscaleType(infoOut) && infoOut->bitDepth == 8) /*conversion from greyscale to greyscale*/ - { - if(!LodePNG_InfoColor_isGreyscaleType(infoIn)) return 62; - if(infoIn->bitDepth == 8) - { - switch(infoIn->colorType) - { - case 0: /*greyscale color*/ - for(i = 0; i < numpixels; i++) - { - if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255; - out[OUT_BYTES * i] = in[i]; - if(OUT_ALPHA && infoIn->key_defined && in[i] == infoIn->key_r) out[OUT_BYTES * i + 1] = 0; - } - break; - case 4: /*greyscale with alpha*/ - for(i = 0; i < numpixels; i++) - { - out[OUT_BYTES * i + 0] = in[2 * i + 0]; - if(OUT_ALPHA) out[OUT_BYTES * i + 1] = in[2 * i + 1]; - } - break; - default: return 31; - } - } - else if(infoIn->bitDepth == 16) - { - switch(infoIn->colorType) - { - case 0: /*greyscale color*/ - for(i = 0; i < numpixels; i++) - { - if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255; - out[OUT_BYTES * i] = in[2 * i]; - if(OUT_ALPHA && infoIn->key_defined && 256U * in[i] + in[i + 1] == infoIn->key_r) out[OUT_BYTES * i + 1] = 0; - } - break; - case 4: /*greyscale with alpha*/ - for(i = 0; i < numpixels; i++) - { - out[OUT_BYTES * i] = in[4 * i]; /*most significant byte*/ - if(OUT_ALPHA) out[OUT_BYTES * i + 1] = in[4 * i + 2]; /*most significant byte*/ - } - break; - default: return 31; - } - } - else /*infoIn->bitDepth is less than 8 bit per channel*/ - { - if(infoIn->colorType != 0) return 31; /*colorType 0 is the only greyscale type with < 8 bits per channel*/ - for(i = 0; i < numpixels; i++) - { - unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth); - if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255; - if(OUT_ALPHA && infoIn->key_defined && value && ((1U << infoIn->bitDepth) - 1U) == infoIn->key_r && ((1U << infoIn->bitDepth) - 1U)) out[OUT_BYTES * i + 1] = 0; - value = (value * 255) / ((1 << infoIn->bitDepth) - 1); /*scale value from 0 to 255*/ - out[OUT_BYTES * i] = (unsigned char)(value); - } - } - } - else return 59; - - return 0; -} - -/*Path predictor, used by PNG filter type 4*/ -static int paethPredictor(int a, int b, int c) -{ - int p = a + b - c; - int pa = p > a ? p - a : a - p; - int pb = p > b ? p - b : b - p; - int pc = p > c ? p - c : c - p; - - if(pa <= pb && pa <= pc) return a; - else if(pb <= pc) return b; - else return c; -} - -/*shared values used by multiple Adam7 related functions*/ - -static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/ -static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/ -static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/ -static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/ - -static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp) -{ - /*the passstart values have 8 values: the 8th one actually indicates the byte after the end of the 7th (= last) pass*/ - unsigned i; - - /*calculate width and height in pixels of each pass*/ - for(i = 0; i < 7; i++) - { - passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i]; - passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i]; - if(passw[i] == 0) passh[i] = 0; - if(passh[i] == 0) passw[i] = 0; - } - - filter_passstart[0] = padded_passstart[0] = passstart[0] = 0; - for(i = 0; i < 7; i++) - { - filter_passstart[i + 1] = filter_passstart[i] + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0); /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/ - padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8); /*bits padded if needed to fill full byte at end of each scanline*/ - passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8; /*only padded at end of reduced image*/ - } -} - - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / PNG Encoder / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/*chunkName must be string of 4 characters*/ -static unsigned addChunk(ucvector* out, const char* chunkName, const unsigned char* data, size_t length) -{ - unsigned error = LodePNG_create_chunk(&out->data, &out->size, (unsigned)length, chunkName, data); - if(error) return error; - out->allocsize = out->size; /*fix the allocsize again*/ - return 0; -} - -static void writeSignature(ucvector* out) -{ - /*8 bytes PNG signature*/ - ucvector_push_back(out, 137); - ucvector_push_back(out, 80); - ucvector_push_back(out, 78); - ucvector_push_back(out, 71); - ucvector_push_back(out, 13); - ucvector_push_back(out, 10); - ucvector_push_back(out, 26); - ucvector_push_back(out, 10); -} - -static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, unsigned bitDepth, unsigned colorType, unsigned interlaceMethod) -{ - unsigned error = 0; - ucvector header; - ucvector_init(&header); - - LodePNG_add32bitInt(&header, w); /*width*/ - LodePNG_add32bitInt(&header, h); /*height*/ - ucvector_push_back(&header, (unsigned char)bitDepth); /*bit depth*/ - ucvector_push_back(&header, (unsigned char)colorType); /*color type*/ - ucvector_push_back(&header, 0); /*compression method*/ - ucvector_push_back(&header, 0); /*filter method*/ - ucvector_push_back(&header, interlaceMethod); /*interlace method*/ - - error = addChunk(out, "IHDR", header.data, header.size); - ucvector_cleanup(&header); - - return error; -} - -static unsigned addChunk_PLTE(ucvector* out, const LodePNG_InfoColor* info) -{ - unsigned error = 0; - size_t i; - ucvector PLTE; - ucvector_init(&PLTE); - for(i = 0; i < info->palettesize * 4; i++) if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]); /*add all channels except alpha channel*/ - error = addChunk(out, "PLTE", PLTE.data, PLTE.size); - ucvector_cleanup(&PLTE); - - return error; -} - -static unsigned addChunk_tRNS(ucvector* out, const LodePNG_InfoColor* info) -{ - unsigned error = 0; - size_t i; - ucvector tRNS; - ucvector_init(&tRNS); - if(info->colorType == 3) - { - for(i = 0; i < info->palettesize; i++) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); /*add only alpha channel*/ - } - else if(info->colorType == 0) - { - if(info->key_defined) - { - ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256)); - } - } - else if(info->colorType == 2) - { - if(info->key_defined) - { - ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_g / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_g % 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_b / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_b % 256)); - } - } - - error = addChunk(out, "tRNS", tRNS.data, tRNS.size); - ucvector_cleanup(&tRNS); - - return error; -} - -static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize, LodeZlib_DeflateSettings* zlibsettings) -{ - ucvector zlibdata; - unsigned error = 0; - - /*compress with the Zlib compressor*/ - ucvector_init(&zlibdata); - error = LodePNG_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings); - if(!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size); - ucvector_cleanup(&zlibdata); - - return error; -} - -static unsigned addChunk_IEND(ucvector* out) -{ - unsigned error = 0; - error = addChunk(out, "IEND", 0, 0); - return error; -} - -static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline, size_t length, size_t bytewidth, unsigned char filterType) -{ - size_t i; - switch(filterType) - { - case 0: - for(i = 0; i < length; i++) out[i] = scanline[i]; - break; - case 1: - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth]; - break; - case 2: - if(prevline) for(i = 0; i < length; i++) out[i] = scanline[i] - prevline[i]; - else for(i = 0; i < length; i++) out[i] = scanline[i]; - break; - case 3: - if(prevline) - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i] - prevline[i] / 2; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2); - } - else - { - for(i = 0; i < length; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth] / 2; - } - break; - case 4: - if(prevline) - { - for(i = 0; i < bytewidth; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(0, prevline[i], 0)); - for(i = bytewidth; i < length; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth])); - } - else - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(scanline[i - bytewidth], 0, 0)); - } - break; - default: return; /*unexisting filter type given*/ - } -} - -static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, const LodePNG_InfoColor* info) -{ - /* - For PNG filter method 0 - out must be a buffer with as size: h + (w * h * bpp + 7) / 8, because there are the scanlines with 1 extra byte per scanline - - There is a nice heuristic described here: http://www.cs.toronto.edu/~cosmin/pngtech/optipng.html. It says: - * If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e. use fixed filtering, with the filter None). - * (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply all five filters and select the filter that produces the smallest sum of absolute values per row. - - Here the above method is used mostly. Note though that it appears to be better to use the adaptive filtering on the plasma 8-bit palette example, but that image isn't the best reference for palette images in general. - */ - - unsigned bpp = LodePNG_InfoColor_getBpp(info); - size_t linebytes = (w * bpp + 7) / 8; /*the width of a scanline in bytes, not including the filter type*/ - size_t bytewidth = (bpp + 7) / 8; /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ - const unsigned char* prevline = 0; - unsigned x, y; - unsigned heuristic; - unsigned error = 0; - - if(bpp == 0) return 31; /*invalid color type*/ - - /*choose heuristic as described above*/ - if(info->colorType == 3 || info->bitDepth < 8) heuristic = 0; - else heuristic = 1; - - if(heuristic == 0) /*None filtertype for everything*/ - { - for(y = 0; y < h; y++) - { - size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ - size_t inindex = linebytes * y; - const unsigned TYPE = 0; - out[outindex] = TYPE; /*filter type byte*/ - filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, TYPE); - prevline = &in[inindex]; - } - } - else if(heuristic == 1) /*adaptive filtering*/ - { - size_t sum[5]; - ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ - size_t smallest = 0; - unsigned type, bestType = 0; - - for(type = 0; type < 5; type++) ucvector_init(&attempt[type]); - for(type = 0; type < 5; type++) - { - if(!ucvector_resize(&attempt[type], linebytes)) { error = 9949; break; } - } - - if(!error) - { - for(y = 0; y < h; y++) - { - /*try the 5 filter types*/ - for(type = 0; type < 5; type++) - { - filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); - - /*calculate the sum of the result*/ - sum[type] = 0; - for(x = 0; x < attempt[type].size; x+=3) sum[type] += attempt[type].data[x]; /*note that not all pixels are checked to speed this up while still having probably the best choice*/ - - /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ - if(type == 0 || sum[type] < smallest) - { - bestType = type; - smallest = sum[type]; - } - } - - prevline = &in[y * linebytes]; - - /*now fill the out values*/ - out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; - } - } - - for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); - } - - return error; -} - -static void addPaddingBits(unsigned char* out, const unsigned char* in, size_t olinebits, size_t ilinebits, unsigned h) -{ - /*The opposite of the removePaddingBits function - olinebits must be >= ilinebits*/ - unsigned y; - size_t diff = olinebits - ilinebits; - size_t obp = 0, ibp = 0; /*bit pointers*/ - for(y = 0; y < h; y++) - { - size_t x; - for(x = 0; x < ilinebits; x++) - { - unsigned char bit = readBitFromReversedStream(&ibp, in); - setBitOfReversedStream(&obp, out, bit); - } - /*obp += diff; --> no, fill in some value in the padding bits too, to avoid "Use of uninitialised value of size ###" warning from valgrind*/ - for(x = 0; x < diff; x++) setBitOfReversedStream(&obp, out, 0); - } -} - -static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) -{ - /*Note: this function works on image buffers WITHOUT padding bits at end of scanlines with non-multiple-of-8 bit amounts, only between reduced images is padding*/ - unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; - unsigned i; - - Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); - - if(bpp >= 8) - { - for(i = 0; i < 7; i++) - { - unsigned x, y, b; - size_t bytewidth = bpp / 8; - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) - { - size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; - size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth; - for(b = 0; b < bytewidth; b++) - { - out[pixeloutstart + b] = in[pixelinstart + b]; - } - } - } - } - else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ - { - for(i = 0; i < 7; i++) - { - unsigned x, y, b; - unsigned ilinebits = bpp * passw[i]; - unsigned olinebits = bpp * w; - size_t obp, ibp; /*bit pointers (for out and in buffer)*/ - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) - { - ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; - obp = (8 * passstart[i]) + (y * ilinebits + x * bpp); - for(b = 0; b < bpp; b++) - { - unsigned char bit = readBitFromReversedStream(&ibp, in); - setBitOfReversedStream(&obp, out, bit); - } - } - } - } -} - -/*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image*/ -static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in, const LodePNG_InfoPng* infoPng) /*return value is error*/ -{ - /* - This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps: - *) if no Adam7: 1) add padding bits (= possible extra bits per scanline if bpp < 8) 2) filter - *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter - */ - unsigned bpp = LodePNG_InfoColor_getBpp(&infoPng->color); - unsigned w = infoPng->width; - unsigned h = infoPng->height; - unsigned error = 0; - - if(infoPng->interlaceMethod == 0) - { - *outsize = h + (h * ((w * bpp + 7) / 8)); /*image size plus an extra byte per scanline + possible padding bits*/ - *out = (unsigned char*)malloc(*outsize); - if(!(*out) && (*outsize)) error = 9950; - - if(!error) - { - if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) /*non multiple of 8 bits per scanline, padding bits needed per scanline*/ - { - ucvector padded; - ucvector_init(&padded); - if(!ucvector_resize(&padded, h * ((w * bpp + 7) / 8))) error = 9951; - if(!error) - { - addPaddingBits(padded.data, in, ((w * bpp + 7) / 8) * 8, w * bpp, h); - error = filter(*out, padded.data, w, h, &infoPng->color); - } - ucvector_cleanup(&padded); - } - else error = filter(*out, in, w, h, &infoPng->color); /*we can immediately filter into the out buffer, no other steps needed*/ - } - } - else /*interlaceMethod is 1 (Adam7)*/ - { - unsigned char* adam7 = (unsigned char*)malloc((h * w * bpp + 7) / 8); - if(!adam7 && ((h * w * bpp + 7) / 8)) error = 9952; /*malloc failed*/ - - while(!error) /*not a real while loop, used to break out to cleanup to avoid a goto*/ - { - unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; - unsigned i; - - Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); - - *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/ - *out = (unsigned char*)malloc(*outsize); - if(!(*out) && (*outsize)) { error = 9953; break; } - - Adam7_interlace(adam7, in, w, h, bpp); - - for(i = 0; i < 7; i++) - { - if(bpp < 8) - { - ucvector padded; - ucvector_init(&padded); - if(!ucvector_resize(&padded, h * ((w * bpp + 7) / 8))) error = 9954; - if(!error) - { - addPaddingBits(&padded.data[padded_passstart[i]], &adam7[passstart[i]], ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]); - error = filter(&(*out)[filter_passstart[i]], &padded.data[padded_passstart[i]], passw[i], passh[i], &infoPng->color); - } - - ucvector_cleanup(&padded); - } - else - { - error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], passw[i], passh[i], &infoPng->color); - } - } - - break; - } - - free(adam7); - } - - return error; -} - -/*palette must have 4 * palettesize bytes allocated*/ -static unsigned isPaletteFullyOpaque(const unsigned char* palette, size_t palettesize) /*palette given in format RGBARGBARGBARGBA...*/ -{ - size_t i; - for(i = 0; i < palettesize; i++) - { - if(palette[4 * i + 3] != 255) return 0; - } - return 1; -} - -/*this function checks if the input image given by the user has no transparent pixels*/ -static unsigned isFullyOpaque(const unsigned char* image, unsigned w, unsigned h, const LodePNG_InfoColor* info) -{ - /*TODO: When the user specified a color key for the input image, then this function must also check for pixels that are the same as the color key and treat those as transparent.*/ - - unsigned i, numpixels = w * h; - if(info->colorType == 6) - { - if(info->bitDepth == 8) - { - for(i = 0; i < numpixels; i++) if(image[i * 4 + 3] != 255) return 0; - } - else - { - for(i = 0; i < numpixels; i++) if(image[i * 8 + 6] != 255 || image[i * 8 + 7] != 255) return 0; - } - return 1; /*no single pixel with alpha channel other than 255 found*/ - } - else if(info->colorType == 4) - { - if(info->bitDepth == 8) - { - for(i = 0; i < numpixels; i++) if(image[i * 2 + 1] != 255) return 0; - } - else - { - for(i = 0; i < numpixels; i++) if(image[i * 4 + 2] != 255 || image[i * 4 + 3] != 255) return 0; - } - return 1; /*no single pixel with alpha channel other than 255 found*/ - } - else if(info->colorType == 3) - { - /*when there's a palette, we could check every pixel for translucency, but much quicker is to just check the palette*/ - return(isPaletteFullyOpaque(info->palette, info->palettesize)); - } - - return 0; /*color type that isn't supported by this function yet, so assume there is transparency to be safe*/ -} - -void LodePNG_encode(LodePNG_Encoder* encoder, unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) -{ - LodePNG_InfoPng info; - ucvector outv; - unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/ - size_t datasize = 0; - - /*provide some proper output values if error will happen*/ - *out = 0; - *outsize = 0; - encoder->error = 0; - - info = encoder->infoPng; /*UNSAFE copy to avoid having to cleanup! but we will only change primitive parameters, and not invoke the cleanup function nor touch the palette's buffer so we use it safely*/ - info.width = w; - info.height = h; - - if(encoder->settings.autoLeaveOutAlphaChannel && isFullyOpaque(image, w, h, &encoder->infoRaw.color)) - { - /*go to a color type without alpha channel*/ - if(info.color.colorType == 6) info.color.colorType = 2; - else if(info.color.colorType == 4) info.color.colorType = 0; - } - - if(encoder->settings.zlibsettings.windowSize > 32768) { encoder->error = 60; return; } /*error: windowsize larger than allowed*/ - if(encoder->settings.zlibsettings.btype > 2) { encoder->error = 61; return; } /*error: unexisting btype*/ - if(encoder->infoPng.interlaceMethod > 1) { encoder->error = 71; return; } /*error: unexisting interlace mode*/ - if((encoder->error = checkColorValidity(info.color.colorType, info.color.bitDepth))) return; /*error: unexisting color type given*/ - if((encoder->error = checkColorValidity(encoder->infoRaw.color.colorType, encoder->infoRaw.color.bitDepth))) return; /*error: unexisting color type given*/ - - if(!LodePNG_InfoColor_equal(&encoder->infoRaw.color, &info.color)) - { - unsigned char* converted; - size_t size = (w * h * LodePNG_InfoColor_getBpp(&info.color) + 7) / 8; - - if((info.color.colorType != 6 && info.color.colorType != 2) || (info.color.bitDepth != 8)) { encoder->error = 59; return; } /*for the output image, only these types are supported*/ - converted = (unsigned char*)malloc(size); - if(!converted && size) encoder->error = 9955; /*error: malloc failed*/ - if(!encoder->error) encoder->error = LodePNG_convert(converted, image, &info.color, &encoder->infoRaw.color, w, h); - if(!encoder->error) preProcessScanlines(&data, &datasize, converted, &info);/*filter(data.data, converted.data, w, h, LodePNG_InfoColor_getBpp(&info.color));*/ - free(converted); - } - else preProcessScanlines(&data, &datasize, image, &info);/*filter(data.data, image, w, h, LodePNG_InfoColor_getBpp(&info.color));*/ - - ucvector_init(&outv); - while(!encoder->error) /*not really a while loop, this is only used to break out if an error happens to avoid goto's to do the ucvector cleanup*/ - { - /*write signature and chunks*/ - writeSignature(&outv); - /*IHDR*/ - addChunk_IHDR(&outv, w, h, info.color.bitDepth, info.color.colorType, info.interlaceMethod); - /*PLTE*/ - if(info.color.colorType == 3) - { - if(info.color.palettesize == 0 || info.color.palettesize > 256) { encoder->error = 68; break; } - addChunk_PLTE(&outv, &info.color); - } - if(encoder->settings.force_palette && (info.color.colorType == 2 || info.color.colorType == 6)) - { - if(info.color.palettesize == 0 || info.color.palettesize > 256) { encoder->error = 68; break; } - addChunk_PLTE(&outv, &info.color); - } - /*tRNS*/ - if(info.color.colorType == 3 && !isPaletteFullyOpaque(info.color.palette, info.color.palettesize)) addChunk_tRNS(&outv, &info.color); - if((info.color.colorType == 0 || info.color.colorType == 2) && info.color.key_defined) addChunk_tRNS(&outv, &info.color); - /*IDAT (multiple IDAT chunks must be consecutive)*/ - encoder->error = addChunk_IDAT(&outv, data, datasize, &encoder->settings.zlibsettings); - if(encoder->error) break; - /*IEND*/ - addChunk_IEND(&outv); - - break; /*this isn't really a while loop; no error happened so break out now!*/ - } - - free(data); - /*instead of cleaning the vector up, give it to the output*/ - *out = outv.data; - *outsize = outv.size; -} - -void LodePNG_EncodeSettings_init(LodePNG_EncodeSettings* settings) -{ - LodeZlib_DeflateSettings_init(&settings->zlibsettings); - settings->autoLeaveOutAlphaChannel = 1; - settings->force_palette = 0; -} - -void LodePNG_Encoder_init(LodePNG_Encoder* encoder) -{ - LodePNG_EncodeSettings_init(&encoder->settings); - LodePNG_InfoPng_init(&encoder->infoPng); - LodePNG_InfoRaw_init(&encoder->infoRaw); - encoder->error = 1; -} - -void LodePNG_Encoder_cleanup(LodePNG_Encoder* encoder) -{ - LodePNG_InfoPng_cleanup(&encoder->infoPng); - LodePNG_InfoRaw_cleanup(&encoder->infoRaw); -} - -void LodePNG_Encoder_copy(LodePNG_Encoder* dest, const LodePNG_Encoder* source) -{ - LodePNG_Encoder_cleanup(dest); - *dest = *source; - LodePNG_InfoPng_init(&dest->infoPng); - LodePNG_InfoRaw_init(&dest->infoRaw); - dest->error = LodePNG_InfoPng_copy(&dest->infoPng, &source->infoPng); if(dest->error) return; - dest->error = LodePNG_InfoRaw_copy(&dest->infoRaw, &source->infoRaw); if(dest->error) return; -} - -/* ////////////////////////////////////////////////////////////////////////// */ -/* / File IO / */ -/* ////////////////////////////////////////////////////////////////////////// */ - -/*write given buffer to the file, overwriting the file, it doesn't append to it.*/ -unsigned LodePNG_saveFile(const unsigned char* buffer, size_t buffersize, const char* filename) -{ - FILE* file; - file = portable_fopen(filename, "wb" ); - if(!file) return 79; - fwrite((char*)buffer , 1 , buffersize, file); - fclose(file); - return 0; -} - diff --git a/src/lodepng.h b/src/lodepng.h deleted file mode 100644 index fb079cc..0000000 --- a/src/lodepng.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -LodePNG version 20080927 - -Copyright (c) 2005-2008 Lode Vandevenne - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -/** Minified version of LodePNG, with only the encoder code */ - -#ifndef LODEPNG_H -#define LODEPNG_H - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -/* ////////////////////////////////////////////////////////////////////////// */ -/* LodeFlate & LodeZlib Setting structs */ -/* ////////////////////////////////////////////////////////////////////////// */ - - -typedef struct LodeZlib_DeflateSettings /*deflate = compress*/ -{ - /*LZ77 related settings*/ - unsigned btype; /*the block type for LZ*/ - unsigned useLZ77; /*whether or not to use LZ77*/ - unsigned windowSize; /*the maximum is 32768*/ -} LodeZlib_DeflateSettings; - - -/* ////////////////////////////////////////////////////////////////////////// */ -/* LodePNG */ -/* ////////////////////////////////////////////////////////////////////////// */ - -typedef struct LodePNG_InfoColor /*info about the color type of an image*/ -{ - /*header (IHDR)*/ - unsigned colorType; /*color type*/ - unsigned bitDepth; /*bits per sample*/ - - /*palette (PLTE)*/ - unsigned char* palette; /*palette in RGBARGBA... order*/ - size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/ - - /*transparent color key (tRNS)*/ - unsigned key_defined; /*is a transparent color key given?*/ - unsigned key_r; /*red component of color key*/ - unsigned key_g; /*green component of color key*/ - unsigned key_b; /*blue component of color key*/ -} LodePNG_InfoColor; - -typedef struct LodePNG_InfoPng /*information about the PNG image, except pixels and sometimes except width and height*/ -{ - /*header (IHDR), palette (PLTE) and transparency (tRNS)*/ - unsigned width; /*width of the image in pixels (ignored by encoder, but filled in by decoder)*/ - unsigned height; /*height of the image in pixels (ignored by encoder, but filled in by decoder)*/ - unsigned compressionMethod; /*compression method of the original file*/ - unsigned filterMethod; /*filter method of the original file*/ - unsigned interlaceMethod; /*interlace method of the original file*/ - LodePNG_InfoColor color; /*color type and bits, palette, transparency*/ -} LodePNG_InfoPng; - -typedef struct LodePNG_InfoRaw /*contains user-chosen information about the raw image data, which is independent of the PNG image*/ -{ - LodePNG_InfoColor color; -} LodePNG_InfoRaw; - -unsigned LodePNG_InfoColor_addPalette(LodePNG_InfoColor* info, unsigned char r, unsigned char g, unsigned char b, unsigned char a); /*add 1 color to the palette*/ - -typedef struct LodePNG_EncodeSettings -{ - LodeZlib_DeflateSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ - - unsigned autoLeaveOutAlphaChannel; /*automatically use color type without alpha instead of given one, if given image is opaque*/ - unsigned force_palette; /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). If colortype is 3, PLTE is _always_ created.*/ -} LodePNG_EncodeSettings; - -void LodePNG_EncodeSettings_init(LodePNG_EncodeSettings* settings); - -typedef struct LodePNG_Encoder -{ - LodePNG_EncodeSettings settings; - LodePNG_InfoPng infoPng; /*the info specified by the user may not be changed by the encoder. The encoder will try to generate a PNG close to the given info.*/ - LodePNG_InfoRaw infoRaw; /*put the properties of the input raw image in here*/ - unsigned error; -} LodePNG_Encoder; - -void LodePNG_Encoder_init(LodePNG_Encoder* encoder); -void LodePNG_Encoder_cleanup(LodePNG_Encoder* encoder); -void LodePNG_Encoder_copy(LodePNG_Encoder* dest, const LodePNG_Encoder* source); - -/*This function allocates the out buffer and stores the size in *outsize.*/ -void LodePNG_encode(LodePNG_Encoder* encoder, unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h); - -/*free functions allowing to load and save a file from/to harddisk*/ -/*This function allocates the out buffer and stores the size in *outsize.*/ -//unsigned LodePNG_loadFile(unsigned char** out, size_t* outsize, const char* filename); -unsigned LodePNG_saveFile(const unsigned char* buffer, size_t buffersize, const char* filename); - -#endif - diff --git a/src/logos.cpp b/src/logos.cpp deleted file mode 100644 index e9e0905..0000000 --- a/src/logos.cpp +++ /dev/null @@ -1,1985 +0,0 @@ -/****************************************************************************** - * - * - * - * 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 - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ - -#include <stdio.h> - -#include <qfile.h> -#include <qdir.h> - -// Stripped version of FreeSans.ttf part of FreeFonts package, -// see http://www.nongnu.org/freefont for more info -unsigned char FreeSans_ttf[] = { - 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x80, 0x00, 0x03, 0x00, 0x70, - 0x47, 0x44, 0x45, 0x46, 0x01, 0x0a, 0x00, 0xe3, 0x00, 0x00, 0x48, 0x28, - 0x00, 0x00, 0x00, 0x2a, 0x47, 0x50, 0x4f, 0x53, 0x9d, 0x1a, 0x99, 0x8a, - 0x00, 0x00, 0x49, 0x50, 0x00, 0x00, 0x10, 0x42, 0x47, 0x53, 0x55, 0x42, - 0xa8, 0x85, 0x92, 0x0c, 0x00, 0x00, 0x48, 0x54, 0x00, 0x00, 0x00, 0xfc, - 0x4f, 0x53, 0x2f, 0x32, 0x67, 0x3f, 0xcf, 0x10, 0x00, 0x00, 0x01, 0x78, - 0x00, 0x00, 0x00, 0x56, 0x63, 0x6d, 0x61, 0x70, 0xe6, 0xd7, 0x91, 0x3d, - 0x00, 0x00, 0x04, 0xec, 0x00, 0x00, 0x01, 0x8a, 0x63, 0x76, 0x74, 0x20, - 0x00, 0x21, 0x02, 0x79, 0x00, 0x00, 0x06, 0x78, 0x00, 0x00, 0x00, 0x04, - 0x67, 0x61, 0x73, 0x70, 0xff, 0xff, 0x00, 0x03, 0x00, 0x00, 0x48, 0x20, - 0x00, 0x00, 0x00, 0x08, 0x67, 0x6c, 0x79, 0x66, 0xb3, 0x58, 0xaf, 0x41, - 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x37, 0xca, 0x68, 0x65, 0x61, 0x64, - 0xe7, 0x18, 0xbe, 0xac, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x36, - 0x68, 0x68, 0x65, 0x61, 0x10, 0xbb, 0x06, 0xf2, 0x00, 0x00, 0x01, 0x34, - 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, 0x74, 0x78, 0x55, 0x0d, 0x49, 0xe2, - 0x00, 0x00, 0x01, 0xd0, 0x00, 0x00, 0x03, 0x1a, 0x6c, 0x6f, 0x63, 0x61, - 0x1f, 0xdd, 0x2c, 0xb6, 0x00, 0x00, 0x06, 0x7c, 0x00, 0x00, 0x01, 0x94, - 0x6d, 0x61, 0x78, 0x70, 0x01, 0x16, 0x00, 0xb3, 0x00, 0x00, 0x01, 0x58, - 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x85, 0x1f, 0xf3, 0x73, - 0x00, 0x00, 0x3f, 0xdc, 0x00, 0x00, 0x06, 0x69, 0x70, 0x6f, 0x73, 0x74, - 0x46, 0xf5, 0x10, 0xd8, 0x00, 0x00, 0x46, 0x48, 0x00, 0x00, 0x01, 0xd6, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xc2, 0x8f, 0x00, 0x8a, 0xba, 0xad, - 0x5f, 0x0f, 0x3c, 0xf5, 0x00, 0x0b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x44, 0xd8, 0x89, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x44, 0xd8, 0x89, - 0xff, 0xd3, 0xfe, 0x3d, 0x07, 0x9c, 0x07, 0xd1, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x07, 0xd1, 0xfe, 0x3d, 0x01, 0x78, 0x08, 0x1e, 0xff, 0xd3, 0xff, 0xd2, - 0x07, 0x9c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x01, 0x00, 0x00, - 0x00, 0xc9, 0x00, 0x66, 0x00, 0x05, 0x00, 0x49, 0x00, 0x04, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x03, 0x87, 0x01, 0x90, 0x00, 0x05, - 0x00, 0x00, 0x05, 0x33, 0x05, 0x99, 0x00, 0x00, 0x03, 0xd7, 0x05, 0x33, - 0x05, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x02, 0x12, 0x00, 0x00, - 0x02, 0x0b, 0x05, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, - 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x50, 0x66, 0x45, 0x64, 0x00, 0x40, 0x00, 0x0d, 0x02, 0xdc, - 0x06, 0x66, 0xfe, 0x66, 0x00, 0x00, 0x07, 0xd1, 0x01, 0xc3, 0x80, 0x02, - 0x00, 0xbf, 0xdf, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x89, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0xb2, 0x00, 0x00, - 0x02, 0x39, 0x00, 0x00, 0x02, 0x39, 0x00, 0xfe, 0x02, 0xd7, 0x00, 0x6a, - 0x04, 0x72, 0x00, 0x1d, 0x04, 0x72, 0x00, 0x44, 0x07, 0x1c, 0x00, 0x3b, - 0x05, 0x56, 0x00, 0x6a, 0x01, 0x87, 0x00, 0x62, 0x02, 0xa9, 0x00, 0x96, - 0x02, 0xa9, 0x00, 0x4e, 0x03, 0x1c, 0x00, 0x52, 0x04, 0xac, 0x00, 0x66, - 0x02, 0x39, 0x00, 0xb2, 0x02, 0xa9, 0x00, 0x5e, 0x02, 0x39, 0x00, 0xb2, - 0x02, 0x39, 0xff, 0xf0, 0x04, 0x72, 0x00, 0x58, 0x04, 0x72, 0x00, 0xd1, - 0x04, 0x72, 0x00, 0x46, 0x04, 0x72, 0x00, 0x42, 0x04, 0x72, 0x00, 0x39, - 0x04, 0x72, 0x00, 0x48, 0x04, 0x72, 0x00, 0x58, 0x04, 0x72, 0x00, 0x5e, - 0x04, 0x72, 0x00, 0x4c, 0x04, 0x72, 0x00, 0x4e, 0x02, 0x39, 0x00, 0xe1, - 0x02, 0x39, 0x00, 0xe1, 0x04, 0xac, 0x00, 0x5c, 0x04, 0xac, 0x00, 0x66, - 0x04, 0xac, 0x00, 0x66, 0x04, 0x72, 0x00, 0x9e, 0x08, 0x1e, 0x00, 0x46, - 0x05, 0x56, 0x00, 0x23, 0x05, 0x56, 0x00, 0xa2, 0x05, 0xc6, 0x00, 0x62, - 0x05, 0xc6, 0x00, 0xb6, 0x05, 0x56, 0x00, 0xb8, 0x04, 0xe3, 0x00, 0xb8, - 0x06, 0x39, 0x00, 0x5a, 0x05, 0xc6, 0x00, 0xaa, 0x02, 0x39, 0x00, 0xcd, - 0x04, 0x00, 0x00, 0x23, 0x05, 0x56, 0x00, 0xa2, 0x04, 0x72, 0x00, 0xa4, - 0x06, 0xa9, 0x00, 0x9a, 0x05, 0xc6, 0x00, 0x9c, 0x06, 0x39, 0x00, 0x4e, - 0x05, 0x56, 0x00, 0xba, 0x06, 0x39, 0x00, 0x4e, 0x05, 0xc6, 0x00, 0xbe, - 0x05, 0x56, 0x00, 0x62, 0x04, 0xe3, 0x00, 0x2b, 0x05, 0xc6, 0x00, 0xae, - 0x05, 0x56, 0x00, 0x3d, 0x07, 0x8d, 0x00, 0x2d, 0x05, 0x56, 0x00, 0x2d, - 0x05, 0x56, 0x00, 0x1b, 0x04, 0xe3, 0x00, 0x39, 0x02, 0x39, 0x00, 0x83, - 0x02, 0x39, 0xff, 0xf0, 0x02, 0x39, 0x00, 0x2f, 0x03, 0xc0, 0x00, 0x5a, - 0x04, 0x72, 0xff, 0xd3, 0x02, 0xa9, 0x00, 0x2d, 0x04, 0x72, 0x00, 0x56, - 0x04, 0x72, 0x00, 0x6f, 0x04, 0x00, 0x00, 0x3f, 0x04, 0x72, 0x00, 0x35, - 0x04, 0x72, 0x00, 0x52, 0x02, 0x39, 0x00, 0x25, 0x04, 0x72, 0x00, 0x3b, - 0x04, 0x72, 0x00, 0x8f, 0x01, 0xc6, 0x00, 0x87, 0x01, 0xc6, 0xff, 0xdb, - 0x04, 0x00, 0x00, 0x77, 0x01, 0xc6, 0x00, 0x8b, 0x06, 0xa9, 0x00, 0x8f, - 0x04, 0x72, 0x00, 0x8f, 0x04, 0x72, 0x00, 0x4a, 0x04, 0x72, 0x00, 0x6f, - 0x04, 0x72, 0x00, 0x35, 0x02, 0xa9, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x46, - 0x02, 0x39, 0x00, 0x1d, 0x04, 0x72, 0x00, 0x85, 0x04, 0x00, 0x00, 0x14, - 0x05, 0xc6, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x23, 0x04, 0x00, 0x00, 0x29, - 0x04, 0x00, 0x00, 0x3f, 0x02, 0xac, 0x00, 0x58, 0x02, 0x14, 0x00, 0xcd, - 0x02, 0xac, 0x00, 0x3b, 0x04, 0xac, 0x00, 0x9a, 0x02, 0x39, 0x00, 0x00, - 0x02, 0x39, 0x00, 0xfa, 0x04, 0x72, 0x00, 0x6a, 0x04, 0x72, 0x00, 0x35, - 0x04, 0x72, 0x00, 0x89, 0x04, 0x72, 0x00, 0x17, 0x02, 0x14, 0x00, 0xcd, - 0x04, 0x72, 0x00, 0x58, 0x02, 0xa9, 0x00, 0x3d, 0x05, 0xe5, 0xff, 0xe5, - 0x02, 0xf5, 0x00, 0x4c, 0x04, 0x72, 0x00, 0xc9, 0x04, 0xac, 0x00, 0x52, - 0x02, 0xa9, 0x00, 0x5e, 0x05, 0xe5, 0xff, 0xe5, 0x02, 0xa9, 0x00, 0x39, - 0x04, 0xd9, 0x01, 0x35, 0x04, 0xac, 0x00, 0x66, 0x02, 0xce, 0x00, 0x27, - 0x02, 0xce, 0x00, 0x21, 0x02, 0xa9, 0x00, 0xbc, 0x04, 0x72, 0x00, 0x85, - 0x04, 0x4b, 0x00, 0x62, 0x02, 0x39, 0x00, 0xb2, 0x02, 0xa9, 0x00, 0x50, - 0x02, 0xce, 0x00, 0x7d, 0x02, 0xeb, 0x00, 0x52, 0x04, 0x72, 0x00, 0xc9, - 0x06, 0xf3, 0x00, 0x7d, 0x06, 0xf3, 0x00, 0x7d, 0x06, 0xf3, 0x00, 0x21, - 0x04, 0x72, 0x00, 0xc5, 0x05, 0x56, 0x00, 0x23, 0x05, 0x56, 0x00, 0x23, - 0x05, 0x56, 0x00, 0x23, 0x05, 0x56, 0x00, 0x23, 0x05, 0x56, 0x00, 0x23, - 0x05, 0x56, 0x00, 0x23, 0x08, 0x00, 0x00, 0x17, 0x05, 0xc6, 0x00, 0x62, - 0x05, 0x56, 0x00, 0xb8, 0x05, 0x56, 0x00, 0xb8, 0x05, 0x56, 0x00, 0xb8, - 0x05, 0x56, 0x00, 0xb8, 0x02, 0x39, 0x00, 0xcd, 0x02, 0x39, 0x00, 0xcd, - 0x02, 0x39, 0x00, 0xcd, 0x02, 0x39, 0x00, 0x1c, 0x05, 0xc6, 0x00, 0x29, - 0x05, 0xc6, 0x00, 0x9c, 0x06, 0x39, 0x00, 0x4e, 0x06, 0x39, 0x00, 0x4e, - 0x06, 0x39, 0x00, 0x4e, 0x06, 0x39, 0x00, 0x4e, 0x06, 0x39, 0x00, 0x4e, - 0x04, 0xac, 0x00, 0xc3, 0x06, 0x39, 0x00, 0x3d, 0x05, 0xc6, 0x00, 0xae, - 0x05, 0xc6, 0x00, 0xae, 0x05, 0xc6, 0x00, 0xae, 0x05, 0xc6, 0x00, 0xae, - 0x05, 0x56, 0x00, 0x1b, 0x05, 0x53, 0x00, 0xba, 0x04, 0xe3, 0x00, 0x89, - 0x04, 0x72, 0x00, 0x56, 0x04, 0x72, 0x00, 0x56, 0x04, 0x72, 0x00, 0x56, - 0x04, 0x72, 0x00, 0x56, 0x04, 0x72, 0x00, 0x56, 0x04, 0x72, 0x00, 0x56, - 0x07, 0x1c, 0x00, 0x46, 0x04, 0x00, 0x00, 0x3f, 0x04, 0x72, 0x00, 0x52, - 0x04, 0x72, 0x00, 0x52, 0x04, 0x72, 0x00, 0x52, 0x04, 0x72, 0x00, 0x52, - 0x02, 0x39, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, - 0x02, 0x39, 0x00, 0x06, 0x04, 0x72, 0x00, 0x4a, 0x04, 0x72, 0x00, 0x8f, - 0x04, 0x72, 0x00, 0x4a, 0x04, 0x72, 0x00, 0x4a, 0x04, 0x72, 0x00, 0x4a, - 0x04, 0x72, 0x00, 0x4a, 0x04, 0x72, 0x00, 0x4a, 0x04, 0xac, 0x00, 0x66, - 0x04, 0xe3, 0x00, 0x25, 0x04, 0x72, 0x00, 0x85, 0x04, 0x72, 0x00, 0x85, - 0x04, 0x72, 0x00, 0x85, 0x04, 0x72, 0x00, 0x85, 0x04, 0x00, 0x00, 0x29, - 0x04, 0x70, 0x00, 0x6f, 0x04, 0x00, 0x00, 0x29, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x03, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x16, - 0x00, 0x10, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, - 0x00, 0x7e, 0x00, 0xff, 0x01, 0x31, 0x02, 0xc6, 0x02, 0xcb, 0x02, 0xda, - 0x02, 0xdc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0e, - 0x00, 0x20, 0x00, 0xa0, 0x01, 0x31, 0x02, 0xc6, 0x02, 0xca, 0x02, 0xda, - 0x02, 0xdc, 0xff, 0xff, 0x00, 0x01, 0xff, 0xf6, 0xff, 0xf5, 0xff, 0xe4, - 0xff, 0xc3, 0xff, 0x92, 0xfd, 0xfe, 0xfd, 0xfb, 0xfd, 0xed, 0xfd, 0xec, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x93, 0xb3, 0x00, 0x00, 0x00, - 0x00, 0xa0, 0xc0, 0x02, 0x00, 0xa1, 0xc1, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x7f, 0x7c, 0x81, 0x76, 0x75, 0x69, 0x70, 0x9a, - 0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, - 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, - 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, - 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, - 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, - 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, - 0x62, 0x00, 0x87, 0x88, 0x8a, 0x8c, 0x94, 0x99, 0x9f, 0xa4, 0xa3, 0xa5, - 0xa7, 0xa6, 0xa8, 0xaa, 0xac, 0xab, 0xad, 0xae, 0xb0, 0xaf, 0xb1, 0xb2, - 0xb4, 0xb6, 0xb5, 0xb7, 0xb9, 0xb8, 0xbd, 0xbc, 0xbe, 0xbf, 0x00, 0x73, - 0x65, 0x66, 0x6a, 0x00, 0x79, 0xa2, 0x71, 0x6c, 0x00, 0x77, 0x6b, 0x00, - 0x89, 0x9b, 0x00, 0x74, 0x00, 0x00, 0x68, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x6d, 0x7d, 0x00, 0xa9, 0xbb, 0x82, 0x64, 0x6f, 0x00, 0x00, 0x00, - 0x00, 0x6e, 0x7e, 0x00, 0x63, 0x83, 0x86, 0x98, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xba, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x85, 0x8d, 0x84, 0x8e, 0x8b, - 0x90, 0x91, 0x92, 0x8f, 0x96, 0x97, 0x00, 0x95, 0x9d, 0x9e, 0x9c, 0x00, - 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x21, 0x02, 0x79, 0x00, 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, - 0x00, 0x16, 0x00, 0x16, 0x00, 0x2e, 0x00, 0x48, 0x00, 0x7f, 0x00, 0xe5, - 0x01, 0x5d, 0x01, 0xc9, 0x01, 0xd9, 0x01, 0xfd, 0x02, 0x20, 0x02, 0x3e, - 0x02, 0x56, 0x02, 0x6c, 0x02, 0x79, 0x02, 0x85, 0x02, 0x93, 0x02, 0xc3, - 0x02, 0xda, 0x03, 0x16, 0x03, 0x63, 0x03, 0x80, 0x03, 0xbe, 0x04, 0x0c, - 0x04, 0x2a, 0x04, 0x84, 0x04, 0xd4, 0x04, 0xe6, 0x05, 0x03, 0x05, 0x17, - 0x05, 0x2b, 0x05, 0x3f, 0x05, 0x7d, 0x06, 0x10, 0x06, 0x2c, 0x06, 0x6d, - 0x06, 0xaa, 0x06, 0xd3, 0x06, 0xec, 0x07, 0x02, 0x07, 0x50, 0x07, 0x68, - 0x07, 0x76, 0x07, 0x99, 0x07, 0xb5, 0x07, 0xc6, 0x07, 0xe2, 0x07, 0xfa, - 0x08, 0x47, 0x08, 0x72, 0x08, 0xc7, 0x09, 0x08, 0x09, 0x57, 0x09, 0x6a, - 0x09, 0x8f, 0x09, 0xa2, 0x09, 0xc1, 0x09, 0xe0, 0x09, 0xf7, 0x0a, 0x0e, - 0x0a, 0x20, 0x0a, 0x2f, 0x0a, 0x41, 0x0a, 0x54, 0x0a, 0x61, 0x0a, 0x70, - 0x0a, 0xd1, 0x0b, 0x0b, 0x0b, 0x3e, 0x0b, 0x79, 0x0b, 0xba, 0x0b, 0xdc, - 0x0c, 0x34, 0x0c, 0x5b, 0x0c, 0x6f, 0x0c, 0x91, 0x0c, 0xae, 0x0c, 0xbc, - 0x0c, 0xfb, 0x0d, 0x21, 0x0d, 0x55, 0x0d, 0x8c, 0x0d, 0xc6, 0x0d, 0xe3, - 0x0e, 0x2f, 0x0e, 0x55, 0x0e, 0x7b, 0x0e, 0x8e, 0x0e, 0xaa, 0x0e, 0xc9, - 0x0e, 0xec, 0x0f, 0x03, 0x0f, 0x43, 0x0f, 0x50, 0x0f, 0x8f, 0x0f, 0xc0, - 0x0f, 0xc8, 0x0f, 0xd2, 0x10, 0x13, 0x10, 0x73, 0x10, 0xbe, 0x10, 0xe8, - 0x10, 0xfb, 0x11, 0x77, 0x11, 0x89, 0x12, 0x03, 0x12, 0x5c, 0x12, 0x78, - 0x12, 0x88, 0x12, 0x95, 0x13, 0x17, 0x13, 0x24, 0x13, 0x55, 0x13, 0x74, - 0x13, 0xb1, 0x13, 0xf8, 0x14, 0x06, 0x14, 0x38, 0x14, 0x5a, 0x14, 0x68, - 0x14, 0x99, 0x14, 0xb1, 0x14, 0xea, 0x15, 0x07, 0x15, 0x3d, 0x15, 0x94, - 0x15, 0xf9, 0x16, 0x03, 0x16, 0x0f, 0x16, 0x1b, 0x16, 0x27, 0x16, 0x33, - 0x16, 0x3f, 0x16, 0x4b, 0x16, 0x72, 0x16, 0xdc, 0x16, 0xe8, 0x16, 0xf4, - 0x17, 0x00, 0x17, 0x0c, 0x17, 0x18, 0x17, 0x24, 0x17, 0x30, 0x17, 0x3c, - 0x17, 0x70, 0x17, 0x7c, 0x17, 0x88, 0x17, 0x94, 0x17, 0xa0, 0x17, 0xac, - 0x17, 0xb8, 0x17, 0xd9, 0x18, 0x2e, 0x18, 0x3a, 0x18, 0x46, 0x18, 0x52, - 0x18, 0x5e, 0x18, 0x6a, 0x18, 0x95, 0x18, 0xdf, 0x18, 0xeb, 0x18, 0xf7, - 0x19, 0x03, 0x19, 0x0f, 0x19, 0x1b, 0x19, 0x27, 0x19, 0xa9, 0x1a, 0x05, - 0x1a, 0x11, 0x1a, 0x1d, 0x1a, 0x29, 0x1a, 0x35, 0x1a, 0x40, 0x1a, 0x4b, - 0x1a, 0x56, 0x1a, 0x61, 0x1a, 0xb5, 0x1a, 0xc1, 0x1a, 0xcd, 0x1a, 0xd9, - 0x1a, 0xe5, 0x1a, 0xf1, 0x1a, 0xfd, 0x1b, 0x17, 0x1b, 0x60, 0x1b, 0x6c, - 0x1b, 0x78, 0x1b, 0x84, 0x1b, 0x90, 0x1b, 0x9c, 0x1b, 0xd7, 0x1b, 0xe3, - 0x1b, 0xe3, 0x1b, 0xe3, 0x1b, 0xe3, 0x1b, 0xe3, 0x1b, 0xe3, 0x1b, 0xe3, - 0x00, 0x02, 0x00, 0x89, 0x00, 0x00, 0x03, 0xbe, 0x07, 0xd1, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x05, 0x21, 0x11, 0x21, - 0x03, 0xbe, 0xfc, 0xcb, 0x02, 0xac, 0xfd, 0xdd, 0x02, 0x23, 0x07, 0xd1, - 0xf8, 0x2f, 0x07, 0xd1, 0x89, 0xf9, 0x41, 0x00, 0x00, 0x02, 0x00, 0xfe, - 0x00, 0x00, 0x01, 0xaa, 0x05, 0xd5, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, - 0x01, 0x11, 0x03, 0x23, 0x03, 0x11, 0x13, 0x15, 0x23, 0x35, 0x01, 0xaa, - 0x2d, 0x50, 0x2d, 0xaa, 0xac, 0x05, 0xd5, 0xfd, 0x4c, 0xfe, 0x37, 0x01, - 0xc9, 0x02, 0xb4, 0xfb, 0x00, 0xd5, 0xd5, 0x00, 0x00, 0x02, 0x00, 0x6a, - 0x03, 0xb6, 0x02, 0x71, 0x05, 0xac, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, - 0x13, 0x33, 0x15, 0x03, 0x23, 0x03, 0x25, 0x33, 0x15, 0x03, 0x23, 0x03, - 0x6a, 0xbf, 0x37, 0x50, 0x38, 0x01, 0x48, 0xbf, 0x38, 0x50, 0x37, 0x05, - 0xac, 0xe3, 0xfe, 0xed, 0x01, 0x13, 0xe3, 0xe3, 0xfe, 0xed, 0x01, 0x13, - 0x00, 0x02, 0x00, 0x1d, 0xff, 0xd7, 0x04, 0x56, 0x05, 0x93, 0x00, 0x1b, - 0x00, 0x1f, 0x00, 0x00, 0x01, 0x03, 0x33, 0x15, 0x23, 0x03, 0x33, 0x15, - 0x23, 0x03, 0x23, 0x13, 0x23, 0x03, 0x23, 0x13, 0x23, 0x35, 0x33, 0x13, - 0x23, 0x35, 0x33, 0x13, 0x33, 0x03, 0x21, 0x13, 0x03, 0x23, 0x03, 0x21, - 0x03, 0xe1, 0x49, 0xbe, 0xd9, 0x40, 0xd7, 0xef, 0x50, 0x9c, 0x4e, 0xfe, - 0x50, 0x9b, 0x4e, 0xcf, 0xe9, 0x40, 0xde, 0xf8, 0x4a, 0x9c, 0x4a, 0x01, - 0x00, 0x48, 0x63, 0xfe, 0x41, 0x01, 0x00, 0x05, 0x93, 0xfe, 0x6f, 0x8b, - 0xfe, 0x9b, 0x8b, 0xfe, 0x50, 0x01, 0xb0, 0xfe, 0x50, 0x01, 0xb0, 0x8b, - 0x01, 0x65, 0x8b, 0x01, 0x91, 0xfe, 0x6f, 0x01, 0x91, 0xfd, 0xe4, 0xfe, - 0x9b, 0x00, 0x00, 0x03, 0x00, 0x44, 0xfe, 0xfe, 0x04, 0x25, 0x06, 0x29, - 0x00, 0x2f, 0x00, 0x38, 0x00, 0x41, 0x00, 0x00, 0x01, 0x14, 0x07, 0x06, - 0x07, 0x15, 0x23, 0x35, 0x24, 0x27, 0x26, 0x3d, 0x01, 0x33, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x17, 0x11, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x35, 0x33, 0x15, 0x16, 0x17, 0x16, 0x15, 0x23, 0x26, - 0x27, 0x26, 0x27, 0x11, 0x17, 0x16, 0x17, 0x16, 0x01, 0x11, 0x06, 0x07, - 0x06, 0x15, 0x14, 0x17, 0x16, 0x13, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x27, 0x04, 0x25, 0xb0, 0x6a, 0xa1, 0x78, 0xfe, 0xec, 0x66, 0x34, - 0xa1, 0x0b, 0x12, 0x2e, 0x9b, 0x13, 0x14, 0xab, 0x3e, 0x0c, 0x0d, 0x92, - 0xcc, 0x54, 0x74, 0x78, 0xdb, 0x69, 0x4a, 0xa2, 0x02, 0x59, 0x3c, 0x55, - 0x8a, 0xde, 0x3c, 0x17, 0xfd, 0xcd, 0xa9, 0x33, 0x12, 0xbe, 0x16, 0x92, - 0xbd, 0x3e, 0x18, 0x41, 0x3c, 0x96, 0x01, 0x8f, 0xf9, 0x74, 0x46, 0x0b, - 0xd3, 0xd3, 0x12, 0xbd, 0x61, 0x86, 0x23, 0x77, 0x31, 0x7d, 0x20, 0x04, - 0x03, 0x02, 0x2d, 0x33, 0x27, 0x08, 0x09, 0x68, 0xc3, 0xf8, 0x68, 0x2b, - 0x0e, 0x6f, 0x6f, 0x10, 0x8f, 0x64, 0x90, 0x85, 0x49, 0x32, 0x04, 0xfe, - 0x02, 0x27, 0x49, 0xa1, 0x3f, 0x01, 0x60, 0x01, 0xec, 0x17, 0x7a, 0x2d, - 0x36, 0xa6, 0x43, 0x08, 0xfd, 0x1a, 0x17, 0x89, 0x36, 0x43, 0x69, 0x39, - 0x33, 0x2d, 0x00, 0x05, 0x00, 0x3b, 0xff, 0xd7, 0x06, 0xdf, 0x05, 0xac, - 0x00, 0x15, 0x00, 0x25, 0x00, 0x29, 0x00, 0x3f, 0x00, 0x4f, 0x00, 0x00, - 0x01, 0x32, 0x17, 0x16, 0x17, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x34, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x17, 0x22, - 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x25, 0x33, 0x01, 0x23, 0x01, 0x32, 0x17, 0x16, 0x17, 0x14, - 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x34, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x17, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x01, 0x98, 0x91, 0x65, - 0x65, 0x03, 0x60, 0x60, 0x87, 0x0b, 0x0a, 0x8d, 0x66, 0x65, 0x07, 0x62, - 0x60, 0x88, 0x0a, 0x09, 0x5e, 0x3e, 0x33, 0x48, 0x3b, 0x4e, 0x5c, 0x3f, - 0x33, 0x48, 0x3a, 0x02, 0xf9, 0x87, 0xfc, 0xd7, 0x87, 0x03, 0xcb, 0x93, - 0x65, 0x64, 0x02, 0x61, 0x5f, 0x85, 0x0b, 0x0c, 0x8c, 0x65, 0x65, 0x08, - 0x61, 0x60, 0x88, 0x0a, 0x09, 0x5e, 0x3e, 0x33, 0x48, 0x3b, 0x4e, 0x5d, - 0x3f, 0x33, 0x4a, 0x39, 0x05, 0x7b, 0x65, 0x6b, 0x92, 0x89, 0x65, 0x64, - 0x08, 0x01, 0x62, 0x61, 0x8a, 0x09, 0x09, 0x8b, 0x66, 0x65, 0x07, 0x01, - 0x8f, 0x47, 0x3b, 0x4d, 0x5d, 0x3f, 0x33, 0x46, 0x3a, 0x4d, 0x61, 0x3e, - 0x32, 0xc0, 0xfa, 0x2b, 0x02, 0xbc, 0x65, 0x69, 0x92, 0x88, 0x65, 0x63, - 0x09, 0x01, 0x62, 0x60, 0x89, 0x0a, 0x09, 0x8b, 0x65, 0x64, 0x07, 0x01, - 0x8f, 0x47, 0x3a, 0x4c, 0x5e, 0x3e, 0x33, 0x47, 0x39, 0x4b, 0x62, 0x3e, - 0x31, 0x00, 0x00, 0x03, 0x00, 0x6a, 0xff, 0xd1, 0x05, 0x19, 0x05, 0xac, - 0x00, 0x29, 0x00, 0x39, 0x00, 0x46, 0x00, 0x00, 0x25, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x01, 0x36, 0x37, 0x34, 0x3d, 0x01, 0x33, 0x14, 0x07, 0x06, 0x07, - 0x13, 0x23, 0x01, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, - 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x09, 0x01, 0x06, 0x07, 0x06, 0x15, - 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x03, 0xba, 0x4a, 0x27, 0x8e, - 0xad, 0xc8, 0x74, 0x68, 0x49, 0x46, 0xbd, 0x7c, 0x1c, 0x0e, 0x65, 0x66, - 0x94, 0x9c, 0x5e, 0x53, 0x4b, 0x3f, 0x90, 0x01, 0x10, 0x3a, 0x06, 0xa4, - 0x6d, 0x05, 0x05, 0xfa, 0xe0, 0xfe, 0x0f, 0x8f, 0x29, 0x1b, 0x46, 0x2f, - 0x3e, 0x67, 0x2f, 0x1a, 0x1f, 0x1b, 0x01, 0x66, 0xfe, 0xb8, 0xa9, 0x31, - 0x1f, 0x53, 0x4e, 0x6b, 0x75, 0x6e, 0x27, 0xa0, 0x49, 0x1d, 0x69, 0x7b, - 0x6e, 0xae, 0x8e, 0x5d, 0x5c, 0x6e, 0x9c, 0x56, 0x2b, 0x30, 0x86, 0x5d, - 0x5f, 0x65, 0x59, 0x84, 0x79, 0x53, 0x46, 0x52, 0xfe, 0xb2, 0x68, 0x73, - 0x09, 0x08, 0x08, 0xb4, 0xb3, 0x08, 0x08, 0xfe, 0xcb, 0x03, 0x73, 0x5a, - 0x40, 0x2b, 0x37, 0x5a, 0x32, 0x22, 0x4c, 0x2b, 0x39, 0x3a, 0x32, 0x2c, - 0xfd, 0x44, 0x01, 0x99, 0x6c, 0x57, 0x36, 0x42, 0x70, 0x4d, 0x49, 0x5b, - 0x1f, 0x00, 0x00, 0x01, 0x00, 0x62, 0x03, 0xb6, 0x01, 0x23, 0x05, 0xac, - 0x00, 0x05, 0x00, 0x00, 0x13, 0x33, 0x15, 0x03, 0x23, 0x03, 0x62, 0xc1, - 0x37, 0x52, 0x38, 0x05, 0xac, 0xe3, 0xfe, 0xed, 0x01, 0x13, 0x00, 0x01, - 0x00, 0x96, 0xfe, 0x4e, 0x02, 0x54, 0x05, 0xd5, 0x00, 0x11, 0x00, 0x00, - 0x01, 0x33, 0x02, 0x03, 0x06, 0x15, 0x10, 0x13, 0x16, 0x17, 0x23, 0x26, - 0x03, 0x26, 0x35, 0x10, 0x13, 0x36, 0x01, 0xe3, 0x71, 0xd3, 0x36, 0x10, - 0xb3, 0x2e, 0x38, 0x71, 0xbe, 0x58, 0x37, 0x89, 0x51, 0x05, 0xd5, 0xfe, - 0xab, 0xfe, 0x77, 0x74, 0x71, 0xfe, 0x76, 0xfe, 0x82, 0x61, 0x5b, 0xfa, - 0x01, 0x47, 0xc9, 0xba, 0x01, 0x31, 0x01, 0x3f, 0xbd, 0x00, 0x00, 0x01, - 0x00, 0x4e, 0xfe, 0x4e, 0x02, 0x0c, 0x05, 0xd5, 0x00, 0x11, 0x00, 0x00, - 0x13, 0x23, 0x12, 0x13, 0x36, 0x35, 0x10, 0x03, 0x26, 0x27, 0x33, 0x16, - 0x13, 0x16, 0x15, 0x10, 0x03, 0x06, 0xbe, 0x70, 0xd2, 0x36, 0x10, 0xb4, - 0x2d, 0x37, 0x70, 0xbf, 0x59, 0x36, 0x89, 0x52, 0xfe, 0x4e, 0x01, 0x53, - 0x01, 0x8a, 0x74, 0x71, 0x01, 0x8e, 0x01, 0x7e, 0x60, 0x59, 0xfa, 0xfe, - 0xb9, 0xca, 0xba, 0xfe, 0xd1, 0xfe, 0xc2, 0xbe, 0x00, 0x01, 0x00, 0x52, - 0x03, 0x87, 0x02, 0xbe, 0x05, 0xd5, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x33, - 0x07, 0x37, 0x17, 0x07, 0x17, 0x07, 0x27, 0x07, 0x27, 0x37, 0x27, 0x37, - 0x17, 0x01, 0x48, 0x81, 0x0b, 0xda, 0x26, 0xdd, 0x90, 0x69, 0x7f, 0x81, - 0x66, 0x8d, 0xdd, 0x27, 0xd9, 0x05, 0xd5, 0xe5, 0x4d, 0x78, 0x3e, 0xb6, - 0x4a, 0xbf, 0xbf, 0x4a, 0xb6, 0x3e, 0x78, 0x4d, 0x00, 0x01, 0x00, 0x66, - 0xff, 0xec, 0x04, 0x46, 0x03, 0xcb, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x15, - 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x04, 0x46, - 0xfe, 0x58, 0x90, 0xfe, 0x58, 0x01, 0xa8, 0x90, 0x02, 0x23, 0x90, 0xfe, - 0x59, 0x01, 0xa7, 0x90, 0x01, 0xa8, 0xfe, 0x58, 0x00, 0x01, 0x00, 0xb2, - 0xfe, 0xd3, 0x01, 0x89, 0x00, 0xd5, 0x00, 0x0b, 0x00, 0x00, 0x37, 0x33, - 0x15, 0x10, 0x23, 0x35, 0x36, 0x37, 0x36, 0x3d, 0x01, 0x23, 0xb2, 0xd7, - 0xd7, 0x4c, 0x19, 0x16, 0x7b, 0xd5, 0xf6, 0xfe, 0xf4, 0x4e, 0x03, 0x2c, - 0x27, 0x64, 0x25, 0x00, 0x00, 0x01, 0x00, 0x5e, 0x01, 0xec, 0x02, 0x46, - 0x02, 0x7f, 0x00, 0x03, 0x00, 0x00, 0x01, 0x15, 0x21, 0x35, 0x02, 0x46, - 0xfe, 0x18, 0x02, 0x7f, 0x93, 0x93, 0x00, 0x01, 0x00, 0xb2, 0x00, 0x00, - 0x01, 0x87, 0x00, 0xd5, 0x00, 0x03, 0x00, 0x00, 0x25, 0x15, 0x23, 0x35, - 0x01, 0x87, 0xd5, 0xd5, 0xd5, 0xd5, 0x00, 0x01, 0xff, 0xf0, 0xff, 0xd7, - 0x02, 0x46, 0x05, 0xd5, 0x00, 0x03, 0x00, 0x00, 0x01, 0x33, 0x01, 0x23, - 0x01, 0xd5, 0x71, 0xfe, 0x1a, 0x70, 0x05, 0xd5, 0xfa, 0x02, 0x00, 0x02, - 0x00, 0x58, 0xff, 0xd1, 0x04, 0x0e, 0x05, 0xac, 0x00, 0x0f, 0x00, 0x19, - 0x00, 0x00, 0x13, 0x10, 0x25, 0x36, 0x33, 0x20, 0x13, 0x16, 0x15, 0x10, - 0x07, 0x06, 0x23, 0x20, 0x03, 0x26, 0x01, 0x20, 0x11, 0x10, 0x21, 0x32, - 0x13, 0x36, 0x35, 0x10, 0x58, 0x01, 0x24, 0x52, 0x65, 0x01, 0x7d, 0x4c, - 0x12, 0xd1, 0x6c, 0x9e, 0xfe, 0xcf, 0x6f, 0x3b, 0x01, 0xdb, 0xfe, 0xdd, - 0x01, 0x1f, 0xc7, 0x3f, 0x21, 0x02, 0xbe, 0x02, 0x43, 0x86, 0x25, 0xfe, - 0x10, 0x77, 0x93, 0xfe, 0x27, 0xae, 0x5a, 0x01, 0x44, 0xab, 0x03, 0x4c, - 0xfd, 0xb0, 0xfd, 0xaa, 0x01, 0x06, 0x86, 0xd1, 0x02, 0x49, 0x00, 0x01, - 0x00, 0xd1, 0x00, 0x00, 0x02, 0xc7, 0x05, 0xac, 0x00, 0x0a, 0x00, 0x00, - 0x01, 0x21, 0x35, 0x3e, 0x01, 0x37, 0x36, 0x37, 0x33, 0x11, 0x23, 0x02, - 0x12, 0xfe, 0xbf, 0xb3, 0x7f, 0x24, 0x12, 0x17, 0x77, 0xb5, 0x04, 0x0a, - 0x81, 0x16, 0x43, 0x50, 0x29, 0x4f, 0xfa, 0x54, 0x00, 0x01, 0x00, 0x46, - 0x00, 0x00, 0x04, 0x17, 0x05, 0xac, 0x00, 0x23, 0x00, 0x00, 0x13, 0x12, - 0x21, 0x32, 0x17, 0x16, 0x15, 0x10, 0x05, 0x06, 0x0f, 0x01, 0x06, 0x07, - 0x06, 0x07, 0x21, 0x15, 0x21, 0x36, 0x37, 0x36, 0x37, 0x36, 0x3f, 0x01, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x20, 0x03, 0x06, 0x07, 0x66, 0x0f, - 0x01, 0xd1, 0xd0, 0x82, 0x7f, 0xfe, 0xec, 0x0f, 0x11, 0xcc, 0xa8, 0x37, - 0x1d, 0x0b, 0x02, 0xfc, 0xfc, 0x3a, 0x0b, 0x48, 0x45, 0xa7, 0x28, 0x30, - 0xbd, 0xc4, 0x5b, 0x51, 0x73, 0xfe, 0xfe, 0x1f, 0x02, 0x01, 0x03, 0xb4, - 0x01, 0xf8, 0x79, 0x76, 0xbb, 0xff, 0x00, 0xa4, 0x09, 0x09, 0x6f, 0x5a, - 0x5e, 0x31, 0x42, 0xb2, 0xe0, 0x7d, 0x78, 0x6b, 0x1a, 0x1b, 0x6a, 0x70, - 0xaf, 0x7c, 0x4f, 0x45, 0xfe, 0xcd, 0x12, 0x15, 0x00, 0x01, 0x00, 0x42, - 0xff, 0xd1, 0x04, 0x0c, 0x05, 0xac, 0x00, 0x32, 0x00, 0x00, 0x01, 0x22, - 0x07, 0x06, 0x07, 0x23, 0x12, 0x25, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x20, 0x03, - 0x26, 0x27, 0x33, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x23, 0x07, 0x23, 0x35, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x02, 0x29, 0xd2, 0x32, 0x0f, 0x02, 0xb4, 0x07, 0x01, 0x1a, 0x4a, - 0x5c, 0xf3, 0x75, 0x52, 0xca, 0xa3, 0x34, 0x1e, 0x8e, 0x85, 0xd8, 0xfe, - 0xa3, 0x5f, 0x1c, 0x07, 0xb4, 0x0d, 0xa0, 0x38, 0x4c, 0xb3, 0x4d, 0x2d, - 0xff, 0x16, 0x18, 0x4c, 0x16, 0xc4, 0x4b, 0x55, 0x6b, 0x3e, 0x05, 0x0e, - 0xb3, 0x36, 0x4e, 0x01, 0x70, 0x50, 0x15, 0x8f, 0x65, 0x9b, 0xde, 0x4f, - 0x38, 0x77, 0x45, 0x66, 0xd6, 0x7c, 0x73, 0x01, 0x18, 0x52, 0x6b, 0xea, - 0x38, 0x13, 0x77, 0x46, 0x65, 0xf3, 0x14, 0x02, 0x02, 0x99, 0x03, 0x2b, - 0x32, 0x84, 0x93, 0x40, 0x24, 0x00, 0x00, 0x02, 0x00, 0x39, 0x00, 0x00, - 0x04, 0x29, 0x05, 0xac, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x21, - 0x35, 0x01, 0x33, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0x19, 0x01, 0x01, - 0x02, 0x9e, 0xfd, 0x9b, 0x02, 0x94, 0x85, 0xd7, 0xd7, 0xb4, 0xfe, 0x39, - 0x01, 0x5c, 0xbf, 0x03, 0x91, 0xfc, 0x52, 0xa2, 0xfe, 0xa4, 0x01, 0xfe, - 0x02, 0x7b, 0xfd, 0x85, 0x00, 0x01, 0x00, 0x48, 0xff, 0xd1, 0x04, 0x1b, - 0x05, 0xac, 0x00, 0x26, 0x00, 0x00, 0x01, 0x15, 0x21, 0x03, 0x36, 0x37, - 0x32, 0x17, 0x16, 0x17, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x20, 0x03, - 0x26, 0x27, 0x33, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x23, 0x13, 0x03, 0xcf, 0xfd, - 0xa4, 0x3a, 0x7c, 0x91, 0xcf, 0x82, 0x83, 0x01, 0x85, 0x82, 0xce, 0x0e, - 0x0f, 0xfe, 0x71, 0x4d, 0x02, 0x03, 0xb4, 0x3d, 0xd5, 0x0b, 0x0c, 0xb0, - 0x54, 0x39, 0x74, 0x51, 0x78, 0x71, 0x4d, 0x24, 0x28, 0xa6, 0x6c, 0x05, - 0xac, 0xb2, 0xfe, 0x6a, 0x56, 0x02, 0x84, 0x86, 0xd9, 0xe0, 0x91, 0x8c, - 0x0a, 0x01, 0x01, 0x7b, 0x06, 0x12, 0xe7, 0x0b, 0x01, 0x7c, 0x55, 0x7f, - 0xbe, 0x5d, 0x41, 0x3b, 0x1d, 0x2f, 0x03, 0x16, 0x00, 0x02, 0x00, 0x58, - 0xff, 0xd1, 0x04, 0x1b, 0x05, 0xac, 0x00, 0x22, 0x00, 0x32, 0x00, 0x00, - 0x13, 0x10, 0x25, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x23, 0x26, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, - 0x14, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x20, 0x03, 0x26, 0x25, - 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x58, 0x01, 0x17, 0x69, 0x88, 0xc8, 0x72, 0x4d, 0x15, - 0xb4, 0x20, 0x76, 0x2b, 0x33, 0xc2, 0x51, 0x30, 0x01, 0x76, 0xd8, 0xbf, - 0x7c, 0x7e, 0x04, 0x7d, 0x7b, 0xc1, 0x11, 0x12, 0xfe, 0x42, 0x26, 0x03, - 0x01, 0xf0, 0x93, 0x55, 0x45, 0x5d, 0x53, 0x77, 0x81, 0x53, 0x4c, 0x6f, - 0x46, 0x02, 0x96, 0x02, 0x33, 0xa5, 0x3e, 0x8d, 0x5f, 0x8f, 0x9b, 0x2f, - 0x11, 0xdb, 0x84, 0xc8, 0xa2, 0x7c, 0x7e, 0xc7, 0x06, 0x06, 0xcd, 0x89, - 0x86, 0x0c, 0x01, 0x02, 0x56, 0x35, 0x8b, 0x65, 0x52, 0x7a, 0x93, 0x5e, - 0x54, 0x60, 0x59, 0x82, 0xb4, 0x53, 0x34, 0x00, 0x00, 0x01, 0x00, 0x5e, - 0x00, 0x00, 0x04, 0x29, 0x05, 0xac, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x15, - 0x00, 0x03, 0x06, 0x07, 0x23, 0x12, 0x13, 0x12, 0x13, 0x21, 0x35, 0x04, - 0x29, 0xfe, 0xa5, 0x94, 0x3c, 0x23, 0xc0, 0x56, 0x8b, 0x7e, 0xf5, 0xfc, - 0xef, 0x05, 0xac, 0x98, 0xfe, 0x33, 0xfe, 0x3c, 0xba, 0xc9, 0x01, 0x7a, - 0x01, 0x20, 0x01, 0x03, 0x01, 0x5d, 0xb2, 0x00, 0x00, 0x03, 0x00, 0x4c, - 0xff, 0xd1, 0x04, 0x1b, 0x05, 0xac, 0x00, 0x1c, 0x00, 0x2c, 0x00, 0x3c, - 0x00, 0x00, 0x01, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x22, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x34, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x01, 0x22, 0x07, 0x06, 0x15, - 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x03, - 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x03, 0x21, 0xfa, 0x83, 0x85, 0xd5, 0x05, 0x06, 0xd7, - 0x88, 0x85, 0x03, 0xf8, 0x7e, 0x29, 0x1e, 0xf4, 0xc0, 0xc8, 0x7a, 0x72, - 0x3e, 0x2c, 0xfe, 0xb6, 0x8b, 0x44, 0x2d, 0x5e, 0x41, 0x5d, 0x8b, 0x45, - 0x2c, 0x63, 0x3f, 0x5a, 0x99, 0x54, 0x42, 0x63, 0x51, 0x77, 0x9f, 0x55, - 0x3f, 0x66, 0x51, 0x02, 0xfc, 0x77, 0xf4, 0xc2, 0x7c, 0x7e, 0x04, 0x7d, - 0x83, 0xc2, 0xf1, 0x78, 0x4f, 0x4d, 0x3a, 0x57, 0xaa, 0xd9, 0x73, 0x6b, - 0xa5, 0x78, 0x49, 0x34, 0x01, 0xd8, 0x59, 0x3a, 0x52, 0x7a, 0x3e, 0x2b, - 0x58, 0x39, 0x50, 0x82, 0x3e, 0x27, 0xfd, 0xa0, 0x62, 0x4c, 0x6f, 0x8c, - 0x51, 0x41, 0x65, 0x4b, 0x6e, 0x8e, 0x50, 0x3f, 0x00, 0x02, 0x00, 0x4e, - 0xff, 0xd1, 0x04, 0x12, 0x05, 0xac, 0x00, 0x22, 0x00, 0x32, 0x00, 0x00, - 0x01, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x33, 0x16, 0x17, - 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x27, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x20, 0x13, 0x16, 0x01, - 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x04, 0x12, 0xfe, 0xea, 0x6a, 0x8a, 0xc7, 0x72, 0x4d, - 0x15, 0xb4, 0x1e, 0x72, 0x2d, 0x36, 0xc2, 0x51, 0x30, 0x01, 0x6e, 0x8e, - 0x25, 0x2b, 0xc2, 0x7d, 0x7d, 0x02, 0x7d, 0x7a, 0xc1, 0x11, 0x12, 0x01, - 0x9e, 0x40, 0x0b, 0xfe, 0x15, 0x83, 0x53, 0x4b, 0x6e, 0x47, 0x66, 0x8f, - 0x55, 0x49, 0x5d, 0x53, 0x02, 0xe7, 0xfd, 0xd0, 0xa6, 0x40, 0x8c, 0x5f, - 0x90, 0x97, 0x31, 0x13, 0xdb, 0x84, 0xc8, 0x84, 0x18, 0x06, 0x7e, 0x86, - 0xc9, 0xcd, 0x89, 0x86, 0x0c, 0x01, 0xfe, 0x01, 0x5b, 0x01, 0xbc, 0x62, - 0x58, 0x83, 0xb3, 0x53, 0x35, 0x62, 0x53, 0x7c, 0x95, 0x5e, 0x54, 0x00, - 0x00, 0x02, 0x00, 0xe1, 0x00, 0x00, 0x01, 0xb6, 0x04, 0x31, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x25, 0x15, 0x23, 0x35, 0x13, 0x15, 0x23, 0x35, - 0x01, 0xb6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0x03, 0x5c, 0xd5, 0xd5, - 0x00, 0x02, 0x00, 0xe1, 0xfe, 0xd3, 0x01, 0xb8, 0x04, 0x31, 0x00, 0x03, - 0x00, 0x0f, 0x00, 0x00, 0x01, 0x15, 0x23, 0x35, 0x03, 0x33, 0x15, 0x10, - 0x23, 0x35, 0x36, 0x37, 0x36, 0x3d, 0x01, 0x23, 0x01, 0xb8, 0xd5, 0x02, - 0xd7, 0xd7, 0x4d, 0x18, 0x16, 0x7b, 0x04, 0x31, 0xd5, 0xd5, 0xfc, 0xa4, - 0xf6, 0xfe, 0xf4, 0x4e, 0x03, 0x2c, 0x27, 0x64, 0x25, 0x00, 0x00, 0x01, - 0x00, 0x5c, 0xff, 0xee, 0x04, 0x46, 0x03, 0xcb, 0x00, 0x06, 0x00, 0x00, - 0x13, 0x35, 0x01, 0x15, 0x09, 0x01, 0x15, 0x5c, 0x03, 0xea, 0xfc, 0xd9, - 0x03, 0x27, 0x01, 0x96, 0x8d, 0x01, 0xa8, 0xa2, 0xfe, 0xb6, 0xfe, 0xb0, - 0xa1, 0x00, 0x00, 0x02, 0x00, 0x66, 0x00, 0xe3, 0x04, 0x46, 0x02, 0xd3, - 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x15, 0x21, 0x35, 0x01, 0x15, - 0x21, 0x35, 0x04, 0x46, 0xfc, 0x20, 0x03, 0xe0, 0xfc, 0x20, 0x02, 0xd3, - 0x8f, 0x8f, 0xfe, 0xa0, 0x90, 0x90, 0x00, 0x01, 0x00, 0x66, 0xff, 0xee, - 0x04, 0x50, 0x03, 0xcb, 0x00, 0x06, 0x00, 0x00, 0x01, 0x15, 0x01, 0x35, - 0x09, 0x01, 0x35, 0x04, 0x50, 0xfc, 0x16, 0x03, 0x27, 0xfc, 0xd9, 0x02, - 0x23, 0x8d, 0xfe, 0x58, 0xa1, 0x01, 0x4a, 0x01, 0x50, 0xa2, 0x00, 0x02, - 0x00, 0x9e, 0x00, 0x00, 0x04, 0x12, 0x05, 0xee, 0x00, 0x23, 0x00, 0x27, - 0x00, 0x00, 0x01, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x1d, 0x01, - 0x23, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x23, 0x10, 0x25, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x01, 0x15, 0x23, 0x35, 0x04, 0x12, 0x6e, 0x1a, 0x5b, 0x58, - 0x1c, 0x17, 0xb8, 0x66, 0x14, 0x5d, 0x61, 0x1f, 0x17, 0x5f, 0x44, 0x63, - 0xc4, 0x31, 0x13, 0xae, 0x01, 0x1f, 0x48, 0x59, 0xdc, 0x77, 0x61, 0xfe, - 0x92, 0xb8, 0x04, 0x64, 0x99, 0x7a, 0x1c, 0x51, 0x50, 0x3a, 0x2e, 0x34, - 0x60, 0x70, 0x78, 0x6f, 0x15, 0x58, 0x5a, 0x43, 0x33, 0x38, 0x7b, 0x41, - 0x2e, 0xa2, 0x3f, 0x5f, 0x01, 0x7c, 0x50, 0x14, 0x80, 0x68, 0xfb, 0xcf, - 0xd5, 0xd5, 0x00, 0x02, 0x00, 0x46, 0xfe, 0xdd, 0x07, 0x9c, 0x05, 0xee, - 0x00, 0x51, 0x00, 0x65, 0x00, 0x00, 0x01, 0x33, 0x03, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x17, 0x16, 0x33, 0x32, 0x37, 0x17, 0x06, 0x23, 0x20, 0x27, 0x26, 0x27, - 0x26, 0x35, 0x10, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x20, 0x17, - 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x01, 0x32, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x05, 0x52, 0xaa, 0xb8, 0x19, 0x2e, 0x1a, 0x1e, 0x6f, 0x62, 0x65, 0x1b, - 0x07, 0x92, 0x8c, 0xd9, 0x6a, 0x6f, 0xfd, 0xd4, 0xc1, 0x59, 0x3a, 0x9e, - 0x97, 0xf1, 0x69, 0x71, 0xa3, 0xe8, 0x39, 0xe6, 0xe9, 0xfe, 0xc9, 0xf6, - 0xd9, 0x60, 0x3d, 0x8d, 0x4c, 0x6a, 0xb6, 0xfc, 0x7e, 0x7a, 0x01, 0x1e, - 0xe9, 0xcd, 0x5b, 0x3a, 0x7b, 0x18, 0x1d, 0x9b, 0xe2, 0xc5, 0x1d, 0x75, - 0x7f, 0x17, 0x18, 0x8d, 0x5f, 0x61, 0x78, 0x6d, 0x9e, 0x45, 0x46, 0xac, - 0x4e, 0xfe, 0x7b, 0x79, 0x5f, 0x4e, 0x14, 0x05, 0x47, 0x33, 0x46, 0x72, - 0x5f, 0x61, 0x14, 0x04, 0x48, 0x39, 0x04, 0x02, 0xfd, 0xc3, 0x45, 0x22, - 0x2f, 0x1c, 0x0f, 0x6e, 0x72, 0x9f, 0x2c, 0x2c, 0xcf, 0xa9, 0xa1, 0x3e, - 0x1e, 0x9a, 0x8d, 0xd8, 0x8d, 0x95, 0xf3, 0xb9, 0xb0, 0x3d, 0x1b, 0x41, - 0x89, 0x56, 0xa1, 0x8e, 0xdf, 0x8c, 0x99, 0x01, 0x07, 0xee, 0x80, 0x60, - 0xa6, 0x42, 0x21, 0x99, 0x86, 0xce, 0x82, 0x8b, 0xcc, 0xb7, 0x25, 0x21, - 0xb6, 0x9d, 0x7f, 0x11, 0x03, 0x6a, 0x6c, 0xa1, 0xbc, 0x9f, 0x90, 0x35, - 0x17, 0xb2, 0xfd, 0x87, 0x99, 0x7e, 0x98, 0x23, 0x1e, 0x5b, 0x36, 0x27, - 0x6c, 0x6f, 0x9c, 0x20, 0x1f, 0x72, 0x48, 0x38, 0x00, 0x02, 0x00, 0x23, - 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x00, - 0x01, 0x21, 0x03, 0x23, 0x01, 0x33, 0x01, 0x23, 0x0b, 0x02, 0x03, 0xcb, - 0xfd, 0xc0, 0x9d, 0xcb, 0x02, 0x14, 0xf6, 0x02, 0x0c, 0xd5, 0xce, 0xe6, - 0xf6, 0x01, 0xc1, 0xfe, 0x3f, 0x05, 0xd5, 0xfa, 0x2b, 0x02, 0x60, 0x02, - 0xa8, 0xfd, 0x58, 0x00, 0x00, 0x03, 0x00, 0xa2, 0x00, 0x00, 0x04, 0xfc, - 0x05, 0xd5, 0x00, 0x10, 0x00, 0x1b, 0x00, 0x26, 0x00, 0x00, 0x01, 0x14, - 0x07, 0x06, 0x23, 0x21, 0x11, 0x21, 0x20, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x16, 0x17, 0x16, 0x01, 0x34, 0x27, 0x26, 0x23, 0x21, 0x11, 0x21, 0x32, - 0x37, 0x36, 0x03, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x21, - 0x11, 0x04, 0xfc, 0x82, 0x77, 0xbf, 0xfd, 0x5e, 0x02, 0x5e, 0x01, 0x17, - 0x6d, 0x36, 0xce, 0xbd, 0x37, 0x1c, 0xff, 0x00, 0xd0, 0x29, 0x32, 0xfe, - 0x8f, 0x01, 0x71, 0xf7, 0x2b, 0x09, 0xcb, 0xb8, 0x3d, 0x17, 0x67, 0x42, - 0x63, 0xfe, 0x2f, 0x01, 0xaa, 0xc7, 0x76, 0x6d, 0x05, 0xd5, 0xb4, 0x59, - 0x6e, 0xe4, 0x62, 0x48, 0x85, 0x43, 0x02, 0x3b, 0xc9, 0x1f, 0x06, 0xfe, - 0x25, 0x9f, 0x23, 0xfc, 0x94, 0x8c, 0x35, 0x3f, 0x92, 0x44, 0x2c, 0xfd, - 0xfe, 0x00, 0x00, 0x01, 0x00, 0x62, 0xff, 0xd1, 0x05, 0x6a, 0x05, 0xee, - 0x00, 0x23, 0x00, 0x00, 0x13, 0x34, 0x37, 0x12, 0x25, 0x36, 0x33, 0x20, - 0x13, 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x11, - 0x10, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x33, 0x02, 0x21, 0x20, - 0x03, 0x26, 0x03, 0x26, 0x62, 0x65, 0x92, 0x01, 0x3a, 0x3a, 0x3f, 0x01, - 0xa2, 0x7c, 0x15, 0x0d, 0xc3, 0x2f, 0xb2, 0x4c, 0x66, 0xde, 0x7e, 0x79, - 0x91, 0x81, 0xd3, 0xec, 0x66, 0x36, 0x18, 0xc4, 0x43, 0xfd, 0xdd, 0xfe, - 0x8f, 0xb1, 0x76, 0x09, 0x01, 0x02, 0xd9, 0xfc, 0xc5, 0x01, 0x1d, 0x2e, - 0x09, 0xfe, 0x9b, 0x3c, 0x47, 0xe6, 0x3f, 0x1b, 0xad, 0xa5, 0xfe, 0xe7, - 0xfe, 0xd9, 0xa6, 0x95, 0xb2, 0x5e, 0x98, 0xfd, 0xb0, 0x01, 0x1d, 0xbc, - 0x01, 0x08, 0x14, 0x00, 0x00, 0x02, 0x00, 0xb6, 0x00, 0x00, 0x05, 0x56, - 0x05, 0xd5, 0x00, 0x09, 0x00, 0x14, 0x00, 0x00, 0x33, 0x11, 0x21, 0x20, - 0x00, 0x11, 0x10, 0x07, 0x06, 0x21, 0x25, 0x21, 0x20, 0x13, 0x36, 0x35, - 0x10, 0x25, 0x26, 0x23, 0x21, 0xb6, 0x02, 0x40, 0x01, 0x1b, 0x01, 0x45, - 0xaf, 0xa2, 0xfe, 0xf1, 0xfe, 0x7f, 0x01, 0x60, 0x01, 0x2f, 0x65, 0x2f, - 0xff, 0x00, 0x55, 0x6e, 0xfe, 0xa0, 0x05, 0xd5, 0xfe, 0x72, 0xfe, 0xa5, - 0xfe, 0x95, 0xc9, 0xb8, 0xa8, 0x01, 0x10, 0x7d, 0xb4, 0x01, 0xaf, 0x70, - 0x25, 0x00, 0x00, 0x01, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xe7, 0x05, 0xd5, - 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x21, 0x15, 0x01, 0x77, 0x03, 0x70, 0xfb, 0xd1, 0x04, 0x0b, - 0xfc, 0xb4, 0x03, 0x2d, 0x02, 0xa8, 0xfe, 0x00, 0xa8, 0x05, 0xd5, 0xa8, - 0xfe, 0x23, 0xa8, 0x00, 0x00, 0x01, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xa2, - 0x05, 0xd5, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x21, 0x15, 0x01, 0x77, 0xbf, 0x03, 0xea, 0xfc, 0xd5, 0x02, - 0xc8, 0x02, 0xa8, 0xfd, 0x58, 0x05, 0xd5, 0xa8, 0xfe, 0x23, 0xa8, 0x00, - 0x00, 0x01, 0x00, 0x5a, 0xff, 0xd1, 0x05, 0xac, 0x05, 0xee, 0x00, 0x31, - 0x00, 0x00, 0x01, 0x14, 0x17, 0x16, 0x05, 0x32, 0x33, 0x32, 0x37, 0x36, - 0x37, 0x36, 0x3d, 0x01, 0x21, 0x35, 0x21, 0x11, 0x23, 0x27, 0x06, 0x07, - 0x06, 0x23, 0x20, 0x27, 0x26, 0x03, 0x26, 0x35, 0x34, 0x37, 0x12, 0x25, - 0x36, 0x33, 0x20, 0x17, 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, - 0x07, 0x06, 0x03, 0x14, 0x01, 0x19, 0x58, 0x88, 0x01, 0x28, 0x07, 0x07, - 0xc6, 0x84, 0x81, 0x09, 0x01, 0xfe, 0x39, 0x02, 0x6f, 0x79, 0x2f, 0xbe, - 0xfb, 0x22, 0x23, 0xfe, 0xf7, 0xb7, 0xb4, 0x2c, 0x0c, 0x61, 0x8d, 0x01, - 0x30, 0x52, 0x5d, 0x01, 0x35, 0xaa, 0x72, 0x20, 0xc3, 0x24, 0x95, 0x6a, - 0x8d, 0xe5, 0x8f, 0x93, 0x05, 0x02, 0xe5, 0xd1, 0xa0, 0xf5, 0x06, 0x7b, - 0x79, 0xbc, 0x0e, 0x0d, 0x29, 0xa7, 0xfc, 0xe4, 0xc6, 0xd3, 0x17, 0x03, - 0xab, 0xa7, 0x01, 0x17, 0x4e, 0x53, 0xea, 0xc0, 0x01, 0x19, 0x3f, 0x11, - 0xb2, 0x76, 0xb6, 0xaa, 0x52, 0x3a, 0x9d, 0xa2, 0xfe, 0xef, 0x08, 0x00, - 0x00, 0x01, 0x00, 0xaa, 0x00, 0x00, 0x05, 0x27, 0x05, 0xd5, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x21, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, - 0x11, 0x23, 0x04, 0x68, 0xfd, 0x00, 0xbe, 0xbe, 0x03, 0x00, 0xbf, 0xbf, - 0x02, 0xa8, 0xfd, 0x58, 0x05, 0xd5, 0xfd, 0x7b, 0x02, 0x85, 0xfa, 0x2b, - 0x00, 0x01, 0x00, 0xcd, 0x00, 0x00, 0x01, 0x8d, 0x05, 0xd5, 0x00, 0x03, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x01, 0x8d, 0xc0, 0x05, 0xd5, 0xfa, - 0x2b, 0x05, 0xd5, 0x00, 0x00, 0x01, 0x00, 0x23, 0xff, 0xd1, 0x03, 0x68, - 0x05, 0xd5, 0x00, 0x15, 0x00, 0x00, 0x25, 0x32, 0x37, 0x36, 0x35, 0x11, - 0x33, 0x11, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x3d, 0x01, 0x33, - 0x15, 0x14, 0x17, 0x16, 0x01, 0xc5, 0xa7, 0x2c, 0x12, 0xbe, 0x88, 0x6f, - 0xae, 0xd6, 0x71, 0x59, 0xc2, 0x80, 0x2a, 0x71, 0xa0, 0x42, 0x67, 0x04, - 0x1b, 0xfb, 0xa0, 0xd6, 0x72, 0x5c, 0x83, 0x67, 0xa1, 0x83, 0x60, 0xc6, - 0x36, 0x12, 0x00, 0x01, 0x00, 0xa2, 0x00, 0x00, 0x05, 0x44, 0x05, 0xd5, - 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x33, 0x11, 0x01, 0x33, - 0x09, 0x01, 0x23, 0x01, 0x01, 0x60, 0xbe, 0xbe, 0x02, 0xe8, 0xf5, 0xfd, - 0xa0, 0x02, 0x67, 0xe2, 0xfd, 0xf2, 0x02, 0x0a, 0xfd, 0xf6, 0x05, 0xd5, - 0xfd, 0x0c, 0x02, 0xf4, 0xfd, 0xa0, 0xfc, 0x8b, 0x02, 0xfe, 0x00, 0x01, - 0x00, 0xa4, 0x00, 0x00, 0x04, 0x44, 0x05, 0xd5, 0x00, 0x05, 0x00, 0x00, - 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, 0x01, 0x62, 0x02, 0xe2, 0xfc, 0x60, - 0x05, 0xd5, 0xfa, 0xd3, 0xa8, 0x05, 0xd5, 0x00, 0x00, 0x01, 0x00, 0x9a, - 0x00, 0x00, 0x06, 0x17, 0x05, 0xd5, 0x00, 0x0c, 0x00, 0x00, 0x21, 0x23, - 0x01, 0x11, 0x23, 0x11, 0x21, 0x09, 0x01, 0x21, 0x11, 0x23, 0x11, 0x03, - 0xbe, 0xc8, 0xfe, 0x58, 0xb4, 0x01, 0x08, 0x01, 0xba, 0x01, 0xb2, 0x01, - 0x09, 0xb5, 0x04, 0xe3, 0xfb, 0x1d, 0x05, 0xd5, 0xfa, 0xec, 0x05, 0x14, - 0xfa, 0x2b, 0x04, 0xe3, 0x00, 0x01, 0x00, 0x9c, 0x00, 0x00, 0x05, 0x2b, - 0x05, 0xd5, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, 0x23, 0x01, 0x11, 0x23, - 0x11, 0x33, 0x01, 0x11, 0x05, 0x2b, 0xd7, 0xfc, 0xfc, 0xb4, 0xce, 0x03, - 0x0d, 0x05, 0xd5, 0xfa, 0x2b, 0x04, 0xba, 0xfb, 0x46, 0x05, 0xd5, 0xfb, - 0x3b, 0x04, 0xc5, 0x00, 0x00, 0x02, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0, - 0x05, 0xee, 0x00, 0x16, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x10, 0x00, 0x07, - 0x06, 0x23, 0x20, 0x27, 0x26, 0x03, 0x26, 0x35, 0x10, 0x37, 0x36, 0x25, - 0x36, 0x33, 0x20, 0x17, 0x16, 0x13, 0x16, 0x01, 0x22, 0x07, 0x06, 0x03, - 0x06, 0x15, 0x10, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, - 0x36, 0x35, 0x10, 0x27, 0x26, 0x05, 0xf0, 0xfe, 0xd4, 0xfc, 0x51, 0x58, - 0xfe, 0xe0, 0xc1, 0xbd, 0x29, 0x0a, 0xa8, 0x9d, 0x01, 0x03, 0x41, 0x46, - 0x01, 0x2d, 0xc2, 0xbf, 0x20, 0x05, 0xfd, 0x2d, 0xe2, 0x90, 0x94, 0x0a, - 0x01, 0x8f, 0x88, 0xdd, 0x0f, 0x10, 0xde, 0x91, 0x93, 0x0f, 0x01, 0x94, - 0x96, 0x02, 0xd3, 0xfe, 0xe0, 0xfe, 0x66, 0x36, 0x12, 0xb0, 0xac, 0x01, - 0x20, 0x47, 0x4b, 0x01, 0x3f, 0xd3, 0xc6, 0x2c, 0x0b, 0xb9, 0xb8, 0xfe, - 0xc7, 0x37, 0x02, 0x39, 0x9a, 0x9f, 0xfe, 0xf7, 0x12, 0x13, 0xfe, 0xf0, - 0xa9, 0xa1, 0x0b, 0x01, 0x97, 0x98, 0xfc, 0x19, 0x1a, 0x01, 0x1e, 0xab, - 0xa3, 0x00, 0x00, 0x02, 0x00, 0xba, 0x00, 0x00, 0x04, 0xf0, 0x05, 0xd5, - 0x00, 0x0c, 0x00, 0x17, 0x00, 0x00, 0x01, 0x14, 0x07, 0x06, 0x23, 0x21, - 0x11, 0x23, 0x11, 0x21, 0x20, 0x17, 0x16, 0x01, 0x21, 0x32, 0x37, 0x36, - 0x35, 0x34, 0x27, 0x26, 0x23, 0x21, 0x04, 0xf0, 0x7e, 0x72, 0xb2, 0xfe, - 0x2b, 0xbf, 0x02, 0x69, 0x01, 0x17, 0x73, 0x43, 0xfc, 0x89, 0x01, 0x8d, - 0xb1, 0x4a, 0x28, 0x77, 0x46, 0x66, 0xfe, 0x73, 0x04, 0x1f, 0xc7, 0x75, - 0x6a, 0xfd, 0x87, 0x05, 0xd5, 0xb1, 0x69, 0xfe, 0x66, 0x71, 0x3e, 0x57, - 0x9b, 0x43, 0x28, 0x00, 0x00, 0x02, 0x00, 0x4e, 0xff, 0x87, 0x05, 0xf0, - 0x05, 0xee, 0x00, 0x18, 0x00, 0x33, 0x00, 0x00, 0x05, 0x07, 0x27, 0x06, - 0x23, 0x20, 0x27, 0x26, 0x03, 0x26, 0x35, 0x10, 0x37, 0x36, 0x25, 0x36, - 0x33, 0x20, 0x17, 0x16, 0x13, 0x16, 0x15, 0x10, 0x07, 0x01, 0x17, 0x36, - 0x11, 0x10, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x03, 0x06, - 0x15, 0x10, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x27, - 0x05, 0xdd, 0x60, 0xd7, 0xb1, 0xd6, 0xfe, 0xe0, 0xc1, 0xbd, 0x29, 0x0a, - 0xa8, 0x9e, 0x01, 0x04, 0x41, 0x46, 0x01, 0x1f, 0xc2, 0xbb, 0x2a, 0x0b, - 0xd3, 0xfe, 0xbc, 0xb6, 0xa2, 0x8e, 0x87, 0xdc, 0x10, 0x11, 0xe4, 0x90, - 0x94, 0x0a, 0x01, 0x8f, 0x89, 0xdf, 0x0d, 0x0d, 0x75, 0x6f, 0x08, 0x09, - 0x97, 0x02, 0x77, 0xb2, 0x68, 0xb0, 0xac, 0x01, 0x20, 0x47, 0x4b, 0x01, - 0x3f, 0xd3, 0xc6, 0x2c, 0x0b, 0xaf, 0xaa, 0xfe, 0xe3, 0x48, 0x4d, 0xfe, - 0xa1, 0xe8, 0x01, 0x08, 0x96, 0xb6, 0x01, 0x1d, 0x01, 0x0f, 0xa8, 0xa1, - 0x0c, 0x01, 0x9b, 0x9f, 0xfe, 0xf6, 0x11, 0x12, 0xfe, 0xee, 0xa9, 0xa1, - 0x09, 0x01, 0x31, 0x04, 0x04, 0x7f, 0x00, 0x02, 0x00, 0xbe, 0x00, 0x00, - 0x05, 0x6f, 0x05, 0xd5, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x00, 0x01, 0x16, - 0x17, 0x16, 0x07, 0x06, 0x17, 0x16, 0x17, 0x15, 0x23, 0x26, 0x3d, 0x01, - 0x34, 0x27, 0x26, 0x23, 0x21, 0x11, 0x23, 0x11, 0x21, 0x20, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x03, 0x34, 0x27, 0x26, 0x23, 0x21, 0x11, 0x21, - 0x32, 0x37, 0x36, 0x04, 0x4a, 0x9d, 0x23, 0x0e, 0x02, 0x02, 0x14, 0x15, - 0x32, 0xe8, 0x29, 0x7b, 0x32, 0x49, 0xfe, 0x15, 0xbf, 0x02, 0xb1, 0x01, - 0x28, 0x6a, 0x34, 0x67, 0x32, 0x2d, 0xa6, 0x35, 0x4a, 0xfe, 0x33, 0x01, - 0xcd, 0xdb, 0x36, 0x14, 0x02, 0xe1, 0x44, 0x91, 0x3d, 0x89, 0x81, 0x39, - 0x3a, 0x23, 0x2f, 0x60, 0x94, 0x85, 0xc3, 0x32, 0x15, 0xfd, 0x7d, 0x05, - 0xd5, 0xb6, 0x5a, 0x7f, 0xab, 0x62, 0x30, 0x01, 0x22, 0xc9, 0x2b, 0x0e, - 0xfd, 0xfe, 0x86, 0x32, 0x00, 0x01, 0x00, 0x62, 0xff, 0xd1, 0x04, 0xf8, - 0x05, 0xee, 0x00, 0x32, 0x00, 0x00, 0x25, 0x20, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x27, 0x25, 0x24, 0x11, 0x34, 0x37, 0x36, 0x33, 0x20, 0x17, - 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x17, 0x05, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x21, - 0x20, 0x27, 0x26, 0x27, 0x33, 0x15, 0x14, 0x17, 0x16, 0x02, 0xbc, 0x01, - 0x22, 0x47, 0x14, 0xa5, 0x2f, 0x3e, 0xfe, 0x8d, 0xfe, 0xdb, 0x9e, 0x8d, - 0xe8, 0x01, 0x31, 0x8e, 0x63, 0x01, 0xb5, 0x02, 0xa5, 0x54, 0x79, 0xb2, - 0x5c, 0x40, 0x4b, 0x37, 0x74, 0x01, 0x76, 0xd2, 0x4a, 0x22, 0x62, 0x97, - 0xfe, 0xb1, 0xfe, 0xe4, 0x9c, 0x93, 0x03, 0xb5, 0x74, 0x6c, 0x79, 0xa8, - 0x2f, 0x37, 0x87, 0x47, 0x14, 0x10, 0x62, 0x4c, 0x01, 0x10, 0xd7, 0x76, - 0x6a, 0xa7, 0x74, 0xb4, 0xc1, 0x49, 0x25, 0x5e, 0x41, 0x5d, 0x62, 0x35, - 0x27, 0x1f, 0x65, 0x39, 0x9d, 0x49, 0x57, 0x9f, 0x75, 0xb5, 0x8d, 0x86, - 0xf7, 0x0a, 0xa7, 0x5c, 0x55, 0x00, 0x00, 0x01, 0x00, 0x2b, 0x00, 0x00, - 0x04, 0xbe, 0x05, 0xd5, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, - 0x21, 0x35, 0x21, 0x15, 0x02, 0xd5, 0xbe, 0xfe, 0x14, 0x04, 0x93, 0x05, - 0x2d, 0xfa, 0xd3, 0x05, 0x2d, 0xa8, 0xa8, 0x00, 0x00, 0x01, 0x00, 0xae, - 0xff, 0xd1, 0x05, 0x29, 0x05, 0xd5, 0x00, 0x15, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x14, 0x07, 0x06, 0x21, 0x20, 0x27, 0x26, 0x35, 0x11, 0x33, 0x11, - 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x04, 0x6a, 0xbf, 0x9d, - 0x9d, 0xfe, 0xfa, 0xfe, 0xe0, 0x9a, 0x81, 0xbf, 0xae, 0x56, 0x78, 0xd9, - 0x66, 0x42, 0x05, 0xd5, 0xfb, 0xe7, 0xe1, 0x86, 0x84, 0x9a, 0x81, 0xd0, - 0x04, 0x19, 0xfb, 0xe7, 0xd0, 0x4d, 0x26, 0x7b, 0x50, 0x78, 0x00, 0x01, - 0x00, 0x3d, 0x00, 0x00, 0x05, 0x29, 0x05, 0xd5, 0x00, 0x06, 0x00, 0x00, - 0x21, 0x23, 0x01, 0x33, 0x09, 0x01, 0x33, 0x03, 0x23, 0xcd, 0xfd, 0xe7, - 0xcd, 0x01, 0xb7, 0x01, 0x9d, 0xcb, 0x05, 0xd5, 0xfb, 0x10, 0x04, 0xf0, - 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x07, 0x6f, 0x05, 0xd5, 0x00, 0x0c, - 0x00, 0x00, 0x21, 0x23, 0x09, 0x01, 0x23, 0x01, 0x33, 0x09, 0x01, 0x33, - 0x09, 0x01, 0x33, 0x05, 0xf4, 0xd1, 0xfe, 0xa8, 0xfe, 0xb2, 0xd1, 0xfe, - 0x81, 0xd5, 0x01, 0x19, 0x01, 0x4b, 0xcd, 0x01, 0x54, 0x01, 0x13, 0xd5, - 0x04, 0xcb, 0xfb, 0x35, 0x05, 0xd5, 0xfb, 0x44, 0x04, 0xbc, 0xfb, 0x44, - 0x04, 0xbc, 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x05, 0x31, 0x05, 0xd5, - 0x00, 0x0b, 0x00, 0x00, 0x09, 0x01, 0x23, 0x09, 0x01, 0x23, 0x09, 0x01, - 0x33, 0x09, 0x01, 0x33, 0x03, 0x21, 0x02, 0x10, 0xeb, 0xfe, 0x68, 0xfe, - 0x66, 0xe7, 0x02, 0x10, 0xfe, 0x11, 0xe7, 0x01, 0x7f, 0x01, 0x81, 0xe4, - 0x02, 0xfe, 0xfd, 0x02, 0x02, 0x6f, 0xfd, 0x91, 0x02, 0xfe, 0x02, 0xd7, - 0xfd, 0xb6, 0x02, 0x4a, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x05, 0x4a, - 0x05, 0xd5, 0x00, 0x08, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x01, 0x33, - 0x09, 0x01, 0x33, 0x03, 0x19, 0xbf, 0xfd, 0xc1, 0xeb, 0x01, 0xb6, 0x01, - 0xaa, 0xe4, 0x02, 0x4a, 0xfd, 0xb6, 0x02, 0x4a, 0x03, 0x8b, 0xfd, 0x29, - 0x02, 0xd7, 0x00, 0x01, 0x00, 0x39, 0x00, 0x00, 0x04, 0xaa, 0x05, 0xd5, - 0x00, 0x09, 0x00, 0x00, 0x01, 0x15, 0x01, 0x21, 0x15, 0x21, 0x35, 0x01, - 0x21, 0x35, 0x04, 0xa6, 0xfc, 0x83, 0x03, 0x81, 0xfb, 0x8f, 0x03, 0x81, - 0xfc, 0xb9, 0x05, 0xd5, 0xac, 0xfb, 0x7f, 0xa8, 0xa8, 0x04, 0x85, 0xa8, - 0x00, 0x01, 0x00, 0x83, 0xfe, 0x4e, 0x02, 0x00, 0x05, 0xd5, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x15, 0x23, 0x11, 0x33, 0x15, 0x21, 0x11, 0x02, 0x00, - 0xd3, 0xd3, 0xfe, 0x83, 0x05, 0xd5, 0x93, 0xf9, 0x9f, 0x93, 0x07, 0x87, - 0x00, 0x01, 0xff, 0xf0, 0xff, 0xd7, 0x02, 0x46, 0x05, 0xd5, 0x00, 0x03, - 0x00, 0x00, 0x13, 0x01, 0x23, 0x01, 0x60, 0x01, 0xe6, 0x71, 0xfe, 0x1b, - 0x05, 0xd5, 0xfa, 0x02, 0x05, 0xfe, 0x00, 0x01, 0x00, 0x2f, 0xfe, 0x4e, - 0x01, 0xac, 0x05, 0xd5, 0x00, 0x07, 0x00, 0x00, 0x13, 0x35, 0x33, 0x11, - 0x23, 0x35, 0x21, 0x11, 0x2f, 0xd3, 0xd3, 0x01, 0x7d, 0xfe, 0x4e, 0x93, - 0x06, 0x61, 0x93, 0xf8, 0x79, 0x00, 0x00, 0x01, 0x00, 0x5a, 0x02, 0xa2, - 0x03, 0x66, 0x05, 0xac, 0x00, 0x06, 0x00, 0x00, 0x01, 0x33, 0x01, 0x23, - 0x0b, 0x01, 0x23, 0x01, 0x93, 0x96, 0x01, 0x3d, 0x8d, 0xfa, 0xf8, 0x8d, - 0x05, 0xac, 0xfc, 0xf6, 0x02, 0x66, 0xfd, 0x9a, 0x00, 0x01, 0xff, 0xd3, - 0xfe, 0x98, 0x04, 0xa0, 0xfe, 0xfe, 0x00, 0x03, 0x00, 0x00, 0x01, 0x15, - 0x21, 0x35, 0x04, 0xa0, 0xfb, 0x33, 0xfe, 0xfe, 0x66, 0x66, 0x00, 0x01, - 0x00, 0x2d, 0x04, 0xbc, 0x01, 0xd9, 0x05, 0xec, 0x00, 0x03, 0x00, 0x00, - 0x01, 0x13, 0x23, 0x01, 0x01, 0x14, 0xc5, 0x7b, 0xfe, 0xcf, 0x05, 0xec, - 0xfe, 0xd0, 0x01, 0x30, 0x00, 0x02, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, - 0x04, 0x50, 0x00, 0x31, 0x00, 0x40, 0x00, 0x00, 0x13, 0x12, 0x25, 0x36, - 0x33, 0x20, 0x17, 0x16, 0x15, 0x11, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x15, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x3d, 0x01, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x13, 0x32, - 0x37, 0x36, 0x3d, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, - 0x16, 0x85, 0x0a, 0x01, 0x43, 0x2e, 0x33, 0x01, 0x31, 0x4c, 0x17, 0x46, - 0x0a, 0x0c, 0x12, 0x13, 0x48, 0x2d, 0x7f, 0x23, 0x0a, 0x04, 0x90, 0x94, - 0x23, 0x26, 0xc0, 0x5e, 0x42, 0x77, 0x54, 0xc6, 0x25, 0x5e, 0x84, 0x20, - 0x0f, 0x82, 0x30, 0x3e, 0xb7, 0x31, 0x0f, 0x05, 0xaa, 0x9b, 0x61, 0x46, - 0x38, 0x98, 0x9c, 0x3c, 0x6d, 0x66, 0x2e, 0x02, 0xf4, 0x01, 0x30, 0x27, - 0x05, 0xae, 0x34, 0x43, 0xfd, 0x89, 0x48, 0x0a, 0x02, 0x04, 0x81, 0x12, - 0x5e, 0x1c, 0x24, 0x84, 0x15, 0x05, 0x74, 0x51, 0x78, 0xb0, 0x4c, 0x36, - 0x1d, 0x06, 0x0c, 0x10, 0x2d, 0x16, 0x23, 0x2d, 0x72, 0x22, 0x0c, 0x70, - 0x21, 0x2d, 0xfd, 0x72, 0x5d, 0x43, 0x4c, 0xc0, 0x19, 0x17, 0x17, 0x1b, - 0x31, 0x6d, 0x70, 0x29, 0x13, 0x00, 0x00, 0x02, 0x00, 0x6f, 0xff, 0xd1, - 0x04, 0x2f, 0x05, 0xd5, 0x00, 0x14, 0x00, 0x24, 0x00, 0x00, 0x13, 0x33, - 0x11, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x10, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x15, 0x23, 0x01, 0x22, 0x07, 0x06, 0x15, - 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x6f, - 0xaa, 0x68, 0xb6, 0x16, 0x17, 0xdd, 0x7c, 0x72, 0x8a, 0x7e, 0xcb, 0xd5, - 0x77, 0x04, 0x04, 0x99, 0x01, 0xd5, 0x91, 0x53, 0x47, 0x6b, 0x4d, 0x73, - 0x90, 0x57, 0x52, 0x6e, 0x51, 0x05, 0xd5, 0xfd, 0xcb, 0x9f, 0x0f, 0x02, - 0xa3, 0x96, 0xfa, 0xfe, 0xe8, 0xa1, 0x93, 0xac, 0x06, 0x06, 0x89, 0x03, - 0xb0, 0x81, 0x6f, 0xb0, 0xdb, 0x72, 0x52, 0x78, 0x71, 0xb0, 0xdd, 0x73, - 0x56, 0x00, 0x00, 0x01, 0x00, 0x3f, 0xff, 0xd1, 0x03, 0xd1, 0x04, 0x50, - 0x00, 0x1f, 0x00, 0x00, 0x01, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x13, 0x33, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x11, 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x03, 0xc5, 0xac, 0x18, 0x83, 0x2c, 0x37, 0xa5, 0x4d, 0x37, 0x7a, 0x49, - 0x6a, 0xdb, 0x2b, 0xac, 0x13, 0xa3, 0x69, 0x97, 0xde, 0x81, 0x7d, 0x8b, - 0x82, 0xd1, 0xf3, 0x6d, 0x3d, 0x02, 0xc9, 0xa9, 0x30, 0x10, 0x99, 0x6c, - 0xa7, 0xf0, 0x69, 0x3e, 0x01, 0x02, 0xf0, 0x6b, 0x45, 0x9d, 0x99, 0x00, - 0xff, 0x01, 0x14, 0xa1, 0x95, 0xa5, 0x5c, 0x00, 0x00, 0x02, 0x00, 0x35, - 0xff, 0xd1, 0x03, 0xf6, 0x05, 0xd5, 0x00, 0x14, 0x00, 0x24, 0x00, 0x00, - 0x01, 0x11, 0x23, 0x35, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x11, - 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x11, 0x01, 0x22, 0x07, - 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x03, 0xf6, 0x98, 0x62, 0x85, 0x32, 0x3d, 0xe2, 0x7e, 0x73, 0x87, - 0x7d, 0xc9, 0xd4, 0x6e, 0x04, 0x04, 0xfe, 0xd3, 0x93, 0x57, 0x4e, 0x6b, - 0x53, 0x7c, 0x8f, 0x53, 0x49, 0x6e, 0x4d, 0x05, 0xd5, 0xfa, 0x2b, 0x8d, - 0x8e, 0x21, 0x0d, 0xaa, 0x9b, 0x01, 0x05, 0x01, 0x0a, 0x9c, 0x8f, 0x9a, - 0x06, 0x06, 0x02, 0x2b, 0xfd, 0xdb, 0x7d, 0x71, 0xb2, 0xd2, 0x73, 0x5a, - 0x7d, 0x6f, 0xaf, 0xe2, 0x72, 0x50, 0x00, 0x02, 0x00, 0x52, 0xff, 0xd1, - 0x04, 0x1b, 0x04, 0x50, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x00, 0x01, 0x21, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x33, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x05, 0x21, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, - 0x22, 0x07, 0x06, 0x04, 0x1b, 0xfc, 0xe9, 0x02, 0x28, 0x07, 0x08, 0x4f, - 0x90, 0x11, 0x12, 0xd2, 0x47, 0xac, 0x27, 0xa3, 0x6d, 0x94, 0xec, 0x83, - 0x78, 0x8d, 0x85, 0xd9, 0xc5, 0x83, 0x46, 0x25, 0x2b, 0xfc, 0xed, 0x02, - 0x5a, 0x02, 0x5a, 0x55, 0x7a, 0x95, 0x56, 0x3e, 0x01, 0xdf, 0x84, 0x48, - 0x0d, 0x0c, 0x7b, 0x0e, 0x02, 0xd7, 0xd3, 0x61, 0x41, 0xa6, 0x97, 0xfc, - 0x01, 0x11, 0x9f, 0x96, 0x7c, 0x42, 0x5d, 0x73, 0x58, 0x05, 0x08, 0x88, - 0x5c, 0x57, 0x74, 0x55, 0x00, 0x01, 0x00, 0x25, 0x00, 0x00, 0x02, 0x10, - 0x05, 0xdb, 0x00, 0x15, 0x00, 0x00, 0x01, 0x15, 0x23, 0x11, 0x23, 0x11, - 0x23, 0x35, 0x33, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x15, 0x26, - 0x23, 0x22, 0x1d, 0x01, 0x02, 0x10, 0xb2, 0xaa, 0x8f, 0x8f, 0x72, 0x3a, - 0x50, 0x2f, 0x31, 0x27, 0x14, 0x77, 0x04, 0x31, 0x8b, 0xfc, 0x5a, 0x03, - 0xa6, 0x8b, 0xb6, 0x9a, 0x3c, 0x1e, 0x0a, 0x8d, 0x02, 0x6d, 0xa8, 0x00, - 0x00, 0x02, 0x00, 0x3b, 0xfe, 0x42, 0x03, 0xe9, 0x04, 0x50, 0x00, 0x2a, - 0x00, 0x3a, 0x00, 0x00, 0x05, 0x22, 0x27, 0x26, 0x27, 0x26, 0x35, 0x10, - 0x37, 0x36, 0x37, 0x32, 0x33, 0x32, 0x17, 0x16, 0x17, 0x35, 0x33, 0x11, - 0x10, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x33, 0x16, - 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x06, 0x07, 0x06, 0x03, - 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x10, 0x27, 0x26, 0x01, 0xf6, 0xac, 0x79, 0x89, 0x0c, 0x01, 0x80, 0x78, - 0xbf, 0x09, 0x09, 0xc4, 0x7e, 0x03, 0x03, 0x9d, 0x45, 0x5a, 0xf0, 0x26, - 0x2a, 0xf3, 0x70, 0x3f, 0x0a, 0xae, 0x18, 0xa2, 0x22, 0x28, 0xbe, 0x41, - 0x2c, 0x64, 0x73, 0x32, 0x1b, 0x99, 0x50, 0x40, 0x78, 0x49, 0x6a, 0x9b, - 0x4d, 0x3a, 0x80, 0x44, 0x2f, 0x81, 0x91, 0xf8, 0x15, 0x16, 0x01, 0x07, - 0xa3, 0x98, 0x08, 0xb1, 0x04, 0x05, 0x9b, 0xfc, 0x7f, 0xfe, 0xe3, 0x87, - 0xb0, 0x16, 0x04, 0x89, 0x4c, 0x6e, 0x92, 0x1c, 0x06, 0x82, 0x58, 0xaf, - 0x37, 0x8d, 0x24, 0x0f, 0x03, 0xe1, 0x89, 0x6d, 0xac, 0xf4, 0x6c, 0x41, - 0x8d, 0x69, 0xa5, 0x01, 0x09, 0x68, 0x37, 0x00, 0x00, 0x01, 0x00, 0x8f, - 0x00, 0x00, 0x03, 0xe3, 0x05, 0xd5, 0x00, 0x17, 0x00, 0x00, 0x01, 0x34, - 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x11, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x11, 0x23, 0x03, 0x39, - 0x79, 0x2f, 0x35, 0x91, 0x50, 0x42, 0xaa, 0xaa, 0x5e, 0x67, 0x3e, 0x55, - 0xbe, 0x59, 0x3b, 0xaa, 0x02, 0xe7, 0x90, 0x30, 0x13, 0x75, 0x61, 0x94, - 0xfd, 0xb0, 0x05, 0xd5, 0xfd, 0xc9, 0x7a, 0x23, 0x15, 0x70, 0x4a, 0x6b, - 0xfc, 0xd5, 0x00, 0x02, 0x00, 0x87, 0x00, 0x00, 0x01, 0x33, 0x05, 0xd5, - 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x15, 0x23, 0x35, 0x13, 0x11, - 0x23, 0x11, 0x01, 0x33, 0xac, 0xac, 0xa9, 0x05, 0xd5, 0xd7, 0xd7, 0xfe, - 0x5c, 0xfb, 0xcf, 0x04, 0x31, 0x00, 0x00, 0x02, 0xff, 0xdb, 0xfe, 0x42, - 0x01, 0x39, 0x05, 0xd5, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x01, 0x15, - 0x23, 0x35, 0x11, 0x33, 0x11, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x35, - 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x01, 0x39, 0xaa, 0xaa, 0xce, 0x28, - 0x2f, 0x1a, 0x1f, 0x23, 0x06, 0x5d, 0x1c, 0x12, 0x05, 0xd5, 0xd7, 0xd7, - 0xfe, 0x5c, 0xfa, 0xf0, 0xb9, 0x20, 0x06, 0x06, 0x91, 0x02, 0x2e, 0x1f, - 0x40, 0x00, 0x00, 0x01, 0x00, 0x77, 0x00, 0x00, 0x04, 0x04, 0x05, 0xd5, - 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x01, 0x33, 0x09, 0x01, 0x23, 0x01, - 0x07, 0x11, 0x23, 0x11, 0x01, 0x21, 0x01, 0xc6, 0xdc, 0xfe, 0x8b, 0x01, - 0xb6, 0xd3, 0xfe, 0x96, 0xa6, 0xaa, 0x05, 0xd5, 0xfc, 0x95, 0x01, 0xc7, - 0xfe, 0x8d, 0xfd, 0x42, 0x02, 0x46, 0xa4, 0xfe, 0x5e, 0x05, 0xd5, 0x00, - 0x00, 0x01, 0x00, 0x8b, 0x00, 0x00, 0x01, 0x37, 0x05, 0xd5, 0x00, 0x03, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x01, 0x37, 0xac, 0x05, 0xd5, 0xfa, - 0x2b, 0x05, 0xd5, 0x00, 0x00, 0x01, 0x00, 0x8f, 0x00, 0x00, 0x06, 0x19, - 0x04, 0x50, 0x00, 0x2a, 0x00, 0x00, 0x13, 0x33, 0x15, 0x36, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x17, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x15, 0x11, 0x23, 0x11, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, - 0x11, 0x23, 0x11, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, - 0x23, 0x8f, 0x9e, 0x5d, 0x72, 0x36, 0x45, 0x9d, 0x54, 0x1a, 0x16, 0x5e, - 0x62, 0x3a, 0x4f, 0xd4, 0x46, 0x1e, 0xac, 0x62, 0x2b, 0x3a, 0x6c, 0x4a, - 0x46, 0xac, 0x71, 0x25, 0x31, 0x6c, 0x4a, 0x46, 0xac, 0x04, 0x31, 0x97, - 0x83, 0x22, 0x11, 0x5e, 0x1e, 0x28, 0x71, 0x20, 0x13, 0x95, 0x40, 0x56, - 0xfc, 0xdb, 0x02, 0xe3, 0x8e, 0x32, 0x17, 0x56, 0x51, 0x71, 0xfd, 0x5e, - 0x02, 0xe3, 0x9c, 0x2c, 0x0f, 0x56, 0x51, 0x71, 0xfd, 0x5e, 0x00, 0x01, - 0x00, 0x8f, 0x00, 0x00, 0x03, 0xe5, 0x04, 0x50, 0x00, 0x17, 0x00, 0x00, - 0x13, 0x33, 0x15, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x11, - 0x23, 0x11, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, 0x23, - 0x8f, 0x9e, 0x5d, 0x7a, 0x3d, 0x50, 0xb6, 0x5d, 0x41, 0xaa, 0x5c, 0x35, - 0x4c, 0x91, 0x50, 0x42, 0xac, 0x04, 0x31, 0xb4, 0x94, 0x2a, 0x15, 0x6b, - 0x4b, 0x6f, 0xfc, 0xd5, 0x02, 0xe7, 0x7a, 0x38, 0x21, 0x75, 0x61, 0x94, - 0xfd, 0xb0, 0x00, 0x02, 0x00, 0x4a, 0xff, 0xd1, 0x04, 0x14, 0x04, 0x50, - 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x20, 0x17, 0x16, 0x15, 0x10, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, 0x17, 0x22, - 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x02, 0x2d, 0x01, 0x08, 0x7f, 0x60, 0x9a, 0x7f, 0xcc, 0xf9, - 0x81, 0x6b, 0xa0, 0x7c, 0xc9, 0x9f, 0x53, 0x41, 0x77, 0x4c, 0x70, 0x9d, - 0x53, 0x43, 0x7e, 0x4a, 0x04, 0x50, 0xc3, 0x95, 0xf0, 0xfe, 0xde, 0x98, - 0x7d, 0xb4, 0x95, 0xf6, 0x01, 0x2f, 0x99, 0x78, 0x9e, 0x8a, 0x6d, 0xab, - 0xee, 0x6d, 0x46, 0x86, 0x6c, 0xa9, 0xfd, 0x6c, 0x3f, 0x00, 0x00, 0x02, - 0x00, 0x6f, 0xfe, 0x42, 0x04, 0x2f, 0x04, 0x50, 0x00, 0x11, 0x00, 0x21, - 0x00, 0x00, 0x13, 0x11, 0x33, 0x15, 0x36, 0x20, 0x17, 0x16, 0x11, 0x10, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x11, 0x01, 0x22, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x6f, 0x9d, 0x7a, 0x01, 0xb8, 0x7d, 0x74, 0x88, 0x7c, 0xc7, 0xa9, 0x72, - 0x17, 0x17, 0x01, 0x2b, 0x91, 0x53, 0x47, 0x6b, 0x4d, 0x73, 0x91, 0x57, - 0x4f, 0x6d, 0x51, 0xfe, 0x42, 0x05, 0xef, 0xa2, 0xc1, 0xa7, 0x9d, 0xfe, - 0xfa, 0xfe, 0xf5, 0x9c, 0x8e, 0x6d, 0x17, 0x1c, 0xfd, 0xd1, 0x05, 0x6e, - 0x81, 0x6f, 0xb0, 0xdb, 0x72, 0x52, 0x7a, 0x70, 0xaf, 0xdc, 0x73, 0x57, - 0x00, 0x02, 0x00, 0x35, 0xfe, 0x42, 0x03, 0xf6, 0x04, 0x50, 0x00, 0x14, - 0x00, 0x24, 0x00, 0x00, 0x01, 0x23, 0x11, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x35, - 0x33, 0x05, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x03, 0xf6, 0xaa, 0x60, 0x9d, 0x25, 0x2a, - 0xdd, 0x7c, 0x72, 0x89, 0x7f, 0xcb, 0xc3, 0x7a, 0x0d, 0x0c, 0x98, 0xfe, - 0x2b, 0x94, 0x57, 0x4f, 0x6b, 0x53, 0x7c, 0x8f, 0x53, 0x49, 0x6d, 0x4d, - 0xfe, 0x42, 0x02, 0x39, 0x8d, 0x17, 0x06, 0xa3, 0x96, 0xfa, 0x01, 0x15, - 0xa2, 0x95, 0x8e, 0x0f, 0x11, 0x8f, 0x81, 0x7d, 0x71, 0xb2, 0xd2, 0x73, - 0x5a, 0x7d, 0x6e, 0xae, 0xe3, 0x73, 0x50, 0x00, 0x00, 0x01, 0x00, 0x8d, - 0x00, 0x00, 0x02, 0x91, 0x04, 0x50, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x06, - 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x36, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x02, 0x91, 0xb0, 0x4e, 0x5a, 0xac, 0x9e, 0x64, 0x5f, 0x2d, - 0x35, 0x17, 0x2a, 0x03, 0x9c, 0x03, 0x49, 0x55, 0xce, 0xfd, 0xd3, 0x04, - 0x31, 0xc2, 0xa2, 0x2b, 0x14, 0x06, 0x00, 0x01, 0x00, 0x46, 0xff, 0xd1, - 0x03, 0xac, 0x04, 0x50, 0x00, 0x32, 0x00, 0x00, 0x13, 0x1e, 0x01, 0x33, - 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2f, 0x01, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x23, 0x26, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x1f, 0x01, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x20, 0x27, 0x26, 0x27, 0xfa, - 0x0f, 0x7e, 0x79, 0x93, 0x42, 0x25, 0x4f, 0x22, 0x35, 0xa0, 0xd4, 0x48, - 0x38, 0x80, 0x6f, 0xad, 0xfc, 0x5c, 0x2c, 0x01, 0xb4, 0x05, 0xa3, 0x16, - 0x19, 0x8f, 0x3a, 0x1b, 0x65, 0x28, 0x3a, 0xa4, 0xd1, 0x3e, 0x20, 0x88, - 0x76, 0xbc, 0xfe, 0xa4, 0x41, 0x0d, 0x02, 0x01, 0x3f, 0x72, 0x5e, 0x4a, - 0x28, 0x36, 0x50, 0x27, 0x11, 0x0d, 0x27, 0x33, 0x52, 0x41, 0x6f, 0xa1, - 0x5a, 0x4d, 0x9a, 0x49, 0x67, 0x96, 0x13, 0x03, 0x4d, 0x25, 0x30, 0x50, - 0x2b, 0x10, 0x0e, 0x27, 0x32, 0x6d, 0x3a, 0x52, 0xa6, 0x5d, 0x51, 0xfc, - 0x34, 0x3e, 0x00, 0x01, 0x00, 0x1d, 0xff, 0xd1, 0x02, 0x08, 0x05, 0x58, - 0x00, 0x17, 0x00, 0x00, 0x01, 0x15, 0x23, 0x11, 0x14, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x15, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x11, 0x23, 0x35, - 0x33, 0x11, 0x33, 0x11, 0x02, 0x08, 0xb0, 0x1f, 0x14, 0x2b, 0x36, 0x1c, - 0x50, 0x3b, 0x9e, 0x26, 0x0b, 0x91, 0x91, 0xaa, 0x04, 0x31, 0x8b, 0xfd, - 0x21, 0x45, 0x11, 0x0b, 0x09, 0x90, 0x0e, 0x69, 0x1d, 0x24, 0x03, 0x2b, - 0x8b, 0x01, 0x27, 0xfe, 0xd9, 0x00, 0x00, 0x01, 0x00, 0x85, 0xff, 0xd1, - 0x03, 0xdb, 0x04, 0x31, 0x00, 0x17, 0x00, 0x00, 0x21, 0x23, 0x35, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x11, 0x33, 0x11, 0x14, 0x17, - 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, 0x33, 0x03, 0xdb, 0x99, 0x60, - 0x71, 0x41, 0x55, 0xb9, 0x5c, 0x41, 0xaa, 0x5c, 0x35, 0x4c, 0x93, 0x50, - 0x42, 0xaa, 0x96, 0x87, 0x28, 0x16, 0x6c, 0x4b, 0x6e, 0x03, 0x3b, 0xfd, - 0x08, 0x7a, 0x38, 0x21, 0x76, 0x61, 0x94, 0x02, 0x60, 0x00, 0x00, 0x01, - 0x00, 0x14, 0x00, 0x00, 0x03, 0xe3, 0x04, 0x31, 0x00, 0x06, 0x00, 0x00, - 0x21, 0x23, 0x01, 0x33, 0x09, 0x01, 0x33, 0x02, 0x48, 0xbb, 0xfe, 0x87, - 0xc1, 0x01, 0x1f, 0x01, 0x2f, 0xc0, 0x04, 0x31, 0xfc, 0x9a, 0x03, 0x66, - 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x05, 0xaa, 0x04, 0x31, 0x00, 0x0c, - 0x00, 0x00, 0x21, 0x23, 0x0b, 0x01, 0x23, 0x01, 0x33, 0x1b, 0x01, 0x33, - 0x1b, 0x01, 0x33, 0x04, 0x6f, 0xc3, 0xd9, 0xcf, 0xc0, 0xfe, 0xc8, 0xbd, - 0xdb, 0xcd, 0xd1, 0xd2, 0xd5, 0xc1, 0x03, 0x4a, 0xfc, 0xb6, 0x04, 0x31, - 0xfc, 0xbd, 0x03, 0x43, 0xfc, 0xbd, 0x03, 0x43, 0x00, 0x01, 0x00, 0x23, - 0x00, 0x00, 0x03, 0xc9, 0x04, 0x31, 0x00, 0x0b, 0x00, 0x00, 0x09, 0x01, - 0x23, 0x09, 0x01, 0x23, 0x09, 0x01, 0x33, 0x09, 0x01, 0x33, 0x02, 0x56, - 0x01, 0x73, 0xc7, 0xfe, 0xf4, 0xfe, 0xef, 0xc2, 0x01, 0x7b, 0xfe, 0x99, - 0xc3, 0x01, 0x02, 0x01, 0x02, 0xc0, 0x02, 0x2b, 0xfd, 0xd5, 0x01, 0x9c, - 0xfe, 0x64, 0x02, 0x23, 0x02, 0x0e, 0xfe, 0x7b, 0x01, 0x85, 0x00, 0x01, - 0x00, 0x29, 0xfe, 0x42, 0x03, 0xd3, 0x04, 0x31, 0x00, 0x11, 0x00, 0x00, - 0x01, 0x33, 0x01, 0x06, 0x23, 0x22, 0x27, 0x35, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x3f, 0x01, 0x01, 0x33, 0x01, 0x03, 0x1b, 0xb8, 0xfe, 0x23, 0x54, - 0xc1, 0x41, 0x31, 0x3b, 0x1f, 0x4c, 0x24, 0x0d, 0x0c, 0x41, 0xfe, 0x96, - 0xb6, 0x01, 0x13, 0x04, 0x31, 0xfa, 0xee, 0xdd, 0x1a, 0x9a, 0x0d, 0x36, - 0x15, 0x1e, 0xaa, 0x04, 0x35, 0xfc, 0xbd, 0x00, 0x00, 0x01, 0x00, 0x3f, - 0x00, 0x00, 0x03, 0xa8, 0x04, 0x31, 0x00, 0x09, 0x00, 0x00, 0x01, 0x15, - 0x01, 0x21, 0x15, 0x21, 0x35, 0x01, 0x21, 0x35, 0x03, 0x8b, 0xfd, 0x83, - 0x02, 0x9a, 0xfc, 0x97, 0x02, 0x82, 0xfd, 0xa9, 0x04, 0x31, 0x97, 0xfc, - 0xfc, 0x96, 0x9a, 0x03, 0x02, 0x95, 0x00, 0x01, 0x00, 0x58, 0xfe, 0x4e, - 0x02, 0x35, 0x05, 0xd5, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x15, 0x23, 0x22, - 0x07, 0x06, 0x15, 0x11, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x16, 0x15, - 0x11, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x35, - 0x11, 0x34, 0x27, 0x26, 0x27, 0x35, 0x36, 0x37, 0x36, 0x35, 0x11, 0x34, - 0x37, 0x36, 0x33, 0x02, 0x35, 0x1e, 0x55, 0x19, 0x13, 0x3d, 0x25, 0x46, - 0x8b, 0x18, 0x05, 0x25, 0x1b, 0x41, 0x1e, 0x5e, 0x8e, 0x36, 0x1b, 0x32, - 0x23, 0x4b, 0x5e, 0x22, 0x20, 0x6f, 0x30, 0x40, 0x05, 0xd5, 0x85, 0x26, - 0x1e, 0x45, 0xfe, 0x8d, 0xae, 0x4a, 0x2e, 0x1c, 0x41, 0xad, 0x27, 0x2e, - 0xfe, 0x8d, 0x5b, 0x1a, 0x14, 0x85, 0x7a, 0x3d, 0x55, 0x01, 0x56, 0xa6, - 0x3c, 0x2a, 0x0f, 0x8d, 0x13, 0x41, 0x3d, 0x8a, 0x01, 0x56, 0xb3, 0x3e, - 0x1b, 0x00, 0x00, 0x01, 0x00, 0xcd, 0xfe, 0x4e, 0x01, 0x48, 0x05, 0xd5, - 0x00, 0x03, 0x00, 0x00, 0x13, 0x33, 0x11, 0x23, 0xcd, 0x7b, 0x7b, 0x05, - 0xd5, 0xf8, 0x79, 0x00, 0x00, 0x01, 0x00, 0x3b, 0xfe, 0x4e, 0x02, 0x19, - 0x05, 0xd5, 0x00, 0x2a, 0x00, 0x00, 0x13, 0x35, 0x33, 0x32, 0x37, 0x36, - 0x35, 0x11, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x35, 0x11, 0x34, - 0x27, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x17, 0x16, 0x15, 0x11, 0x14, - 0x17, 0x16, 0x17, 0x15, 0x06, 0x07, 0x06, 0x15, 0x11, 0x14, 0x07, 0x06, - 0x23, 0x3b, 0x21, 0x56, 0x1a, 0x13, 0x79, 0x15, 0x1a, 0x8f, 0x15, 0x04, - 0x25, 0x1c, 0x42, 0x21, 0x61, 0x92, 0x35, 0x1a, 0x33, 0x22, 0x47, 0x5d, - 0x21, 0x1e, 0x71, 0x30, 0x40, 0xfe, 0x4e, 0x85, 0x26, 0x1d, 0x46, 0x01, - 0x73, 0xd4, 0x53, 0x0f, 0x0b, 0x43, 0xb7, 0x22, 0x28, 0x01, 0x73, 0x5b, - 0x1a, 0x14, 0x85, 0x7d, 0x3c, 0x53, 0xfe, 0xaa, 0xa7, 0x3c, 0x29, 0x0f, - 0x8d, 0x14, 0x44, 0x3e, 0x85, 0xfe, 0xaa, 0xb4, 0x3e, 0x1a, 0x00, 0x01, - 0x00, 0x9a, 0x02, 0x25, 0x04, 0x10, 0x03, 0x81, 0x00, 0x1f, 0x00, 0x00, - 0x01, 0x22, 0x07, 0x06, 0x15, 0x23, 0x36, 0x37, 0x36, 0x33, 0x32, 0x1f, - 0x01, 0x16, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x33, 0x15, 0x14, 0x07, - 0x06, 0x23, 0x22, 0x2f, 0x01, 0x26, 0x27, 0x26, 0x01, 0x73, 0x5e, 0x0e, - 0x01, 0x6c, 0x0c, 0x87, 0x22, 0x28, 0x39, 0x35, 0xf0, 0x39, 0x2d, 0x51, - 0x12, 0x06, 0x6c, 0x59, 0x35, 0x49, 0x4f, 0x57, 0xc8, 0x28, 0x28, 0x05, - 0x02, 0xf8, 0x95, 0x05, 0x06, 0xea, 0x32, 0x0d, 0x21, 0x8d, 0x23, 0x4d, - 0x1b, 0x27, 0x0b, 0x21, 0x96, 0x45, 0x29, 0x35, 0x81, 0x17, 0x05, 0x01, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06, - 0x00, 0x04, 0x00, 0x00, 0xff, 0xff, 0x00, 0xfa, 0xfe, 0x5c, 0x01, 0xa6, - 0x04, 0x31, 0x10, 0x0f, 0x00, 0x05, 0x02, 0xa4, 0x04, 0x31, 0xc0, 0x00, - 0x00, 0x02, 0x00, 0x6a, 0xff, 0x0a, 0x04, 0x14, 0x05, 0x06, 0x00, 0x1e, - 0x00, 0x27, 0x00, 0x00, 0x01, 0x11, 0x36, 0x37, 0x33, 0x06, 0x07, 0x06, - 0x07, 0x15, 0x23, 0x35, 0x26, 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, 0x37, - 0x35, 0x33, 0x15, 0x16, 0x17, 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, 0x03, - 0x11, 0x06, 0x03, 0x06, 0x15, 0x14, 0x17, 0x16, 0x02, 0x7f, 0xc6, 0x23, - 0xac, 0x0c, 0x8f, 0x65, 0x95, 0x56, 0xe0, 0x78, 0x67, 0x96, 0x73, 0xb6, - 0x56, 0xef, 0x62, 0x32, 0x06, 0xac, 0x0f, 0x6b, 0x2c, 0x8d, 0xe7, 0x20, - 0x05, 0x80, 0x3b, 0x03, 0xb2, 0xfc, 0xbb, 0x15, 0xef, 0xd8, 0x71, 0x50, - 0x07, 0xc7, 0xc9, 0x14, 0xac, 0x93, 0xe0, 0x01, 0x1a, 0xa0, 0x7b, 0x13, - 0xb8, 0xb6, 0x11, 0xa9, 0x56, 0x77, 0x93, 0x3a, 0x18, 0xfc, 0xc3, 0x03, - 0x3f, 0x2b, 0xfe, 0xdf, 0x2c, 0x32, 0xef, 0x69, 0x31, 0x00, 0x00, 0x01, - 0x00, 0x35, 0xff, 0xd1, 0x04, 0x48, 0x05, 0xd5, 0x00, 0x41, 0x00, 0x00, - 0x01, 0x14, 0x1f, 0x01, 0x16, 0x17, 0x21, 0x15, 0x21, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x07, 0x36, 0x33, 0x32, 0x17, 0x16, 0x33, 0x32, 0x37, 0x17, - 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x27, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x23, 0x35, 0x33, 0x26, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, - 0x23, 0x02, 0x21, 0x22, 0x07, 0x06, 0x01, 0x2d, 0x34, 0x3e, 0x04, 0x03, - 0x01, 0x48, 0xfe, 0xe9, 0x1f, 0x4f, 0x35, 0x6e, 0x79, 0x81, 0x45, 0x72, - 0x60, 0x33, 0x4f, 0x5b, 0x56, 0x67, 0x7b, 0x15, 0x16, 0x58, 0x82, 0x75, - 0x36, 0x17, 0x16, 0x6d, 0x72, 0x62, 0xb3, 0x31, 0x1c, 0x31, 0xe2, 0xa6, - 0x54, 0x0f, 0x09, 0x7a, 0x7a, 0xba, 0x1c, 0x1d, 0xf8, 0x74, 0x54, 0x03, - 0xb5, 0x09, 0xfe, 0xf3, 0x9a, 0x50, 0x37, 0x04, 0x2f, 0x56, 0x5d, 0x6d, - 0x06, 0x07, 0x71, 0x57, 0x3a, 0x5f, 0x6c, 0x49, 0x6f, 0x50, 0x23, 0x1d, - 0x3e, 0x87, 0x65, 0x0c, 0x02, 0x2c, 0x29, 0x06, 0x03, 0x4c, 0x87, 0x9a, - 0x6e, 0x3d, 0x43, 0x4c, 0x53, 0x71, 0x8b, 0x3a, 0x24, 0x34, 0xac, 0x7b, - 0x7a, 0x12, 0x03, 0xa1, 0x76, 0xc4, 0x01, 0x3b, 0x61, 0x43, 0x00, 0x02, - 0x00, 0x89, 0x01, 0x10, 0x03, 0xe9, 0x04, 0x68, 0x00, 0x1f, 0x00, 0x2f, - 0x00, 0x00, 0x01, 0x07, 0x27, 0x06, 0x23, 0x22, 0x27, 0x07, 0x27, 0x37, - 0x26, 0x27, 0x34, 0x35, 0x34, 0x37, 0x36, 0x37, 0x27, 0x37, 0x17, 0x36, - 0x33, 0x32, 0x17, 0x37, 0x17, 0x07, 0x16, 0x17, 0x14, 0x07, 0x01, 0x22, - 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x03, 0xe1, 0x77, 0x6c, 0x52, 0x7b, 0x6e, 0x52, 0x69, 0x72, - 0x62, 0x3c, 0x06, 0x3f, 0x01, 0x02, 0x6f, 0x73, 0x71, 0x59, 0x6d, 0x77, - 0x52, 0x79, 0x74, 0x70, 0x32, 0x03, 0x3b, 0xfe, 0xbe, 0x62, 0x41, 0x36, - 0x4a, 0x3e, 0x53, 0x5e, 0x42, 0x39, 0x4b, 0x3d, 0x01, 0x85, 0x6e, 0x6c, - 0x3d, 0x33, 0x69, 0x75, 0x64, 0x52, 0x6e, 0x09, 0x08, 0x71, 0x5b, 0x03, - 0x02, 0x71, 0x6c, 0x70, 0x35, 0x39, 0x6c, 0x77, 0x70, 0x57, 0x68, 0x67, - 0x5f, 0x01, 0x9b, 0x49, 0x3d, 0x51, 0x5f, 0x40, 0x36, 0x47, 0x3d, 0x4f, - 0x64, 0x41, 0x34, 0x00, 0x00, 0x01, 0x00, 0x17, 0x00, 0x00, 0x04, 0x5c, - 0x05, 0xac, 0x00, 0x16, 0x00, 0x00, 0x01, 0x15, 0x21, 0x15, 0x21, 0x15, - 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x35, 0x21, 0x35, 0x21, 0x01, - 0x33, 0x09, 0x01, 0x33, 0x01, 0x03, 0xf6, 0xfe, 0xa4, 0x01, 0x5c, 0xfe, - 0xa4, 0xb5, 0xfe, 0xa0, 0x01, 0x60, 0xfe, 0xa0, 0x01, 0x35, 0xfe, 0x5d, - 0xae, 0x01, 0x7a, 0x01, 0x6f, 0xae, 0xfe, 0x65, 0x02, 0xd5, 0x68, 0x9e, - 0x69, 0xfe, 0x9a, 0x01, 0x66, 0x69, 0x9e, 0x68, 0x02, 0xd7, 0xfd, 0x6d, - 0x02, 0x93, 0xfd, 0x29, 0x00, 0x02, 0x00, 0xcd, 0xfe, 0x4e, 0x01, 0x48, - 0x05, 0xd5, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x13, 0x33, 0x11, 0x23, - 0x11, 0x33, 0x11, 0x23, 0xcd, 0x7b, 0x7b, 0x7b, 0x7b, 0x05, 0xd5, 0xfc, - 0xcb, 0xfe, 0xe3, 0xfc, 0xcb, 0x00, 0x00, 0x02, 0x00, 0x58, 0xfe, 0x4c, - 0x04, 0x0c, 0x05, 0xd5, 0x00, 0x45, 0x00, 0x55, 0x00, 0x00, 0x05, 0x14, - 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x25, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x32, 0x33, 0x32, 0x17, 0x16, 0x1d, 0x01, 0x23, - 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x17, 0x05, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x13, 0x05, 0x36, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x25, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x01, 0x4c, 0x92, 0x1d, 0x22, 0x6d, 0x36, 0x21, 0x54, 0x0d, 0x0f, 0xfe, - 0xa3, 0x91, 0x20, 0x0b, 0x71, 0x2a, 0x3c, 0x4d, 0x0a, 0x03, 0x68, 0x6b, - 0x9d, 0x06, 0x05, 0xac, 0x63, 0x57, 0xac, 0x54, 0x30, 0x42, 0x60, 0x34, - 0x23, 0x3b, 0x17, 0x23, 0x01, 0x2b, 0x90, 0x2e, 0x21, 0xdf, 0x56, 0x11, - 0x06, 0x6c, 0x6d, 0xa6, 0xc0, 0x64, 0x59, 0xe3, 0x01, 0x54, 0x7b, 0x16, - 0x04, 0x95, 0xfe, 0xb6, 0x6b, 0x1a, 0x0c, 0x27, 0x1c, 0x1d, 0xcc, 0x26, - 0x08, 0x49, 0x2c, 0x3c, 0x5b, 0x44, 0x0a, 0x0b, 0xef, 0x65, 0x7d, 0x2c, - 0x34, 0x93, 0x5e, 0x22, 0x20, 0x5a, 0x4f, 0x13, 0x15, 0x89, 0x61, 0x64, - 0x04, 0x71, 0x63, 0x97, 0x39, 0x35, 0x7a, 0x37, 0x20, 0x44, 0x2d, 0x3d, - 0x3e, 0x34, 0x14, 0x17, 0xc1, 0x5c, 0x5c, 0x41, 0x5d, 0xec, 0x53, 0x62, - 0x4e, 0x1e, 0x24, 0x92, 0x62, 0x64, 0x75, 0x68, 0xba, 0x01, 0xf2, 0xfc, - 0x41, 0x69, 0x13, 0x14, 0x7e, 0x67, 0xe0, 0x47, 0x42, 0x20, 0x26, 0x48, - 0x2f, 0x22, 0x00, 0x02, 0x00, 0x3d, 0x04, 0xe5, 0x02, 0x5e, 0x05, 0xb8, - 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x15, 0x23, 0x35, 0x21, 0x15, - 0x23, 0x35, 0x01, 0x12, 0xd5, 0x02, 0x21, 0xd5, 0x05, 0xb8, 0xd3, 0xd3, - 0xd3, 0xd3, 0x00, 0x03, 0xff, 0xe5, 0xff, 0xd3, 0x06, 0x02, 0x05, 0xf0, - 0x00, 0x21, 0x00, 0x39, 0x00, 0x51, 0x00, 0x00, 0x01, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, - 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x03, 0x20, 0x17, 0x16, 0x17, 0x16, - 0x15, 0x10, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x35, 0x10, 0x37, 0x36, 0x37, 0x36, 0x17, 0x22, 0x07, 0x06, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, - 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x04, 0x6a, 0x1c, 0x28, 0x5e, 0xc8, - 0xaf, 0x6f, 0x6f, 0x79, 0x6e, 0xac, 0xd7, 0x56, 0x18, 0x0f, 0x91, 0x24, - 0x4d, 0x24, 0x34, 0x84, 0x46, 0x36, 0x51, 0x46, 0x69, 0x96, 0x35, 0x08, - 0x06, 0xe5, 0x01, 0x04, 0xd0, 0xbf, 0x4f, 0x2c, 0x9f, 0x92, 0xe8, 0x7b, - 0x85, 0xf8, 0xcd, 0xbc, 0x52, 0x31, 0x9c, 0x8e, 0xe0, 0x7e, 0x87, 0xde, - 0xaf, 0xa4, 0x39, 0x19, 0x88, 0x7e, 0xc0, 0x58, 0x5d, 0xe7, 0xb1, 0xa6, - 0x37, 0x16, 0x8b, 0x80, 0xc5, 0x58, 0x02, 0x7f, 0x8a, 0x49, 0xaa, 0x83, - 0x84, 0xd2, 0xe2, 0x86, 0x79, 0xc4, 0x35, 0x44, 0x89, 0x24, 0x11, 0x78, - 0x5c, 0x8c, 0xa2, 0x64, 0x56, 0xbc, 0x1f, 0x23, 0x03, 0x71, 0x9c, 0x8e, - 0xdf, 0x7e, 0x86, 0xfe, 0xf6, 0xd1, 0xc0, 0x4c, 0x29, 0x99, 0x8c, 0xdb, - 0x83, 0x8b, 0x01, 0x04, 0xd0, 0xbf, 0x4f, 0x2d, 0x7f, 0x8d, 0x83, 0xcb, - 0x58, 0x5d, 0xdf, 0xb3, 0xa5, 0x3c, 0x1c, 0x8f, 0x86, 0xcf, 0x54, 0x59, - 0xe2, 0xb2, 0xa6, 0x3a, 0x1a, 0x00, 0x00, 0x03, 0x00, 0x4c, 0x02, 0x6d, - 0x02, 0xaa, 0x05, 0xf0, 0x00, 0x03, 0x00, 0x2d, 0x00, 0x3c, 0x00, 0x00, - 0x01, 0x15, 0x21, 0x35, 0x25, 0x15, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x3d, 0x01, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x23, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x15, 0x11, 0x14, 0x33, 0x32, 0x27, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x35, 0x02, 0x8f, 0xfd, 0xc9, 0x02, 0x52, 0x20, 0x22, 0x50, 0x17, 0x06, - 0x03, 0x65, 0x72, 0x81, 0x37, 0x1d, 0x4b, 0x4a, 0xac, 0x4f, 0x10, 0x06, - 0x54, 0x18, 0x1e, 0x53, 0x1d, 0x12, 0x09, 0x79, 0x05, 0xab, 0x29, 0x30, - 0xf9, 0x30, 0x09, 0xad, 0x25, 0x6a, 0x63, 0x20, 0x1d, 0x4e, 0x11, 0x15, - 0x5b, 0x39, 0x27, 0x02, 0xd5, 0x68, 0x68, 0xc3, 0x5b, 0x0c, 0x38, 0x0e, - 0x12, 0x58, 0x57, 0x2f, 0x3f, 0x6b, 0x30, 0x2f, 0x0d, 0x06, 0x1d, 0x0c, - 0x14, 0x1b, 0x44, 0x11, 0x05, 0x27, 0x19, 0x33, 0xb2, 0x24, 0x08, 0xc1, - 0xfe, 0x92, 0x30, 0xfa, 0x10, 0x0f, 0x0e, 0x1b, 0x1a, 0x2d, 0x4c, 0x10, - 0x04, 0x36, 0x25, 0x2c, 0x00, 0x02, 0x00, 0xc9, 0x00, 0xd9, 0x03, 0xa4, - 0x03, 0x81, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x00, 0x13, 0x35, 0x25, 0x15, - 0x07, 0x17, 0x15, 0x37, 0x35, 0x25, 0x15, 0x07, 0x17, 0x15, 0xc9, 0x01, - 0x37, 0xd9, 0xd9, 0x6d, 0x01, 0x37, 0xd9, 0xd9, 0x01, 0xd1, 0xb6, 0xfa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xf8, 0xb6, 0xfa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, - 0x00, 0x01, 0x00, 0x52, 0x00, 0xb0, 0x04, 0x5a, 0x03, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x13, 0x21, 0x11, 0x23, 0x11, 0x21, 0x52, 0x04, 0x08, 0x8f, - 0xfc, 0x87, 0x03, 0x00, 0xfd, 0xb0, 0x01, 0xc1, 0x00, 0x01, 0x00, 0x5e, - 0x01, 0xec, 0x02, 0x46, 0x02, 0x7f, 0x00, 0x03, 0x00, 0x00, 0x01, 0x15, - 0x21, 0x35, 0x02, 0x46, 0xfe, 0x18, 0x02, 0x7f, 0x93, 0x93, 0x00, 0x04, - 0xff, 0xe5, 0xff, 0xd3, 0x06, 0x02, 0x05, 0xf0, 0x00, 0x1a, 0x00, 0x25, - 0x00, 0x3d, 0x00, 0x55, 0x00, 0x00, 0x01, 0x16, 0x1f, 0x01, 0x16, 0x17, - 0x15, 0x23, 0x26, 0x3f, 0x01, 0x34, 0x27, 0x26, 0x23, 0x21, 0x11, 0x23, - 0x11, 0x21, 0x20, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x25, 0x21, 0x32, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x21, 0x13, 0x20, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x10, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, 0x37, 0x36, 0x17, 0x22, 0x07, 0x06, - 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x03, 0xf6, 0x55, 0x07, - 0x01, 0x05, 0x29, 0xa2, 0x22, 0x04, 0x02, 0x45, 0x1a, 0x25, 0xfe, 0xee, - 0x8f, 0x01, 0xa6, 0x01, 0x07, 0x17, 0x02, 0x2b, 0x17, 0xfe, 0x0b, 0x01, - 0x08, 0x7f, 0x16, 0x05, 0x4d, 0x1f, 0x2e, 0xfe, 0xf8, 0xc7, 0x01, 0x04, - 0xd0, 0xbf, 0x4f, 0x2c, 0x9f, 0x92, 0xe8, 0x7b, 0x85, 0xf8, 0xcd, 0xbc, - 0x52, 0x31, 0x9c, 0x8e, 0xe0, 0x7e, 0x87, 0xde, 0xaf, 0xa4, 0x39, 0x19, - 0x88, 0x7e, 0xc0, 0x58, 0x5d, 0xe7, 0xb1, 0xa6, 0x37, 0x16, 0x8b, 0x80, - 0xc5, 0x58, 0x02, 0xe1, 0x37, 0x6c, 0x8d, 0x41, 0x1e, 0x33, 0x51, 0x4c, - 0x52, 0x6b, 0x18, 0x09, 0xfe, 0x85, 0x03, 0x8f, 0xd5, 0x15, 0x18, 0x5a, - 0x35, 0x1c, 0x1a, 0x59, 0x15, 0x1b, 0x66, 0x19, 0x0a, 0x01, 0xc3, 0x9c, - 0x8e, 0xdf, 0x7e, 0x86, 0xfe, 0xf6, 0xd1, 0xc0, 0x4c, 0x29, 0x99, 0x8c, - 0xdb, 0x83, 0x8b, 0x01, 0x04, 0xd0, 0xbf, 0x4f, 0x2d, 0x7f, 0x8d, 0x83, - 0xcb, 0x58, 0x5d, 0xdf, 0xb3, 0xa5, 0x3c, 0x1c, 0x8f, 0x86, 0xcf, 0x54, - 0x59, 0xe2, 0xb2, 0xa6, 0x3a, 0x1a, 0x00, 0x01, 0x00, 0x39, 0x05, 0x0c, - 0x02, 0x6a, 0x05, 0x9c, 0x00, 0x03, 0x00, 0x00, 0x01, 0x15, 0x21, 0x35, - 0x02, 0x6a, 0xfd, 0xcf, 0x05, 0x9c, 0x90, 0x90, 0x00, 0x02, 0x01, 0x35, - 0x03, 0x10, 0x03, 0xa2, 0x05, 0x7d, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x00, - 0x01, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x34, 0x36, 0x17, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x02, 0x6d, 0x80, 0x5b, 0x5a, - 0x5e, 0x5b, 0x81, 0x7c, 0x5a, 0x5b, 0x02, 0xb7, 0x81, 0x59, 0x3c, 0x2e, - 0x44, 0x36, 0x44, 0x5f, 0x3a, 0x2c, 0x45, 0x35, 0x05, 0x7d, 0x5b, 0x5b, - 0x7f, 0x84, 0x5b, 0x59, 0x5a, 0x60, 0x7e, 0x80, 0xb5, 0x75, 0x45, 0x36, - 0x45, 0x59, 0x3c, 0x2e, 0x47, 0x35, 0x47, 0x5a, 0x39, 0x2d, 0x00, 0x02, - 0x00, 0x66, 0xff, 0xe9, 0x04, 0x46, 0x04, 0xfc, 0x00, 0x0b, 0x00, 0x0f, - 0x00, 0x00, 0x01, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x11, - 0x33, 0x11, 0x01, 0x15, 0x21, 0x35, 0x04, 0x46, 0xfe, 0x58, 0x90, 0xfe, - 0x58, 0x01, 0xa8, 0x90, 0x01, 0xa8, 0xfc, 0x20, 0x03, 0x54, 0x8f, 0xfe, - 0x58, 0x01, 0xa8, 0x8f, 0x01, 0xa8, 0xfe, 0x58, 0xfd, 0x25, 0x90, 0x90, - 0x00, 0x01, 0x00, 0x27, 0x02, 0x46, 0x02, 0x9c, 0x05, 0xac, 0x00, 0x25, - 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, 0x07, 0x23, 0x36, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x0f, 0x01, 0x06, 0x07, 0x06, - 0x07, 0x21, 0x15, 0x21, 0x36, 0x37, 0x36, 0x37, 0x36, 0x3f, 0x01, 0x36, - 0x35, 0x34, 0x27, 0x26, 0x01, 0x6d, 0x8b, 0x1e, 0x07, 0x03, 0x7f, 0x08, - 0xc6, 0x2e, 0x3a, 0x96, 0x55, 0x40, 0xaa, 0x0d, 0x0e, 0x81, 0x59, 0x21, - 0x10, 0x0b, 0x01, 0xd5, 0xfd, 0x91, 0x08, 0x35, 0x34, 0x8f, 0x02, 0x02, - 0x77, 0x79, 0x43, 0x2f, 0x05, 0x3f, 0x85, 0x1c, 0x29, 0xfe, 0x2e, 0x0b, - 0x5b, 0x44, 0x63, 0x9b, 0x5f, 0x07, 0x07, 0x42, 0x2f, 0x36, 0x1a, 0x25, - 0x76, 0x96, 0x4e, 0x4c, 0x4d, 0x01, 0x01, 0x3f, 0x41, 0x61, 0x4e, 0x2d, - 0x1e, 0x00, 0x00, 0x01, 0x00, 0x21, 0x02, 0x29, 0x02, 0x93, 0x05, 0xac, - 0x00, 0x30, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, 0x15, 0x23, 0x12, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x33, 0x16, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x23, 0x35, 0x32, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x01, 0x5a, 0x7e, 0x1d, 0x0b, 0x81, 0x06, - 0xf4, 0x16, 0x17, 0xa7, 0x4a, 0x2c, 0x75, 0x91, 0x6d, 0x53, 0x7d, 0xc8, - 0x49, 0x24, 0x7f, 0x07, 0x61, 0x22, 0x30, 0x7d, 0x2a, 0x11, 0x3f, 0x18, - 0x1f, 0x1f, 0x69, 0x99, 0x2b, 0x1e, 0x4d, 0x22, 0x05, 0x3f, 0x5d, 0x23, - 0x36, 0x01, 0x0b, 0x16, 0x02, 0x65, 0x3c, 0x55, 0x78, 0x36, 0x31, 0x9c, - 0x8d, 0x4b, 0x3a, 0x87, 0x41, 0x5b, 0x8b, 0x20, 0x0b, 0x56, 0x22, 0x2d, - 0x51, 0x29, 0x10, 0x06, 0x04, 0x68, 0x26, 0x1b, 0x3c, 0x5a, 0x22, 0x0f, - 0x00, 0x01, 0x00, 0xbc, 0x04, 0xbc, 0x02, 0x68, 0x05, 0xec, 0x00, 0x03, - 0x00, 0x00, 0x01, 0x33, 0x01, 0x23, 0x01, 0x81, 0xe7, 0xfe, 0xcf, 0x7b, - 0x05, 0xec, 0xfe, 0xd0, 0x00, 0x01, 0x00, 0x85, 0xfe, 0x3d, 0x04, 0x5a, - 0x04, 0x31, 0x00, 0x20, 0x00, 0x00, 0x25, 0x15, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x27, 0x06, 0x23, 0x22, 0x27, 0x11, 0x23, 0x11, 0x33, 0x11, 0x14, - 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x17, - 0x16, 0x33, 0x32, 0x04, 0x5a, 0x44, 0x31, 0x8f, 0x1a, 0x06, 0x01, 0x78, - 0xd6, 0x6f, 0x49, 0xaa, 0xaa, 0x5a, 0x36, 0x4b, 0x93, 0x50, 0x42, 0xaa, - 0x4f, 0x06, 0x07, 0x11, 0x64, 0x81, 0x12, 0x74, 0x18, 0x1e, 0xaa, 0x35, - 0xfe, 0x37, 0x05, 0xf4, 0xfd, 0x08, 0x79, 0x39, 0x21, 0x76, 0x61, 0x94, - 0x02, 0x60, 0xfc, 0x83, 0x4d, 0x06, 0x01, 0x00, 0x00, 0x01, 0x00, 0x62, - 0xfe, 0x96, 0x04, 0x2d, 0x05, 0xd5, 0x00, 0x13, 0x00, 0x00, 0x01, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x21, 0x15, 0x23, - 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x02, 0x0a, 0xd1, 0x75, 0x62, 0x75, - 0x6f, 0xa8, 0x1f, 0x20, 0x02, 0x00, 0x75, 0x83, 0xa8, 0x83, 0x02, 0x12, - 0x0b, 0x98, 0x7f, 0xb5, 0xc1, 0x8b, 0x84, 0x18, 0x04, 0x83, 0xf9, 0x44, - 0x06, 0xbc, 0xf9, 0x44, 0x00, 0x01, 0x00, 0xb2, 0x02, 0x6a, 0x01, 0xb0, - 0x03, 0x6a, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x01, 0xb0, - 0xfe, 0x03, 0x6a, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x50, - 0xfe, 0x4a, 0x02, 0x4c, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x13, 0x17, - 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x27, 0x37, 0x33, 0x07, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x7b, 0x6e, 0x2e, 0x2d, 0x43, 0x1e, - 0x0d, 0x3c, 0x0f, 0x13, 0x1f, 0x21, 0x18, 0x56, 0x4e, 0x2f, 0x1a, 0x1f, - 0x7a, 0x1f, 0x09, 0x67, 0x3d, 0x58, 0x50, 0x58, 0x22, 0x36, 0xfe, 0xe1, - 0x32, 0x11, 0x2e, 0x15, 0x19, 0x3a, 0x0e, 0x04, 0x11, 0x0f, 0xbc, 0x73, - 0x04, 0x54, 0x18, 0x1d, 0x6f, 0x31, 0x1e, 0x21, 0x0d, 0x17, 0x00, 0x01, - 0x00, 0x7d, 0x02, 0x46, 0x01, 0xc7, 0x05, 0xac, 0x00, 0x0b, 0x00, 0x00, - 0x01, 0x23, 0x35, 0x37, 0x3e, 0x01, 0x37, 0x36, 0x37, 0x33, 0x11, 0x23, - 0x01, 0x48, 0xcb, 0x1f, 0x6c, 0x4a, 0x18, 0x03, 0x02, 0x58, 0x7f, 0x04, - 0xa4, 0x5e, 0x02, 0x0a, 0x38, 0x56, 0x07, 0x09, 0xfc, 0x9a, 0x00, 0x03, - 0x00, 0x52, 0x02, 0x6d, 0x02, 0x98, 0x05, 0xf0, 0x00, 0x03, 0x00, 0x13, - 0x00, 0x23, 0x00, 0x00, 0x01, 0x15, 0x21, 0x35, 0x01, 0x32, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x17, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x35, 0x34, 0x27, 0x26, 0x02, 0x83, 0xfd, 0xe5, 0x01, 0x0d, 0xbb, 0x45, - 0x23, 0x79, 0x46, 0x64, 0xb1, 0x49, 0x29, 0x82, 0x43, 0x5e, 0x68, 0x2c, - 0x18, 0x56, 0x25, 0x31, 0x65, 0x2d, 0x1a, 0x5b, 0x23, 0x02, 0xd5, 0x68, - 0x68, 0x03, 0x1b, 0xa1, 0x51, 0x73, 0xcf, 0x58, 0x33, 0x92, 0x54, 0x7a, - 0xde, 0x55, 0x2c, 0x6b, 0x68, 0x3a, 0x52, 0xa2, 0x3a, 0x19, 0x64, 0x3a, - 0x53, 0xaa, 0x38, 0x16, 0x00, 0x02, 0x00, 0xc9, 0x00, 0xd9, 0x03, 0x9c, - 0x03, 0x81, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x15, 0x05, 0x35, - 0x37, 0x27, 0x35, 0x05, 0x15, 0x05, 0x35, 0x37, 0x27, 0x35, 0x02, 0x04, - 0xfe, 0xc5, 0xdd, 0xdd, 0x02, 0xd3, 0xfe, 0xc4, 0xdd, 0xdd, 0x02, 0x89, - 0xb6, 0xfa, 0xaa, 0xaa, 0xaa, 0xaa, 0xf8, 0xb6, 0xfa, 0xaa, 0xaa, 0xaa, - 0xaa, 0x00, 0x00, 0x04, 0x00, 0x7d, 0xff, 0xd7, 0x06, 0xcb, 0x05, 0xac, - 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x1a, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x23, - 0x35, 0x37, 0x3e, 0x01, 0x37, 0x36, 0x37, 0x33, 0x11, 0x23, 0x01, 0x33, - 0x01, 0x23, 0x25, 0x21, 0x35, 0x01, 0x33, 0x11, 0x33, 0x15, 0x23, 0x15, - 0x23, 0x19, 0x01, 0x01, 0x01, 0x48, 0xcb, 0x1f, 0x6c, 0x4a, 0x18, 0x03, - 0x02, 0x58, 0x7f, 0x03, 0xdd, 0x77, 0xfc, 0x62, 0x77, 0x04, 0x3c, 0xfe, - 0x7f, 0x01, 0xa1, 0x5f, 0x89, 0x89, 0x7f, 0xfe, 0xf7, 0x04, 0xa4, 0x5e, - 0x02, 0x0a, 0x38, 0x56, 0x07, 0x09, 0xfc, 0x9a, 0x03, 0x66, 0xfa, 0x2b, - 0xf6, 0x79, 0x02, 0x20, 0xfd, 0xd3, 0x6c, 0xcd, 0x01, 0x39, 0x01, 0x5d, - 0xfe, 0xa3, 0x00, 0x03, 0x00, 0x7d, 0xff, 0xd7, 0x06, 0xc1, 0x05, 0xac, - 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x35, 0x00, 0x00, 0x01, 0x23, 0x35, 0x37, - 0x3e, 0x01, 0x37, 0x36, 0x37, 0x33, 0x11, 0x23, 0x01, 0x33, 0x01, 0x23, - 0x01, 0x22, 0x07, 0x06, 0x07, 0x23, 0x12, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x21, - 0x15, 0x21, 0x36, 0x37, 0x36, 0x37, 0x36, 0x3f, 0x01, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x01, 0x48, 0xcb, 0x1f, 0x6c, 0x4a, 0x18, 0x03, 0x02, 0x58, - 0x7f, 0x03, 0xac, 0x76, 0xfc, 0x63, 0x77, 0x04, 0x3b, 0x8f, 0x1c, 0x05, - 0x02, 0x7f, 0x07, 0xd3, 0x2a, 0x32, 0x96, 0x55, 0x40, 0xaa, 0x0d, 0x0e, - 0x81, 0x59, 0x21, 0x10, 0x0c, 0x01, 0xd5, 0xfd, 0x92, 0x08, 0x35, 0x34, - 0x8d, 0x03, 0x03, 0x77, 0x78, 0x43, 0x2e, 0x04, 0xa4, 0x5e, 0x02, 0x0a, - 0x38, 0x56, 0x07, 0x09, 0xfc, 0x9a, 0x03, 0x66, 0xfa, 0x2b, 0x03, 0x23, - 0x8e, 0x1a, 0x23, 0x01, 0x06, 0x29, 0x08, 0x5b, 0x44, 0x63, 0x9a, 0x60, - 0x07, 0x07, 0x41, 0x2f, 0x36, 0x1a, 0x25, 0x77, 0x97, 0x4d, 0x4d, 0x4b, - 0x01, 0x02, 0x3f, 0x40, 0x62, 0x4e, 0x2d, 0x1f, 0x00, 0x04, 0x00, 0x21, - 0xff, 0xd7, 0x06, 0xcb, 0x05, 0xac, 0x00, 0x30, 0x00, 0x34, 0x00, 0x3f, - 0x00, 0x42, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, 0x15, 0x23, 0x12, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x33, 0x16, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x23, 0x35, 0x32, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x25, 0x33, 0x01, 0x23, 0x25, 0x21, 0x35, - 0x01, 0x33, 0x11, 0x33, 0x15, 0x23, 0x15, 0x23, 0x19, 0x01, 0x01, 0x01, - 0x5a, 0x7e, 0x1d, 0x0b, 0x81, 0x06, 0xf4, 0x16, 0x17, 0xa7, 0x4a, 0x2c, - 0x75, 0x91, 0x6d, 0x53, 0x7d, 0xc8, 0x49, 0x24, 0x7f, 0x07, 0x61, 0x22, - 0x30, 0x7d, 0x2a, 0x11, 0x3f, 0x18, 0x1f, 0x1f, 0x69, 0x99, 0x2b, 0x1e, - 0x4d, 0x22, 0x03, 0xb2, 0x77, 0xfc, 0x62, 0x76, 0x04, 0x27, 0xfe, 0x7f, - 0x01, 0xa1, 0x5f, 0x89, 0x89, 0x7f, 0xfe, 0xf7, 0x05, 0x3f, 0x5d, 0x23, - 0x36, 0x01, 0x0b, 0x16, 0x02, 0x65, 0x3c, 0x55, 0x78, 0x36, 0x31, 0x9c, - 0x8d, 0x4b, 0x3a, 0x87, 0x41, 0x5b, 0x8b, 0x20, 0x0b, 0x56, 0x22, 0x2d, - 0x51, 0x29, 0x10, 0x06, 0x04, 0x68, 0x26, 0x1b, 0x3c, 0x5a, 0x22, 0x0f, - 0x6d, 0xfa, 0x2b, 0xf6, 0x79, 0x02, 0x20, 0xfd, 0xd3, 0x6c, 0xcd, 0x01, - 0x39, 0x01, 0x5d, 0xfe, 0xa3, 0x00, 0xff, 0xff, 0x00, 0xc5, 0xfe, 0x43, - 0x04, 0x39, 0x04, 0x31, 0x10, 0x0f, 0x00, 0x23, 0x04, 0xd7, 0x04, 0x31, - 0xc0, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5, - 0x10, 0x27, 0x00, 0xc6, 0x01, 0x58, 0x01, 0x98, 0x10, 0x06, 0x00, 0x25, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5, - 0x10, 0x27, 0x00, 0xc5, 0x01, 0x75, 0x01, 0x98, 0x10, 0x06, 0x00, 0x25, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5, - 0x10, 0x27, 0x00, 0xc4, 0x01, 0x60, 0x01, 0x98, 0x10, 0x06, 0x00, 0x25, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5, - 0x10, 0x27, 0x00, 0xc8, 0x01, 0x66, 0x01, 0x81, 0x10, 0x06, 0x00, 0x25, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x07, 0x3b, - 0x10, 0x27, 0x00, 0x6b, 0x01, 0x64, 0x01, 0x83, 0x10, 0x06, 0x00, 0x25, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x23, 0x00, 0x00, 0x05, 0x39, 0x05, 0xd5, - 0x10, 0x27, 0x00, 0xc7, 0x01, 0x58, 0x01, 0x98, 0x10, 0x06, 0x00, 0x25, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x17, 0x00, 0x00, 0x07, 0x9a, 0x05, 0xd5, - 0x00, 0x0f, 0x00, 0x13, 0x00, 0x00, 0x01, 0x21, 0x03, 0x23, 0x01, 0x21, - 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x19, 0x01, - 0x23, 0x01, 0x03, 0xbe, 0xfd, 0xda, 0xaf, 0xd2, 0x02, 0x64, 0x04, 0xfa, - 0xfd, 0x08, 0x02, 0xd1, 0xfd, 0x2f, 0x03, 0x1d, 0xfc, 0x24, 0xcc, 0xfe, - 0xe5, 0x01, 0xb6, 0xfe, 0x4a, 0x05, 0xd5, 0xa8, 0xfe, 0x23, 0xa8, 0xfe, - 0x00, 0xa8, 0x02, 0x5e, 0x02, 0xcf, 0xfd, 0x31, 0x00, 0x01, 0x00, 0x62, - 0xfe, 0x4a, 0x05, 0x6a, 0x05, 0xee, 0x00, 0x46, 0x00, 0x00, 0x25, 0x32, - 0x37, 0x36, 0x37, 0x33, 0x02, 0x05, 0x06, 0x23, 0x07, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x37, - 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, - 0x07, 0x27, 0x37, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x12, 0x25, 0x36, 0x33, 0x20, 0x13, 0x16, 0x17, 0x23, 0x26, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x11, 0x10, 0x17, 0x16, 0x03, 0x06, 0xdf, - 0x66, 0x3f, 0x1c, 0xc4, 0x3f, 0xfe, 0x31, 0x29, 0x2b, 0x1a, 0x1a, 0x1f, - 0x7a, 0x1f, 0x09, 0x65, 0x3e, 0x59, 0x53, 0x5d, 0x21, 0x2f, 0x2b, 0x68, - 0x32, 0x2f, 0x43, 0x1e, 0x0d, 0x3c, 0x0f, 0x13, 0x1f, 0x21, 0x16, 0x3f, - 0x9a, 0x4f, 0x21, 0x27, 0xb7, 0x49, 0x27, 0x65, 0x92, 0x01, 0x3a, 0x3a, - 0x3f, 0x01, 0xa2, 0x7c, 0x15, 0x0d, 0xc3, 0x2d, 0xa3, 0x50, 0x71, 0xe0, - 0x7e, 0x79, 0x91, 0x82, 0x77, 0x9d, 0x61, 0xac, 0xfd, 0xe0, 0x2c, 0x04, - 0x44, 0x04, 0x54, 0x18, 0x1d, 0x6d, 0x32, 0x1f, 0x24, 0x0c, 0x15, 0x52, - 0x30, 0x13, 0x2e, 0x15, 0x19, 0x3a, 0x0e, 0x04, 0x11, 0x0f, 0x8d, 0x16, - 0x28, 0x11, 0x1b, 0x84, 0xfc, 0x86, 0x98, 0xfc, 0xc5, 0x01, 0x1d, 0x2e, - 0x09, 0xfe, 0x9b, 0x3c, 0x47, 0xdd, 0x42, 0x21, 0xae, 0xa5, 0xfe, 0xe8, - 0xfe, 0xd6, 0xa6, 0x94, 0xff, 0xff, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xe7, - 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc6, 0x01, 0x7b, 0x01, 0x98, 0x10, 0x06, - 0x00, 0x29, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xe7, - 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc5, 0x01, 0x6d, 0x01, 0x98, 0x10, 0x06, - 0x00, 0x29, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xe7, - 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc4, 0x01, 0x73, 0x01, 0x96, 0x10, 0x06, - 0x00, 0x29, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb8, 0x00, 0x00, 0x04, 0xe7, - 0x07, 0x3b, 0x10, 0x27, 0x00, 0x6b, 0x01, 0x71, 0x01, 0x83, 0x10, 0x06, - 0x00, 0x29, 0x00, 0x00, 0xff, 0xff, 0x00, 0xcd, 0x00, 0x00, 0x01, 0x8d, - 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc6, 0xff, 0xd3, 0x01, 0x98, 0x10, 0x06, - 0x00, 0x2d, 0x00, 0x00, 0xff, 0xff, 0x00, 0xcd, 0x00, 0x00, 0x01, 0x8d, - 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc5, 0xff, 0xd5, 0x01, 0x98, 0x10, 0x06, - 0x00, 0x2d, 0x00, 0x00, 0xff, 0xff, 0x00, 0xcd, 0x00, 0x00, 0x01, 0x8d, - 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc4, 0xff, 0xd5, 0x01, 0x98, 0x10, 0x06, - 0x00, 0x2d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1c, 0x00, 0x00, 0x02, 0x3d, - 0x07, 0x3b, 0x10, 0x27, 0x00, 0x6b, 0xff, 0xdf, 0x01, 0x83, 0x10, 0x06, - 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x29, 0x00, 0x00, 0x05, 0x56, - 0x05, 0xd5, 0x00, 0x0e, 0x00, 0x1d, 0x00, 0x00, 0x13, 0x23, 0x35, 0x33, - 0x11, 0x21, 0x20, 0x17, 0x16, 0x11, 0x10, 0x07, 0x06, 0x29, 0x01, 0x13, - 0x11, 0x21, 0x20, 0x13, 0x36, 0x35, 0x10, 0x27, 0x26, 0x23, 0x21, 0x11, - 0x21, 0x15, 0xb6, 0x8d, 0x8d, 0x02, 0x42, 0x01, 0x19, 0xa2, 0xa3, 0xb0, - 0xa1, 0xfe, 0xf3, 0xfd, 0xbe, 0xbf, 0x01, 0x62, 0x01, 0x37, 0x61, 0x29, - 0xf2, 0x58, 0x77, 0xfe, 0x9e, 0x01, 0x5e, 0x02, 0xb6, 0x89, 0x02, 0x96, - 0xc6, 0xc7, 0xfe, 0xa4, 0xfe, 0x93, 0xc9, 0xb6, 0x02, 0xb6, 0xfd, 0xf2, - 0x01, 0x20, 0x7a, 0xaa, 0x01, 0xa0, 0x76, 0x2b, 0xfe, 0x12, 0x89, 0x00, - 0xff, 0xff, 0x00, 0x9c, 0x00, 0x00, 0x05, 0x2b, 0x05, 0xd5, 0x10, 0x27, - 0x00, 0xc8, 0x01, 0x98, 0x01, 0x81, 0x10, 0x06, 0x00, 0x32, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0, 0x05, 0xee, 0x10, 0x27, - 0x00, 0xc6, 0x01, 0xcb, 0x01, 0x98, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0, 0x05, 0xee, 0x10, 0x27, - 0x00, 0xc5, 0x01, 0xd5, 0x01, 0x98, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0, 0x05, 0xee, 0x10, 0x27, - 0x00, 0xc4, 0x01, 0xd1, 0x01, 0x98, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0, 0x05, 0xee, 0x10, 0x27, - 0x00, 0xc8, 0x01, 0xd1, 0x01, 0x81, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x4e, 0xff, 0xd1, 0x05, 0xf0, 0x07, 0x3b, 0x10, 0x27, - 0x00, 0x6b, 0x01, 0xcf, 0x01, 0x83, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xc3, 0x00, 0x46, 0x03, 0xe7, 0x03, 0x6a, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x17, 0x09, 0x01, 0x07, 0x09, 0x01, 0x27, 0x09, 0x01, - 0x37, 0x01, 0x03, 0x81, 0x64, 0xfe, 0xd5, 0x01, 0x2d, 0x66, 0xfe, 0xd3, - 0xfe, 0xd5, 0x66, 0x01, 0x2d, 0xfe, 0xd5, 0x64, 0x01, 0x2b, 0x03, 0x6a, - 0x66, 0xfe, 0xd5, 0xfe, 0xd3, 0x66, 0x01, 0x2d, 0xfe, 0xd5, 0x64, 0x01, - 0x2d, 0x01, 0x2b, 0x64, 0xfe, 0xd7, 0x00, 0x03, 0x00, 0x3d, 0xff, 0xd1, - 0x05, 0xf4, 0x06, 0x0a, 0x00, 0x1b, 0x00, 0x26, 0x00, 0x31, 0x00, 0x00, - 0x3f, 0x01, 0x26, 0x11, 0x10, 0x37, 0x36, 0x25, 0x36, 0x33, 0x20, 0x17, - 0x37, 0x17, 0x07, 0x16, 0x13, 0x16, 0x15, 0x10, 0x07, 0x06, 0x05, 0x06, - 0x23, 0x20, 0x27, 0x07, 0x13, 0x01, 0x26, 0x23, 0x22, 0x07, 0x06, 0x03, - 0x06, 0x15, 0x14, 0x09, 0x01, 0x16, 0x33, 0x32, 0x37, 0x36, 0x13, 0x36, - 0x35, 0x34, 0x3d, 0xa6, 0x9b, 0xa8, 0x9e, 0x01, 0x05, 0x41, 0x45, 0x01, - 0x17, 0xc0, 0xb2, 0x52, 0xb7, 0x92, 0x16, 0x04, 0xa8, 0x9e, 0xfe, 0xfb, - 0x40, 0x45, 0xfe, 0xd9, 0xc7, 0x9e, 0xd7, 0x03, 0x13, 0x97, 0xc7, 0xe4, - 0x90, 0x94, 0x0a, 0x01, 0x03, 0xb8, 0xfc, 0xe8, 0x97, 0xdc, 0xe2, 0x91, - 0x93, 0x0b, 0x01, 0x27, 0xb6, 0xdb, 0x01, 0x29, 0x01, 0x3e, 0xd2, 0xc7, - 0x2b, 0x0b, 0xa6, 0xc2, 0x49, 0xc7, 0xb7, 0xfe, 0xf1, 0x2b, 0x2c, 0xfe, - 0xc2, 0xd2, 0xc6, 0x2b, 0x0b, 0xb8, 0xac, 0x01, 0x8b, 0x03, 0x5b, 0x83, - 0x9b, 0x9e, 0xfe, 0xf8, 0x12, 0x12, 0xd4, 0x02, 0x62, 0xfc, 0xa1, 0x97, - 0x9a, 0x9e, 0x01, 0x06, 0x13, 0x13, 0xea, 0x00, 0xff, 0xff, 0x00, 0xae, - 0xff, 0xd1, 0x05, 0x29, 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc6, 0x01, 0x98, - 0x01, 0x98, 0x10, 0x06, 0x00, 0x39, 0x00, 0x00, 0xff, 0xff, 0x00, 0xae, - 0xff, 0xd1, 0x05, 0x29, 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc5, 0x01, 0x98, - 0x01, 0x98, 0x10, 0x06, 0x00, 0x39, 0x00, 0x00, 0xff, 0xff, 0x00, 0xae, - 0xff, 0xd1, 0x05, 0x29, 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc4, 0x01, 0x9e, - 0x01, 0x96, 0x10, 0x06, 0x00, 0x39, 0x00, 0x00, 0xff, 0xff, 0x00, 0xae, - 0xff, 0xd1, 0x05, 0x29, 0x07, 0x3b, 0x10, 0x27, 0x00, 0x6b, 0x01, 0x9e, - 0x01, 0x83, 0x10, 0x06, 0x00, 0x39, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1b, - 0x00, 0x00, 0x05, 0x4a, 0x05, 0xd5, 0x10, 0x27, 0x00, 0xc5, 0x01, 0x6a, - 0x01, 0x98, 0x10, 0x06, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x02, 0x00, 0xba, - 0x00, 0x00, 0x04, 0xee, 0x05, 0xd5, 0x00, 0x0e, 0x00, 0x19, 0x00, 0x00, - 0x01, 0x11, 0x23, 0x11, 0x33, 0x15, 0x21, 0x32, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x23, 0x25, 0x21, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x23, 0x21, 0x01, 0x79, 0xbf, 0xbf, 0x01, 0xaa, 0xf0, 0x7b, 0x60, 0x77, - 0x74, 0xb5, 0xfe, 0x2b, 0x01, 0x8d, 0xae, 0x47, 0x26, 0x77, 0x43, 0x61, - 0xfe, 0x73, 0x01, 0x83, 0xfe, 0x7d, 0x05, 0xd5, 0xf6, 0x90, 0x71, 0xb1, - 0xbd, 0x78, 0x75, 0xa8, 0x72, 0x3e, 0x56, 0x9e, 0x43, 0x25, 0x00, 0x01, - 0x00, 0x89, 0xff, 0xe1, 0x04, 0x91, 0x05, 0xd3, 0x00, 0x31, 0x00, 0x00, - 0x01, 0x20, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, - 0x15, 0x11, 0x23, 0x11, 0x34, 0x37, 0x36, 0x33, 0x20, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x16, 0x15, 0x10, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x35, 0x16, 0x33, 0x20, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x2b, 0x01, 0x02, 0x5a, 0x01, 0x0e, 0x29, 0x07, 0x71, 0x4e, 0x79, 0xd1, - 0x39, 0x19, 0xb4, 0x8b, 0x7d, 0xd1, 0x01, 0x00, 0x85, 0x65, 0x97, 0x03, - 0x0e, 0x71, 0x46, 0x36, 0xdf, 0x79, 0xac, 0x31, 0x3b, 0x2d, 0x2d, 0x01, - 0x23, 0x30, 0x09, 0xec, 0x32, 0x3e, 0x21, 0x03, 0x6a, 0xac, 0x1c, 0x20, - 0x7e, 0x3d, 0x2a, 0x87, 0x3c, 0x60, 0xfb, 0xec, 0x04, 0x42, 0xc2, 0x6d, - 0x62, 0x7e, 0x60, 0x93, 0xbe, 0x66, 0x02, 0x09, 0x1f, 0x7a, 0x5e, 0x5d, - 0xfe, 0xbf, 0x7b, 0x42, 0x0f, 0x99, 0x06, 0xda, 0x29, 0x30, 0xef, 0x27, - 0x09, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x04, 0x50, - 0x10, 0x27, 0x00, 0xc6, 0x00, 0xec, 0x00, 0x00, 0x10, 0x06, 0x00, 0x45, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x04, 0x50, - 0x10, 0x27, 0x00, 0xc5, 0x00, 0xec, 0xff, 0xfe, 0x10, 0x06, 0x00, 0x45, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x04, 0x50, - 0x10, 0x27, 0x00, 0xc4, 0x00, 0xe5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x45, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x04, 0x50, - 0x10, 0x27, 0x00, 0xc8, 0x00, 0xe7, 0xff, 0xe3, 0x10, 0x06, 0x00, 0x45, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x05, 0x9d, - 0x10, 0x27, 0x00, 0x6b, 0x00, 0xe5, 0xff, 0xe5, 0x10, 0x06, 0x00, 0x45, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x56, 0xff, 0xd1, 0x04, 0x48, 0x04, 0x50, - 0x10, 0x27, 0x00, 0xc7, 0x00, 0xdd, 0x00, 0x00, 0x10, 0x06, 0x00, 0x45, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x46, 0xff, 0xd1, 0x06, 0xc3, 0x04, 0x50, - 0x00, 0x3c, 0x00, 0x4d, 0x00, 0x56, 0x00, 0x00, 0x01, 0x16, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x33, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x2f, - 0x01, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x25, 0x36, 0x33, 0x36, 0x37, 0x36, 0x3d, 0x01, 0x34, 0x27, 0x26, 0x23, - 0x22, 0x07, 0x06, 0x07, 0x23, 0x12, 0x25, 0x36, 0x33, 0x20, 0x17, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x01, 0x32, 0x37, - 0x36, 0x37, 0x36, 0x3d, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x01, 0x21, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x03, - 0xac, 0x05, 0xa7, 0x41, 0x4e, 0xd1, 0x4a, 0xac, 0x26, 0x9f, 0x6e, 0x96, - 0xb7, 0x77, 0x24, 0x1a, 0x21, 0xa2, 0x97, 0x3d, 0x44, 0xb3, 0x5e, 0x47, - 0x98, 0x70, 0x01, 0x02, 0x05, 0x05, 0x7e, 0x20, 0x14, 0xa4, 0x23, 0x2a, - 0xb7, 0x31, 0x0d, 0x05, 0xac, 0x0a, 0x01, 0x20, 0x3a, 0x46, 0x01, 0x07, - 0x5f, 0x51, 0x96, 0x3c, 0x3f, 0xc0, 0x83, 0x48, 0x26, 0x2b, 0xfb, 0x02, - 0x9e, 0x6a, 0x36, 0x08, 0x01, 0x43, 0x9f, 0x94, 0x37, 0x67, 0x5b, 0x30, - 0x02, 0x2d, 0x02, 0x5a, 0x63, 0x4f, 0x75, 0x93, 0x56, 0x41, 0x01, 0xdf, - 0xfe, 0x52, 0x20, 0xd7, 0xcf, 0x62, 0x44, 0x65, 0x1f, 0x26, 0x37, 0xa8, - 0x29, 0x10, 0x6e, 0x53, 0x7c, 0xbc, 0x50, 0x3b, 0x17, 0x01, 0x0b, 0x27, - 0x18, 0x2e, 0x2d, 0x82, 0x19, 0x05, 0x73, 0x20, 0x2b, 0x01, 0x1e, 0x34, - 0x0a, 0xa8, 0x72, 0x27, 0x0f, 0x79, 0x44, 0x5e, 0x73, 0xe3, 0xfe, 0x87, - 0x6f, 0x38, 0x2d, 0x05, 0x03, 0xce, 0x1d, 0x17, 0x16, 0x18, 0x2e, 0x6e, - 0x69, 0x2c, 0x17, 0x02, 0x04, 0xa2, 0x5c, 0x4a, 0x72, 0x55, 0x00, 0x01, - 0x00, 0x3f, 0xfe, 0x4a, 0x03, 0xd1, 0x04, 0x50, 0x00, 0x3e, 0x00, 0x00, - 0x05, 0x24, 0x03, 0x26, 0x35, 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, - 0x16, 0x33, 0x32, 0x13, 0x33, 0x06, 0x07, 0x06, 0x23, 0x07, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, - 0x37, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, - 0x22, 0x07, 0x27, 0x01, 0xcd, 0xfe, 0xf2, 0x59, 0x27, 0x8b, 0x82, 0xd1, - 0xf3, 0x6d, 0x3d, 0x0b, 0xac, 0x18, 0x83, 0x2c, 0x37, 0xa5, 0x4e, 0x36, - 0x7a, 0x49, 0x6a, 0xda, 0x2c, 0xac, 0x0c, 0x8b, 0x72, 0xab, 0x1b, 0x1d, - 0x1c, 0x77, 0x21, 0x0a, 0x67, 0x3d, 0x58, 0x4f, 0x53, 0x24, 0x3a, 0x2b, - 0x69, 0x31, 0x2f, 0x42, 0x1f, 0x0e, 0x3d, 0x0f, 0x13, 0x20, 0x1f, 0x19, - 0x2b, 0x32, 0x01, 0x05, 0x70, 0x8a, 0x01, 0x14, 0xa1, 0x95, 0xa5, 0x5c, - 0x86, 0xa9, 0x30, 0x10, 0x9b, 0x6c, 0xa7, 0xf0, 0x69, 0x3e, 0x01, 0x04, - 0xd3, 0x71, 0x5c, 0x44, 0x04, 0x51, 0x19, 0x1f, 0x6f, 0x31, 0x1e, 0x1e, - 0x0c, 0x19, 0x54, 0x30, 0x13, 0x2e, 0x15, 0x19, 0x3a, 0x0e, 0x04, 0x11, - 0x0f, 0x00, 0xff, 0xff, 0x00, 0x52, 0xff, 0xd1, 0x04, 0x1b, 0x04, 0x50, - 0x10, 0x27, 0x00, 0xc6, 0x00, 0xf2, 0x00, 0x00, 0x10, 0x06, 0x00, 0x49, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x52, 0xff, 0xd1, 0x04, 0x1b, 0x04, 0x50, - 0x10, 0x27, 0x00, 0xc5, 0x00, 0xf6, 0xff, 0xfe, 0x10, 0x06, 0x00, 0x49, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x52, 0xff, 0xd1, 0x04, 0x1b, 0x04, 0x50, - 0x10, 0x27, 0x00, 0xc4, 0x00, 0xfc, 0x00, 0x02, 0x10, 0x06, 0x00, 0x49, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x52, 0xff, 0xd1, 0x04, 0x1b, 0x05, 0x9d, - 0x10, 0x27, 0x00, 0x6b, 0x00, 0xf0, 0xff, 0xe5, 0x10, 0x06, 0x00, 0x49, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x26, 0x00, 0xc6, 0xcb, 0xfc, 0x10, 0x06, 0x00, 0xc3, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, - 0x00, 0xc5, 0xc9, 0xfe, 0x10, 0x06, 0x00, 0xc3, 0x00, 0x00, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, 0x00, 0xc4, - 0xc9, 0x00, 0x10, 0x06, 0x00, 0xc3, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, - 0x04, 0xca, 0x02, 0x27, 0x05, 0x9d, 0x10, 0x26, 0x00, 0x6b, 0xc9, 0xe5, - 0x10, 0x06, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x02, 0x00, 0x4a, 0xff, 0xd1, - 0x04, 0x14, 0x05, 0xf2, 0x00, 0x24, 0x00, 0x34, 0x00, 0x00, 0x13, 0x10, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x26, 0x27, 0x26, 0x27, 0x07, 0x27, 0x37, - 0x26, 0x27, 0x26, 0x27, 0x37, 0x16, 0x17, 0x16, 0x17, 0x37, 0x17, 0x07, - 0x16, 0x17, 0x16, 0x11, 0x10, 0x07, 0x06, 0x23, 0x20, 0x27, 0x26, 0x01, - 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x4a, 0xc7, 0x6d, 0x8a, 0x33, 0x4e, 0x48, 0x64, 0x0b, - 0x11, 0xc7, 0x4a, 0xae, 0x38, 0x64, 0x05, 0x07, 0x5a, 0x45, 0x5f, 0x19, - 0x27, 0xc6, 0x52, 0xb8, 0x99, 0x57, 0xd0, 0xb7, 0x77, 0xb7, 0xfe, 0xf3, - 0x7d, 0x5b, 0x01, 0xe5, 0x9f, 0x53, 0x41, 0x75, 0x4c, 0x72, 0x9d, 0x53, - 0x43, 0x7e, 0x4a, 0x02, 0x10, 0x01, 0x5d, 0x90, 0x4f, 0x1b, 0x4a, 0x54, - 0x09, 0x0f, 0x5c, 0x50, 0x52, 0x2b, 0x39, 0x03, 0x04, 0x5a, 0x1d, 0x3b, - 0x10, 0x19, 0x5c, 0x4c, 0x54, 0x75, 0x6a, 0xfb, 0xfe, 0xbf, 0xfe, 0xb1, - 0x92, 0x60, 0xc7, 0x91, 0x02, 0x89, 0x8a, 0x6d, 0xab, 0xea, 0x6e, 0x49, - 0x86, 0x6c, 0xa9, 0xfd, 0x6c, 0x3f, 0xff, 0xff, 0x00, 0x8f, 0x00, 0x00, - 0x03, 0xe5, 0x04, 0x50, 0x10, 0x27, 0x00, 0xc8, 0x00, 0xee, 0xff, 0xe3, - 0x10, 0x06, 0x00, 0x52, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4a, 0xff, 0xd1, - 0x04, 0x14, 0x04, 0x50, 0x10, 0x27, 0x00, 0xc6, 0x00, 0xdf, 0x00, 0x02, - 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4a, 0xff, 0xd1, - 0x04, 0x14, 0x04, 0x50, 0x10, 0x27, 0x00, 0xc5, 0x00, 0xe1, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4a, 0xff, 0xd1, - 0x04, 0x14, 0x04, 0x50, 0x10, 0x27, 0x00, 0xc4, 0x00, 0xe1, 0x00, 0x02, - 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4a, 0xff, 0xd1, - 0x04, 0x14, 0x04, 0x50, 0x10, 0x27, 0x00, 0xc8, 0x00, 0xe1, 0xff, 0xe3, - 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4a, 0xff, 0xd1, - 0x04, 0x14, 0x05, 0x9d, 0x10, 0x27, 0x00, 0x6b, 0x00, 0xdf, 0xff, 0xe5, - 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, 0x00, 0x03, 0x00, 0x66, 0x00, 0x00, - 0x04, 0x46, 0x03, 0xc7, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, - 0x01, 0x15, 0x21, 0x35, 0x01, 0x15, 0x23, 0x35, 0x13, 0x15, 0x23, 0x35, - 0x04, 0x46, 0xfc, 0x20, 0x02, 0x5b, 0xd5, 0xd5, 0xd5, 0x02, 0x2b, 0x8f, - 0x8f, 0xfe, 0xaa, 0xd5, 0xd5, 0x02, 0xf2, 0xd5, 0xd5, 0x00, 0x00, 0x03, - 0x00, 0x25, 0xff, 0xc3, 0x04, 0x3b, 0x04, 0x50, 0x00, 0x17, 0x00, 0x20, - 0x00, 0x2b, 0x00, 0x00, 0x01, 0x07, 0x16, 0x15, 0x10, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x07, 0x27, 0x37, 0x26, 0x35, 0x10, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x37, 0x03, 0x01, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x09, 0x01, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, - 0x04, 0x3b, 0x81, 0x5a, 0xa1, 0x7c, 0xc6, 0xd2, 0x7c, 0x7d, 0x41, 0x87, - 0x62, 0xa1, 0x7d, 0xc7, 0xc6, 0x81, 0x07, 0x06, 0x77, 0xbd, 0xfe, 0x19, - 0x58, 0x81, 0xa3, 0x52, 0x3e, 0xfd, 0xc5, 0x01, 0xe9, 0x49, 0x79, 0x0f, - 0x10, 0x9f, 0x53, 0x41, 0x04, 0x17, 0x92, 0x94, 0xe1, 0xfe, 0xce, 0x98, - 0x75, 0x7f, 0x8d, 0x39, 0x97, 0x92, 0xeb, 0x01, 0x31, 0x98, 0x77, 0x78, - 0x07, 0x06, 0x85, 0xfe, 0xa8, 0xfd, 0xd9, 0x62, 0x8e, 0x6b, 0xa8, 0x89, - 0xfe, 0x88, 0x02, 0x27, 0x5c, 0x0c, 0x02, 0x8a, 0x6d, 0xab, 0x8c, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xd1, 0x03, 0xdb, 0x04, 0x31, 0x10, 0x27, - 0x00, 0xc6, 0x00, 0xdd, 0xff, 0xfe, 0x10, 0x06, 0x00, 0x59, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xd1, 0x03, 0xdb, 0x04, 0x31, 0x10, 0x27, - 0x00, 0xc5, 0x00, 0xdd, 0x00, 0x00, 0x10, 0x06, 0x00, 0x59, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xd1, 0x03, 0xdb, 0x04, 0x31, 0x10, 0x27, - 0x00, 0xc4, 0x00, 0xe3, 0x00, 0x02, 0x10, 0x06, 0x00, 0x59, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xd1, 0x03, 0xdb, 0x05, 0x9d, 0x10, 0x27, - 0x00, 0x6b, 0x00, 0xe1, 0xff, 0xe5, 0x10, 0x06, 0x00, 0x59, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x29, 0xfe, 0x42, 0x03, 0xd3, 0x04, 0x31, 0x10, 0x27, - 0x00, 0xc5, 0x00, 0xa6, 0xff, 0xfe, 0x10, 0x06, 0x00, 0x5d, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x6f, 0xfe, 0x42, 0x04, 0x2d, 0x05, 0xb6, 0x00, 0x14, - 0x00, 0x24, 0x00, 0x00, 0x13, 0x11, 0x33, 0x11, 0x36, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x11, 0x10, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, - 0x11, 0x01, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x6f, 0xaa, 0x59, 0x9f, 0x27, 0x2a, 0xd0, - 0x7c, 0x7f, 0x88, 0x7c, 0xc7, 0xa9, 0x72, 0x17, 0x17, 0x01, 0x2b, 0x91, - 0x53, 0x47, 0x6b, 0x4d, 0x73, 0x91, 0x57, 0x4f, 0x6d, 0x51, 0xfe, 0x42, - 0x07, 0x74, 0xfd, 0xf6, 0x7f, 0x1e, 0x07, 0x9d, 0xa0, 0xfe, 0xf3, 0xfe, - 0xf5, 0x9c, 0x8e, 0x6d, 0x17, 0x1c, 0xfd, 0xd1, 0x05, 0x6e, 0x81, 0x6f, - 0xb0, 0xdb, 0x72, 0x52, 0x7a, 0x70, 0xaf, 0xdc, 0x73, 0x57, 0xff, 0xff, - 0x00, 0x29, 0xfe, 0x42, 0x03, 0xd3, 0x05, 0x9d, 0x10, 0x27, 0x00, 0x6b, - 0x00, 0xb0, 0xff, 0xe5, 0x10, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x01, 0x9e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x9c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x00, 0xb7, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x4a, 0x00, 0xcc, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x01, 0x3e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x34, 0x01, 0x5c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x01, 0xad, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x8c, 0x01, 0xc8, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x48, 0x02, 0x9d, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x58, 0x03, 0x0c, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x68, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0xae, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0xc5, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x25, 0x01, 0x18, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x09, 0x01, 0x52, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x1a, 0x01, 0x92, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x01, 0xbf, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x46, 0x02, 0x56, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x24, 0x02, 0xe7, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2c, 0x03, 0x66, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x09, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x10, 0x00, 0x9c, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0c, 0x00, 0xb7, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x4a, 0x00, 0xcc, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x09, 0x00, 0x04, 0x00, 0x12, 0x01, 0x3e, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x09, 0x00, 0x05, 0x00, 0x34, 0x01, 0x5c, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x10, 0x01, 0xad, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x09, 0x00, 0x0d, 0x00, 0x8c, 0x01, 0xc8, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x09, 0x00, 0x0e, 0x00, 0x48, 0x02, 0x9d, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x09, 0x00, 0x13, 0x00, 0x58, 0x03, 0x0c, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x24, 0x00, 0x02, 0x00, 0x0e, 0x03, 0x93, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x24, 0x00, 0x0d, 0x00, 0x86, 0x03, 0xa3, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x24, 0x00, 0x0e, 0x00, 0x48, 0x04, 0x2b, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x24, 0x00, 0x13, 0x00, 0x54, 0x04, 0x75, 0x00, 0x43, - 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x66, - 0x00, 0x74, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x32, - 0x00, 0x2c, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, - 0x00, 0x2c, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x35, - 0x00, 0x20, 0x00, 0x46, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x20, - 0x00, 0x53, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x77, 0x00, 0x61, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x75, - 0x00, 0x6e, 0x00, 0x64, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, - 0x00, 0x6e, 0x00, 0x2e, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, - 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x32, 0x2c, 0x20, 0x32, 0x30, 0x30, - 0x33, 0x2c, 0x20, 0x32, 0x30, 0x30, 0x35, 0x20, 0x46, 0x72, 0x65, 0x65, - 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x46, 0x6f, - 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x00, 0x00, 0x46, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6e, - 0x00, 0x73, 0x00, 0x00, 0x46, 0x72, 0x65, 0x65, 0x53, 0x61, 0x6e, 0x73, - 0x00, 0x00, 0x4d, 0x00, 0x65, 0x00, 0x64, 0x00, 0x69, 0x00, 0x75, 0x00, - 0x6d, 0x00, 0x00, 0x4d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x00, 0x00, 0x46, - 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x72, - 0x00, 0x67, 0x00, 0x65, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x30, - 0x00, 0x20, 0x00, 0x3a, 0x00, 0x20, 0x00, 0x46, 0x00, 0x72, 0x00, 0x65, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x73, - 0x00, 0x20, 0x00, 0x3a, 0x00, 0x20, 0x00, 0x32, 0x00, 0x36, 0x00, 0x2d, - 0x00, 0x31, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x36, - 0x00, 0x00, 0x46, 0x6f, 0x6e, 0x74, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x20, - 0x31, 0x2e, 0x30, 0x20, 0x3a, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20, 0x53, - 0x61, 0x6e, 0x73, 0x20, 0x3a, 0x20, 0x32, 0x36, 0x2d, 0x31, 0x2d, 0x32, - 0x30, 0x30, 0x36, 0x00, 0x00, 0x46, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, - 0x00, 0x20, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x00, - 0x46, 0x72, 0x65, 0x65, 0x20, 0x53, 0x61, 0x6e, 0x73, 0x00, 0x00, 0x56, - 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x20, 0x00, 0x24, 0x00, 0x52, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, - 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x3a, 0x00, 0x20, - 0x00, 0x31, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x36, 0x00, 0x20, 0x00, 0x24, - 0x00, 0x20, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, - 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, - 0x2e, 0x37, 0x36, 0x20, 0x24, 0x20, 0x00, 0x00, 0x46, 0x00, 0x72, 0x00, - 0x65, 0x00, 0x65, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x73, 0x00, - 0x00, 0x46, 0x72, 0x65, 0x65, 0x53, 0x61, 0x6e, 0x73, 0x00, 0x00, 0x54, - 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, - 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x74, 0x00, 0x20, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x67, - 0x00, 0x72, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, - 0x00, 0x20, 0x00, 0x73, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x65, - 0x00, 0x63, 0x00, 0x74, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, - 0x00, 0x47, 0x00, 0x4e, 0x00, 0x55, 0x00, 0x20, 0x00, 0x47, 0x00, 0x65, - 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, - 0x00, 0x50, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, - 0x00, 0x20, 0x00, 0x4c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e, - 0x00, 0x73, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x00, 0x54, 0x68, 0x65, 0x20, - 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, - 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, - 0x74, 0x65, 0x64, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, - 0x74, 0x6f, 0x20, 0x47, 0x4e, 0x55, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, - 0x61, 0x6c, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x4c, 0x69, - 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2e, 0x00, 0x00, 0x68, 0x00, 0x74, 0x00, - 0x74, 0x00, 0x70, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x77, 0x00, - 0x77, 0x00, 0x77, 0x00, 0x2e, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x75, 0x00, - 0x2e, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x67, 0x00, 0x2f, 0x00, 0x63, 0x00, - 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x66, 0x00, - 0x74, 0x00, 0x2f, 0x00, 0x67, 0x00, 0x70, 0x00, 0x6c, 0x00, 0x2e, 0x00, - 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6e, 0x75, 0x2e, - 0x6f, 0x72, 0x67, 0x2f, 0x63, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, - 0x2f, 0x67, 0x70, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x00, 0x00, 0x54, - 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x71, 0x00, 0x75, 0x00, 0x69, - 0x00, 0x63, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x62, 0x00, 0x72, 0x00, 0x6f, - 0x00, 0x77, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x78, - 0x00, 0x20, 0x00, 0x6a, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x73, - 0x00, 0x20, 0x00, 0x6f, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, - 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x61, - 0x00, 0x7a, 0x00, 0x79, 0x00, 0x20, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x67, - 0x00, 0x2e, 0x00, 0x00, 0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63, - 0x6b, 0x20, 0x62, 0x72, 0x6f, 0x77, 0x6e, 0x20, 0x66, 0x6f, 0x78, 0x20, - 0x6a, 0x75, 0x6d, 0x70, 0x73, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x6c, 0x61, 0x7a, 0x79, 0x20, 0x64, 0x6f, 0x67, 0x2e, - 0x00, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x76, 0x00, 0x61, 0x00, 0x64, 0x00, - 0x6e, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x76, 0x00, - 0x6f, 0x00, 0x6c, 0x00, 0x6a, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00, - 0x20, 0x00, 0x6a, 0x00, 0x65, 0x00, 0x20, 0x00, 0x75, 0x00, 0x70, 0x00, - 0x6f, 0x00, 0x72, 0x00, 0x61, 0x00, 0x62, 0x00, 0x61, 0x00, 0x20, 0x00, - 0x76, 0x00, 0x20, 0x00, 0x73, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x61, 0x00, - 0x64, 0x00, 0x75, 0x00, 0x20, 0x00, 0x7a, 0x00, 0x20, 0x00, 0x6c, 0x00, - 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x6f, 0x00, - 0x20, 0x00, 0x47, 0x00, 0x4e, 0x00, 0x55, 0x00, 0x20, 0x00, 0x47, 0x00, - 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6c, 0x00, - 0x20, 0x00, 0x50, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x69, 0x00, - 0x63, 0x00, 0x20, 0x00, 0x4c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, - 0x6e, 0x00, 0x73, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x68, 0x00, - 0x74, 0x00, 0x74, 0x00, 0x70, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x2f, 0x00, - 0x77, 0x00, 0x77, 0x00, 0x77, 0x00, 0x2e, 0x00, 0x67, 0x00, 0x6e, 0x00, - 0x75, 0x00, 0x2e, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x67, 0x00, 0x2f, 0x00, - 0x63, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, - 0x66, 0x00, 0x74, 0x00, 0x2f, 0x00, 0x67, 0x00, 0x70, 0x00, 0x6c, 0x00, - 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x01, - 0x60, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x66, 0x00, 0x20, 0x00, - 0x62, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x7a, 0x00, 0x61, 0x00, 0x20, 0x00, - 0x76, 0x00, 0x61, 0x00, 0x6a, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x73, 0x00, - 0x70, 0x00, 0x65, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6b, 0x00, 0x75, 0x00, - 0x68, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x64, 0x00, 0x6f, 0x00, - 0x6d, 0x00, 0x61, 0x01, 0x0d, 0x00, 0x65, 0x00, 0x20, 0x01, 0x7e, 0x00, - 0x67, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x2e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0xcb, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x01, 0x02, 0x00, 0x03, - 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, - 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, - 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, - 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, - 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, - 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, - 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, - 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, - 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, - 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, - 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, - 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, - 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, - 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, - 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, - 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0xac, 0x00, 0xa3, - 0x00, 0x84, 0x00, 0x85, 0x00, 0xbd, 0x00, 0x96, 0x00, 0xe8, 0x00, 0x86, - 0x00, 0x8e, 0x00, 0x8b, 0x00, 0x9d, 0x00, 0xa9, 0x00, 0xa4, 0x01, 0x03, - 0x00, 0x8a, 0x00, 0xda, 0x00, 0x83, 0x00, 0x93, 0x00, 0xf2, 0x00, 0xf3, - 0x00, 0x8d, 0x00, 0x97, 0x00, 0x88, 0x00, 0xc3, 0x00, 0xde, 0x00, 0xf1, - 0x00, 0x9e, 0x00, 0xaa, 0x00, 0xf5, 0x00, 0xf4, 0x00, 0xf6, 0x00, 0xa2, - 0x00, 0xad, 0x00, 0xc9, 0x00, 0xc7, 0x00, 0xae, 0x00, 0x62, 0x00, 0x63, - 0x00, 0x90, 0x00, 0x64, 0x00, 0xcb, 0x00, 0x65, 0x00, 0xc8, 0x00, 0xca, - 0x00, 0xcf, 0x00, 0xcc, 0x00, 0xcd, 0x00, 0xce, 0x00, 0xe9, 0x00, 0x66, - 0x00, 0xd3, 0x00, 0xd0, 0x00, 0xd1, 0x00, 0xaf, 0x00, 0x67, 0x00, 0xf0, - 0x00, 0x91, 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0x68, 0x00, 0xeb, - 0x00, 0xed, 0x00, 0x89, 0x00, 0x6a, 0x00, 0x69, 0x00, 0x6b, 0x00, 0x6d, - 0x00, 0x6c, 0x00, 0x6e, 0x00, 0xa0, 0x00, 0x6f, 0x00, 0x71, 0x00, 0x70, - 0x00, 0x72, 0x00, 0x73, 0x00, 0x75, 0x00, 0x74, 0x00, 0x76, 0x00, 0x77, - 0x00, 0xea, 0x00, 0x78, 0x00, 0x7a, 0x00, 0x79, 0x00, 0x7b, 0x00, 0x7d, - 0x00, 0x7c, 0x00, 0xb8, 0x00, 0xa1, 0x00, 0x7f, 0x00, 0x7e, 0x00, 0x80, - 0x00, 0x81, 0x00, 0xec, 0x00, 0xee, 0x00, 0xba, 0x00, 0xd7, 0x00, 0xd8, - 0x01, 0x04, 0x01, 0x05, 0x00, 0xdd, 0x00, 0xd9, 0x06, 0x67, 0x6c, 0x79, - 0x70, 0x68, 0x33, 0x0a, 0x73, 0x6f, 0x66, 0x74, 0x68, 0x79, 0x70, 0x68, - 0x65, 0x6e, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x43, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x32, 0x43, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0xff, 0xff, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, - 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6a, - 0x00, 0x01, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x03, 0x00, 0x6c, 0x00, 0x02, - 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x8e, 0x00, 0x9c, 0x00, 0x08, - 0x44, 0x46, 0x4c, 0x54, 0x00, 0x32, 0x61, 0x72, 0x6d, 0x6e, 0x00, 0x3c, - 0x62, 0x65, 0x6e, 0x67, 0x00, 0x46, 0x64, 0x65, 0x76, 0x61, 0x00, 0x50, - 0x67, 0x75, 0x6a, 0x72, 0x00, 0x5a, 0x67, 0x75, 0x72, 0x75, 0x00, 0x64, - 0x68, 0x65, 0x62, 0x72, 0x00, 0x6e, 0x6c, 0x61, 0x74, 0x6e, 0x00, 0x78, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x63, 0x63, 0x6d, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x46, 0x00, 0x02, - 0x00, 0x12, 0x00, 0x1a, 0x00, 0x22, 0x00, 0x22, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x4d, 0x00, 0x4e, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, - 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x01, 0x00, 0x06, 0x00, 0x76, 0x00, 0x01, 0x00, 0x01, 0x00, 0x4d, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x90, 0x00, 0xaa, 0x00, 0x08, - 0x44, 0x46, 0x4c, 0x54, 0x00, 0x32, 0x61, 0x72, 0x6d, 0x6e, 0x00, 0x3e, - 0x62, 0x65, 0x6e, 0x67, 0x00, 0x48, 0x64, 0x65, 0x76, 0x61, 0x00, 0x52, - 0x67, 0x75, 0x6a, 0x72, 0x00, 0x5c, 0x67, 0x75, 0x72, 0x75, 0x00, 0x66, - 0x68, 0x65, 0x62, 0x72, 0x00, 0x70, 0x6c, 0x61, 0x74, 0x6e, 0x00, 0x7a, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x02, 0x6b, 0x65, 0x72, 0x6e, 0x00, 0x0e, 0x6b, 0x65, 0x72, 0x6e, - 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8e, - 0x00, 0x01, 0x00, 0x7a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, - 0x00, 0x20, 0x00, 0x46, 0x00, 0x54, 0x00, 0x03, 0xff, 0xff, 0xff, 0x33, - 0xff, 0xff, 0xff, 0xac, 0xff, 0xff, 0xff, 0x9a, 0x00, 0x09, 0x00, 0x25, - 0xff, 0xf2, 0x00, 0x38, 0xff, 0x5c, 0x00, 0x3a, 0xff, 0xa2, 0x00, 0x3b, - 0xff, 0xd9, 0x00, 0x3d, 0xff, 0x44, 0x00, 0x84, 0xff, 0xf2, 0x00, 0x87, - 0xff, 0xf2, 0x00, 0x88, 0xff, 0xf2, 0x00, 0x89, 0xff, 0xe9, 0x00, 0x03, - 0xff, 0xff, 0xff, 0x31, 0xff, 0xff, 0xff, 0xac, 0xff, 0xff, 0xff, 0x98, - 0x00, 0x09, 0x00, 0x25, 0xff, 0x9a, 0x00, 0x38, 0xfe, 0xfe, 0x00, 0x3a, - 0xff, 0x42, 0x00, 0x3b, 0xff, 0x79, 0x00, 0x3d, 0xfe, 0xf0, 0x00, 0x84, - 0xff, 0x9a, 0x00, 0x87, 0xff, 0x9a, 0x00, 0x88, 0xff, 0x9a, 0x00, 0x89, - 0xff, 0x91, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, - 0x00, 0x7e, 0x00, 0x01, 0x0e, 0x92, 0x00, 0x04, 0x00, 0x00, 0x00, 0x48, - 0x00, 0x9a, 0x01, 0x34, 0x01, 0x7a, 0x01, 0xa4, 0x01, 0xda, 0x02, 0x50, - 0x02, 0x82, 0x02, 0x94, 0x02, 0xe6, 0x03, 0x5c, 0x03, 0xae, 0x03, 0xd8, - 0x04, 0x2e, 0x04, 0xa4, 0x04, 0xce, 0x05, 0x8c, 0x05, 0xc2, 0x06, 0x5c, - 0x06, 0xee, 0x07, 0x18, 0x07, 0xaa, 0x07, 0xb4, 0x07, 0xca, 0x07, 0xd8, - 0x07, 0xe2, 0x07, 0xfc, 0x08, 0x42, 0x08, 0x5c, 0x08, 0x66, 0x08, 0x70, - 0x08, 0xae, 0x08, 0xb4, 0x08, 0xc6, 0x08, 0xe0, 0x08, 0xfe, 0x09, 0x08, - 0x09, 0x12, 0x09, 0xc0, 0x09, 0xca, 0x0a, 0x08, 0x0a, 0x0e, 0x0a, 0x78, - 0x0a, 0xde, 0x0a, 0xf8, 0x0b, 0x62, 0x0b, 0x90, 0x0c, 0x02, 0x0c, 0x30, - 0x0c, 0x5e, 0x0c, 0xd0, 0x0d, 0x46, 0x0d, 0x4c, 0x0d, 0x5a, 0x0d, 0x70, - 0x0d, 0x7e, 0x0d, 0x8c, 0x0d, 0xa6, 0x0d, 0xac, 0x0d, 0xb2, 0x0d, 0xd0, - 0x0d, 0xd6, 0x0d, 0xf8, 0x0e, 0x06, 0x0e, 0x14, 0x0e, 0x22, 0x0e, 0x30, - 0x0e, 0x3e, 0x0e, 0x4c, 0x0e, 0x5a, 0x0e, 0x68, 0x0e, 0x76, 0x0e, 0x7c, - 0x00, 0x26, 0xff, 0xff, 0xff, 0xae, 0xff, 0xff, 0xff, 0x8d, 0xff, 0xff, - 0xff, 0x7b, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff, 0xb6, 0x00, 0x10, - 0x00, 0x0a, 0x00, 0x11, 0xff, 0xfa, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x27, - 0xff, 0xb6, 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, 0xff, 0xbc, 0x00, 0x35, - 0xff, 0xbe, 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, 0xff, 0xb4, 0x00, 0x3a, - 0xff, 0x66, 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, 0xff, 0x35, 0x00, 0x45, - 0xff, 0xf8, 0x00, 0x46, 0x00, 0x08, 0x00, 0x47, 0xff, 0xe9, 0x00, 0x48, - 0xff, 0xf0, 0x00, 0x49, 0xff, 0xdf, 0x00, 0x4b, 0xff, 0xec, 0x00, 0x53, - 0xff, 0xe5, 0x00, 0x55, 0xff, 0xf0, 0x00, 0x58, 0xff, 0xdf, 0x00, 0x59, - 0xff, 0xe7, 0x00, 0x5a, 0xff, 0xc1, 0x00, 0x5b, 0xff, 0xd5, 0x00, 0x5d, - 0xff, 0xba, 0x00, 0x6e, 0xff, 0xa6, 0x00, 0x8a, 0xff, 0xb6, 0x00, 0x99, - 0xff, 0xbc, 0x00, 0x9c, 0xff, 0xb4, 0x00, 0x9d, 0xff, 0xb4, 0x00, 0x9e, - 0xff, 0xb4, 0x00, 0x9f, 0xff, 0xb4, 0x00, 0xaa, 0xff, 0xec, 0x00, 0x11, - 0xff, 0xff, 0xff, 0xf6, 0x00, 0x25, 0xff, 0xd5, 0x00, 0x33, 0xff, 0xf2, - 0x00, 0x3a, 0xff, 0xac, 0x00, 0x3b, 0xff, 0xcd, 0x00, 0x3d, 0xff, 0xa6, - 0x00, 0x84, 0xff, 0xd5, 0x00, 0x85, 0xff, 0xd5, 0x00, 0x86, 0xff, 0xd5, - 0x00, 0x87, 0xff, 0xd5, 0x00, 0x88, 0xff, 0xd5, 0x00, 0x89, 0xff, 0xd5, - 0x00, 0x95, 0xff, 0xf2, 0x00, 0x96, 0xff, 0xf2, 0x00, 0x97, 0xff, 0xf2, - 0x00, 0x99, 0xff, 0xf2, 0x00, 0x9b, 0xff, 0xfe, 0x00, 0x0a, 0x00, 0x25, - 0xff, 0xbe, 0x00, 0x2c, 0xff, 0xe7, 0x00, 0x2f, 0xff, 0xec, 0x00, 0x33, - 0xff, 0xf0, 0x00, 0x84, 0xff, 0xbe, 0x00, 0x87, 0xff, 0xbe, 0x00, 0x88, - 0xff, 0xbe, 0x00, 0x89, 0xff, 0xbc, 0x00, 0x96, 0xff, 0xf0, 0x00, 0x99, - 0xff, 0xf0, 0x00, 0x0d, 0x00, 0x25, 0xff, 0xaa, 0x00, 0x2e, 0xff, 0xf6, - 0x00, 0x38, 0xff, 0xa4, 0x00, 0x3a, 0xff, 0x98, 0x00, 0x3b, 0xff, 0xc5, - 0x00, 0x3c, 0xff, 0x93, 0x00, 0x3d, 0xff, 0x7f, 0x00, 0x83, 0xff, 0xaa, - 0x00, 0x84, 0xff, 0xaa, 0x00, 0x85, 0xff, 0xaa, 0x00, 0x86, 0xff, 0xaa, - 0x00, 0x87, 0xff, 0xaa, 0x00, 0x88, 0xff, 0xaa, 0x00, 0x1d, 0xff, 0xff, - 0xff, 0xd1, 0x00, 0x10, 0xff, 0x23, 0x00, 0x11, 0xff, 0xe3, 0x00, 0x12, - 0xff, 0x23, 0x00, 0x25, 0xff, 0x73, 0x00, 0x2e, 0xff, 0x98, 0x00, 0x33, - 0xff, 0xd3, 0x00, 0x45, 0xff, 0xbc, 0x00, 0x49, 0xff, 0xcf, 0x00, 0x4d, - 0xff, 0xec, 0x00, 0x4e, 0xff, 0xe7, 0x00, 0x53, 0xff, 0xd5, 0x00, 0x56, - 0xff, 0xb8, 0x00, 0x59, 0xff, 0xbc, 0x00, 0x83, 0xff, 0x73, 0x00, 0x84, - 0xff, 0x73, 0x00, 0x85, 0xff, 0x73, 0x00, 0x86, 0xff, 0x73, 0x00, 0x87, - 0xff, 0x73, 0x00, 0x88, 0xff, 0x73, 0x00, 0x99, 0xff, 0xd3, 0x00, 0xa4, - 0xff, 0xbc, 0x00, 0xa7, 0xff, 0xbc, 0x00, 0xa8, 0xff, 0xbc, 0x00, 0xa9, - 0xff, 0xc5, 0x00, 0xac, 0xff, 0xcf, 0x00, 0xb6, 0xff, 0xd5, 0x00, 0xb9, - 0xff, 0xd5, 0x00, 0xbb, 0xff, 0xd5, 0x00, 0x0c, 0x00, 0x25, 0xff, 0xf4, - 0x00, 0x38, 0xff, 0xa6, 0x00, 0x3a, 0xff, 0x9a, 0x00, 0x3b, 0xff, 0xc7, - 0x00, 0x3d, 0xff, 0x81, 0x00, 0x83, 0xff, 0xf4, 0x00, 0x84, 0xff, 0xf4, - 0x00, 0x85, 0xff, 0xf4, 0x00, 0x86, 0xff, 0xf4, 0x00, 0x87, 0xff, 0xf4, - 0x00, 0x88, 0xff, 0xf4, 0x00, 0x89, 0xff, 0xfa, 0x00, 0x04, 0x00, 0x25, - 0xff, 0xbe, 0x00, 0x87, 0xff, 0xbe, 0x00, 0x88, 0xff, 0xbe, 0x00, 0x89, - 0xff, 0xc1, 0x00, 0x14, 0xff, 0xff, 0xff, 0xa4, 0x00, 0x11, 0xff, 0xa0, - 0x00, 0x27, 0xff, 0x98, 0x00, 0x2b, 0xff, 0x98, 0x00, 0x33, 0xff, 0x9e, - 0x00, 0x37, 0xff, 0xb2, 0x00, 0x38, 0x00, 0x29, 0x00, 0x45, 0xff, 0xe9, - 0x00, 0x49, 0xff, 0xbe, 0x00, 0x53, 0xff, 0xc5, 0x00, 0x59, 0xff, 0xd9, - 0x00, 0x5d, 0xff, 0x81, 0x00, 0x96, 0xff, 0x9e, 0x00, 0x99, 0xff, 0x9e, - 0x00, 0xa7, 0xff, 0xe9, 0x00, 0xa8, 0xff, 0xe9, 0x00, 0xa9, 0xff, 0xf2, - 0x00, 0xb6, 0xff, 0xc5, 0x00, 0xb9, 0xff, 0xc5, 0x00, 0xbf, 0xff, 0xd9, - 0x00, 0x1d, 0xff, 0xff, 0xfe, 0xdf, 0xff, 0xff, 0xfe, 0xcf, 0xff, 0xff, - 0xff, 0xd9, 0xff, 0xff, 0xff, 0xac, 0x00, 0x11, 0xff, 0x00, 0x00, 0x25, - 0x00, 0x23, 0x00, 0x27, 0xff, 0xac, 0x00, 0x2b, 0xff, 0xaa, 0x00, 0x33, - 0xff, 0xac, 0x00, 0x37, 0xff, 0xd9, 0x00, 0x38, 0xff, 0x29, 0x00, 0x39, - 0xff, 0xb8, 0x00, 0x3a, 0xff, 0x29, 0x00, 0x3b, 0xff, 0x75, 0x00, 0x3d, - 0xff, 0x08, 0x00, 0x59, 0xff, 0xf2, 0x00, 0x5d, 0xff, 0x8d, 0x00, 0x84, - 0x00, 0x23, 0x00, 0x87, 0x00, 0x23, 0x00, 0x88, 0x00, 0x23, 0x00, 0x89, - 0x00, 0x29, 0x00, 0x8a, 0xff, 0xb4, 0x00, 0x95, 0xff, 0xac, 0x00, 0x96, - 0xff, 0xac, 0x00, 0x97, 0xff, 0xac, 0x00, 0x98, 0xff, 0xac, 0x00, 0x99, - 0xff, 0xac, 0x00, 0x9f, 0xff, 0xb8, 0x00, 0xbf, 0xff, 0xf2, 0x00, 0x14, - 0xff, 0xff, 0xff, 0xfa, 0x00, 0x10, 0xff, 0xf2, 0x00, 0x12, 0xff, 0xf2, - 0x00, 0x25, 0xff, 0xee, 0x00, 0x27, 0xff, 0xfa, 0x00, 0x2b, 0xff, 0xfc, - 0x00, 0x45, 0xff, 0xf6, 0x00, 0x53, 0x00, 0x04, 0x00, 0x84, 0xff, 0xee, - 0x00, 0x87, 0xff, 0xee, 0x00, 0x88, 0xff, 0xee, 0x00, 0x89, 0xff, 0xf4, - 0x00, 0x8a, 0xff, 0xfa, 0x00, 0xa4, 0xff, 0xf6, 0x00, 0xa7, 0xff, 0xf6, - 0x00, 0xa8, 0xff, 0xf6, 0x00, 0xa9, 0xff, 0xfc, 0x00, 0xb6, 0x00, 0x04, - 0x00, 0xb9, 0x00, 0x04, 0x00, 0xbb, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x25, - 0xff, 0xb8, 0x00, 0x38, 0xff, 0xaa, 0x00, 0x3a, 0xff, 0xa4, 0x00, 0x3b, - 0xff, 0xd1, 0x00, 0x3c, 0xff, 0xa2, 0x00, 0x3d, 0xff, 0x87, 0x00, 0x84, - 0xff, 0xb8, 0x00, 0x87, 0xff, 0xb8, 0x00, 0x88, 0xff, 0xb8, 0x00, 0x89, - 0xff, 0xb0, 0x00, 0x15, 0xff, 0xff, 0xff, 0xc7, 0x00, 0x10, 0xfe, 0xec, - 0x00, 0x11, 0xff, 0xae, 0x00, 0x12, 0xfe, 0xec, 0x00, 0x25, 0xff, 0x60, - 0x00, 0x2e, 0xff, 0x60, 0x00, 0x45, 0xff, 0xc7, 0x00, 0x49, 0xff, 0xc1, - 0x00, 0x53, 0xff, 0xc9, 0x00, 0x84, 0xff, 0x60, 0x00, 0x87, 0xff, 0x60, - 0x00, 0x88, 0xff, 0x60, 0x00, 0x89, 0xff, 0x50, 0x00, 0xa4, 0xff, 0xc7, - 0x00, 0xa7, 0xff, 0xc7, 0x00, 0xa8, 0xff, 0xc7, 0x00, 0xa9, 0xff, 0xcf, - 0x00, 0xac, 0xff, 0xc1, 0x00, 0xb6, 0xff, 0xc9, 0x00, 0xb9, 0xff, 0xc9, - 0x00, 0xbb, 0xff, 0xc9, 0x00, 0x1d, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, - 0xff, 0xe9, 0x00, 0x11, 0xff, 0xfc, 0x00, 0x27, 0xff, 0xdf, 0x00, 0x2b, - 0xff, 0xe1, 0x00, 0x33, 0xff, 0xe5, 0x00, 0x38, 0xff, 0xd1, 0x00, 0x39, - 0xff, 0xdd, 0x00, 0x3a, 0xff, 0xb0, 0x00, 0x3b, 0xff, 0xc9, 0x00, 0x3d, - 0xff, 0xa8, 0x00, 0x45, 0xff, 0xe1, 0x00, 0x49, 0xff, 0xe7, 0x00, 0x53, - 0xff, 0xee, 0x00, 0x59, 0xff, 0xee, 0x00, 0x5d, 0xff, 0xf0, 0x00, 0x8a, - 0xff, 0xdf, 0x00, 0x96, 0xff, 0xe5, 0x00, 0x99, 0xff, 0xe5, 0x00, 0x9f, - 0xff, 0xdd, 0x00, 0xa4, 0xff, 0xe1, 0x00, 0xa7, 0xff, 0xe1, 0x00, 0xa8, - 0xff, 0xe1, 0x00, 0xa9, 0xff, 0xe7, 0x00, 0xac, 0xff, 0xe7, 0x00, 0xb6, - 0xff, 0xee, 0x00, 0xb9, 0xff, 0xee, 0x00, 0xbd, 0xff, 0xee, 0x00, 0xbf, - 0xff, 0xee, 0x00, 0x0a, 0x00, 0x25, 0xff, 0xd3, 0x00, 0x38, 0xff, 0xc7, - 0x00, 0x3a, 0xff, 0xaa, 0x00, 0x3b, 0xff, 0xc7, 0x00, 0x3d, 0xff, 0x9e, - 0x00, 0x58, 0xff, 0xfa, 0x00, 0x84, 0xff, 0xd3, 0x00, 0x87, 0xff, 0xd3, - 0x00, 0x88, 0xff, 0xd3, 0x00, 0x89, 0xff, 0xd3, 0x00, 0x2f, 0xff, 0xff, - 0xff, 0x10, 0xff, 0xff, 0xff, 0x85, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, - 0xff, 0xb8, 0x00, 0x10, 0xff, 0x33, 0x00, 0x11, 0xff, 0x62, 0x00, 0x12, - 0xff, 0x33, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x1f, 0xfe, 0xf8, 0x00, 0x25, - 0xff, 0x3d, 0x00, 0x27, 0xff, 0xa6, 0x00, 0x2b, 0xff, 0xa4, 0x00, 0x2e, - 0xff, 0x33, 0x00, 0x33, 0xff, 0xaa, 0x00, 0x37, 0xff, 0xcf, 0x00, 0x3a, - 0x00, 0x19, 0x00, 0x3b, 0x00, 0x21, 0x00, 0x3d, 0x00, 0x29, 0x00, 0x45, - 0xff, 0x33, 0x00, 0x47, 0xff, 0x48, 0x00, 0x49, 0xff, 0x3d, 0x00, 0x4b, - 0xff, 0x4a, 0x00, 0x4d, 0xff, 0xfa, 0x00, 0x4e, 0xff, 0xf6, 0x00, 0x53, - 0xff, 0x44, 0x00, 0x56, 0xff, 0x44, 0x00, 0x57, 0xff, 0x44, 0x00, 0x59, - 0xff, 0x46, 0x00, 0x5a, 0xff, 0x3d, 0x00, 0x5b, 0xff, 0x42, 0x00, 0x5d, - 0xff, 0x33, 0x00, 0x6e, 0xff, 0x08, 0x00, 0x83, 0xff, 0x3d, 0x00, 0x84, - 0xff, 0x3d, 0x00, 0x85, 0xff, 0x3d, 0x00, 0x86, 0xff, 0x3d, 0x00, 0x87, - 0xff, 0x3d, 0x00, 0x88, 0xff, 0x3d, 0x00, 0x89, 0xff, 0x39, 0x00, 0x95, - 0xff, 0xaa, 0x00, 0x96, 0xff, 0xaa, 0x00, 0x97, 0xff, 0xaa, 0x00, 0x98, - 0xff, 0xaa, 0x00, 0x99, 0xff, 0xaa, 0x00, 0x9b, 0xff, 0xac, 0x00, 0xa9, - 0xff, 0x39, 0x00, 0xbb, 0xff, 0x4e, 0x00, 0x0d, 0x00, 0x10, 0xff, 0xc9, - 0x00, 0x12, 0xff, 0xcd, 0x00, 0x25, 0xff, 0xb6, 0x00, 0x51, 0xff, 0xf8, - 0x00, 0x52, 0xff, 0xf8, 0x00, 0x54, 0x00, 0x06, 0x00, 0x56, 0xff, 0xf8, - 0x00, 0x84, 0xff, 0xb6, 0x00, 0x85, 0xff, 0xb6, 0x00, 0x86, 0xff, 0xb6, - 0x00, 0x87, 0xff, 0xb6, 0x00, 0x88, 0xff, 0xb6, 0x00, 0x89, 0xff, 0xb0, - 0x00, 0x26, 0xff, 0xff, 0xff, 0x5c, 0xff, 0xff, 0xff, 0xb8, 0xff, 0xff, - 0xff, 0xa8, 0x00, 0x10, 0xff, 0x4a, 0x00, 0x11, 0xff, 0xb2, 0x00, 0x12, - 0xff, 0x4a, 0x00, 0x1e, 0xff, 0x79, 0x00, 0x1f, 0xff, 0x79, 0x00, 0x25, - 0xff, 0x6f, 0x00, 0x27, 0xff, 0xa8, 0x00, 0x2b, 0xff, 0xaa, 0x00, 0x33, - 0xff, 0xae, 0x00, 0x37, 0xff, 0xb8, 0x00, 0x38, 0x00, 0x1f, 0x00, 0x45, - 0xff, 0x87, 0x00, 0x49, 0xff, 0x8b, 0x00, 0x4b, 0xff, 0x9a, 0x00, 0x4d, - 0xff, 0xf6, 0x00, 0x53, 0xff, 0x91, 0x00, 0x56, 0xff, 0xaa, 0x00, 0x59, - 0xff, 0xac, 0x00, 0x5d, 0xff, 0xd7, 0x00, 0x6e, 0xff, 0x56, 0x00, 0x83, - 0xff, 0x6f, 0x00, 0x84, 0xff, 0x6f, 0x00, 0x85, 0xff, 0x6f, 0x00, 0x86, - 0xff, 0x6f, 0x00, 0x87, 0xff, 0x6f, 0x00, 0x88, 0xff, 0x6f, 0x00, 0x89, - 0xff, 0x60, 0x00, 0x95, 0xff, 0xae, 0x00, 0x96, 0xff, 0xae, 0x00, 0x97, - 0xff, 0xae, 0x00, 0x98, 0xff, 0xae, 0x00, 0x99, 0xff, 0xae, 0x00, 0x9b, - 0xff, 0xbc, 0x00, 0xa9, 0xff, 0x8f, 0x00, 0xbb, 0xff, 0x9a, 0x00, 0x24, - 0xff, 0xff, 0xff, 0x91, 0x00, 0x10, 0xff, 0x8d, 0x00, 0x11, 0xff, 0xe5, - 0x00, 0x12, 0xff, 0x8d, 0x00, 0x1e, 0xff, 0x96, 0x00, 0x1f, 0xff, 0x93, - 0x00, 0x25, 0xff, 0x9a, 0x00, 0x27, 0xff, 0xd1, 0x00, 0x2b, 0xff, 0xd3, - 0x00, 0x33, 0xff, 0xd7, 0x00, 0x37, 0xff, 0xcf, 0x00, 0x38, 0x00, 0x27, - 0x00, 0x45, 0xff, 0xb2, 0x00, 0x49, 0xff, 0xbe, 0x00, 0x4b, 0xff, 0xcd, - 0x00, 0x4d, 0xff, 0xfe, 0x00, 0x53, 0xff, 0xc5, 0x00, 0x56, 0xff, 0xc7, - 0x00, 0x59, 0xff, 0xc7, 0x00, 0x5d, 0xff, 0xf4, 0x00, 0x6e, 0xff, 0x89, - 0x00, 0x83, 0xff, 0x9a, 0x00, 0x84, 0xff, 0x9a, 0x00, 0x85, 0xff, 0x9a, - 0x00, 0x86, 0xff, 0x9a, 0x00, 0x87, 0xff, 0x9a, 0x00, 0x88, 0xff, 0x9a, - 0x00, 0x89, 0xff, 0x8d, 0x00, 0x95, 0xff, 0xd7, 0x00, 0x96, 0xff, 0xd7, - 0x00, 0x97, 0xff, 0xd7, 0x00, 0x98, 0xff, 0xd7, 0x00, 0x99, 0xff, 0xd7, - 0x00, 0x9b, 0xff, 0xe5, 0x00, 0xa9, 0xff, 0xba, 0x00, 0xbb, 0xff, 0xcd, - 0x00, 0x0a, 0x00, 0x11, 0xff, 0x98, 0x00, 0x27, 0xff, 0x9e, 0x00, 0x33, - 0xff, 0xa4, 0x00, 0x35, 0xff, 0xa6, 0x00, 0x45, 0xff, 0xe1, 0x00, 0x49, - 0xff, 0xb6, 0x00, 0x53, 0xff, 0xbc, 0x00, 0x59, 0xff, 0xcf, 0x00, 0x5d, - 0xff, 0x83, 0x00, 0x99, 0xff, 0xa4, 0x00, 0x24, 0xff, 0xff, 0xff, 0x0c, - 0x00, 0x10, 0xff, 0x1d, 0x00, 0x11, 0xff, 0x54, 0x00, 0x12, 0xff, 0x1d, - 0x00, 0x1e, 0xff, 0x4e, 0x00, 0x1f, 0xff, 0x4c, 0x00, 0x25, 0xff, 0x3b, - 0x00, 0x27, 0xff, 0x89, 0x00, 0x2b, 0xff, 0x89, 0x00, 0x33, 0xff, 0x8d, - 0x00, 0x37, 0xff, 0xac, 0x00, 0x38, 0x00, 0x2f, 0x00, 0x45, 0xff, 0x4c, - 0x00, 0x49, 0xff, 0x4a, 0x00, 0x4b, 0xff, 0x56, 0x00, 0x4d, 0x00, 0x06, - 0x00, 0x53, 0xff, 0x50, 0x00, 0x54, 0xff, 0x91, 0x00, 0x59, 0xff, 0x7f, - 0x00, 0x5a, 0xff, 0xb6, 0x00, 0x6e, 0xff, 0x04, 0x00, 0x83, 0xff, 0x3b, - 0x00, 0x84, 0xff, 0x3b, 0x00, 0x85, 0xff, 0x3b, 0x00, 0x86, 0xff, 0x3b, - 0x00, 0x87, 0xff, 0x3b, 0x00, 0x88, 0xff, 0x3b, 0x00, 0x89, 0xff, 0x2d, - 0x00, 0x95, 0xff, 0x8d, 0x00, 0x96, 0xff, 0x8d, 0x00, 0x97, 0xff, 0x8d, - 0x00, 0x98, 0xff, 0x8d, 0x00, 0x99, 0xff, 0x8d, 0x00, 0x9b, 0xff, 0x91, - 0x00, 0xa9, 0xff, 0x54, 0x00, 0xbb, 0xff, 0x58, 0x00, 0x02, 0x00, 0x5a, - 0xff, 0xbc, 0x00, 0x5d, 0xff, 0xb2, 0x00, 0x05, 0xff, 0xff, 0xff, 0xd1, - 0x00, 0x4e, 0xff, 0xf8, 0x00, 0x5a, 0xff, 0xd5, 0x00, 0x5b, 0xff, 0xe5, - 0x00, 0x5d, 0xff, 0xcb, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xe9, 0x00, 0x5b, - 0xff, 0xfa, 0x00, 0x5d, 0xff, 0xe1, 0x00, 0x02, 0x00, 0x4c, 0x00, 0x02, - 0x00, 0x4f, 0x00, 0x0e, 0x00, 0x06, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x58, - 0xff, 0xec, 0x00, 0x5a, 0xff, 0xe1, 0x00, 0x5b, 0xff, 0xee, 0x00, 0x5c, - 0xff, 0xc9, 0x00, 0x5d, 0xff, 0xd9, 0x00, 0x11, 0xff, 0xff, 0xff, 0xe7, - 0x00, 0x45, 0xff, 0xee, 0x00, 0x49, 0xff, 0xe1, 0x00, 0x4a, 0x00, 0x2d, - 0x00, 0x4d, 0xff, 0xfc, 0x00, 0x4e, 0xff, 0xf8, 0x00, 0x50, 0xff, 0xfa, - 0x00, 0x53, 0xff, 0xec, 0x00, 0x58, 0x00, 0x31, 0x00, 0xa4, 0xff, 0xee, - 0x00, 0xa7, 0xff, 0xee, 0x00, 0xa8, 0xff, 0xee, 0x00, 0xa9, 0xff, 0xf6, - 0x00, 0xac, 0xff, 0xe1, 0x00, 0xb6, 0xff, 0xec, 0x00, 0xb9, 0xff, 0xec, - 0x00, 0xbb, 0xff, 0xee, 0x00, 0x06, 0x00, 0x45, 0xff, 0xf6, 0x00, 0xa7, - 0xff, 0xf6, 0x00, 0xa8, 0xff, 0xf6, 0x00, 0xa9, 0xff, 0xfe, 0x00, 0xb6, - 0x00, 0x06, 0x00, 0xb9, 0x00, 0x06, 0x00, 0x02, 0xff, 0xff, 0xff, 0xe1, - 0x00, 0x5d, 0xff, 0xdb, 0x00, 0x02, 0x00, 0x38, 0xff, 0xf2, 0x00, 0x4e, - 0xff, 0xfa, 0x00, 0x0f, 0x00, 0x11, 0xff, 0xac, 0x00, 0x45, 0xff, 0xfc, - 0x00, 0x49, 0xff, 0xd5, 0x00, 0x4b, 0xff, 0xdf, 0x00, 0x53, 0xff, 0xd9, - 0x00, 0x57, 0xff, 0xfa, 0x00, 0x59, 0xff, 0xe9, 0x00, 0xa4, 0xff, 0xfc, - 0x00, 0xa7, 0xff, 0xfc, 0x00, 0xa8, 0xff, 0xfc, 0x00, 0xa9, 0x00, 0x04, - 0x00, 0xac, 0xff, 0xd5, 0x00, 0xb6, 0xff, 0xd9, 0x00, 0xb9, 0xff, 0xd9, - 0x00, 0xbf, 0xff, 0xf4, 0x00, 0x01, 0x00, 0x5d, 0xff, 0xf6, 0x00, 0x04, - 0x00, 0x54, 0x00, 0x0a, 0x00, 0x5a, 0xff, 0xe5, 0x00, 0x5b, 0xff, 0xf2, - 0x00, 0x5d, 0xff, 0xdb, 0x00, 0x06, 0xff, 0xff, 0xff, 0xe3, 0x00, 0x38, - 0xff, 0x3b, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x5a, 0xff, 0xe5, 0x00, 0x5b, - 0xff, 0xf2, 0x00, 0x5d, 0xff, 0xdb, 0x00, 0x07, 0xff, 0xff, 0xff, 0xd5, - 0x00, 0x38, 0xff, 0x35, 0x00, 0x58, 0xff, 0xec, 0x00, 0x5a, 0xff, 0xdb, - 0x00, 0x5b, 0xff, 0xec, 0x00, 0x5c, 0xff, 0xc9, 0x00, 0x5d, 0xff, 0xd3, - 0x00, 0x02, 0x00, 0x58, 0xff, 0xf8, 0x00, 0x5d, 0xff, 0xdf, 0x00, 0x02, - 0x00, 0x47, 0x00, 0x10, 0x00, 0x59, 0x00, 0x08, 0x00, 0x2b, 0xff, 0xff, - 0x00, 0x02, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf4, 0x00, 0x10, - 0xff, 0x73, 0x00, 0x11, 0xff, 0xa0, 0x00, 0x12, 0xff, 0x73, 0x00, 0x1e, - 0xff, 0xd3, 0x00, 0x1f, 0xff, 0xd3, 0x00, 0x45, 0xff, 0xf6, 0x00, 0x47, - 0xff, 0xf4, 0x00, 0x48, 0xff, 0xfe, 0x00, 0x49, 0xff, 0xe9, 0x00, 0x4a, - 0x00, 0x35, 0x00, 0x4b, 0xff, 0xf8, 0x00, 0x4d, 0x00, 0x02, 0x00, 0x4f, - 0x00, 0x0c, 0x00, 0x50, 0x00, 0x02, 0x00, 0x53, 0xff, 0xf4, 0x00, 0x54, - 0x00, 0x10, 0x00, 0x55, 0xff, 0xfa, 0x00, 0x57, 0x00, 0x08, 0x00, 0x58, - 0x00, 0x39, 0x00, 0x59, 0x00, 0x04, 0x00, 0x5a, 0x00, 0x3b, 0x00, 0x5b, - 0x00, 0x3f, 0x00, 0x5c, 0x00, 0x29, 0x00, 0x5d, 0x00, 0x31, 0x00, 0x5e, - 0x00, 0x12, 0x00, 0xa3, 0xff, 0xf6, 0x00, 0xa4, 0xff, 0xf6, 0x00, 0xa5, - 0xff, 0xf6, 0x00, 0xa7, 0xff, 0xf6, 0x00, 0xa8, 0xff, 0xf6, 0x00, 0xa9, - 0xff, 0xfe, 0x00, 0xaa, 0xff, 0xee, 0x00, 0xab, 0xff, 0xe9, 0x00, 0xac, - 0xff, 0xe9, 0x00, 0xad, 0xff, 0xe9, 0x00, 0xb5, 0xff, 0xf4, 0x00, 0xb6, - 0xff, 0xf4, 0x00, 0xb7, 0xff, 0xf4, 0x00, 0xb9, 0xff, 0xf4, 0x00, 0xbb, - 0xff, 0xf4, 0x00, 0x02, 0xff, 0xff, 0xff, 0xd3, 0x00, 0x58, 0xff, 0xfa, - 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1e, 0xff, 0xc7, 0x00, 0x1f, - 0xff, 0xc7, 0x00, 0x37, 0xff, 0xf0, 0x00, 0x45, 0xff, 0xfe, 0x00, 0x49, - 0xff, 0xe3, 0x00, 0x4c, 0xff, 0xfa, 0x00, 0x53, 0xff, 0xe7, 0x00, 0xa4, - 0xff, 0xfe, 0x00, 0xa7, 0xff, 0xfe, 0x00, 0xa8, 0xff, 0xfe, 0x00, 0xa9, - 0x00, 0x04, 0x00, 0xac, 0xff, 0xe3, 0x00, 0xb6, 0xff, 0xe7, 0x00, 0xb9, - 0xff, 0xe7, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1a, 0xff, 0xff, - 0xff, 0xdf, 0x00, 0x10, 0xff, 0x73, 0x00, 0x11, 0xff, 0xe7, 0x00, 0x12, - 0xff, 0x73, 0x00, 0x1e, 0xff, 0xd1, 0x00, 0x1f, 0xff, 0xd1, 0x00, 0x45, - 0xff, 0xdb, 0x00, 0x47, 0xff, 0xdf, 0x00, 0x49, 0xff, 0xd5, 0x00, 0x4b, - 0xff, 0xe3, 0x00, 0x53, 0xff, 0xdd, 0x00, 0x57, 0xff, 0xee, 0x00, 0xa3, - 0xff, 0xdb, 0x00, 0xa4, 0xff, 0xdb, 0x00, 0xa5, 0xff, 0xdb, 0x00, 0xa6, - 0xff, 0xdb, 0x00, 0xa7, 0xff, 0xdb, 0x00, 0xa8, 0xff, 0xdb, 0x00, 0xa9, - 0xff, 0xe3, 0x00, 0xab, 0xff, 0xd5, 0x00, 0xac, 0xff, 0xd5, 0x00, 0xad, - 0xff, 0xd5, 0x00, 0xb5, 0xff, 0xdd, 0x00, 0xb6, 0xff, 0xdd, 0x00, 0xb9, - 0xff, 0xdd, 0x00, 0xbb, 0xff, 0xdd, 0x00, 0x19, 0x00, 0x10, 0xff, 0x9a, - 0x00, 0x11, 0xff, 0xfe, 0x00, 0x12, 0xff, 0x9a, 0x00, 0x1e, 0xff, 0xd1, - 0x00, 0x1f, 0xff, 0xd1, 0x00, 0x45, 0xff, 0xe1, 0x00, 0x47, 0xff, 0xf2, - 0x00, 0x49, 0xff, 0xe7, 0x00, 0x4b, 0xff, 0xf4, 0x00, 0x53, 0xff, 0xee, - 0x00, 0x57, 0xff, 0xf6, 0x00, 0xa3, 0xff, 0xe1, 0x00, 0xa4, 0xff, 0xe1, - 0x00, 0xa5, 0xff, 0xe1, 0x00, 0xa6, 0xff, 0xe1, 0x00, 0xa7, 0xff, 0xe1, - 0x00, 0xa8, 0xff, 0xe1, 0x00, 0xa9, 0xff, 0xe9, 0x00, 0xab, 0xff, 0xe7, - 0x00, 0xac, 0xff, 0xe7, 0x00, 0xad, 0xff, 0xe7, 0x00, 0xb5, 0xff, 0xee, - 0x00, 0xb6, 0xff, 0xee, 0x00, 0xb9, 0xff, 0xee, 0x00, 0xbb, 0xff, 0xf4, - 0x00, 0x06, 0x00, 0x45, 0xff, 0xdd, 0x00, 0x47, 0xff, 0xd1, 0x00, 0x49, - 0xff, 0xc7, 0x00, 0x53, 0xff, 0xcd, 0x00, 0x55, 0xff, 0xd7, 0x00, 0xac, - 0xff, 0xc7, 0x00, 0x1a, 0x00, 0x10, 0xff, 0x71, 0x00, 0x11, 0xff, 0xe3, - 0x00, 0x12, 0xff, 0x71, 0x00, 0x1e, 0xff, 0xc9, 0x00, 0x1f, 0xff, 0xc9, - 0x00, 0x45, 0xff, 0xd3, 0x00, 0x47, 0xff, 0xd9, 0x00, 0x49, 0xff, 0xcf, - 0x00, 0x4b, 0xff, 0xdd, 0x00, 0x50, 0xff, 0xf8, 0x00, 0x53, 0xff, 0xd7, - 0x00, 0x57, 0xff, 0xe7, 0x00, 0xa3, 0xff, 0xd3, 0x00, 0xa4, 0xff, 0xd3, - 0x00, 0xa5, 0xff, 0xd3, 0x00, 0xa6, 0xff, 0xd3, 0x00, 0xa7, 0xff, 0xd3, - 0x00, 0xa8, 0xff, 0xd3, 0x00, 0xa9, 0xff, 0xdb, 0x00, 0xab, 0xff, 0xcf, - 0x00, 0xac, 0xff, 0xcf, 0x00, 0xad, 0xff, 0xcf, 0x00, 0xb5, 0xff, 0xd7, - 0x00, 0xb6, 0xff, 0xd7, 0x00, 0xb9, 0xff, 0xd7, 0x00, 0xbb, 0xff, 0xd9, - 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x27, - 0xff, 0xb6, 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, 0xff, 0xbc, 0x00, 0x35, - 0xff, 0xbe, 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, 0xff, 0xb4, 0x00, 0x3a, - 0xff, 0x66, 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, 0xff, 0x35, 0x00, 0x1c, - 0xff, 0xff, 0xff, 0xae, 0xff, 0xff, 0xff, 0x7b, 0x00, 0x10, 0x00, 0x0a, - 0x00, 0x11, 0xff, 0xfa, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x27, 0xff, 0xb6, - 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, 0xff, 0xbc, 0x00, 0x35, 0xff, 0xbe, - 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, 0xff, 0xb4, 0x00, 0x3a, 0xff, 0x66, - 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, 0xff, 0x35, 0x00, 0x45, 0xff, 0xf8, - 0x00, 0x46, 0x00, 0x08, 0x00, 0x47, 0xff, 0xe9, 0x00, 0x48, 0xff, 0xf0, - 0x00, 0x49, 0xff, 0xdf, 0x00, 0x4b, 0xff, 0xec, 0x00, 0x53, 0xff, 0xe5, - 0x00, 0x55, 0xff, 0xf0, 0x00, 0x58, 0xff, 0xdf, 0x00, 0x59, 0xff, 0xe7, - 0x00, 0x5a, 0xff, 0xc1, 0x00, 0x5b, 0xff, 0xd5, 0x00, 0x5d, 0xff, 0xba, - 0x00, 0x6e, 0xff, 0xa6, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x12, - 0x00, 0x0a, 0x00, 0x27, 0xff, 0xb6, 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, - 0xff, 0xbc, 0x00, 0x35, 0xff, 0xbe, 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, - 0xff, 0xb4, 0x00, 0x3a, 0xff, 0x66, 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, - 0xff, 0x35, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x0a, - 0x00, 0x27, 0xff, 0xb6, 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, 0xff, 0xbc, - 0x00, 0x35, 0xff, 0xbe, 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, 0xff, 0xb4, - 0x00, 0x3a, 0xff, 0x66, 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, 0xff, 0x35, - 0x00, 0x1c, 0xff, 0xff, 0xff, 0xae, 0xff, 0xff, 0xff, 0x8d, 0xff, 0xff, - 0xff, 0x7b, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x11, 0xff, 0xfa, 0x00, 0x12, - 0x00, 0x0a, 0x00, 0x27, 0xff, 0xb6, 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, - 0xff, 0xbc, 0x00, 0x35, 0xff, 0xbe, 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, - 0xff, 0xb4, 0x00, 0x3a, 0xff, 0x66, 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, - 0xff, 0x35, 0x00, 0x45, 0xff, 0xf8, 0x00, 0x46, 0x00, 0x08, 0x00, 0x47, - 0xff, 0xe9, 0x00, 0x48, 0xff, 0xf0, 0x00, 0x4b, 0xff, 0xec, 0x00, 0x53, - 0xff, 0xe5, 0x00, 0x55, 0xff, 0xf0, 0x00, 0x58, 0xff, 0xdf, 0x00, 0x59, - 0xff, 0xe7, 0x00, 0x5a, 0xff, 0xc1, 0x00, 0x5b, 0xff, 0xd5, 0x00, 0x5d, - 0xff, 0xba, 0x00, 0x6e, 0xff, 0xa6, 0x00, 0x1d, 0xff, 0xff, 0xff, 0xae, - 0xff, 0xff, 0xff, 0x8d, 0xff, 0xff, 0xff, 0x7b, 0x00, 0x10, 0x00, 0x0a, - 0x00, 0x11, 0xff, 0xfa, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x27, 0xff, 0xb6, - 0x00, 0x2b, 0xff, 0xb8, 0x00, 0x33, 0xff, 0xbc, 0x00, 0x35, 0xff, 0xbe, - 0x00, 0x38, 0xff, 0x42, 0x00, 0x39, 0xff, 0xb4, 0x00, 0x3a, 0xff, 0x66, - 0x00, 0x3b, 0xff, 0x98, 0x00, 0x3d, 0xff, 0x35, 0x00, 0x45, 0xff, 0xf8, - 0x00, 0x46, 0x00, 0x08, 0x00, 0x47, 0xff, 0xe9, 0x00, 0x48, 0xff, 0xf0, - 0x00, 0x49, 0xff, 0xdf, 0x00, 0x4b, 0xff, 0xec, 0x00, 0x53, 0xff, 0xe5, - 0x00, 0x55, 0xff, 0xf0, 0x00, 0x58, 0xff, 0xdf, 0x00, 0x59, 0xff, 0xe7, - 0x00, 0x5a, 0xff, 0xc1, 0x00, 0x5b, 0xff, 0xd5, 0x00, 0x5d, 0xff, 0xba, - 0x00, 0x6e, 0xff, 0xa6, 0x00, 0x01, 0x00, 0x25, 0xff, 0xc1, 0x00, 0x03, - 0x00, 0x38, 0xff, 0xaa, 0x00, 0x3a, 0xff, 0xa4, 0x00, 0x3d, 0xff, 0x87, - 0x00, 0x05, 0x00, 0x25, 0xff, 0xb8, 0x00, 0x38, 0xff, 0xaa, 0x00, 0x3a, - 0xff, 0xa4, 0x00, 0x3b, 0xff, 0xd1, 0x00, 0x3d, 0xff, 0x87, 0x00, 0x03, - 0x00, 0x38, 0xff, 0xaa, 0x00, 0x3a, 0xff, 0xa4, 0x00, 0x3d, 0xff, 0x87, - 0x00, 0x03, 0x00, 0x38, 0xff, 0xaa, 0x00, 0x3a, 0xff, 0xa4, 0x00, 0x3d, - 0xff, 0x87, 0x00, 0x06, 0x00, 0x25, 0xff, 0xb8, 0x00, 0x38, 0xff, 0xaa, - 0x00, 0x3a, 0xff, 0xa4, 0x00, 0x3b, 0xff, 0xd1, 0x00, 0x3c, 0xff, 0xa2, - 0x00, 0x3d, 0xff, 0x87, 0x00, 0x01, 0x00, 0x25, 0xff, 0xbc, 0x00, 0x01, - 0x00, 0x25, 0xff, 0xb6, 0x00, 0x07, 0x00, 0x10, 0xff, 0xc9, 0x00, 0x12, - 0xff, 0xcd, 0x00, 0x25, 0xff, 0xb6, 0x00, 0x51, 0xff, 0xf8, 0x00, 0x52, - 0xff, 0xf8, 0x00, 0x54, 0x00, 0x06, 0x00, 0x56, 0xff, 0xf8, 0x00, 0x01, - 0x00, 0x25, 0xff, 0xb6, 0x00, 0x08, 0x00, 0x10, 0xff, 0xc9, 0x00, 0x12, - 0xff, 0xcd, 0x00, 0x25, 0xff, 0xb6, 0x00, 0x46, 0x00, 0x06, 0x00, 0x51, - 0xff, 0xf8, 0x00, 0x52, 0xff, 0xf8, 0x00, 0x54, 0x00, 0x06, 0x00, 0x56, - 0xff, 0xf8, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xd5, 0x00, 0x5b, 0xff, 0xe5, - 0x00, 0x5d, 0xff, 0xcb, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xd5, 0x00, 0x5b, - 0xff, 0xe5, 0x00, 0x5d, 0xff, 0xcb, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xd5, - 0x00, 0x5b, 0xff, 0xe5, 0x00, 0x5d, 0xff, 0xcb, 0x00, 0x03, 0x00, 0x5a, - 0xff, 0xd5, 0x00, 0x5b, 0xff, 0xe5, 0x00, 0x5d, 0xff, 0xcb, 0x00, 0x03, - 0x00, 0x5a, 0xff, 0xdf, 0x00, 0x5b, 0xff, 0xec, 0x00, 0x5d, 0xff, 0xd7, - 0x00, 0x03, 0x00, 0x5a, 0xff, 0xe1, 0x00, 0x5b, 0xff, 0xee, 0x00, 0x5d, - 0xff, 0xd9, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xe1, 0x00, 0x5b, 0xff, 0xee, - 0x00, 0x5d, 0xff, 0xd9, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xdb, 0x00, 0x5b, - 0xff, 0xec, 0x00, 0x5d, 0xff, 0xd3, 0x00, 0x03, 0x00, 0x5a, 0xff, 0xdb, - 0x00, 0x5b, 0xff, 0xec, 0x00, 0x5d, 0xff, 0xd3, 0x00, 0x01, 0x00, 0x58, - 0xff, 0xec, 0x00, 0x05, 0x00, 0x58, 0xff, 0xec, 0x00, 0x5a, 0xff, 0xdb, - 0x00, 0x5b, 0xff, 0xec, 0x00, 0x5c, 0xff, 0xc9, 0x00, 0x5d, 0xff, 0xd3, - 0x00, 0x02, 0x00, 0x11, 0x00, 0x25, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2a, - 0x00, 0x2b, 0x00, 0x04, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x06, 0x00, 0x32, - 0x00, 0x34, 0x00, 0x09, 0x00, 0x36, 0x00, 0x3e, 0x00, 0x0c, 0x00, 0x45, - 0x00, 0x47, 0x00, 0x15, 0x00, 0x49, 0x00, 0x4d, 0x00, 0x18, 0x00, 0x4f, - 0x00, 0x5d, 0x00, 0x1d, 0x00, 0x83, 0x00, 0x88, 0x00, 0x2c, 0x00, 0x8a, - 0x00, 0x8a, 0x00, 0x32, 0x00, 0x95, 0x00, 0x99, 0x00, 0x33, 0x00, 0x9b, - 0x00, 0x9f, 0x00, 0x38, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0x3d, 0x00, 0xa7, - 0x00, 0xa9, 0x00, 0x3f, 0x00, 0xac, 0x00, 0xad, 0x00, 0x42, 0x00, 0xb5, - 0x00, 0xb7, 0x00, 0x44, 0x00, 0xb9, 0x00, 0xb9, 0x00, 0x47, 0x00, 0x00 -}; -unsigned int FreeSans_ttf_len = 22932; - -#if 0 -void writeLogo(const char *dir) -{ - QCString fileName=(QCString)dir+"/doxygen.png"; - QFile f(fileName); - if (f.open(IO_WriteOnly)) - f.writeBlock((char *)doxygen_png_data,doxygen_png_len); - else - { - fprintf(stderr,"warning: Cannot open file %s for writing\n",fileName.data()); - } - f.close(); -} - -void writeSearchButton(const char *dir) -{ - QCString fileName=(QCString)dir+"/search.png"; - QFile f(fileName); - if (f.open(IO_WriteOnly)) - f.writeBlock((char *)search_png,search_png_len); - else - { - fprintf(stderr,"warning: Cannot open file %s for writing\n",fileName.data()); - } - f.close(); -} -#endif - -void writeDoxFont(const char *dir) -{ - QCString fileName=(QCString)dir+"/FreeSans.ttf"; - QFile f(fileName); - if (f.open(IO_WriteOnly)) - f.writeBlock((char *)FreeSans_ttf,FreeSans_ttf_len); - else - { - fprintf(stderr,"error: Cannot open file %s for writing\n",fileName.data()); - } - f.close(); -} - -void removeDoxFont(const char *dir) -{ - QDir d(dir); - d.remove("FreeSans.ttf"); -} diff --git a/src/logos.h b/src/logos.h deleted file mode 100644 index 95a8a39..0000000 --- a/src/logos.h +++ /dev/null @@ -1,27 +0,0 @@ -/****************************************************************************** - * - * - * - * 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 - * 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 LOGOS_H -#define LOGOS_H - -extern void writeLogo(const char *dir); -//extern void writeNullImage(const char *dir); -extern void writeSearchButton(const char *dir); -extern void writeDoxFont(const char *dir); -extern void removeDoxFont(const char *dir); - -#endif diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp index beef632..997b24e 100644 --- a/src/mandocvisitor.cpp +++ b/src/mandocvisitor.cpp @@ -137,9 +137,11 @@ void ManDocVisitor::visit(DocStyleChange *s) m_firstCol=FALSE; break; case DocStyleChange::Strike: + case DocStyleChange::Del: /* not supported */ break; case DocStyleChange::Underline: //underline is shown as emphasis + case DocStyleChange::Ins: if (s->enable()) m_t << "\\fI"; else m_t << "\\fP"; m_firstCol=FALSE; break; @@ -254,20 +256,21 @@ void ManDocVisitor::visit(DocInclude *inc) m_t << ".PP" << endl; m_t << ".nf" << endl; QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), inc->exampleFile(), - &fd, // fileDef, + fd, // fileDef, -1, // start line -1, // end line FALSE, // inline fragment 0, // memberDef TRUE ); + delete fd; if (!m_firstCol) m_t << endl; m_t << ".fi" << endl; m_t << ".PP" << endl; @@ -296,10 +299,9 @@ void ManDocVisitor::visit(DocInclude *inc) m_t << ".PP" << endl; m_firstCol=TRUE; break; - case DocInclude::DontInclude: - break; - case DocInclude::HtmlInclude: - break; + case DocInclude::DontInclude: + case DocInclude::DontIncWithLines: + case DocInclude::HtmlInclude: case DocInclude::LatexInclude: break; case DocInclude::VerbInclude: @@ -335,7 +337,7 @@ void ManDocVisitor::visit(DocInclude *inc) m_t << ".PP" << endl; m_t << ".nf" << endl; QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci, inc->context(), @@ -343,13 +345,14 @@ void ManDocVisitor::visit(DocInclude *inc) langExt, inc->isExample(), inc->exampleFile(), - &fd, + fd, lineBlock(inc->text(),inc->blockId()), -1, // endLine FALSE, // inlineFragment 0, // memberDef TRUE // show line number ); + delete fd; if (!m_firstCol) m_t << endl; m_t << ".fi" << endl; m_t << ".PP" << endl; @@ -366,8 +369,10 @@ void ManDocVisitor::visit(DocInclude *inc) void ManDocVisitor::visit(DocIncOperator *op) { - SrcLangExt langExt = getLanguageFromFileName(m_langExt); - //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n", + QCString locLangExt = getFileNameExtension(op->includeFileName()); + if (locLangExt.isEmpty()) locLangExt = m_langExt; + SrcLangExt langExt = getLanguageFromFileName(locLangExt); + //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", // op->type(),op->isFirst(),op->isLast(),op->text().data()); if (op->isFirst()) { @@ -385,9 +390,24 @@ void ManDocVisitor::visit(DocIncOperator *op) popEnabled(); if (!m_hide) { - Doxygen::parserManager->getParser(m_langExt) + FileDef *fd = 0; + if (!op->includeFileName().isEmpty()) + { + QFileInfo cfi( op->includeFileName() ); + fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + } + + Doxygen::parserManager->getParser(locLangExt) ->parseCode(m_ci,op->context(),op->text(),langExt, - op->isExample(),op->exampleFile()); + op->isExample(),op->exampleFile(), + fd, // fileDef + op->line(), // startLine + -1, // endLine + FALSE, // inline fragment + 0, // memberDef + op->showLineNo() // show line numbers + ); + if (fd) delete fd; } pushEnabled(); m_hide=TRUE; @@ -553,7 +573,7 @@ void ManDocVisitor::visitPre(DocSimpleSect *s) // special case 1: user defined title if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs) { - m_t << ":\\fP" << endl; + m_t << "\\fP" << endl; m_t << ".RS 4" << endl; } } @@ -926,7 +946,7 @@ void ManDocVisitor::visitPre(DocParamSect *s) default: ASSERT(0); } - m_t << ":\\fP" << endl; + m_t << "\\fP" << endl; m_t << ".RS 4" << endl; } @@ -1010,14 +1030,6 @@ void ManDocVisitor::visitPost(DocInternalRef *) m_t << "\\fP"; } -void ManDocVisitor::visitPre(DocCopy *) -{ -} - -void ManDocVisitor::visitPost(DocCopy *) -{ -} - void ManDocVisitor::visitPre(DocText *) { } diff --git a/src/mandocvisitor.h b/src/mandocvisitor.h index 8efc223..fa65424 100644 --- a/src/mandocvisitor.h +++ b/src/mandocvisitor.h @@ -128,8 +128,6 @@ class ManDocVisitor : public DocVisitor void visitPost(DocXRefItem *); void visitPre(DocInternalRef *); void visitPost(DocInternalRef *); - void visitPre(DocCopy *); - void visitPost(DocCopy *); void visitPre(DocText *); void visitPost(DocText *); void visitPre(DocHtmlBlockQuote *); diff --git a/src/mangen.cpp b/src/mangen.cpp index b3ae732..06d3c4a 100644 --- a/src/mangen.cpp +++ b/src/mangen.cpp @@ -706,7 +706,7 @@ void ManGenerator::endParamList() { } -void ManGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *) +void ManGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *) { ManDocVisitor *visitor = new ManDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString("")); n->accept(visitor); diff --git a/src/mangen.h b/src/mangen.h index e109355..d912923 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -41,7 +41,7 @@ class ManGenerator : public OutputGenerator bool isEnabled(OutputType o) { return (o==Man && active); } OutputGenerator *get(OutputType o) { return (o==Man) ? this : 0; } - void writeDoc(DocNode *,Definition *,MemberDef *); + void writeDoc(DocNode *,const Definition *,const MemberDef *); static void init(); void startFile(const char *name,const char *manName,const char *title); @@ -207,16 +207,16 @@ class ManGenerator : public OutputGenerator void endDescTableData() {} void startDotGraph() {} - void endDotGraph(const DotClassGraph &) {} + void endDotGraph(DotClassGraph &) {} void startInclDepGraph() {} - void endInclDepGraph(const DotInclDepGraph &) {} + void endInclDepGraph(DotInclDepGraph &) {} void startGroupCollaboration() {} - void endGroupCollaboration(const DotGroupCollaboration &) {} + void endGroupCollaboration(DotGroupCollaboration &) {} void startCallGraph() {} - void endCallGraph(const DotCallGraph &) {} + void endCallGraph(DotCallGraph &) {} void startDirDepGraph() {} - void endDirDepGraph(const DotDirDeps &) {} - void writeGraphicalHierarchy(const DotGfxHierarchyTable &) {} + void endDirDepGraph(DotDirDeps &) {} + void writeGraphicalHierarchy(DotGfxHierarchyTable &) {} void startTextBlock(bool) {} void endTextBlock(bool) {} @@ -260,7 +260,7 @@ class ManGenerator : public OutputGenerator void endLabels(); void writeCodeAnchor(const char *) {} - void setCurrentDoc(Definition *,const char *,bool) {} + void setCurrentDoc(const Definition *,const char *,bool) {} void addWord(const char *,bool) {} private: diff --git a/src/markdown.cpp b/src/markdown.cpp index b00070e..2cbdcb5 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -107,13 +107,7 @@ static action_t g_actions[256]; static Entry *g_current; static QCString g_fileName; static int g_lineNr; - -// In case a markdown page starts with a level1 header, that header is used -// as a title of the page, in effect making it a level0 header, so the -// level of all other sections needs to be corrected as well. -// This flag is TRUE if corrections are needed. -//static bool g_correctSectionLevel; - +static int g_indentLevel=0; // 0 is outside markdown, -1=page level //---------- @@ -138,6 +132,7 @@ static QCString escapeSpecialChars(const QCString &s) case '>': if (!insideQuote) { growBuf.addChar('\\'); } growBuf.addChar('>'); break; case '\\': if (!insideQuote) { growBuf.addChar('\\'); } growBuf.addChar('\\'); break; case '@': if (!insideQuote) { growBuf.addChar('\\'); } growBuf.addChar('@'); break; + case '#': if (!insideQuote) { growBuf.addChar('\\'); } growBuf.addChar('#'); break; default: growBuf.addChar(c); break; } pc=c; @@ -523,7 +518,7 @@ static int processQuoted(GrowBuf &out,const char *data,int,int size) /** Process a HTML tag. Note that <pre>..</pre> are treated specially, in * the sense that all code inside is written unprocessed */ -static int processHtmlTag(GrowBuf &out,const char *data,int offset,int size) +static int processHtmlTagWrite(GrowBuf &out,const char *data,int offset,int size,bool doWrite) { if (offset>0 && data[-1]=='\\') return 0; // escaped < @@ -546,7 +541,7 @@ static int processHtmlTag(GrowBuf &out,const char *data,int offset,int size) tolower(data[i+2])=='p' && tolower(data[i+3])=='r' && tolower(data[i+4])=='e' && tolower(data[i+5])=='>') { // found </pre> tag, copy from start to end of tag - out.addStr(data,i+6); + if (doWrite) out.addStr(data,i+6); //printf("found <pre>..</pre> [%d..%d]\n",0,i+6); return i+6; } @@ -569,13 +564,13 @@ static int processHtmlTag(GrowBuf &out,const char *data,int offset,int size) if (data[i]=='/' && i<size-1 && data[i+1]=='>') // <bla/> { //printf("Found htmlTag={%s}\n",QCString(data).left(i+2).data()); - out.addStr(data,i+2); + if (doWrite) out.addStr(data,i+2); return i+2; } else if (data[i]=='>') // <bla> { //printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data()); - out.addStr(data,i+1); + if (doWrite) out.addStr(data,i+1); return i+1; } else if (data[i]==' ') // <bla attr=... @@ -595,7 +590,7 @@ static int processHtmlTag(GrowBuf &out,const char *data,int offset,int size) else if (!insideAttr && data[i]=='>') // found end of tag { //printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data()); - out.addStr(data,i+1); + if (doWrite) out.addStr(data,i+1); return i+1; } i++; @@ -606,6 +601,10 @@ static int processHtmlTag(GrowBuf &out,const char *data,int offset,int size) //printf("Not a valid html tag\n"); return 0; } +static int processHtmlTag(GrowBuf &out,const char *data,int offset,int size) +{ + return processHtmlTagWrite(out,data,offset,size,true); +} static int processEmphasis(GrowBuf &out,const char *data,int offset,int size) { @@ -910,7 +909,7 @@ static int processLink(GrowBuf &out,const char *data,int,int size) { SrcLangExt lang = getLanguageFromFileName(link); int lp=-1; - if ((lp=link.find("@ref "))!=-1 || (lp=link.find("\\ref "))!=-1 || lang==SrcLangExt_Markdown) + if ((lp=link.find("@ref "))!=-1 || (lp=link.find("\\ref "))!=-1 || (lang==SrcLangExt_Markdown && !isURL(link))) // assume doxygen symbol link { if (lp==-1) // link to markdown page @@ -980,7 +979,7 @@ static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int s nl++; } else if (data[end]=='\'' && nb==1 && (end==size-1 || (end<size-1 && !isIdChar(end+1)))) - { // look for quoted strings like `some word', but skip strings like `it's cool` + { // look for quoted strings like 'some word', but skip strings like `it's cool` QCString textFragment; convertStringFragment(textFragment,data+nb,end-nb); out.addStr("‘"); @@ -1098,7 +1097,7 @@ static void processInline(GrowBuf &out,const char *data,int size) } /** returns whether the line is a setext-style hdr underline */ -static int isHeaderline(const char *data, int size) +static int isHeaderline(const char *data, int size, bool allowAdjustLevel) { int i=0, c=0; while (i<size && data[i]==' ') i++; @@ -1108,14 +1107,24 @@ static int isHeaderline(const char *data, int size) { while (i<size && data[i]=='=') i++,c++; while (i<size && data[i]==' ') i++; - return (c>1 && (i>=size || data[i]=='\n')) ? 1 : 0; + int level = (c>1 && (i>=size || data[i]=='\n')) ? 1 : 0; + if (allowAdjustLevel && level==1 && g_indentLevel==-1) + { + // In case a page starts with a header line we use it as title, promoting it to @page. + // We set g_indentLevel to -1 to promoting the other sections if they have a deeper + // nesting level than the page header, i.e. @section..@subsection becomes @page..@section. + // In case a section at the same level is found (@section..@section) however we need + // to undo this (and the result will be @page..@section). + g_indentLevel=0; + } + return g_indentLevel+level; } // test of level 2 header if (data[i]=='-') { while (i<size && data[i]=='-') i++,c++; while (i<size && data[i]==' ') i++; - return (c>1 && (i>=size || data[i]=='\n')) ? 2 : 0; + return (c>1 && (i>=size || data[i]=='\n')) ? g_indentLevel+2 : 0; } return 0; } @@ -1290,7 +1299,7 @@ static QCString extractTitleId(QCString &title, int level) static int isAtxHeader(const char *data,int size, - QCString &header,QCString &id) + QCString &header,QCString &id,bool allowAdjustLevel) { int i = 0, end; int level = 0, blanks=0; @@ -1323,7 +1332,29 @@ static int isAtxHeader(const char *data,int size, header=header.left(i+1); } - return level; + if (allowAdjustLevel && level==1 && g_indentLevel==-1) + { + // in case we find a `# Section` on a markdown page that started with the same level + // header, we no longer need to artificially decrease the paragraph level. + // So both + // ------------------- + // # heading 1 <-- here we set g_indentLevel to -1 + // # heading 2 <-- here we set g_indentLevel back to 0 such that this will be a @section + // ------------------- + // and + // ------------------- + // # heading 1 <-- here we set g_indentLevel to -1 + // ## heading 2 <-- here we keep g_indentLevel at -1 such that @subsection will be @section + // ------------------- + // will convert to + // ------------------- + // @page md_page Heading 1 + // @section autotoc_md1 Heading 2 + // ------------------- + + g_indentLevel=0; + } + return level+g_indentLevel; } static int isEmptyLine(const char *data,int size) @@ -1869,7 +1900,7 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) } // need at least one space on either side of the cell text in // order for doxygen to do other formatting - out.addStr("> " + cellText + " </" + cellTag + ">\n"); + out.addStr("> " + cellText + "\n</" + cellTag + ">\n"); } cellTag = "td"; cellClass = "class=\"markdownTableBody"; @@ -1886,10 +1917,16 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) static int hasLineBreak(const char *data,int size) { int i=0; - while (i<size && data[i]!='\n') i++; + int j=0; + // search for end of line and also check if it is not a completely blank + while (i<size && data[i]!='\n') + { + if (data[i]!=' ' && data[i]!='\t') j++; // some non whitespace + i++; + } if (i>=size) return 0; // empty line if (i<2) return 0; // not long enough - return (data[i-1]==' ' && data[i-2]==' '); + return (j>0 && data[i-1]==' ' && data[i-2]==' '); // non blank line with at two spaces at the end } @@ -1902,10 +1939,8 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size) { out.addStr("\n<hr>\n"); } - else if ((level=isAtxHeader(data,size,header,id))) + else if ((level=isAtxHeader(data,size,header,id,TRUE))) { - //if (level==1) g_correctSectionLevel=FALSE; - //if (g_correctSectionLevel) level--; QCString hTag; if (level<5 && !id.isEmpty()) { @@ -1947,7 +1982,7 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size) out.addStr(data,size); if (hasLineBreak(data,size)) { - out.addStr("\n"); + out.addStr("<br>\n"); } } } @@ -2086,17 +2121,9 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size, { if (qstrncmp(&data[end+1],endBlockName,l)==0) { - if (pi!=-1) // output previous line if available - { - //printf("feol out={%s}\n",QCString(data+pi).left(i-pi).data()); - out.addStr(data+pi,i-pi); - } // found end marker, skip over this block //printf("feol.block out={%s}\n",QCString(data+i).left(end+l+1-i).data()); - out.addStr(data+i,end+l+1-i); - pi=-1; - i=end+l+1; // continue after block - end=i+1; + end = end + l + 2; break; } } @@ -2110,16 +2137,8 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size, if (tolower(data[end])=='p' && tolower(data[end+1])=='r' && tolower(data[end+2])=='e' && data[end+3]=='>') // <pre> tag { - if (pi!=-1) // output previous line if available - { - out.addStr(data+pi,i-pi); - } - // output part until <pre> - out.addStr(data+i,end-1-i); - // output part until </pre> - i = end-1 + processHtmlTag(out,data+end-1,end-1,size-end+1); - pi=-1; - end = i+1; + // skip part until including </pre> + end = end + processHtmlTagWrite(out,data+end-1,end-1,size-end+1,false) + 2; break; } else @@ -2263,10 +2282,8 @@ static QCString processBlocks(const QCString &s,int indent) QCString lang; blockIndent = indent; //printf("isHeaderLine(%s)=%d\n",QCString(data+i).left(size-i).data(),level); - if ((level=isHeaderline(data+i,size-i))>0) + if ((level=isHeaderline(data+i,size-i,TRUE))>0) { - //if (level==1) g_correctSectionLevel=FALSE; - //if (g_correctSectionLevel) level--; //printf("Found header at %d-%d\n",i,end); while (pi<size && data[pi]==' ') pi++; QCString header,id; @@ -2282,28 +2299,6 @@ static QCString processBlocks(const QCString &s,int indent) out.addStr(" "); out.addStr(header); out.addStr("\n\n"); - SectionInfo *si = Doxygen::sectionDict->find(id); - if (si) - { - if (si->lineNr != -1) - { - warn(g_fileName,g_lineNr,"multiple use of section label '%s', (first occurrence: %s, line %d)",header.data(),si->fileName.data(),si->lineNr); - } - else - { - warn(g_fileName,g_lineNr,"multiple use of section label '%s', (first occurrence: %s)",header.data(),si->fileName.data()); - } - } - else - { - si = new SectionInfo(g_fileName,g_lineNr,id,header, - level==1 ? SectionInfo::Section : SectionInfo::Subsection,level); - if (g_current) - { - g_current->anchors->append(si); - } - Doxygen::sectionDict->append(id,si); - } } else { @@ -2429,7 +2424,7 @@ static QCString extractPageTitle(QCString &docs,QCString &id) // second line form end1..end2 int end2=end1+1; while (end2<size && data[end2-1]!='\n') end2++; - if (isHeaderline(data+end1,size-end1)) + if (isHeaderline(data+end1,size-end1,FALSE)) { convertStringFragment(title,data+i,end1-i-1); QCString lns; @@ -2440,10 +2435,14 @@ static QCString extractPageTitle(QCString &docs,QCString &id) return title; } } - if (i<end1 && isAtxHeader(data+i,end1-i,title,id)>0) + if (i<end1 && isAtxHeader(data+i,end1-i,title,id,FALSE)>0) { docs=docs.mid(end1); } + else + { + id = extractTitleId(title, 0); + } //printf("extractPageTitle(title='%s' docs='%s' id='%s')\n",title.data(),docs.data(),id.data()); return title; } @@ -2451,8 +2450,8 @@ static QCString extractPageTitle(QCString &docs,QCString &id) static QCString detab(const QCString &s,int &refIndent) { static int tabSize = Config_getInt(TAB_SIZE); - GrowBuf out; int size = s.length(); + GrowBuf out(size); const char *data = s.data(); int i=0; int col=0; @@ -2480,19 +2479,32 @@ static QCString detab(const QCString &s,int &refIndent) col++; break; default: // non-whitespace => update minIndent - out.addChar(c); if (c<0 && i<size) // multibyte sequence { - out.addChar(data[i++]); // >= 2 bytes - if (((uchar)c&0xE0)==0xE0 && i<size) + // special handling of the UTF-8 nbsp character 0xc2 0xa0 + if (c == '\xc2' && data[i] == '\xa0') { - out.addChar(data[i++]); // 3 bytes + out.addStr(" "); + i++; } - if (((uchar)c&0xF0)==0xF0 && i<size) + else { - out.addChar(data[i++]); // 4 byres + out.addChar(c); + out.addChar(data[i++]); // >= 2 bytes + if (((uchar)c&0xE0)==0xE0 && i<size) + { + out.addChar(data[i++]); // 3 bytes + } + if (((uchar)c&0xF0)==0xF0 && i<size) + { + out.addChar(data[i++]); // 4 byres + } } } + else + { + out.addChar(c); + } if (col<minIndent) minIndent=col; col++; } @@ -2535,7 +2547,9 @@ QCString processMarkdown(const QCString &fileName,const int lineNr,Entry *e,cons out.clear(); int refIndent; // for replace tabs by spaces - QCString s = detab(input,refIndent); + QCString s = input; + if (s.at(s.length()-1)!='\n') s += "\n"; // see PR #6766 + s = detab(s,refIndent); //printf("======== DeTab =========\n---- output -----\n%s\n---------\n",s.data()); // then process quotation blocks (as these may contain other blocks) s = processQuotations(s,refIndent); @@ -2561,6 +2575,7 @@ QCString markdownFileNameToId(const QCString &fileName) return "md_"+baseName; } + void MarkdownFileParser::parseInput(const char *fileName, const char *fileBuf, Entry *root, @@ -2575,6 +2590,8 @@ void MarkdownFileParser::parseInput(const char *fileName, QCString docs = fileBuf; QCString id; QCString title=extractPageTitle(docs,id).stripWhiteSpace(); + if (QString(id).startsWith("autotoc_md")) id = ""; + g_indentLevel=title.isEmpty() ? 0 : -1; QCString titleFn = QFileInfo(fileName).baseName().utf8(); QCString fn = QFileInfo(fileName).fileName().utf8(); static QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE); @@ -2601,19 +2618,20 @@ void MarkdownFileParser::parseInput(const char *fileName, } } int lineNr=1; - int position=0; // even without markdown support enabled, we still // parse markdown files as such bool markdownEnabled = Doxygen::markdownSupport; Doxygen::markdownSupport = TRUE; - bool needsEntry = FALSE; Protection prot=Public; + bool needsEntry = FALSE; + int position=0; + QCString processedDocs = preprocessCommentBlock(docs,fileName,lineNr); while (parseCommentBlock( this, current, - docs, + processedDocs, fileName, lineNr, FALSE, // isBrief @@ -2640,7 +2658,7 @@ void MarkdownFileParser::parseInput(const char *fileName, // restore setting Doxygen::markdownSupport = markdownEnabled; - //g_correctSectionLevel = FALSE; + g_indentLevel=0; } void MarkdownFileParser::parseCode(CodeOutputInterface &codeOutIntf, @@ -2653,9 +2671,9 @@ void MarkdownFileParser::parseCode(CodeOutputInterface &codeOutIntf, int startLine, int endLine, bool inlineFragment, - MemberDef *memberDef, + const MemberDef *memberDef, bool showLineNumbers, - Definition *searchCtx, + const Definition *searchCtx, bool collectXRefs ) { diff --git a/src/markdown.h b/src/markdown.h index e2e3a74..1a3895e 100644 --- a/src/markdown.h +++ b/src/markdown.h @@ -47,9 +47,9 @@ class MarkdownFileParser : public ParserInterface int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, - MemberDef *memberDef=0, + const MemberDef *memberDef=0, bool showLineNumbers=TRUE, - Definition *searchCtx=0, + const Definition *searchCtx=0, bool collectXRefs=TRUE ); void resetCodeParserState(); diff --git a/src/marshal.cpp b/src/marshal.cpp deleted file mode 100644 index c68718a..0000000 --- a/src/marshal.cpp +++ /dev/null @@ -1,857 +0,0 @@ -#include <qfile.h> -#include <assert.h> - -#include "sortdict.h" -#include "marshal.h" -#include "entry.h" -#include "section.h" -#include "memberlist.h" -#include "definition.h" -#include "groupdef.h" -#include "example.h" -#include "arguments.h" -#include "doxygen.h" - -#define HEADER ('D'<<24)+('O'<<16)+('X'<<8)+'!' - -void marshalInt(StorageIntf *s,int v) -{ - uchar b[4]; - b[0]=((uint)v)>>24; - b[1]=(((uint)v)>>16)&0xff; - b[2]=(((uint)v)>>8)&0xff; - b[3]=v&0xff; - s->write((const char *)b,4); -} - -void marshalUInt(StorageIntf *s,uint v) -{ - uchar b[4]; - b[0]=v>>24; - b[1]=(v>>16)&0xff; - b[2]=(v>>8)&0xff; - b[3]=v&0xff; - s->write((const char *)b,4); -} - -void marshalUInt64(StorageIntf *s,uint64 v) -{ - marshalUInt(s, uint(v>>32)); - marshalUInt(s, uint(v&0xFFFFFFFF)); -} - -void marshalBool(StorageIntf *s,bool b) -{ - char c = b; - s->write(&c,sizeof(char)); -} - -void marshalQCString(StorageIntf *s,const QCString &str) -{ - uint l=str.length(); - marshalUInt(s,l); - if (l>0) s->write(str.data(),l); -} - -void marshalQGString(StorageIntf *s,const QGString &str) -{ - uint l=str.length(); - marshalUInt(s,l); - if (l>0) s->write(str.data(),l); -} - -void marshalArgumentList(StorageIntf *s,ArgumentList *argList) -{ - ArgumentList::marshal(s,argList); -} - -void marshalArgumentLists(StorageIntf *s,QList<ArgumentList> *argLists) -{ - if (argLists==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,argLists->count()); - QListIterator<ArgumentList> ali(*argLists); - ArgumentList *al; - for (ali.toFirst();(al=ali.current());++ali) - { - marshalArgumentList(s,al); - } - } -} - -void marshalBaseInfoList(StorageIntf *s, QList<BaseInfo> *baseList) -{ - if (baseList==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,baseList->count()); - QListIterator<BaseInfo> bli(*baseList); - BaseInfo *bi; - for (bli.toFirst();(bi=bli.current());++bli) - { - marshalQCString(s,bi->name); - marshalInt(s,(int)bi->prot); - marshalInt(s,(int)bi->virt); - } - } -} - -void marshalGroupingList(StorageIntf *s, QList<Grouping> *groups) -{ - if (groups==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,groups->count()); - QListIterator<Grouping> gli(*groups); - Grouping *g; - for (gli.toFirst();(g=gli.current());++gli) - { - marshalQCString(s,g->groupname); - marshalInt(s,(int)g->pri); - } - } -} - -void marshalSectionInfoList(StorageIntf *s, QList<SectionInfo> *anchors) -{ - if (anchors==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,anchors->count()); - QListIterator<SectionInfo> sli(*anchors); - SectionInfo *si; - for (sli.toFirst();(si=sli.current());++sli) - { - marshalQCString(s,si->label); - marshalQCString(s,si->title); - marshalQCString(s,si->ref); - marshalInt(s,(int)si->type); - marshalQCString(s,si->fileName); - marshalInt(s,si->lineNr); - marshalInt(s,si->level); - } - anchors->clear(); - } -} - -void marshalItemInfoList(StorageIntf *s, QList<ListItemInfo> *sli) -{ - if (sli==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,sli->count()); - QListIterator<ListItemInfo> liii(*sli); - ListItemInfo *lii; - for (liii.toFirst();(lii=liii.current());++liii) - { - marshalQCString(s,lii->type); - marshalInt(s,lii->itemId); - } - } -} - -void marshalObjPointer(StorageIntf *s,void *obj) -{ - char *b = (char *)&obj; - s->write(b,sizeof(void *)); -} - -void marshalSectionDict(StorageIntf *s,SectionDict *sections) -{ - if (sections==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,sections->count()); - SDict<SectionInfo>::IteratorDict sli(*sections); - SectionInfo *si; - for (sli.toFirst();(si=sli.current());++sli) - { - marshalQCString(s,sli.currentKey()); - marshalObjPointer(s,si); - } - } -} - -void marshalMemberSDict(StorageIntf *s,MemberSDict *memberSDict) -{ - if (memberSDict==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,memberSDict->count()); - //printf(" marshalMemberSDict: items=%d\n",memberSDict->count()); - SDict<MemberDef>::IteratorDict mdi(*memberSDict); - MemberDef *md; - int count=0; - for (mdi.toFirst();(md=mdi.current());++mdi) - { - //printf(" marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md); - marshalQCString(s,mdi.currentKey()); - marshalObjPointer(s,md); - count++; - } - assert(count==memberSDict->count()); - } -} - -void marshalDocInfo(StorageIntf *s,DocInfo *docInfo) -{ - if (docInfo==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,1); - marshalQCString(s,docInfo->doc); - marshalInt(s,docInfo->line); - marshalQCString(s,docInfo->file); - } -} - -void marshalBriefInfo(StorageIntf *s,BriefInfo *briefInfo) -{ - if (briefInfo==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,1); - marshalQCString(s,briefInfo->doc); - marshalQCString(s,briefInfo->tooltip); - marshalInt(s,briefInfo->line); - marshalQCString(s,briefInfo->file); - } -} - -void marshalBodyInfo(StorageIntf *s,BodyInfo *bodyInfo) -{ - if (bodyInfo==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,1); - marshalInt(s,bodyInfo->startLine); - marshalInt(s,bodyInfo->endLine); - marshalObjPointer(s,bodyInfo->fileDef); - } -} - -void marshalGroupList(StorageIntf *s,GroupList *groupList) -{ - if (groupList==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,groupList->count()); - QListIterator<GroupDef> gli(*groupList); - GroupDef *gd=0; - for (gli.toFirst();(gd=gli.current());++gli) - { - marshalObjPointer(s,gd); - } - } -} - -void marshalMemberList(StorageIntf *s,MemberList *ml) -{ - if (ml==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,ml->count()); - MemberListIterator mli(*ml); - MemberDef *md; - uint count=0; - for (mli.toFirst();(md=mli.current());++mli) - { - marshalObjPointer(s,md); - count++; - } - assert(count==ml->count()); - - ml->marshal(s); - } -} - -void marshalExampleSDict(StorageIntf *s,ExampleSDict *ed) -{ - if (ed==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,ed->count()); - //printf(" marshalMemberSDict: items=%d\n",memberSDict->count()); - SDict<Example>::IteratorDict edi(*ed); - Example *e; - for (edi.toFirst();(e=edi.current());++edi) - { - //printf(" marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md); - marshalQCString(s,edi.currentKey()); - marshalQCString(s,e->anchor); - marshalQCString(s,e->name); - marshalQCString(s,e->file); - } - } -} - -void marshalMemberLists(StorageIntf *s,SDict<MemberList> *mls) -{ - if (mls==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,mls->count()); - //printf(" marshalMemberSDict: items=%d\n",memberSDict->count()); - SDict<MemberList>::IteratorDict mli(*mls); - MemberList *ml; - for (mli.toFirst();(ml=mli.current());++mli) - { - //printf(" marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md); - marshalQCString(s,mli.currentKey()); - marshalObjPointer(s,ml); // assume we are not owner of the list - } - } -} - -void marshalLocalToc(StorageIntf *s,const LocalToc <) -{ - marshalInt(s,lt.mask()); - marshalInt(s,lt.htmlLevel()); - marshalInt(s,lt.latexLevel()); - marshalInt(s,lt.xmlLevel()); - marshalInt(s,lt.docbookLevel()); -} - -void marshalEntry(StorageIntf *s,Entry *e) -{ - marshalUInt(s,HEADER); - marshalQCString(s,e->name); - marshalQCString(s,e->type); - marshalInt(s,e->section); - marshalInt(s,(int)e->protection); - marshalInt(s,(int)e->mtype); - marshalUInt64(s,e->spec); - marshalInt(s,e->initLines); - marshalBool(s,e->stat); - marshalLocalToc(s,e->localToc); - marshalBool(s,e->explicitExternal); - marshalBool(s,e->proto); - marshalBool(s,e->subGrouping); - marshalBool(s,e->callGraph); - marshalBool(s,e->callerGraph); - marshalBool(s,e->referencedByRelation); - marshalBool(s,e->referencesRelation); - marshalInt(s,(int)e->virt); - marshalQCString(s,e->args); - marshalQCString(s,e->bitfields); - marshalArgumentList(s,e->argList); - marshalArgumentLists(s,e->tArgLists); - marshalQGString(s,e->program); - marshalQGString(s,e->initializer); - marshalQCString(s,e->includeFile); - marshalQCString(s,e->includeName); - marshalQCString(s,e->doc); - marshalInt(s,e->docLine); - marshalQCString(s,e->docFile); - marshalQCString(s,e->brief); - marshalInt(s,e->briefLine); - marshalQCString(s,e->briefFile); - marshalQCString(s,e->inbodyDocs); - marshalInt(s,e->inbodyLine); - marshalQCString(s,e->inbodyFile); - marshalQCString(s,e->relates); - marshalInt(s,e->relatesType); - marshalQCString(s,e->read); - marshalQCString(s,e->write); - marshalQCString(s,e->inside); - marshalQCString(s,e->exception); - marshalArgumentList(s,e->typeConstr); - marshalInt(s,e->bodyLine); - marshalInt(s,e->endBodyLine); - marshalInt(s,e->mGrpId); - marshalBaseInfoList(s,e->extends); - marshalGroupingList(s,e->groups); - marshalSectionInfoList(s,e->anchors); - marshalQCString(s,e->fileName); - marshalInt(s,e->startLine); - marshalItemInfoList(s,e->sli); - marshalInt(s,(int)e->lang); - marshalBool(s,e->hidden); - marshalBool(s,e->artificial); - marshalInt(s,(int)e->groupDocType); - marshalQCString(s,e->id); - marshalQCString(s,e->metaData); -} - -void marshalEntryTree(StorageIntf *s,Entry *e) -{ - marshalEntry(s,e); - marshalUInt(s,e->children()->count()); - QListIterator<Entry> eli(*e->children()); - Entry *child; - for (eli.toFirst();(child=eli.current());++eli) - { - marshalEntryTree(s,child); - } -} - -//------------------------------------------------------------------ - -int unmarshalInt(StorageIntf *s) -{ - uchar b[4]; - s->read((char *)b,4); - int result=(int)((((uint)b[0])<<24)+((uint)b[1]<<16)+((uint)b[2]<<8)+(uint)b[3]); - //printf("unmarshalInt: %x %x %x %x: %x offset=%llx\n",b[0],b[1],b[2],b[3],result,f.pos()); - return result; -} - -uint unmarshalUInt(StorageIntf *s) -{ - uchar b[4]; - s->read((char *)b,4); - uint result=(((uint)b[0])<<24)+((uint)b[1]<<16)+((uint)b[2]<<8)+(uint)b[3]; - //printf("unmarshalUInt: %x %x %x %x: %x offset=%llx\n",b[0],b[1],b[2],b[3],result,f.pos()); - return result; -} - -uint64 unmarshalUInt64(StorageIntf *s) -{ - uint64 result=uint64(unmarshalUInt(s))<<32; - result|=unmarshalUInt(s); - return result; -} - -bool unmarshalBool(StorageIntf *s) -{ - char result; - s->read(&result,sizeof(result)); - //printf("unmarshalBool: %x offset=%llx\n",result,f.pos()); - return result; -} - -QCString unmarshalQCString(StorageIntf *s) -{ - uint len = unmarshalUInt(s); - //printf("unmarshalQCString: len=%d offset=%llx\n",len,f.pos()); - QCString result(len+1); - result.at(len)='\0'; - if (len>0) - { - s->read(result.rawData(),len); - } - //printf("unmarshalQCString: result=%s\n",result.data()); - return result; -} - -QGString unmarshalQGString(StorageIntf *s) -{ - uint len = unmarshalUInt(s); - //printf("unmarshalQCString: len=%d offset=%llx\n",len,f.pos()); - QGString result(len+1); - result.at(len)='\0'; - if (len>0) - { - s->read(result.data(),len); - } - //printf("unmarshalQCString: result=%s\n",result.data()); - return result; -} - -ArgumentList *unmarshalArgumentList(StorageIntf *s) -{ - return ArgumentList::unmarshal(s); -} - -QList<ArgumentList> *unmarshalArgumentLists(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; // null list - QList<ArgumentList> *result = new QList<ArgumentList>; - result->setAutoDelete(TRUE); - assert(count<1000000); - //printf("unmarshalArgumentLists: %d\n",count); - for (i=0;i<count;i++) - { - result->append(unmarshalArgumentList(s)); - } - return result; -} - -QList<BaseInfo> *unmarshalBaseInfoList(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; // null list - QList<BaseInfo> *result = new QList<BaseInfo>; - result->setAutoDelete(TRUE); - assert(count<1000000); - for (i=0;i<count;i++) - { - QCString name = unmarshalQCString(s); - Protection prot = (Protection)unmarshalInt(s); - Specifier virt = (Specifier)unmarshalInt(s); - result->append(new BaseInfo(name,prot,virt)); - } - return result; -} - -QList<Grouping> *unmarshalGroupingList(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; // null list - QList<Grouping> *result = new QList<Grouping>; - result->setAutoDelete(TRUE); - assert(count<1000000); - for (i=0;i<count;i++) - { - QCString name = unmarshalQCString(s); - Grouping::GroupPri_t prio = (Grouping::GroupPri_t)unmarshalInt(s); - result->append(new Grouping(name,prio)); - } - return result; -} - -QList<SectionInfo> *unmarshalSectionInfoList(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; // null list - QList<SectionInfo> *anchors = new QList<SectionInfo>; - assert(count<1000000); - for (i=0;i<count;i++) - { - QCString label = unmarshalQCString(s); - QCString title = unmarshalQCString(s); - QCString ref = unmarshalQCString(s); - SectionInfo::SectionType type = (SectionInfo::SectionType)unmarshalInt(s); - QCString fileName = unmarshalQCString(s); - int lineNr = unmarshalInt(s); - int level = unmarshalInt(s); - SectionInfo *si = Doxygen::sectionDict->find(label); - if (si==0) // This should actually never be true since all anchors should be in sectionDict. - // Could still optimize the marshaling routine by only storing label. - { - SectionInfo *si = new SectionInfo(fileName,lineNr,label,title,type,level,ref); - anchors->append(si); - Doxygen::sectionDict->append(label,si); // this dict owns the anchor objects - } - else - { - anchors->append(si); - } - } - return anchors; -} - -QList<ListItemInfo> *unmarshalItemInfoList(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; // null list - QList<ListItemInfo> *result = new QList<ListItemInfo>; - result->setAutoDelete(TRUE); - assert(count<1000000); - for (i=0;i<count;i++) - { - ListItemInfo *lii = new ListItemInfo; - lii->type = unmarshalQCString(s); - lii->itemId = unmarshalInt(s); - result->append(lii); - } - return result; -} - -void *unmarshalObjPointer(StorageIntf *s) -{ - void *result; - s->read((char *)&result,sizeof(void*)); - return result; -} - -SectionDict *unmarshalSectionDict(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - //printf("unmarshalSectionDict count=%d\n",count); - if (count==NULL_LIST) return 0; // null list - SectionDict *result = new SectionDict(17); - assert(count<1000000); - for (i=0;i<count;i++) - { - QCString key = unmarshalQCString(s); - SectionInfo *si = (SectionInfo *)unmarshalObjPointer(s); - //printf(" unmarshalSectionDict i=%d key=%s si=%s\n",count,key.data(),si->label.data()); - result->append(key,si); - } - return result; -} - -MemberSDict *unmarshalMemberSDict(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - //printf("--- unmarshalMemberSDict count=%d\n",count); - if (count==NULL_LIST) - { - //printf("--- end unmarshalMemberSDict\n"); - return 0; // null list - } - MemberSDict *result = new MemberSDict; - assert(count<1000000); - //printf("Reading %d key-value pairs\n",count); - for (i=0;i<count;i++) - { - //printf(" unmarshaling pair %d\n",i); - QCString key = unmarshalQCString(s); - //printf(" unmarshaling key %s\n",key.data()); - MemberDef *md = (MemberDef *)unmarshalObjPointer(s); - //printf(" unmarshalMemberSDict i=%d key=%s md=%p\n",i,key.data(),md); - result->append(key,md); - } - - //printf("--- end unmarshalMemberSDict\n"); - return result; -} - -DocInfo *unmarshalDocInfo(StorageIntf *s) -{ - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; - DocInfo *result = new DocInfo; - result->doc = unmarshalQCString(s); - result->line = unmarshalInt(s); - result->file = unmarshalQCString(s); - return result; -} - -BriefInfo *unmarshalBriefInfo(StorageIntf *s) -{ - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; - BriefInfo *result = new BriefInfo; - result->doc = unmarshalQCString(s); - result->tooltip = unmarshalQCString(s); - result->line = unmarshalInt(s); - result->file = unmarshalQCString(s); - return result; -} - -BodyInfo *unmarshalBodyInfo(StorageIntf *s) -{ - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; - BodyInfo *result = new BodyInfo; - result->startLine = unmarshalInt(s); - result->endLine = unmarshalInt(s); - result->fileDef = (FileDef*)unmarshalObjPointer(s); - return result; -} - -GroupList *unmarshalGroupList(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; // null list - assert(count<1000000); - GroupList *result = new GroupList; - for (i=0;i<count;i++) - { - GroupDef *gd = (GroupDef *)unmarshalObjPointer(s); - result->append(gd); - } - return result; -} - -MemberList *unmarshalMemberList(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; - MemberList *result = new MemberList; - assert(count<1000000); - for (i=0;i<count;i++) - { - MemberDef *md = (MemberDef*)unmarshalObjPointer(s); - result->append(md); - } - result->unmarshal(s); - return result; -} - -ExampleSDict *unmarshalExampleSDict(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; - ExampleSDict *result = new ExampleSDict; - assert(count<1000000); - for (i=0;i<count;i++) - { - QCString key = unmarshalQCString(s); - Example *e = new Example; - e->anchor = unmarshalQCString(s); - e->name = unmarshalQCString(s); - e->file = unmarshalQCString(s); - result->inSort(key,e); - } - return result; -} - -SDict<MemberList> *unmarshalMemberLists(StorageIntf *s) -{ - uint i; - uint count = unmarshalUInt(s); - if (count==NULL_LIST) return 0; - SDict<MemberList> *result = new SDict<MemberList>(7); - assert(count<1000000); - for (i=0;i<count;i++) - { - QCString key = unmarshalQCString(s); - MemberList *ml = (MemberList *)unmarshalObjPointer(s); - result->append(key,ml); - } - return result; -} - -LocalToc unmarshalLocalToc(StorageIntf *s) -{ - LocalToc result; - int mask = unmarshalInt(s); - int htmlLevel = unmarshalInt(s); - int latexLevel = unmarshalInt(s); - int xmlLevel = unmarshalInt(s); - int docbookLevel = unmarshalInt(s); - if ((mask & (1<<LocalToc::Html))!=0) - { - result.enableHtml(htmlLevel); - } - if ((mask & (1<<LocalToc::Latex))!=0) - { - result.enableLatex(latexLevel); - } - if ((mask & (1<<LocalToc::Xml))!=0) - { - result.enableXml(xmlLevel); - } - if ((mask & (1<<LocalToc::Docbook))!=0) - { - result.enableDocbook(docbookLevel); - } - return result; -} - -Entry * unmarshalEntry(StorageIntf *s) -{ - Entry *e = new Entry; - uint header=unmarshalUInt(s); - ASSERT(header==HEADER); - e->name = unmarshalQCString(s); - e->type = unmarshalQCString(s); - e->section = unmarshalInt(s); - e->protection = (Protection)unmarshalInt(s); - e->mtype = (MethodTypes)unmarshalInt(s); - e->spec = unmarshalUInt64(s); - e->initLines = unmarshalInt(s); - e->stat = unmarshalBool(s); - e->localToc = unmarshalLocalToc(s); - e->explicitExternal = unmarshalBool(s); - e->proto = unmarshalBool(s); - e->subGrouping = unmarshalBool(s); - e->callGraph = unmarshalBool(s); - e->callerGraph = unmarshalBool(s); - e->referencedByRelation = unmarshalBool(s); - e->referencesRelation = unmarshalBool(s); - e->virt = (Specifier)unmarshalInt(s); - e->args = unmarshalQCString(s); - e->bitfields = unmarshalQCString(s); - delete e->argList; - e->argList = unmarshalArgumentList(s); - e->tArgLists = unmarshalArgumentLists(s); - e->program = unmarshalQGString(s); - e->initializer = unmarshalQGString(s); - e->includeFile = unmarshalQCString(s); - e->includeName = unmarshalQCString(s); - e->doc = unmarshalQCString(s); - e->docLine = unmarshalInt(s); - e->docFile = unmarshalQCString(s); - e->brief = unmarshalQCString(s); - e->briefLine = unmarshalInt(s); - e->briefFile = unmarshalQCString(s); - e->inbodyDocs = unmarshalQCString(s); - e->inbodyLine = unmarshalInt(s); - e->inbodyFile = unmarshalQCString(s); - e->relates = unmarshalQCString(s); - e->relatesType = (RelatesType)unmarshalInt(s); - e->read = unmarshalQCString(s); - e->write = unmarshalQCString(s); - e->inside = unmarshalQCString(s); - e->exception = unmarshalQCString(s); - e->typeConstr = unmarshalArgumentList(s); - e->bodyLine = unmarshalInt(s); - e->endBodyLine = unmarshalInt(s); - e->mGrpId = unmarshalInt(s); - delete e->extends; - e->extends = unmarshalBaseInfoList(s); - delete e->groups; - e->groups = unmarshalGroupingList(s); - delete e->anchors; - e->anchors = unmarshalSectionInfoList(s); - e->fileName = unmarshalQCString(s); - e->startLine = unmarshalInt(s); - e->sli = unmarshalItemInfoList(s); - e->lang = (SrcLangExt)unmarshalInt(s); - e->hidden = unmarshalBool(s); - e->artificial = unmarshalBool(s); - e->groupDocType = (Entry::GroupDocType)unmarshalInt(s); - e->id = unmarshalQCString(s); - e->metaData = unmarshalQCString(s); - return e; -} - -Entry * unmarshalEntryTree(StorageIntf *s) -{ - Entry *e = unmarshalEntry(s); - uint count = unmarshalUInt(s); - uint i; - for (i=0;i<count;i++) - { - e->addSubEntry(unmarshalEntryTree(s)); - } - return e; -} diff --git a/src/marshal.h b/src/marshal.h deleted file mode 100644 index 206ab04..0000000 --- a/src/marshal.h +++ /dev/null @@ -1,97 +0,0 @@ -/****************************************************************************** - * - * 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 - * 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 MARSHAL_H -#define MARSHAL_H - -#include <qlist.h> -#include <qfile.h> -#include "sortdict.h" -#include "store.h" - -class ArgumentList; -struct BaseInfo; -struct Grouping; -struct SectionInfo; -struct ListItemInfo; -class QCString; -class QGString; -class SectionDict; -class MemberSDict; -class GroupList; -class MemberList; -struct BodyInfo; -struct DocInfo; -struct BriefInfo; -class ExampleSDict; -class Entry; - -#define NULL_LIST 0xffffffff - -//----- marshaling function: datatype -> byte stream -------------------- - -void marshalInt(StorageIntf *s,int v); -void marshalUInt(StorageIntf *s,uint v); -void marshalUInt64(StorageIntf *s,uint64 v); -void marshalBool(StorageIntf *s,bool b); -void marshalQCString(StorageIntf *s,const QCString &str); -void marshalQGString(StorageIntf *s,const QGString &str); -void marshalArgumentList(StorageIntf *s,ArgumentList *argList); -void marshalArgumentLists(StorageIntf *s,QList<ArgumentList> *argLists); -void marshalBaseInfoList(StorageIntf *s, QList<BaseInfo> *baseList); -void marshalGroupingList(StorageIntf *s, QList<Grouping> *groups); -void marshalSectionInfoList(StorageIntf *s, QList<SectionInfo> *anchors); -void marshalItemInfoList(StorageIntf *s, QList<ListItemInfo> *sli); -void marshalObjPointer(StorageIntf *s,void *obj); -void marshalSectionDict(StorageIntf *s,SectionDict *sections); -void marshalMemberSDict(StorageIntf *s,MemberSDict *memberSDict); -void marshalDocInfo(StorageIntf *s,DocInfo *docInfo); -void marshalBriefInfo(StorageIntf *s,BriefInfo *briefInfo); -void marshalBodyInfo(StorageIntf *s,BodyInfo *bodyInfo); -void marshalGroupList(StorageIntf *s,GroupList *groupList); -void marshalMemberList(StorageIntf *s,MemberList *ml); -void marshalExampleSDict(StorageIntf *s,ExampleSDict *ed); -void marshalMemberLists(StorageIntf *s,SDict<MemberList> *mls); -void marshalEntry(StorageIntf *s,Entry *e); -void marshalEntryTree(StorageIntf *s,Entry *e); - -//----- unmarshaling function: byte stream -> datatype ------------------ - -int unmarshalInt(StorageIntf *s); -uint unmarshalUInt(StorageIntf *s); -uint64 unmarshalUInt64(StorageIntf *s); -bool unmarshalBool(StorageIntf *s); -QCString unmarshalQCString(StorageIntf *s); -QGString unmarshalQGString(StorageIntf *s); -ArgumentList * unmarshalArgumentList(StorageIntf *s); -QList<ArgumentList> *unmarshalArgumentLists(StorageIntf *s); -QList<BaseInfo> * unmarshalBaseInfoList(StorageIntf *s); -QList<Grouping> * unmarshalGroupingList(StorageIntf *s); -QList<SectionInfo> * unmarshalSectionInfoList(StorageIntf *s); -QList<ListItemInfo> *unmarshalItemInfoList(StorageIntf *s); -void * unmarshalObjPointer(StorageIntf *s); -SectionDict * unmarshalSectionDict(StorageIntf *s); -MemberSDict * unmarshalMemberSDict(StorageIntf *s); -DocInfo * unmarshalDocInfo(StorageIntf *s); -BriefInfo * unmarshalBriefInfo(StorageIntf *s); -BodyInfo * unmarshalBodyInfo(StorageIntf *s); -GroupList * unmarshalGroupList(StorageIntf *s); -MemberList * unmarshalMemberList(StorageIntf *s); -ExampleSDict * unmarshalExampleSDict(StorageIntf *s); -SDict<MemberList> * unmarshalMemberLists(StorageIntf *s); -Entry * unmarshalEntry(StorageIntf *s); -Entry * unmarshalEntryTree(StorageIntf *s); - -#endif diff --git a/src/memberdef.cpp b/src/memberdef.cpp index a2fcf69..9d6ac51 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -33,9 +33,9 @@ #include "defargs.h" #include "docparser.h" #include "dot.h" +#include "dotcallgraph.h" #include "searchindex.h" #include "parserintf.h" -#include "marshal.h" #include "objcache.h" #include "vhdldocgen.h" @@ -44,10 +44,822 @@ #include "namespacedef.h" #include "filedef.h" #include "config.h" +#include "definitionimpl.h" //----------------------------------------------------------------------------- -int MemberDef::s_indentLevel = 0; +class MemberDefImpl : public DefinitionImpl, public MemberDef +{ + public: + MemberDefImpl(const char *defFileName,int defLine,int defColumn, + const char *type,const char *name,const char *args, + const char *excp,Protection prot,Specifier virt,bool stat, + Relationship related,MemberType t,const ArgumentList *tal, + const ArgumentList *al,const char *metaData); + virtual ~MemberDefImpl(); + + virtual DefType definitionType() const { return TypeMember; } + virtual MemberDef *resolveAlias() { return this; } + virtual const MemberDef *resolveAlias() const { return this; } + virtual MemberDef *deepCopy() const; + virtual void moveTo(Definition *); + virtual QCString getOutputFileBase() const; + virtual QCString getReference() const; + virtual QCString anchor() const; + virtual const char *declaration() const; + virtual const char *definition() const; + virtual const char *typeString() const; + virtual const char *argsString() const; + virtual const char *excpString() const; + virtual const char *bitfieldString() const; + virtual const char *extraTypeChars() const; + virtual const QCString &initializer() const; + virtual int initializerLines() const; + virtual uint64 getMemberSpecifiers() const; + virtual const MemberList *getSectionList(const Definition *d) const; + virtual QCString displayDefinition() const; + virtual const ClassDef *getClassDef() const; + virtual ClassDef *getClassDef(); + virtual const FileDef *getFileDef() const; + virtual FileDef *getFileDef(); + virtual const NamespaceDef* getNamespaceDef() const; + virtual NamespaceDef* getNamespaceDef(); + virtual const GroupDef *getGroupDef() const; + virtual GroupDef *getGroupDef(); + virtual ClassDef *accessorClass() const; + virtual const char *getReadAccessor() const; + virtual const char *getWriteAccessor() const; + virtual Grouping::GroupPri_t getGroupPri() const; + virtual const char *getGroupFileName() const; + virtual int getGroupStartLine() const; + virtual bool getGroupHasDocs() const; + virtual QCString qualifiedName() const; + virtual QCString objCMethodName(bool localLink,bool showStatic) const; + virtual Protection protection() const; + virtual Specifier virtualness(int count=0) const; + virtual MemberType memberType() const; + virtual QCString memberTypeName() const; + virtual bool isSignal() const; + virtual bool isSlot() const; + virtual bool isVariable() const; + virtual bool isEnumerate() const; + virtual bool isEnumValue() const; + virtual bool isTypedef() const; + virtual bool isSequence() const; + virtual bool isDictionary() const; + virtual bool isFunction() const; + virtual bool isFunctionPtr() const; + virtual bool isDefine() const; + virtual bool isFriend() const; + virtual bool isDCOP() const; + virtual bool isProperty() const; + virtual bool isEvent() const; + virtual bool isRelated() const; + virtual bool isForeign() const; + virtual bool isStatic() const; + virtual bool isInline() const; + virtual bool isExplicit() const; + virtual bool isMutable() const; + virtual bool isGettable() const; + virtual bool isPrivateGettable() const; + virtual bool isProtectedGettable() const; + virtual bool isSettable() const; + virtual bool isPrivateSettable() const; + virtual bool isProtectedSettable() const; + virtual bool isReadable() const; + virtual bool isWritable() const; + virtual bool isAddable() const; + virtual bool isRemovable() const; + virtual bool isRaisable() const; + virtual bool isFinal() const; + virtual bool isAbstract() const; + virtual bool isOverride() const; + virtual bool isInitonly() const; + virtual bool isOptional() const; + virtual bool isRequired() const; + virtual bool isNonAtomic() const; + virtual bool isCopy() const; + virtual bool isAssign() const; + virtual bool isRetain() const; + virtual bool isWeak() const; + virtual bool isStrong() const; + virtual bool isUnretained() const; + virtual bool isNew() const; + virtual bool isSealed() const; + virtual bool isImplementation() const; + virtual bool isExternal() const; + virtual bool isTypeAlias() const; + virtual bool isDefault() const; + virtual bool isDelete() const; + virtual bool isNoExcept() const; + virtual bool isAttribute() const; + virtual bool isUNOProperty() const; + virtual bool isReadonly() const; + virtual bool isBound() const; + virtual bool isConstrained() const; + virtual bool isTransient() const; + virtual bool isMaybeVoid() const; + virtual bool isMaybeDefault() const; + virtual bool isMaybeAmbiguous() const; + virtual bool isPublished() const; + virtual bool isTemplateSpecialization() const; + virtual bool isObjCMethod() const; + virtual bool isObjCProperty() const; + virtual bool isConstructor() const; + virtual bool isDestructor() const; + virtual bool hasOneLineInitializer() const; + virtual bool hasMultiLineInitializer() const; + virtual bool showInCallGraph() const; + virtual bool isStrongEnumValue() const; + virtual bool livesInsideEnum() const; + virtual bool isSliceLocal() const; + virtual bool isConstExpr() const; + virtual int numberOfFlowKeyWords() const; + virtual bool isFriendToHide() const; + virtual bool isNotFriend() const; + virtual bool isFunctionOrSignalSlot() const; + virtual bool isRelatedOrFriend() const; + virtual bool isLinkableInProject() const; + virtual bool isLinkable() const; + virtual bool hasDocumentation() const; + virtual bool isDeleted() const; + virtual bool isBriefSectionVisible() const; + virtual bool isDetailedSectionVisible(bool inGroup,bool inFile) const; + virtual bool isDetailedSectionLinkable() const; + virtual bool isFriendClass() const; + virtual bool isDocumentedFriendClass() const; + virtual MemberDef *reimplements() const; + virtual MemberList *reimplementedBy() const; + virtual bool isReimplementedBy(const ClassDef *cd) const; + virtual ClassDef *relatedAlso() const; + virtual bool hasDocumentedEnumValues() const; + virtual const MemberDef *getAnonymousEnumType() const; + virtual bool isDocsForDefinition() const; + virtual const MemberDef *getEnumScope() const; + virtual const MemberList *enumFieldList() const; + virtual void setEnumBaseType(const QCString &type); + virtual QCString enumBaseType() const; + virtual bool hasExamples() const; + virtual ExampleSDict *getExamples() const; + virtual bool isPrototype() const; + virtual const ArgumentList *argumentList() const; + virtual ArgumentList *argumentList(); + virtual const ArgumentList *declArgumentList() const; + virtual const ArgumentList *templateArguments() const; + virtual const QList<ArgumentList> *definitionTemplateParameterLists() const; + virtual int getMemberGroupId() const; + virtual MemberGroup *getMemberGroup() const; + virtual bool fromAnonymousScope() const; + virtual bool anonymousDeclShown() const; + virtual MemberDef *fromAnonymousMember() const; + virtual bool hasCallGraph() const; + virtual bool hasCallerGraph() const; + virtual bool visibleMemberGroup(bool hideNoHeader) const; + virtual bool hasReferencesRelation() const; + virtual bool hasReferencedByRelation() const; + virtual MemberDef *templateMaster() const; + virtual QCString getScopeString() const; + virtual ClassDef *getClassDefOfAnonymousType() const; + virtual bool isTypedefValCached() const; + virtual const ClassDef *getCachedTypedefVal() const; + virtual QCString getCachedTypedefTemplSpec() const; + virtual QCString getCachedResolvedTypedef() const; + virtual MemberDef *memberDefinition() const; + virtual MemberDef *memberDeclaration() const; + virtual MemberDef *inheritsDocsFrom() const; + virtual const MemberDef *getGroupAlias() const; + virtual ClassDef *category() const; + virtual MemberDef *categoryRelation() const; + virtual QCString displayName(bool=TRUE) const; + virtual QCString getDeclType() const; + virtual void getLabels(QStrList &sl,const Definition *container) const; + virtual const ArgumentList *typeConstraints() const; + virtual QCString documentation() const; + virtual QCString briefDescription(bool abbr=FALSE) const; + virtual QCString fieldType() const; + virtual bool isReference() const; + virtual QCString getDeclFileName() const; + virtual int getDeclLine() const; + virtual int getDeclColumn() const; + virtual void setMemberType(MemberType t); + virtual void setDefinition(const char *d); + virtual void setFileDef(FileDef *fd); + virtual void setAnchor(); + virtual void setProtection(Protection p); + virtual void setMemberSpecifiers(uint64 s); + virtual void mergeMemberSpecifiers(uint64 s); + virtual void setInitializer(const char *i); + virtual void setBitfields(const char *s); + virtual void setMaxInitLines(int lines); + virtual void setMemberClass(ClassDef *cd); + virtual void setSectionList(Definition *d,MemberList *sl); + virtual void setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, + const QCString &fileName,int startLine,bool hasDocs, + MemberDef *member=0); + virtual void setReadAccessor(const char *r); + virtual void setWriteAccessor(const char *w); + virtual void setTemplateSpecialization(bool b); + virtual void makeRelated(); + virtual void makeForeign(); + virtual void setInheritsDocsFrom(MemberDef *md); + virtual void setTagInfo(TagInfo *i); + virtual void setArgsString(const char *as); + virtual void setReimplements(MemberDef *md); + virtual void insertReimplementedBy(MemberDef *md); + virtual void setRelatedAlso(ClassDef *cd); + virtual void insertEnumField(MemberDef *md); + virtual void setEnumScope(MemberDef *md,bool livesInsideEnum=FALSE); + virtual void setEnumClassScope(ClassDef *cd); + virtual void setDocumentedEnumValues(bool value); + virtual void setAnonymousEnumType(const MemberDef *md); + virtual bool addExample(const char *anchor,const char *name,const char *file); + virtual void setPrototype(bool p,const QCString &df,int line, int column); + virtual void setExplicitExternal(bool b,const QCString &df,int line,int column); + virtual void setDeclFile(const QCString &df,int line,int column); + virtual void setArgumentList(ArgumentList *al); + virtual void setDeclArgumentList(ArgumentList *al); + virtual void setDefinitionTemplateParameterLists(QList<ArgumentList> *lists); + virtual void setTypeConstraints(ArgumentList *al); + virtual void setType(const char *t); + virtual void setAccessorType(ClassDef *cd,const char *t); + virtual void setNamespace(NamespaceDef *nd); + virtual void setMemberGroup(MemberGroup *grp); + virtual void setMemberGroupId(int id); + virtual void makeImplementationDetail(); + virtual void setFromAnonymousScope(bool b) const; + virtual void setFromAnonymousMember(MemberDef *m); + virtual void enableCallGraph(bool e); + virtual void enableCallerGraph(bool e); + virtual void enableReferencedByRelation(bool e); + virtual void enableReferencesRelation(bool e); + virtual void setTemplateMaster(MemberDef *mt); + virtual void addListReference(Definition *d); + virtual void setDocsForDefinition(bool b); + virtual void setGroupAlias(const MemberDef *md); + virtual void cacheTypedefVal(const ClassDef *val,const QCString &templSpec,const QCString &resolvedType); + virtual void invalidateTypedefValCache(); + virtual void invalidateCachedArgumentTypes(); + virtual void setMemberDefinition(MemberDef *md); + virtual void setMemberDeclaration(MemberDef *md); + virtual void setAnonymousUsed() const; + virtual void copyArgumentNames(MemberDef *bmd); + virtual void setCategory(ClassDef *); + virtual void setCategoryRelation(MemberDef *); + virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE); + virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine); + virtual void setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine); + virtual void setHidden(bool b); + virtual void incrementFlowKeyWordCount(); + virtual void writeDeclaration(OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + bool inGroup, const ClassDef *inheritFrom=0,const char *inheritId=0) const; + virtual void writeDocumentation(const MemberList *ml,int memCount,int memTotal,OutputList &ol, + const char *scopeName,const Definition *container, + bool inGroup,bool showEnumValues=FALSE,bool + showInline=FALSE) const; + virtual void writeMemberDocSimple(OutputList &ol,const Definition *container) const; + virtual void writeEnumDeclaration(OutputList &typeDecl, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd) const; + virtual void writeTagFile(FTextStream &) const; + virtual void warnIfUndocumented() const; + virtual void warnIfUndocumentedParams() const; + virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const; + virtual MemberDef *createTemplateInstanceMember(ArgumentList *formalArgs, + ArgumentList *actualArgs) const; + virtual void findSectionsInDocumentation(); + virtual void writeLink(OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + bool onlyText=FALSE) const; + virtual void addToSearchIndex() const; + + private: + void _computeLinkableInProject(); + void _computeIsConstructor(); + void _computeIsDestructor(); + void _writeGroupInclude(OutputList &ol,bool inGroup) const; + void _writeCallGraph(OutputList &ol) const; + void _writeCallerGraph(OutputList &ol) const; + void _writeReimplements(OutputList &ol) const; + void _writeReimplementedBy(OutputList &ol) const; + void _writeExamples(OutputList &ol) const; + void _writeTypeConstraints(OutputList &ol) const; + void _writeEnumValues(OutputList &ol,const Definition *container, + const QCString &cfname,const QCString &ciname, + const QCString &cname) const; + void _writeCategoryRelation(OutputList &ol) const; + void _writeTagData(const DefType) const; + + static int s_indentLevel; + + // disable copying of member defs + MemberDefImpl(const MemberDefImpl &); + MemberDefImpl &operator=(const MemberDefImpl &); + + + // PIMPL idiom + class IMPL; + IMPL *m_impl; + uchar m_isLinkableCached; // 0 = not cached, 1=FALSE, 2=TRUE + uchar m_isConstructorCached; // 0 = not cached, 1=FALSE, 2=TRUE + uchar m_isDestructorCached; // 0 = not cached, 1=FALSE, 2=TRUE +}; + +MemberDef *createMemberDef(const char *defFileName,int defLine,int defColumn, + const char *type,const char *name,const char *args, + const char *excp,Protection prot,Specifier virt,bool stat, + Relationship related,MemberType t,const ArgumentList *tal, + const ArgumentList *al,const char *metaData) +{ + return new MemberDefImpl(defFileName,defLine,defColumn,type,name,args,excp,prot,virt, + stat,related,t,tal,al,metaData); +} + +//----------------------------------------------------------------------------- + +class MemberDefAliasImpl : public DefinitionAliasImpl, public MemberDef +{ + public: + MemberDefAliasImpl(const Definition *newScope,const MemberDef *md) + : DefinitionAliasImpl(newScope,md) {} + virtual ~MemberDefAliasImpl() {} + virtual DefType definitionType() const { return TypeMember; } + + const MemberDef *getMdAlias() const { return dynamic_cast<const MemberDef*>(getAlias()); } + virtual MemberDef *resolveAlias() { return const_cast<MemberDef*>(getMdAlias()); } + virtual const MemberDef *resolveAlias() const { return getMdAlias(); } + + virtual MemberDef *deepCopy() const { + return createMemberDefAlias(getScope(),getMdAlias()); + } + virtual void moveTo(Definition *) {} + + virtual QCString getOutputFileBase() const + { return getMdAlias()->getOutputFileBase(); } + virtual QCString getReference() const + { return getMdAlias()->getReference(); } + virtual QCString anchor() const + { return getMdAlias()->anchor(); } + virtual const char *declaration() const + { return getMdAlias()->declaration(); } + virtual const char *definition() const + { return getMdAlias()->definition(); } + virtual const char *typeString() const + { return getMdAlias()->typeString(); } + virtual const char *argsString() const + { return getMdAlias()->argsString(); } + virtual const char *excpString() const + { return getMdAlias()->excpString(); } + virtual const char *bitfieldString() const + { return getMdAlias()->bitfieldString(); } + virtual const char *extraTypeChars() const + { return getMdAlias()->extraTypeChars(); } + virtual const QCString &initializer() const + { return getMdAlias()->initializer(); } + virtual int initializerLines() const + { return getMdAlias()->initializerLines(); } + virtual uint64 getMemberSpecifiers() const + { return getMdAlias()->getMemberSpecifiers(); } + virtual const MemberList *getSectionList(const Definition *d) const + { return getMdAlias()->getSectionList(d); } + virtual QCString displayDefinition() const + { return getMdAlias()->displayDefinition(); } + virtual const ClassDef *getClassDef() const + { return getMdAlias()->getClassDef(); } + virtual const FileDef *getFileDef() const + { return getMdAlias()->getFileDef(); } + virtual const NamespaceDef* getNamespaceDef() const + { return getMdAlias()->getNamespaceDef(); } + virtual ClassDef *accessorClass() const + { return getMdAlias()->accessorClass(); } + virtual const char *getReadAccessor() const + { return getMdAlias()->getReadAccessor(); } + virtual const char *getWriteAccessor() const + { return getMdAlias()->getWriteAccessor(); } + virtual const GroupDef *getGroupDef() const + { return getMdAlias()->getGroupDef(); } + virtual Grouping::GroupPri_t getGroupPri() const + { return getMdAlias()->getGroupPri(); } + virtual const char *getGroupFileName() const + { return getMdAlias()->getGroupFileName(); } + virtual int getGroupStartLine() const + { return getMdAlias()->getGroupStartLine(); } + virtual bool getGroupHasDocs() const + { return getMdAlias()->getGroupHasDocs(); } + virtual QCString qualifiedName() const + { return getMdAlias()->qualifiedName(); } + virtual QCString objCMethodName(bool localLink,bool showStatic) const + { return getMdAlias()->objCMethodName(localLink,showStatic); } + virtual Protection protection() const + { return getMdAlias()->protection(); } + virtual Specifier virtualness(int count) const + { return getMdAlias()->virtualness(); } + virtual MemberType memberType() const + { return getMdAlias()->memberType(); } + virtual QCString memberTypeName() const + { return getMdAlias()->memberTypeName(); } + virtual bool isSignal() const + { return getMdAlias()->isSignal(); } + virtual bool isSlot() const + { return getMdAlias()->isSlot(); } + virtual bool isVariable() const + { return getMdAlias()->isVariable(); } + virtual bool isEnumerate() const + { return getMdAlias()->isEnumerate(); } + virtual bool isEnumValue() const + { return getMdAlias()->isEnumValue(); } + virtual bool isTypedef() const + { return getMdAlias()->isTypedef(); } + virtual bool isSequence() const + { return getMdAlias()->isSequence(); } + virtual bool isDictionary() const + { return getMdAlias()->isDictionary(); } + virtual bool isFunction() const + { return getMdAlias()->isFunction(); } + virtual bool isFunctionPtr() const + { return getMdAlias()->isFunctionPtr(); } + virtual bool isDefine() const + { return getMdAlias()->isDefine(); } + virtual bool isFriend() const + { return getMdAlias()->isFriend(); } + virtual bool isDCOP() const + { return getMdAlias()->isDCOP(); } + virtual bool isProperty() const + { return getMdAlias()->isProperty(); } + virtual bool isEvent() const + { return getMdAlias()->isEvent(); } + virtual bool isRelated() const + { return getMdAlias()->isRelated(); } + virtual bool isForeign() const + { return getMdAlias()->isForeign(); } + virtual bool isStatic() const + { return getMdAlias()->isStatic(); } + virtual bool isInline() const + { return getMdAlias()->isInline(); } + virtual bool isExplicit() const + { return getMdAlias()->isExplicit(); } + virtual bool isMutable() const + { return getMdAlias()->isMutable(); } + virtual bool isGettable() const + { return getMdAlias()->isGettable(); } + virtual bool isPrivateGettable() const + { return getMdAlias()->isPrivateGettable(); } + virtual bool isProtectedGettable() const + { return getMdAlias()->isProtectedGettable(); } + virtual bool isSettable() const + { return getMdAlias()->isSettable(); } + virtual bool isPrivateSettable() const + { return getMdAlias()->isPrivateSettable(); } + virtual bool isProtectedSettable() const + { return getMdAlias()->isProtectedSettable(); } + virtual bool isReadable() const + { return getMdAlias()->isReadable(); } + virtual bool isWritable() const + { return getMdAlias()->isWritable(); } + virtual bool isAddable() const + { return getMdAlias()->isAddable(); } + virtual bool isRemovable() const + { return getMdAlias()->isRemovable(); } + virtual bool isRaisable() const + { return getMdAlias()->isRaisable(); } + virtual bool isFinal() const + { return getMdAlias()->isFinal(); } + virtual bool isAbstract() const + { return getMdAlias()->isAbstract(); } + virtual bool isOverride() const + { return getMdAlias()->isOverride(); } + virtual bool isInitonly() const + { return getMdAlias()->isInitonly(); } + virtual bool isOptional() const + { return getMdAlias()->isOptional(); } + virtual bool isRequired() const + { return getMdAlias()->isRequired(); } + virtual bool isNonAtomic() const + { return getMdAlias()->isNonAtomic(); } + virtual bool isCopy() const + { return getMdAlias()->isCopy(); } + virtual bool isAssign() const + { return getMdAlias()->isAssign(); } + virtual bool isRetain() const + { return getMdAlias()->isRetain(); } + virtual bool isWeak() const + { return getMdAlias()->isWeak(); } + virtual bool isStrong() const + { return getMdAlias()->isStrong(); } + virtual bool isUnretained() const + { return getMdAlias()->isUnretained(); } + virtual bool isNew() const + { return getMdAlias()->isNew(); } + virtual bool isSealed() const + { return getMdAlias()->isSealed(); } + virtual bool isImplementation() const + { return getMdAlias()->isImplementation(); } + virtual bool isExternal() const + { return getMdAlias()->isExternal(); } + virtual bool isTypeAlias() const + { return getMdAlias()->isTypeAlias(); } + virtual bool isDefault() const + { return getMdAlias()->isDefault(); } + virtual bool isDelete() const + { return getMdAlias()->isDelete(); } + virtual bool isNoExcept() const + { return getMdAlias()->isNoExcept(); } + virtual bool isAttribute() const + { return getMdAlias()->isAttribute(); } + virtual bool isUNOProperty() const + { return getMdAlias()->isUNOProperty(); } + virtual bool isReadonly() const + { return getMdAlias()->isReadable(); } + virtual bool isBound() const + { return getMdAlias()->isBound(); } + virtual bool isConstrained() const + { return getMdAlias()->isConstrained(); } + virtual bool isTransient() const + { return getMdAlias()->isTransient(); } + virtual bool isMaybeVoid() const + { return getMdAlias()->isMaybeVoid(); } + virtual bool isMaybeDefault() const + { return getMdAlias()->isMaybeDefault(); } + virtual bool isMaybeAmbiguous() const + { return getMdAlias()->isMaybeAmbiguous(); } + virtual bool isPublished() const + { return getMdAlias()->isPublished(); } + virtual bool isTemplateSpecialization() const + { return getMdAlias()->isTemplateSpecialization(); } + virtual bool isObjCMethod() const + { return getMdAlias()->isObjCMethod(); } + virtual bool isObjCProperty() const + { return getMdAlias()->isObjCProperty(); } + virtual bool isConstructor() const + { return getMdAlias()->isConstructor(); } + virtual bool isDestructor() const + { return getMdAlias()->isDestructor(); } + virtual bool hasOneLineInitializer() const + { return getMdAlias()->hasOneLineInitializer(); } + virtual bool hasMultiLineInitializer() const + { return getMdAlias()->hasMultiLineInitializer(); } + virtual bool showInCallGraph() const + { return getMdAlias()->showInCallGraph(); } + virtual bool isStrongEnumValue() const + { return getMdAlias()->isStrongEnumValue(); } + virtual bool livesInsideEnum() const + { return getMdAlias()->livesInsideEnum(); } + virtual bool isSliceLocal() const + { return getMdAlias()->isSliceLocal(); } + virtual bool isConstExpr() const + { return getMdAlias()->isConstExpr(); } + virtual int numberOfFlowKeyWords() const + { return getMdAlias()->numberOfFlowKeyWords(); } + virtual bool isFriendToHide() const + { return getMdAlias()->isFriendToHide(); } + virtual bool isNotFriend() const + { return getMdAlias()->isNotFriend(); } + virtual bool isFunctionOrSignalSlot() const + { return getMdAlias()->isFunctionOrSignalSlot(); } + virtual bool isRelatedOrFriend() const + { return getMdAlias()->isRelatedOrFriend(); } + virtual bool isLinkableInProject() const + { return getMdAlias()->isLinkableInProject(); } + virtual bool isLinkable() const + { return getMdAlias()->isLinkable(); } + virtual bool hasDocumentation() const + { return getMdAlias()->hasDocumentation(); } + virtual bool isDeleted() const + { return getMdAlias()->isDeleted(); } + virtual bool isBriefSectionVisible() const + { return getMdAlias()->isBriefSectionVisible(); } + virtual bool isDetailedSectionVisible(bool inGroup,bool inFile) const + { return getMdAlias()->isDetailedSectionVisible(inGroup,inFile); } + virtual bool isDetailedSectionLinkable() const + { return getMdAlias()->isDetailedSectionLinkable(); } + virtual bool isFriendClass() const + { return getMdAlias()->isFriendClass(); } + virtual bool isDocumentedFriendClass() const + { return getMdAlias()->isDocumentedFriendClass(); } + virtual MemberDef *reimplements() const + { return getMdAlias()->reimplements(); } + virtual MemberList *reimplementedBy() const + { return getMdAlias()->reimplementedBy(); } + virtual bool isReimplementedBy(const ClassDef *cd) const + { return getMdAlias()->isReimplementedBy(cd); } + virtual ClassDef *relatedAlso() const + { return getMdAlias()->relatedAlso(); } + virtual bool hasDocumentedEnumValues() const + { return getMdAlias()->hasDocumentedEnumValues(); } + virtual const MemberDef *getAnonymousEnumType() const + { return getMdAlias()->getAnonymousEnumType(); } + virtual bool isDocsForDefinition() const + { return getMdAlias()->isDocsForDefinition(); } + virtual const MemberDef *getEnumScope() const + { return getMdAlias()->getEnumScope(); } + virtual const MemberList *enumFieldList() const + { return getMdAlias()->enumFieldList(); } + virtual QCString enumBaseType() const + { return getMdAlias()->enumBaseType(); } + virtual bool hasExamples() const + { return getMdAlias()->hasExamples(); } + virtual ExampleSDict *getExamples() const + { return getMdAlias()->getExamples(); } + virtual bool isPrototype() const + { return getMdAlias()->isPrototype(); } + virtual const ArgumentList *argumentList() const + { return getMdAlias()->argumentList(); } + virtual const ArgumentList *declArgumentList() const + { return getMdAlias()->declArgumentList(); } + virtual const ArgumentList *templateArguments() const + { return getMdAlias()->templateArguments(); } + virtual const QList<ArgumentList> *definitionTemplateParameterLists() const + { return getMdAlias()->definitionTemplateParameterLists(); } + virtual int getMemberGroupId() const + { return getMdAlias()->getMemberGroupId(); } + virtual MemberGroup *getMemberGroup() const + { return getMdAlias()->getMemberGroup(); } + virtual bool fromAnonymousScope() const + { return getMdAlias()->fromAnonymousScope(); } + virtual bool anonymousDeclShown() const + { return getMdAlias()->anonymousDeclShown(); } + virtual MemberDef *fromAnonymousMember() const + { return getMdAlias()->fromAnonymousMember(); } + virtual bool hasCallGraph() const + { return getMdAlias()->hasCallGraph(); } + virtual bool hasCallerGraph() const + { return getMdAlias()->hasCallerGraph(); } + virtual bool visibleMemberGroup(bool hideNoHeader) const + { return getMdAlias()->visibleMemberGroup(hideNoHeader); } + virtual bool hasReferencesRelation() const + { return getMdAlias()->hasReferencesRelation(); } + virtual bool hasReferencedByRelation() const + { return getMdAlias()->hasReferencedByRelation(); } + virtual MemberDef *templateMaster() const + { return getMdAlias()->templateMaster(); } + virtual QCString getScopeString() const + { return getMdAlias()->getScopeString(); } + virtual ClassDef *getClassDefOfAnonymousType() const + { return getMdAlias()->getClassDefOfAnonymousType(); } + virtual bool isTypedefValCached() const + { return getMdAlias()->isTypedefValCached(); } + virtual const ClassDef *getCachedTypedefVal() const + { return getMdAlias()->getCachedTypedefVal(); } + virtual QCString getCachedTypedefTemplSpec() const + { return getMdAlias()->getCachedTypedefTemplSpec(); } + virtual QCString getCachedResolvedTypedef() const + { return getMdAlias()->getCachedResolvedTypedef(); } + virtual MemberDef *memberDefinition() const + { return getMdAlias()->memberDefinition(); } + virtual MemberDef *memberDeclaration() const + { return getMdAlias()->memberDeclaration(); } + virtual MemberDef *inheritsDocsFrom() const + { return getMdAlias()->inheritsDocsFrom(); } + virtual const MemberDef *getGroupAlias() const + { return getMdAlias()->getGroupAlias(); } + virtual ClassDef *category() const + { return getMdAlias()->category(); } + virtual MemberDef *categoryRelation() const + { return getMdAlias()->categoryRelation(); } + virtual QCString displayName(bool b=TRUE) const + { return getMdAlias()->displayName(b); } + virtual QCString getDeclType() const + { return getMdAlias()->getDeclType(); } + virtual void getLabels(QStrList &sl,const Definition *container) const + { return getMdAlias()->getLabels(sl,container); } + virtual const ArgumentList *typeConstraints() const + { return getMdAlias()->typeConstraints(); } + virtual QCString documentation() const + { return getMdAlias()->documentation(); } + virtual QCString briefDescription(bool abbr=FALSE) const + { return getMdAlias()->briefDescription(); } + virtual QCString fieldType() const + { return getMdAlias()->fieldType(); } + virtual bool isReference() const + { return getMdAlias()->isReference(); } + virtual QCString getDeclFileName() const + { return getMdAlias()->getDeclFileName(); } + virtual int getDeclLine() const + { return getMdAlias()->getDeclLine(); } + virtual int getDeclColumn() const + { return getMdAlias()->getDeclColumn(); } + + // non-const getters should not be called + virtual ClassDef *getClassDef() + { err("non-const getClassDef() called on aliased member. Please report as a bug.\n"); return 0; } + virtual FileDef *getFileDef() + { err("non-const getFileDef() called on aliased member. Please report as a bug.\n"); return 0; } + virtual NamespaceDef* getNamespaceDef() + { err("non-const getNamespaceDef() called on aliased member. Please report as a bug.\n"); return 0; } + virtual GroupDef *getGroupDef() + { err("non-const getGroupDef() called on aliased member. Please report as a bug.\n"); return 0; } + virtual ArgumentList *argumentList() + { err("non-const argumentList() called on aliased member. Please report as bug.\n"); return 0; } + + virtual void setEnumBaseType(const QCString &type) {} + virtual void setMemberType(MemberType t) {} + virtual void setDefinition(const char *d) {} + virtual void setFileDef(FileDef *fd) {} + virtual void setAnchor() {} + virtual void setProtection(Protection p) {} + virtual void setMemberSpecifiers(uint64 s) {} + virtual void mergeMemberSpecifiers(uint64 s) {} + virtual void setInitializer(const char *i) {} + virtual void setBitfields(const char *s) {} + virtual void setMaxInitLines(int lines) {} + virtual void setMemberClass(ClassDef *cd) {} + virtual void setSectionList(Definition *d,MemberList *sl) {} + virtual void setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, + const QCString &fileName,int startLine,bool hasDocs, + MemberDef *member=0) {} + virtual void setReadAccessor(const char *r) {} + virtual void setWriteAccessor(const char *w) {} + virtual void setTemplateSpecialization(bool b) {} + virtual void makeRelated() {} + virtual void makeForeign() {} + virtual void setInheritsDocsFrom(MemberDef *md) {} + virtual void setTagInfo(TagInfo *i) {} + virtual void setArgsString(const char *as) {} + virtual void setReimplements(MemberDef *md) {} + virtual void insertReimplementedBy(MemberDef *md) {} + virtual void setRelatedAlso(ClassDef *cd) {} + virtual void insertEnumField(MemberDef *md) {} + virtual void setEnumScope(MemberDef *md,bool livesInsideEnum=FALSE) {} + virtual void setEnumClassScope(ClassDef *cd) {} + virtual void setDocumentedEnumValues(bool value) {} + virtual void setAnonymousEnumType(const MemberDef *md) {} + virtual bool addExample(const char *anchor,const char *name,const char *file) { return FALSE; } + virtual void setPrototype(bool p,const QCString &df,int line, int column) {} + virtual void setExplicitExternal(bool b,const QCString &df,int line,int column) {} + virtual void setDeclFile(const QCString &df,int line,int column) {} + virtual void setArgumentList(ArgumentList *al) {} + virtual void setDeclArgumentList(ArgumentList *al) {} + virtual void setDefinitionTemplateParameterLists(QList<ArgumentList> *lists) {} + virtual void setTypeConstraints(ArgumentList *al) {} + virtual void setType(const char *t) {} + virtual void setAccessorType(ClassDef *cd,const char *t) {} + virtual void setNamespace(NamespaceDef *nd) {} + virtual void setMemberGroup(MemberGroup *grp) {} + virtual void setMemberGroupId(int id) {} + virtual void makeImplementationDetail() {} + virtual void setFromAnonymousScope(bool b) const {} + virtual void setFromAnonymousMember(MemberDef *m) {} + virtual void enableCallGraph(bool e) {} + virtual void enableCallerGraph(bool e) {} + virtual void enableReferencedByRelation(bool e) {} + virtual void enableReferencesRelation(bool e) {} + virtual void setTemplateMaster(MemberDef *mt) {} + virtual void addListReference(Definition *d) {} + virtual void setDocsForDefinition(bool b) {} + virtual void setGroupAlias(const MemberDef *md) {} + virtual void cacheTypedefVal(const ClassDef *val,const QCString &templSpec,const QCString &resolvedType) {} + virtual void invalidateTypedefValCache() {} + virtual void invalidateCachedArgumentTypes() {} + virtual void setMemberDefinition(MemberDef *md) {} + virtual void setMemberDeclaration(MemberDef *md) {} + virtual void setAnonymousUsed() const {} + virtual void copyArgumentNames(MemberDef *bmd) {} + virtual void setCategory(ClassDef *) {} + virtual void setCategoryRelation(MemberDef *) {} + virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE) {} + virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine) {} + virtual void setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine) {} + virtual void setHidden(bool b) {} + virtual void addToSearchIndex() const {} + virtual void findSectionsInDocumentation() {} + virtual MemberDef *createTemplateInstanceMember(ArgumentList *formalArgs, + ArgumentList *actualArgs) const + { return getMdAlias()->createTemplateInstanceMember(formalArgs,actualArgs); } + virtual void incrementFlowKeyWordCount() {} + + virtual void writeDeclaration(OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + bool inGroup, const ClassDef *inheritFrom=0,const char *inheritId=0) const + { + getMdAlias()->writeDeclaration(ol,cd,nd,fd,gd,inGroup,inheritFrom,inheritId); + } + virtual void writeEnumDeclaration(OutputList &typeDecl, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd) const + { + getMdAlias()->writeEnumDeclaration(typeDecl,cd,nd,fd,gd); + } + virtual void writeDocumentation(const MemberList *ml,int memCount,int memTotal,OutputList &ol, + const char *scopeName,const Definition *container, + bool inGroup,bool showEnumValues=FALSE,bool + showInline=FALSE) const {} + virtual void writeMemberDocSimple(OutputList &ol,const Definition *container) const {} + virtual void writeLink(OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + bool onlyText=FALSE) const {} + virtual void writeTagFile(FTextStream &) const {} + virtual void warnIfUndocumented() const {} + virtual void warnIfUndocumentedParams() const {} + virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const {} +}; + + +MemberDef *createMemberDefAlias(const Definition *newScope,const MemberDef *aliasMd) +{ + return new MemberDefAliasImpl(newScope,aliasMd); +} + +//----------------------------------------------------------------------------- + +int MemberDefImpl::s_indentLevel = 0; //----------------------------------------------------------------------------- @@ -118,11 +930,11 @@ static QCString addTemplateNames(const QCString &s,const QCString &n,const QCStr // ol.endMemberDoc(hasArgs=FALSE); // -static bool writeDefArgumentList(OutputList &ol,Definition *scope,MemberDef *md) +static bool writeDefArgumentList(OutputList &ol,const Definition *scope,const MemberDef *md) { - ArgumentList *defArgList=(md->isDocsForDefinition()) ? + const ArgumentList *defArgList=(md->isDocsForDefinition()) ? md->argumentList() : md->declArgumentList(); - //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition()); + //printf("writeDefArgumentList '%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition()); if (defArgList==0 || md->isProperty()) { return FALSE; // member has no function like argument list @@ -194,9 +1006,9 @@ static bool writeDefArgumentList(OutputList &ol,Definition *scope,MemberDef *md) cName=cName.mid(il,ir-il+1); //printf("1. cName=%s\n",cName.data()); } - else if (scope->definitionType()==Definition::TypeClass && ((ClassDef*)scope)->templateArguments()) + else if (scope->definitionType()==Definition::TypeClass && (dynamic_cast<const ClassDef*>(scope))->templateArguments()) { - cName=tempArgListToString(((ClassDef*)scope)->templateArguments(),scope->getLanguage()); + cName=tempArgListToString((dynamic_cast<const ClassDef*>(scope))->templateArguments(),scope->getLanguage()); //printf("2. cName=%s\n",cName.data()); } else // no template specifier @@ -236,7 +1048,7 @@ static bool writeDefArgumentList(OutputList &ol,Definition *scope,MemberDef *md) } if (hasFuncPtrType) // argument type is a function pointer { - //printf("a->type=`%s' a->name=`%s'\n",a->type.data(),a->name.data()); + //printf("a->type='%s' a->name='%s'\n",a->type.data(),a->name.data()); QCString n=a->type.left(vp); if (hasFuncPtrType) n=a->type.left(wp); if (md->isObjCMethod()) { n.prepend("("); n.append(")"); } @@ -389,7 +1201,7 @@ static bool writeDefArgumentList(OutputList &ol,Definition *scope,MemberDef *md) } static void writeExceptionListImpl( - OutputList &ol, ClassDef *cd, MemberDef *md, QCString const& exception) + OutputList &ol, const ClassDef *cd, const MemberDef *md, QCString const& exception) { // this is ordinary exception spec - there must be a '(' //printf("exception='%s'\n",exception.data()); @@ -427,7 +1239,7 @@ static void writeExceptionListImpl( } } -static void writeExceptionList(OutputList &ol, ClassDef *cd, MemberDef *md) +static void writeExceptionList(OutputList &ol, const ClassDef *cd, const MemberDef *md) { QCString exception(QCString(md->excpString()).stripWhiteSpace()); if ('{'==exception.at(0)) @@ -450,7 +1262,7 @@ static void writeExceptionList(OutputList &ol, ClassDef *cd, MemberDef *md) } } -static void writeTemplatePrefix(OutputList &ol,ArgumentList *al) +static void writeTemplatePrefix(OutputList &ol,const ArgumentList *al) { ol.docify("template<"); ArgumentListIterator ali(*al); @@ -476,11 +1288,11 @@ static void writeTemplatePrefix(OutputList &ol,ArgumentList *al) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -class MemberDefImpl +class MemberDefImpl::IMPL { public: - MemberDefImpl(); - ~MemberDefImpl(); + IMPL(); + ~IMPL(); void init(Definition *def,const char *t,const char *a,const char *e, Protection p,Specifier v,bool s,Relationship r, MemberType mt,const ArgumentList *tal, @@ -493,7 +1305,7 @@ class MemberDefImpl MemberDef *enumScope; // the enclosing scope, if this is an enum field bool livesInsideEnum; - MemberDef *annEnumType; // the anonymous enum that is the type of this member + const MemberDef *annEnumType; // the anonymous enum that is the type of this member MemberList *enumFields; // enumeration fields MemberDef *redefines; // the members that this member redefines @@ -547,7 +1359,7 @@ class MemberDefImpl // cached here. SDict<MemberList> *classSectionSDict; // not accessible - MemberDef *groupAlias; // Member containing the definition + const MemberDef *groupAlias; // Member containing the definition int grpId; // group id MemberGroup *memberGroup; // group's member definition GroupDef *group; // group in which this member is in @@ -557,7 +1369,7 @@ class MemberDefImpl MemberDef *groupMember; bool isTypedefValCached; - ClassDef *cachedTypedefValue; + const ClassDef *cachedTypedefValue; QCString cachedTypedefTemplSpec; QCString cachedResolvedType; @@ -575,15 +1387,17 @@ class MemberDefImpl // objective-c bool implOnly; // function found in implementation but not // in the interface - bool hasDocumentedParams; - bool hasDocumentedReturnType; + mutable bool hasDocumentedParams; + mutable bool hasDocumentedReturnType; bool isDMember; Relationship related; // relationship of this to the class bool stat; // is it a static function? bool proto; // is it a prototype; bool docEnumValues; // is an enum with documented enum values. - bool annScope; // member is part of an anonymous scope - bool annUsed; + + mutable bool annScope; // member is part of an anonymous scope + mutable bool annUsed; // ugly: needs to be mutable to allow setAnonymousUsed to act as a + // const member. bool hasCallGraph; bool hasCallerGraph; bool hasReferencedByRelation; @@ -596,9 +1410,13 @@ class MemberDefImpl // FALSE => block is put before declaration. ClassDef *category; MemberDef *categoryRelation; + QCString declFileName; + int declLine; + int declColumn; + int numberOfFlowKW; }; -MemberDefImpl::MemberDefImpl() : +MemberDefImpl::IMPL::IMPL() : enumFields(0), redefinedBy(0), exampleSDict(0), @@ -609,11 +1427,14 @@ MemberDefImpl::MemberDefImpl() : defTmpArgLists(0), classSectionSDict(0), category(0), - categoryRelation(0) + categoryRelation(0), + declLine(-1), + declColumn(-1), + numberOfFlowKW(0) { } -MemberDefImpl::~MemberDefImpl() +MemberDefImpl::IMPL::~IMPL() { delete redefinedBy; delete exampleSDict; @@ -626,7 +1447,7 @@ MemberDefImpl::~MemberDefImpl() delete declArgList; } -void MemberDefImpl::init(Definition *def, +void MemberDefImpl::IMPL::init(Definition *def, const char *t,const char *a,const char *e, Protection p,Specifier v,bool s,Relationship r, MemberType mt,const ArgumentList *tal, @@ -746,7 +1567,7 @@ void MemberDefImpl::init(Definition *def, * \param e A string representing the throw clause of the members. * \param p The protection context of the member, possible values are: * \c Public, \c Protected, \c Private. - * \param v The degree of `virtualness' of the member, possible values are: + * \param v The degree of 'virtualness' of the member, possible values are: * \c Normal, \c Virtual, \c Pure. * \param s A boolean that is true iff the member is static. * \param r The relationship between the class and the member. @@ -758,33 +1579,32 @@ void MemberDefImpl::init(Definition *def, * \param meta Slice metadata. */ -MemberDef::MemberDef(const char *df,int dl,int dc, +MemberDefImpl::MemberDefImpl(const char *df,int dl,int dc, const char *t,const char *na,const char *a,const char *e, Protection p,Specifier v,bool s,Relationship r,MemberType mt, const ArgumentList *tal,const ArgumentList *al,const char *meta - ) : Definition(df,dl,dc,removeRedundantWhiteSpace(na)), visited(FALSE) + ) : DefinitionImpl(df,dl,dc,removeRedundantWhiteSpace(na)) { - //printf("MemberDef::MemberDef(%s)\n",na); - m_impl = new MemberDefImpl; + //printf("MemberDefImpl::MemberDef(%s)\n",na); + m_impl = new MemberDefImpl::IMPL; m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al,meta); - number_of_flowkw = 1; m_isLinkableCached = 0; m_isConstructorCached = 0; m_isDestructorCached = 0; } -MemberDef::MemberDef(const MemberDef &md) : Definition(md), visited(FALSE) +MemberDefImpl::MemberDefImpl(const MemberDefImpl &md) : DefinitionImpl(md) { - m_impl = new MemberDefImpl; + m_impl = new MemberDefImpl::IMPL; m_isLinkableCached = 0; m_isConstructorCached = 0; m_isDestructorCached = 0; } -MemberDef *MemberDef::deepCopy() const +MemberDef *MemberDefImpl::deepCopy() const { //MemberDef *result = new MemberDef(getDefFileName(),getDefLine(),name()); - MemberDef *result = new MemberDef(*this); + MemberDefImpl *result = new MemberDefImpl(*this); // first copy everything by reference *result->m_impl = *m_impl; // clear pointers owned by object @@ -855,20 +1675,20 @@ MemberDef *MemberDef::deepCopy() const return result; } -void MemberDef::moveTo(Definition *scope) +void MemberDefImpl::moveTo(Definition *scope) { setOuterScope(scope); if (scope->definitionType()==Definition::TypeClass) { - m_impl->classDef = (ClassDef*)scope; + m_impl->classDef = dynamic_cast<ClassDef*>(scope); } else if (scope->definitionType()==Definition::TypeFile) { - m_impl->fileDef = (FileDef*)scope; + m_impl->fileDef = dynamic_cast<FileDef*>(scope); } else if (scope->definitionType()==Definition::TypeNamespace) { - m_impl->nspace = (NamespaceDef*)scope; + m_impl->nspace = dynamic_cast<NamespaceDef*>(scope); } m_isLinkableCached = 0; m_isConstructorCached = 0; @@ -876,19 +1696,19 @@ void MemberDef::moveTo(Definition *scope) /*! Destroys the member definition. */ -MemberDef::~MemberDef() +MemberDefImpl::~MemberDefImpl() { delete m_impl; //printf("%p: ~MemberDef()\n",this); m_impl=0; } -void MemberDef::setReimplements(MemberDef *md) +void MemberDefImpl::setReimplements(MemberDef *md) { m_impl->redefines = md; } -void MemberDef::insertReimplementedBy(MemberDef *md) +void MemberDefImpl::insertReimplementedBy(MemberDef *md) { if (m_impl->templateMaster) { @@ -901,17 +1721,17 @@ void MemberDef::insertReimplementedBy(MemberDef *md) } } -MemberDef *MemberDef::reimplements() const +MemberDef *MemberDefImpl::reimplements() const { return m_impl->redefines; } -MemberList *MemberDef::reimplementedBy() const +MemberList *MemberDefImpl::reimplementedBy() const { return m_impl->redefinedBy; } -bool MemberDef::isReimplementedBy(ClassDef *cd) const +bool MemberDefImpl::isReimplementedBy(const ClassDef *cd) const { if (cd && m_impl->redefinedBy) { @@ -919,7 +1739,7 @@ bool MemberDef::isReimplementedBy(ClassDef *cd) const MemberDef *md; for (mi.toFirst();(md=mi.current());++mi) { - ClassDef *mcd = md->getClassDef(); + const ClassDef *mcd = md->getClassDef(); if (mcd) { if (cd==mcd || cd->isBaseClass(mcd,TRUE)) @@ -932,13 +1752,13 @@ bool MemberDef::isReimplementedBy(ClassDef *cd) const return FALSE; } -void MemberDef::insertEnumField(MemberDef *md) +void MemberDefImpl::insertEnumField(MemberDef *md) { if (m_impl->enumFields==0) m_impl->enumFields=new MemberList(MemberListType_enumFields); m_impl->enumFields->append(md); } -bool MemberDef::addExample(const char *anchor,const char *nameStr, +bool MemberDefImpl::addExample(const char *anchor,const char *nameStr, const char *file) { //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file); @@ -956,7 +1776,7 @@ bool MemberDef::addExample(const char *anchor,const char *nameStr, return FALSE; } -bool MemberDef::hasExamples() +bool MemberDefImpl::hasExamples() const { if (m_impl->exampleSDict==0) return FALSE; @@ -964,7 +1784,7 @@ bool MemberDef::hasExamples() return m_impl->exampleSDict->count()>0; } -QCString MemberDef::getOutputFileBase() const +QCString MemberDefImpl::getOutputFileBase() const { static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES); static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS); @@ -973,33 +1793,37 @@ QCString MemberDef::getOutputFileBase() const //printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n", // name().data(),m_impl->templateMaster,m_impl->group,m_impl->classDef, // m_impl->nspace,m_impl->fileDef); + const NamespaceDef *nspace = getNamespaceDef(); + const FileDef *fileDef = getFileDef(); + const ClassDef *classDef = getClassDef(); + const GroupDef *groupDef = getGroupDef(); if (!m_impl->explicitOutputFileBase.isEmpty()) { return m_impl->explicitOutputFileBase; } - else if (m_impl->templateMaster) + else if (templateMaster()) { - return m_impl->templateMaster->getOutputFileBase(); + return templateMaster()->getOutputFileBase(); } - else if (m_impl->group) + else if (groupDef) { - baseName=m_impl->group->getOutputFileBase(); + baseName=groupDef->getOutputFileBase(); } - else if (m_impl->classDef) + else if (classDef) { - baseName=m_impl->classDef->getOutputFileBase(); - if (inlineSimpleClasses && m_impl->classDef->isSimple()) + baseName=classDef->getOutputFileBase(); + if (inlineSimpleClasses && classDef->isSimple()) { return baseName; } } - else if (m_impl->nspace && m_impl->nspace->isLinkableInProject()) + else if (nspace && nspace->isLinkableInProject()) { - baseName=m_impl->nspace->getOutputFileBase(); + baseName=nspace->getOutputFileBase(); } - else if (m_impl->fileDef) + else if (fileDef) { - baseName=m_impl->fileDef->getOutputFileBase(); + baseName=fileDef->getOutputFileBase(); } if (baseName.isEmpty()) @@ -1024,37 +1848,41 @@ QCString MemberDef::getOutputFileBase() const return baseName; } -QCString MemberDef::getReference() const +QCString MemberDefImpl::getReference() const { - QCString ref = Definition::getReference(); + QCString ref = DefinitionImpl::getReference(); if (!ref.isEmpty()) { return ref; } - if (m_impl->templateMaster) + const NamespaceDef *nspace = getNamespaceDef(); + const FileDef *fileDef = getFileDef(); + const ClassDef *classDef = getClassDef(); + const GroupDef *groupDef = getGroupDef(); + if (templateMaster()) { - return m_impl->templateMaster->getReference(); + return templateMaster()->getReference(); } - else if (m_impl->group) + else if (groupDef) { - return m_impl->group->getReference(); + return groupDef->getReference(); } - else if (m_impl->classDef) + else if (classDef) { - return m_impl->classDef->getReference(); + return classDef->getReference(); } - else if (m_impl->nspace) + else if (nspace) { - return m_impl->nspace->getReference(); + return nspace->getReference(); } - else if (m_impl->fileDef) + else if (fileDef) { - return m_impl->fileDef->getReference(); + return fileDef->getReference(); } return ""; } -QCString MemberDef::anchor() const +QCString MemberDefImpl::anchor() const { QCString result=m_impl->anc; if (m_impl->groupAlias) return m_impl->groupAlias->anchor(); @@ -1063,7 +1891,7 @@ QCString MemberDef::anchor() const { result.prepend(m_impl->enumScope->anchor()); } - if (m_impl->group) + if (getGroupDef()) { if (m_impl->groupMember) { @@ -1077,21 +1905,22 @@ QCString MemberDef::anchor() const return result; } -void MemberDef::_computeLinkableInProject() +void MemberDefImpl::_computeLinkableInProject() { static bool extractStatic = Config_getBool(EXTRACT_STATIC); + static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); m_isLinkableCached = 2; // linkable - //printf("MemberDef::isLinkableInProject(name=%s)\n",name().data()); + //printf("MemberDefImpl::isLinkableInProject(name=%s)\n",name().data()); if (isHidden()) { //printf("is hidden\n"); m_isLinkableCached = 1; return; } - if (m_impl->templateMaster) + if (templateMaster()) { //printf("has template master\n"); - m_isLinkableCached = m_impl->templateMaster->isLinkableInProject() ? 2 : 1; + m_isLinkableCached = templateMaster()->isLinkableInProject() ? 2 : 1; return; } if (name().isEmpty() || name().at(0)=='@') @@ -1106,40 +1935,45 @@ void MemberDef::_computeLinkableInProject() m_isLinkableCached = 1; // no documentation return; } - if (m_impl->group && !m_impl->group->isLinkableInProject()) + const GroupDef *groupDef = getGroupDef(); + const ClassDef *classDef = getClassDef(); + if (groupDef && !groupDef->isLinkableInProject()) { //printf("group but group not linkable!\n"); m_isLinkableCached = 1; // group but group not linkable return; } - if (!m_impl->group && m_impl->classDef && !m_impl->classDef->isLinkableInProject()) + if (!groupDef && classDef && !classDef->isLinkableInProject()) { //printf("in a class but class not linkable!\n"); m_isLinkableCached = 1; // in class but class not linkable return; } - if (!m_impl->group && m_impl->nspace && !m_impl->related && !m_impl->nspace->isLinkableInProject() - && (m_impl->fileDef==0 || !m_impl->fileDef->isLinkableInProject())) + const NamespaceDef *nspace = getNamespaceDef(); + const FileDef *fileDef = getFileDef(); + if (!groupDef && nspace && !m_impl->related && !nspace->isLinkableInProject() + && (fileDef==0 || !fileDef->isLinkableInProject())) { //printf("in a namespace but namespace not linkable!\n"); m_isLinkableCached = 1; // in namespace but namespace not linkable return; } - if (!m_impl->group && !m_impl->nspace && - !m_impl->related && !m_impl->classDef && - m_impl->fileDef && !m_impl->fileDef->isLinkableInProject()) + if (!groupDef && !nspace && + !m_impl->related && !classDef && + fileDef && !fileDef->isLinkableInProject()) { //printf("in a file but file not linkable!\n"); m_isLinkableCached = 1; // in file (and not in namespace) but file not linkable return; } - if (!protectionLevelVisible(m_impl->prot) && m_impl->mtype!=MemberType_Friend) + if ((!protectionLevelVisible(m_impl->prot) && m_impl->mtype!=MemberType_Friend) && + !(m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual)) { //printf("private and invisible!\n"); m_isLinkableCached = 1; // hidden due to protection return; } - if (m_impl->stat && m_impl->classDef==0 && !extractStatic) + if (m_impl->stat && classDef==0 && !extractStatic) { //printf("static and invisible!\n"); m_isLinkableCached = 1; // hidden due to staticness @@ -1149,42 +1983,42 @@ void MemberDef::_computeLinkableInProject() return; // linkable! } -void MemberDef::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) +void MemberDefImpl::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) { - Definition::setDocumentation(d,docFile,docLine,stripWhiteSpace); + DefinitionImpl::setDocumentation(d,docFile,docLine,stripWhiteSpace); m_isLinkableCached = 0; } -void MemberDef::setBriefDescription(const char *b,const char *briefFile,int briefLine) +void MemberDefImpl::setBriefDescription(const char *b,const char *briefFile,int briefLine) { - Definition::setBriefDescription(b,briefFile,briefLine); + DefinitionImpl::setBriefDescription(b,briefFile,briefLine); m_isLinkableCached = 0; } -void MemberDef::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine) +void MemberDefImpl::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine) { - Definition::setInbodyDocumentation(d,inbodyFile,inbodyLine); + DefinitionImpl::setInbodyDocumentation(d,inbodyFile,inbodyLine); m_isLinkableCached = 0; } -void MemberDef::setHidden(bool b) +void MemberDefImpl::setHidden(bool b) { - Definition::setHidden(b); + DefinitionImpl::setHidden(b); m_isLinkableCached = 0; } -bool MemberDef::isLinkableInProject() const +bool MemberDefImpl::isLinkableInProject() const { if (m_isLinkableCached==0) { - MemberDef *that = (MemberDef*)this; + MemberDefImpl *that = (MemberDefImpl*)this; that->_computeLinkableInProject(); } ASSERT(m_isLinkableCached>0); return m_isLinkableCached==2; } -bool MemberDef::isLinkable() const +bool MemberDefImpl::isLinkable() const { if (m_impl->templateMaster) { @@ -1197,7 +2031,7 @@ bool MemberDef::isLinkable() const } -void MemberDef::setDefinitionTemplateParameterLists(QList<ArgumentList> *lists) +void MemberDefImpl::setDefinitionTemplateParameterLists(QList<ArgumentList> *lists) { if (lists) { @@ -1206,26 +2040,29 @@ void MemberDef::setDefinitionTemplateParameterLists(QList<ArgumentList> *lists) } } -void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *, - FileDef *fd,GroupDef *gd,bool onlyText) +void MemberDefImpl::writeLink(OutputList &ol, + const ClassDef *,const NamespaceDef *,const FileDef *fd,const GroupDef *gd, + bool onlyText) const { SrcLangExt lang = getLanguage(); static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES); QCString sep = getLanguageSpecificSeparator(lang,TRUE); QCString n = name(); + const ClassDef *classDef = getClassDef(); + const NamespaceDef *nspace = getNamespaceDef(); if (!hideScopeNames) { if (m_impl->enumScope && m_impl->livesInsideEnum) { n.prepend(m_impl->enumScope->displayName()+sep); } - if (m_impl->classDef && gd && !isRelated()) + if (classDef && gd && !isRelated()) { - n.prepend(m_impl->classDef->displayName()+sep); + n.prepend(classDef->displayName()+sep); } - else if (m_impl->nspace && (gd || fd)) + else if (nspace && (gd || fd)) { - n.prepend(m_impl->nspace->displayName()+sep); + n.prepend(nspace->displayName()+sep); } } @@ -1238,7 +2075,7 @@ void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *, if (m_impl->mtype==MemberType_EnumValue && getGroupDef()==0 && // enum value is not grouped getEnumScope() && getEnumScope()->getGroupDef()) // but its container is { - GroupDef *enumValGroup = getEnumScope()->getGroupDef(); + const GroupDef *enumValGroup = getEnumScope()->getGroupDef(); ol.writeObjectLink(enumValGroup->getReference(), enumValGroup->getOutputFileBase(), anchor(),n); @@ -1259,27 +2096,27 @@ void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *, /*! If this member has an anonymous class/struct/union as its type, then * this method will return the ClassDef that describes this return type. */ -ClassDef *MemberDef::getClassDefOfAnonymousType() +ClassDef *MemberDefImpl::getClassDefOfAnonymousType() const { if (m_impl->cachedAnonymousType) return m_impl->cachedAnonymousType; QCString cname; if (getClassDef()!=0) { - cname=getClassDef()->name().copy(); + cname=getClassDef()->name(); } else if (getNamespaceDef()!=0) { - cname=getNamespaceDef()->name().copy(); + cname=getNamespaceDef()->name(); } QCString ltype(m_impl->type); - // strip `static' keyword from ltype + // strip 'static' keyword from ltype //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7); - // strip `friend' keyword from ltype + // strip 'friend' keyword from ltype ltype.stripPrefix("friend "); static QRegExp r("@[0-9]+"); int l,i=r.match(ltype,0,&l); - //printf("ltype=`%s' i=%d\n",ltype.data(),i); + //printf("ltype='%s' i=%d\n",ltype.data(),i); // search for the last anonymous scope in the member type ClassDef *annoClassDef=0; if (i!=-1) // found anonymous scope in type @@ -1312,9 +2149,10 @@ ClassDef *MemberDef::getClassDefOfAnonymousType() /*! This methods returns TRUE iff the brief section (also known as * declaration section) is visible in the documentation. */ -bool MemberDef::isBriefSectionVisible() const +bool MemberDefImpl::isBriefSectionVisible() const { static bool extractStatic = Config_getBool(EXTRACT_STATIC); + static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC); static bool repeatBrief = Config_getBool(REPEAT_BRIEF); @@ -1365,9 +2203,12 @@ bool MemberDef::isBriefSectionVisible() const ); // only include members that are non-private unless EXTRACT_PRIVATE is - // set to YES or the member is part of a group + // set to YES or the member is part of a group. And as a special case, + // private *documented* virtual members are shown if EXTRACT_PRIV_VIRTUAL + // is set to YES bool visibleIfPrivate = (protectionLevelVisible(protection()) || - m_impl->mtype==MemberType_Friend + m_impl->mtype==MemberType_Friend || + (m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual && hasDocs) ); // hide member if it overrides a member in a superclass and has no @@ -1402,22 +2243,22 @@ bool MemberDef::isBriefSectionVisible() const /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor && visibleIfFriendCompound && !m_impl->annScope && !isHidden(); - //printf("MemberDef::isBriefSectionVisible() %d\n",visible); + //printf("MemberDefImpl::isBriefSectionVisible() %d\n",visible); return visible; } -QCString MemberDef::getDeclType() const +QCString MemberDefImpl::getDeclType() const { QCString ltype(m_impl->type); if (isTypedef() && getLanguage() != SrcLangExt_Slice) { ltype.prepend("typedef "); } - if (isAlias()) + if (isTypeAlias()) { ltype="using"; } - // strip `friend' keyword from ltype + // strip 'friend' keyword from ltype ltype.stripPrefix("friend "); if (ltype=="@") // rename type from enum values { @@ -1434,18 +2275,18 @@ QCString MemberDef::getDeclType() const return ltype; } -void MemberDef::writeDeclaration(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, - bool inGroup, ClassDef *inheritedFrom,const char *inheritId) +void MemberDefImpl::writeDeclaration(OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + bool inGroup, const ClassDef *inheritedFrom,const char *inheritId) const { - //printf("%s MemberDef::writeDeclaration() inGroup=%d\n",qualifiedName().data(),inGroup); + //printf("%s MemberDefImpl::writeDeclaration() inGroup=%d\n",qualifiedName().data(),inGroup); // hide enum value, since they appear already as part of the enum, unless they // are explicitly grouped. if (!inGroup && m_impl->mtype==MemberType_EnumValue) return; - Definition *d=0; + const Definition *d=0; ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd; if (d==gd) // see bug 753608 @@ -1455,8 +2296,7 @@ void MemberDef::writeDeclaration(OutputList &ol, else if (getFileDef()) d = getFileDef(); } - //_writeTagData(compoundType); - _addToSearchIndex(); + addToSearchIndex(); QCString cname = d->name(); QCString cdname = d->displayName(); @@ -1477,7 +2317,7 @@ void MemberDef::writeDeclaration(OutputList &ol, // If there is no detailed description we need to write the anchor here. bool detailsVisible = isDetailedSectionLinkable(); - bool writeAnchor = (inGroup || m_impl->group==0) && // only write anchors for member that have no details and are + bool writeAnchor = (inGroup || getGroupDef()==0) && // only write anchors for member that have no details and are !detailsVisible && !m_impl->annMemb; // rendered inside the group page or are not grouped at all if (writeAnchor) { @@ -1523,11 +2363,11 @@ void MemberDef::writeDeclaration(OutputList &ol, { ltype.prepend("typedef "); } - if (isAlias()) + if (isTypeAlias()) { ltype="using"; } - // strip `friend' keyword from ltype + // strip 'friend' keyword from ltype ltype.stripPrefix("friend "); static QRegExp r("@[0-9]+"); @@ -1535,7 +2375,7 @@ void MemberDef::writeDeclaration(OutputList &ol, int l,i=r.match(ltype,0,&l); if (i!=-1) // member has an anonymous type { - //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n", + //printf("annoClassDef=%p annMemb=%p scopeName='%s' anonymous='%s'\n", // annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data()); if (annoClassDef) // type is an anonymous compound @@ -1552,7 +2392,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ol.writeNonBreakableSpace(3); } QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace(); - //printf(">>>>>> ltype=`%s' varName=`%s'\n",ltype.data(),varName.data()); + //printf(">>>>>> ltype='%s' varName='%s'\n",ltype.data(),varName.data()); ol.docify("}"); if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@')) { @@ -1578,7 +2418,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ); getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd); //ol+=*getAnonymousEnumType()->enumDecl(); - linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,this,ltype.right(ltype.length()-i-l),TRUE); + linkifyText(TextGeneratorOLImpl(ol),d,getFileDef(),this,ltype.right(ltype.length()-i-l),TRUE); } else { @@ -1639,12 +2479,13 @@ void MemberDef::writeDeclaration(OutputList &ol, if (!name().isEmpty() && name().at(0)!='@') // hide anonymous stuff { static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); + static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); static bool extractStatic = Config_getBool(EXTRACT_STATIC); //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d hasDocumentation=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable(),hasDocumentation()); if (!(name().isEmpty() || name().at(0)=='@') && // name valid (hasDocumentation() || isReference()) && // has docs - !(m_impl->prot==Private && !extractPrivate && m_impl->mtype!=MemberType_Friend) && // hidden due to protection - !(isStatic() && m_impl->classDef==0 && !extractStatic) // hidden due to static-ness + !(m_impl->prot==Private && !extractPrivate && (m_impl->virt==Normal || !extractPrivateVirtual) && m_impl->mtype!=MemberType_Friend) && // hidden due to protection + !(isStatic() && getClassDef()==0 && !extractStatic) // hidden due to static-ness ) { if (m_impl->annMemb) @@ -1662,8 +2503,8 @@ void MemberDef::writeDeclaration(OutputList &ol, else { //printf("writeLink %s->%d\n",name.data(),hasDocumentation()); - ClassDef *rcd = cd; - if (isReference() && m_impl->classDef) rcd = m_impl->classDef; + const ClassDef *rcd = cd; + if (isReference() && getClassDef()) rcd = getClassDef(); writeLink(ol,rcd,nd,fd,gd); } } @@ -1682,8 +2523,8 @@ void MemberDef::writeDeclaration(OutputList &ol, m_impl->annMemb->setAnonymousUsed(); setAnonymousUsed(); } - ClassDef *rcd = cd; - if (isReference() && m_impl->classDef) rcd = m_impl->classDef; + const ClassDef *rcd = cd; + if (isReference() && getClassDef()) rcd = getClassDef(); writeLink(ol,rcd,nd,fd,gd,TRUE); } } @@ -1756,7 +2597,7 @@ void MemberDef::writeDeclaration(OutputList &ol, linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->initializer); } } - else if (isAlias()) // using template alias + else if (isTypeAlias()) // using template alias { ol.writeString(" = "); linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->type); @@ -1855,18 +2696,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ol.disableAllBut(OutputGenerator::Html); //ol.endEmphasis(); ol.docify(" "); - if (inheritedFrom || - separateMemberPages || - (m_impl->group!=0 && gd==0) || - (m_impl->nspace!=0 && nd==0) - ) // forward link to the page or group or namespace - { - ol.startTextLink(getOutputFileBase(),anchor()); - } - else // local link - { - ol.startTextLink(0,anchor()); - } + ol.startTextLink(getOutputFileBase(),anchor()); ol.parseText(theTranslator->trMore()); ol.endTextLink(); //ol.startEmphasis(); @@ -1888,7 +2718,7 @@ void MemberDef::writeDeclaration(OutputList &ol, warnIfUndocumented(); } -bool MemberDef::isDetailedSectionLinkable() const +bool MemberDefImpl::isDetailedSectionLinkable() const { static bool extractAll = Config_getBool(EXTRACT_ALL); static bool alwaysDetailedSec = Config_getBool(ALWAYS_DETAILED_SEC); @@ -1896,6 +2726,7 @@ bool MemberDef::isDetailedSectionLinkable() const static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC); static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); static bool extractStatic = Config_getBool(EXTRACT_STATIC); + static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); // the member has details documentation for any of the following reasons bool docFilter = @@ -1933,12 +2764,8 @@ bool MemberDef::isDetailedSectionLinkable() const // only include members that are non-private unless EXTRACT_PRIVATE is // set to YES or the member is part of a group - bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==MemberType_Friend; - - // member is part of an anonymous scope that is the type of - // another member in the list. - // - //bool inAnonymousScope = !briefDescription().isEmpty() && annUsed; + bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==MemberType_Friend || + (m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual); // hide friend (class|struct|union) member if HIDE_FRIEND_COMPOUNDS // is true @@ -1951,12 +2778,11 @@ bool MemberDef::isDetailedSectionLinkable() const ); - bool result = ((docFilter && staticFilter && privateFilter && friendCompoundFilter && !isHidden())); - //printf("%s::isDetailedSectionLinkable: %d\n",name().data(),result); + bool result = (docFilter && staticFilter && privateFilter && friendCompoundFilter && !isHidden()); return result; } -bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const +bool MemberDefImpl::isDetailedSectionVisible(bool inGroup,bool inFile) const { static bool separateMemPages = Config_getBool(SEPARATE_MEMBER_PAGES); static bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS); @@ -1974,7 +2800,7 @@ bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const return result; } -void MemberDef::getLabels(QStrList &sl,Definition *container) const +void MemberDefImpl::getLabels(QStrList &sl,const Definition *container) const { static bool inlineInfo = Config_getBool(INLINE_INFO); @@ -1985,7 +2811,7 @@ void MemberDef::getLabels(QStrList &sl,Definition *container) const (isInline() && inlineInfo) || isSignal() || isSlot() || isStatic() || - (m_impl->classDef && m_impl->classDef!=container && container->definitionType()==TypeClass) || + (getClassDef() && getClassDef()!=container && container->definitionType()==TypeClass) || (m_impl->memSpec & ~Entry::Inline)!=0 ) ) @@ -2020,6 +2846,7 @@ void MemberDef::getLabels(QStrList &sl,Definition *container) const if (isPrivateGettable()) sl.append("private get"); if (isPrivateSettable()) sl.append("private set"); } + if (isConstExpr()) sl.append("constexpr"); if (isAddable()) sl.append("add"); if (!isUNOProperty() && isRemovable()) sl.append("remove"); if (isRaisable()) sl.append("raise"); @@ -2075,9 +2902,9 @@ void MemberDef::getLabels(QStrList &sl,Definition *container) const sl.append("implementation"); } } - if (m_impl->classDef && + if (getClassDef() && container->definitionType()==TypeClass && - m_impl->classDef!=container && + getClassDef()!=container && !isRelated() ) { @@ -2091,7 +2918,7 @@ void MemberDef::getLabels(QStrList &sl,Definition *container) const } } -void MemberDef::_writeCallGraph(OutputList &ol) +void MemberDefImpl::_writeCallGraph(OutputList &ol) const { // write call graph if (m_impl->hasCallGraph @@ -2115,7 +2942,7 @@ void MemberDef::_writeCallGraph(OutputList &ol) } } -void MemberDef::_writeCallerGraph(OutputList &ol) +void MemberDefImpl::_writeCallerGraph(OutputList &ol) const { if (m_impl->hasCallerGraph && (isFunction() || isSlot() || isSignal()) && Config_getBool(HAVE_DOT) @@ -2126,7 +2953,7 @@ void MemberDef::_writeCallerGraph(OutputList &ol) { warn_uncond("Caller graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",qPrint(qualifiedName())); } - else if (!callerGraph.isTrivial() && !callerGraph.isTooBig()) + else if (!callerGraph.isTrivial()) { msg("Generating caller graph for function %s\n",qPrint(qualifiedName())); ol.disable(OutputGenerator::Man); @@ -2138,10 +2965,10 @@ void MemberDef::_writeCallerGraph(OutputList &ol) } } -void MemberDef::_writeReimplements(OutputList &ol) +void MemberDefImpl::_writeReimplements(OutputList &ol) const { MemberDef *bmd=reimplements(); - ClassDef *bcd=0; + const ClassDef *bcd=0; if (bmd && (bcd=bmd->getClassDef())) { // write class that contains a member that is reimplemented by this one @@ -2197,7 +3024,7 @@ void MemberDef::_writeReimplements(OutputList &ol) } } -void MemberDef::_writeReimplementedBy(OutputList &ol) +void MemberDefImpl::_writeReimplementedBy(OutputList &ol) const { MemberList *bml=reimplementedBy(); if (bml) @@ -2205,7 +3032,7 @@ void MemberDef::_writeReimplementedBy(OutputList &ol) MemberListIterator mli(*bml); MemberDef *bmd=0; uint count=0; - ClassDef *bcd=0; + const ClassDef *bcd=0; for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli) { // count the members that directly inherit from md and for @@ -2222,7 +3049,7 @@ void MemberDef::_writeReimplementedBy(OutputList &ol) ol.startParagraph(); QCString reimplInLine; - if (m_impl->virt==Pure || (m_impl->classDef && m_impl->classDef->compoundType()==ClassDef::Interface)) + if (m_impl->virt==Pure || (getClassDef() && getClassDef()->compoundType()==ClassDef::Interface)) { reimplInLine = theTranslator->trImplementedInList(count); } @@ -2272,9 +3099,9 @@ void MemberDef::_writeReimplementedBy(OutputList &ol) } } -void MemberDef::_writeCategoryRelation(OutputList &ol) +void MemberDefImpl::_writeCategoryRelation(OutputList &ol) const { - if (m_impl->classDef) // this should be a member of a class/category + if (getClassDef()) // this should be a member of a class/category { //printf("%s: category %s relation %s class=%s categoryOf=%s\n", // name().data(), @@ -2298,12 +3125,12 @@ void MemberDef::_writeCategoryRelation(OutputList &ol) text = theTranslator->trProvidedByCategory(); name = m_impl->category->displayName(); } - else if (m_impl->classDef->categoryOf()) + else if (getClassDef()->categoryOf()) { // this member is part of a category so link to the corresponding class member of the class we extend // so link to method 'categoryRelation' with 'extends class 'classDef->categoryOf()' text = theTranslator->trExtendsClass(); - name = m_impl->classDef->categoryOf()->displayName(); + name = getClassDef()->categoryOf()->displayName(); } i=text.find("@0"); if (i!=-1) @@ -2325,7 +3152,7 @@ void MemberDef::_writeCategoryRelation(OutputList &ol) } } -void MemberDef::_writeExamples(OutputList &ol) +void MemberDefImpl::_writeExamples(OutputList &ol) const { // write the list of examples that use this member if (hasExamples()) @@ -2338,7 +3165,7 @@ void MemberDef::_writeExamples(OutputList &ol) } } -void MemberDef::_writeTypeConstraints(OutputList &ol) +void MemberDefImpl::_writeTypeConstraints(OutputList &ol) const { if (m_impl->typeConstraints) { @@ -2346,15 +3173,15 @@ void MemberDef::_writeTypeConstraints(OutputList &ol) } } -void MemberDef::_writeEnumValues(OutputList &ol,Definition *container, +void MemberDefImpl::_writeEnumValues(OutputList &ol,const Definition *container, const QCString &cfname,const QCString &ciname, - const QCString &cname) + const QCString &cname) const { // For enum, we also write the documented enum values if (isEnumerate()) { bool first=TRUE; - MemberList *fmdl=enumFieldList(); + const MemberList *fmdl=enumFieldList(); //printf("** %s: enum values=%d\n",name().data(),fmdl!=0 ? fmdl->count() : 0); if (fmdl) { @@ -2420,7 +3247,7 @@ void MemberDef::_writeEnumValues(OutputList &ol,Definition *container, } } -QCString MemberDef::displayDefinition() const +QCString MemberDefImpl::displayDefinition() const { QCString ldef = definition(); QCString title = name(); @@ -2465,7 +3292,7 @@ QCString MemberDef::displayDefinition() const if (ni>=ei) ei=ni+2; ldef = ldef.left(si) + " { ... } " + ldef.right(ldef.length()-ei); } - ClassDef *cd=getClassDef(); + const ClassDef *cd=getClassDef(); if (cd && cd->isObjectiveC()) { // strip scope name @@ -2503,12 +3330,12 @@ QCString MemberDef::displayDefinition() const return substitute(ldef,"::",sep); } -void MemberDef::_writeGroupInclude(OutputList &ol,bool inGroup) +void MemberDefImpl::_writeGroupInclude(OutputList &ol,bool inGroup) const { // only write out the include file if this is not part of a class or file // definition static bool showGroupedMembInc = Config_getBool(SHOW_GROUPED_MEMB_INC); - FileDef *fd = getFileDef(); + const FileDef *fd = getFileDef(); QCString nm; if (fd) nm = getFileDef()->docName(); if (inGroup && fd && showGroupedMembInc && !nm.isEmpty()) @@ -2547,22 +3374,22 @@ void MemberDef::_writeGroupInclude(OutputList &ol,bool inGroup) /*! Writes the "detailed documentation" section of this member to * all active output formats. */ -void MemberDef::writeDocumentation(MemberList *ml, +void MemberDefImpl::writeDocumentation(const MemberList *ml, int memCount,int memTotal, OutputList &ol, const char *scName, - Definition *container, + const Definition *container, bool inGroup, bool showEnumValues, bool showInline - ) + ) const { // if this member is in a group find the real scope name. bool hasParameterList = FALSE; bool inFile = container->definitionType()==Definition::TypeFile; bool hasDocs = isDetailedSectionVisible(inGroup,inFile); - //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d sectionLinkable=%d\n", + //printf("MemberDefImpl::writeDocumentation(): name='%s' hasDocs='%d' containerType=%d inGroup=%d sectionLinkable=%d\n", // name().data(),hasDocs,container->definitionType(),inGroup,isDetailedSectionLinkable()); //if ( !hasDocs ) return; @@ -2576,13 +3403,13 @@ void MemberDef::writeDocumentation(MemberList *ml, QCString scopeName = scName; QCString memAnchor = anchor(); QCString ciname = container->displayName(); - Definition *scopedContainer = container; // see bug 753608 + const Definition *scopedContainer = container; // see bug 753608 if (container->definitionType()==TypeGroup) { if (getClassDef()) { scopeName=getClassDef()->displayName(); scopedContainer=getClassDef(); } else if (getNamespaceDef()) { scopeName=getNamespaceDef()->displayName(); scopedContainer=getNamespaceDef(); } else if (getFileDef()) { scopeName=getFileDef()->displayName(); scopedContainer=getFileDef(); } - ciname = ((GroupDef *)container)->groupTitle(); + ciname = (dynamic_cast<const GroupDef *>(container))->groupTitle(); } else if (container->definitionType()==TypeFile && getNamespaceDef() && lang != SrcLangExt_Python) { // member is in a namespace, but is written as part of the file documentation @@ -2604,7 +3431,7 @@ void MemberDef::writeDocumentation(MemberList *ml, QCString ldef = definition(); QCString title = name(); - //printf("member `%s' def=`%s'\n",name().data(),ldef.data()); + //printf("member '%s' def='%s'\n",name().data(),ldef.data()); if (isEnumerate()) { if (title.at(0)=='@') @@ -2678,7 +3505,7 @@ void MemberDef::writeDocumentation(MemberList *ml, } if (!found) // anonymous compound { - //printf("Anonymous compound `%s'\n",cname.data()); + //printf("Anonymous compound '%s'\n",cname.data()); ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs); ol.startMemberDoc(ciname,name(),memAnchor,name(),memCount,memTotal,showInline); // search for the last anonymous compound name in the definition @@ -2711,8 +3538,8 @@ void MemberDef::writeDocumentation(MemberList *ml, ol.endMemberDocPrefixItem(); } - ClassDef *cd=getClassDef(); - NamespaceDef *nd=getNamespaceDef(); + const ClassDef *cd=getClassDef(); + const NamespaceDef *nd=getNamespaceDef(); if (!Config_getBool(HIDE_SCOPE_NAMES)) { bool first=TRUE; @@ -2826,7 +3653,7 @@ void MemberDef::writeDocumentation(MemberList *ml, ldef.left(pos) ); ol.docify(ldef.mid(pos)); - Definition *scope = cd; + const Definition *scope = cd; if (scope==0) scope = nd; hasParameterList=writeDefArgumentList(ol,scope,this); } @@ -2838,7 +3665,7 @@ void MemberDef::writeDocumentation(MemberList *ml, this, substitute(ldef,"::",sep) ); - Definition *scope = cd; + const Definition *scope = cd; if (scope==0) scope = nd; hasParameterList=writeDefArgumentList(ol,scope,this); } @@ -2929,7 +3756,7 @@ void MemberDef::writeDocumentation(MemberList *ml, // ) ) { - //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data()); + //printf("md=%s initLines=%d init='%s'\n",name().data(),initLines,init.data()); ol.startBold(); if (m_impl->mtype==MemberType_Define) ol.parseText(theTranslator->trDefineValue()); @@ -2939,7 +3766,7 @@ void MemberDef::writeDocumentation(MemberList *ml, ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension()); pIntf->resetCodeParserState(); ol.startCodeFragment(); - pIntf->parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,getFileDef(), + pIntf->parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,const_cast<FileDef*>(getFileDef()), -1,-1,TRUE,this,FALSE,this); ol.endCodeFragment(); } @@ -3126,7 +3953,7 @@ static Definition *getClassFromType(Definition *scope,const QCString &type,SrcLa } #endif -QCString MemberDef::fieldType() const +QCString MemberDefImpl::fieldType() const { QCString type = m_impl->accessorType; if (type.isEmpty()) @@ -3138,7 +3965,7 @@ QCString MemberDef::fieldType() const return simplifyTypeForTable(type); } -void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container) +void MemberDefImpl::writeMemberDocSimple(OutputList &ol, const Definition *container) const { Definition *scope = getOuterScope(); QCString doxyName = name(); @@ -3156,7 +3983,7 @@ void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container) //printf("===> %s::anonymous: %s\n",name().data(),cd?cd->name().data():"<none>"); if (container && container->definitionType()==Definition::TypeClass && - !((ClassDef*)container)->isJavaEnum()) + !(dynamic_cast<const ClassDef*>(container))->isJavaEnum()) { ol.startInlineMemberType(); ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs); @@ -3233,7 +4060,7 @@ void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container) ol.endInlineMemberDoc(); } -QCString MemberDef::memberTypeName() const +QCString MemberDefImpl::memberTypeName() const { switch (m_impl->mtype) { @@ -3257,17 +4084,17 @@ QCString MemberDef::memberTypeName() const } } -void MemberDef::warnIfUndocumented() +void MemberDefImpl::warnIfUndocumented() const { /* * Removed bug_303020: * if (m_impl->memberGroup) return; */ - ClassDef *cd = getClassDef(); - NamespaceDef *nd = getNamespaceDef(); - FileDef *fd = getFileDef(); - GroupDef *gd = getGroupDef(); - Definition *d=0; + const ClassDef *cd = getClassDef(); + const NamespaceDef *nd = getNamespaceDef(); + const FileDef *fd = getFileDef(); + const GroupDef *gd = getGroupDef(); + const Definition *d=0; const char *t=0; if (cd) t="class", d=cd; @@ -3304,22 +4131,114 @@ void MemberDef::warnIfUndocumented() } } +void MemberDefImpl::detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const +{ + if (!Config_getBool(WARN_NO_PARAMDOC)) return; + QCString returnType = typeString(); + bool isPython = getLanguage()==SrcLangExt_Python; + + if (!m_impl->hasDocumentedParams && hasParamCommand) + { + //printf("%s:hasDocumentedParams=TRUE;\n",name().data()); + m_impl->hasDocumentedParams = TRUE; + } + else if (!m_impl->hasDocumentedParams) + { + const ArgumentList *al = argumentList(); + const ArgumentList *declAl = declArgumentList(); + bool allDoc=TRUE; // no parameter => all parameters are documented + if ( // member has parameters + al!=0 && // but the member has a parameter list + al->count()>0 // with at least one parameter (that is not void) + ) + { + ArgumentListIterator ali(*al); + Argument *a; + + // see if all parameters have documentation + for (ali.toFirst();(a=ali.current()) && allDoc;++ali) + { + if (!a->name.isEmpty() && a->type!="void" && + !(isPython && (a->name=="self" || a->name=="cls")) + ) + { + allDoc = !a->docs.isEmpty(); + } + //printf("a->type=%s a->name=%s doc=%s\n", + // a->type.data(),a->name.data(),a->docs.data()); + } + if (!allDoc && declAl!=0) // try declaration arguments as well + { + allDoc=TRUE; + ArgumentListIterator ali(*declAl); + Argument *a; + for (ali.toFirst();(a=ali.current()) && allDoc;++ali) + { + if (!a->name.isEmpty() && a->type!="void" && + !(isPython && (a->name=="self" || a->name=="cls")) + ) + { + allDoc = !a->docs.isEmpty(); + } + //printf("a->name=%s doc=%s\n",a->name.data(),a->docs.data()); + } + } + } + if (allDoc) + { + //printf("%s:hasDocumentedParams=TRUE;\n",name().data()); + m_impl->hasDocumentedParams = TRUE; + } + } + + //printf("Member %s hasDocumentedReturnType=%d hasReturnCommand=%d\n", + // name().data(),m_impl->hasDocumentedReturnType,hasReturnCommand); + if (!m_impl->hasDocumentedReturnType && // docs not yet found + hasReturnCommand) + { + m_impl->hasDocumentedReturnType = TRUE; + } + else if ( // see if return type is documented in a function w/o return type + hasReturnCommand && + ( + returnType.find("void")!=-1 || // void return type + returnType.find("subroutine")!=-1 || // fortran subroutine + isConstructor() || // a constructor + isDestructor() // or destructor + ) + ) + { + warn_doc_error(getDefFileName(),getDefLine(),"documented empty return type of %s", + qualifiedName().data()); + } + else if ( // see if return needs to documented + m_impl->hasDocumentedReturnType || + returnType.find("void")!=-1 || // void return type + returnType.find("subroutine")!=-1 || // fortran subroutine + isConstructor() || // a constructor + isDestructor() // or destructor + ) + { + m_impl->hasDocumentedReturnType = TRUE; + } +} -void MemberDef::warnIfUndocumentedParams() +void MemberDefImpl::warnIfUndocumentedParams() const { if (!Config_getBool(EXTRACT_ALL) && Config_getBool(WARN_IF_UNDOCUMENTED) && Config_getBool(WARN_NO_PARAMDOC) && + !isDeleted() && !isReference() && !Doxygen::suppressDocWarnings) { - if (!hasDocumentedParams()) + if (!m_impl->hasDocumentedParams) { warn_doc_error(getDefFileName(),getDefLine(), "parameters of member %s are not (all) documented", qPrint(qualifiedName())); } - if (!hasDocumentedReturnType() && + if (!m_impl->hasDocumentedReturnType && isFunction() && hasDocumentation()) { warn_doc_error(getDefFileName(),getDefLine(), @@ -3329,14 +4248,14 @@ void MemberDef::warnIfUndocumentedParams() } } -bool MemberDef::isFriendClass() const +bool MemberDefImpl::isFriendClass() const { return (isFriend() && (m_impl->type=="friend class" || m_impl->type=="friend struct" || m_impl->type=="friend union")); } -bool MemberDef::isDocumentedFriendClass() const +bool MemberDefImpl::isDocumentedFriendClass() const { ClassDef *fcd=0; QCString baseName=name(); @@ -3346,39 +4265,39 @@ bool MemberDef::isDocumentedFriendClass() const (fcd=getClass(baseName)) && fcd->isLinkable()); } -bool MemberDef::isDeleted() const +bool MemberDefImpl::isDeleted() const { return m_impl->defArgList && m_impl->defArgList->isDeleted; } -bool MemberDef::hasDocumentation() const +bool MemberDefImpl::hasDocumentation() const { - return Definition::hasDocumentation() || + return DefinitionImpl::hasDocumentation() || (m_impl->mtype==MemberType_Enumeration && m_impl->docEnumValues) || // has enum values (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()); // has doc arguments } #if 0 -bool MemberDef::hasUserDocumentation() const +bool MemberDefImpl::hasUserDocumentation() const { - bool hasDocs = Definition::hasUserDocumentation(); + bool hasDocs = DefinitionImpl::hasUserDocumentation(); return hasDocs; } #endif -void MemberDef::setMemberGroup(MemberGroup *grp) +void MemberDefImpl::setMemberGroup(MemberGroup *grp) { m_impl->memberGroup = grp; } -bool MemberDef::visibleMemberGroup(bool hideNoHeader) +bool MemberDefImpl::visibleMemberGroup(bool hideNoHeader) const { return m_impl->memberGroup!=0 && (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]"); } -QCString MemberDef::getScopeString() const +QCString MemberDefImpl::getScopeString() const { QCString result; if (getClassDef()) result=getClassDef()->displayName(); @@ -3411,7 +4330,7 @@ static QCString escapeAnchor(const QCString &anchor) } #endif -void MemberDef::setAnchor() +void MemberDefImpl::setAnchor() { QCString memAnchor = name(); if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args; @@ -3440,11 +4359,11 @@ void MemberDef::setAnchor() m_impl->anc = "a"+sigStr; } -void MemberDef::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, +void MemberDefImpl::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, const QCString &fileName,int startLine, bool hasDocs,MemberDef *member) { - //printf("%s MemberDef::setGroupDef(%s)\n",name().data(),gd->name().data()); + //printf("%s MemberDefImpl::setGroupDef(%s)\n",name().data(),gd->name().data()); m_impl->group=gd; m_impl->grouppri=pri; m_impl->groupFileName=fileName; @@ -3454,7 +4373,7 @@ void MemberDef::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, m_isLinkableCached = 0; } -void MemberDef::setEnumScope(MemberDef *md,bool livesInsideEnum) +void MemberDefImpl::setEnumScope(MemberDef *md,bool livesInsideEnum) { m_impl->enumScope=md; m_impl->livesInsideEnum=livesInsideEnum; @@ -3469,7 +4388,7 @@ void MemberDef::setEnumScope(MemberDef *md,bool livesInsideEnum) } } -void MemberDef::setMemberClass(ClassDef *cd) +void MemberDefImpl::setMemberClass(ClassDef *cd) { m_impl->classDef=cd; m_isLinkableCached = 0; @@ -3477,14 +4396,14 @@ void MemberDef::setMemberClass(ClassDef *cd) setOuterScope(cd); } -void MemberDef::setNamespace(NamespaceDef *nd) +void MemberDefImpl::setNamespace(NamespaceDef *nd) { m_impl->nspace=nd; setOuterScope(nd); } -MemberDef *MemberDef::createTemplateInstanceMember( - ArgumentList *formalArgs,ArgumentList *actualArgs) +MemberDef *MemberDefImpl::createTemplateInstanceMember( + ArgumentList *formalArgs,ArgumentList *actualArgs) const { //printf(" Member %s %s %s\n",typeString(),name().data(),argsString()); ArgumentList *actualArgList = 0; @@ -3509,7 +4428,7 @@ MemberDef *MemberDef::createTemplateInstanceMember( methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs); } - MemberDef *imd = new MemberDef( + MemberDef *imd = createMemberDef( getDefFileName(),getDefLine(),getDefColumn(), substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs), methodName, @@ -3528,7 +4447,7 @@ MemberDef *MemberDef::createTemplateInstanceMember( return imd; } -bool MemberDef::hasOneLineInitializer() const +bool MemberDefImpl::hasOneLineInitializer() const { //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n", // name().data(),m_impl->initializer.data(),m_impl->initLines, @@ -3537,7 +4456,7 @@ bool MemberDef::hasOneLineInitializer() const ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly } -bool MemberDef::hasMultiLineInitializer() const +bool MemberDefImpl::hasMultiLineInitializer() const { //printf("initLines=%d userInitLines=%d maxInitLines=%d\n", // initLines,userInitLines,maxInitLines); @@ -3547,7 +4466,7 @@ bool MemberDef::hasMultiLineInitializer() const ); } -void MemberDef::setInitializer(const char *initializer) +void MemberDefImpl::setInitializer(const char *initializer) { m_impl->initializer=initializer; int l=m_impl->initializer.length(); @@ -3558,14 +4477,13 @@ void MemberDef::setInitializer(const char *initializer) //printf("%s::setInitializer(%s)\n",name().data(),m_impl->initializer.data()); } -void MemberDef::addListReference(Definition *) +void MemberDefImpl::addListReference(Definition *) { static bool optimizeOutputForC = Config_getBool(OPTIMIZE_OUTPUT_FOR_C); //static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES); //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); SrcLangExt lang = getLanguage(); - visited=TRUE; if (!isLinkableInProject()) return; QCString memLabel; if (optimizeOutputForC) @@ -3583,7 +4501,7 @@ void MemberDef::addListReference(Definition *) QCString memName = name(); Definition *pd=getOuterScope(); QCString pdName = pd->definitionType()==Definition::TypeClass ? - ((ClassDef*)pd)->displayName() : pd->name(); + (dynamic_cast<ClassDef*>(pd))->displayName() : pd->name(); QCString sep = getLanguageSpecificSeparator(lang,TRUE); QCString memArgs; if (!isRelated() @@ -3618,16 +4536,16 @@ void MemberDef::addListReference(Definition *) } } -MemberList *MemberDef::getSectionList(Definition *d) const +const MemberList *MemberDefImpl::getSectionList(const Definition *d) const { char key[20]; sprintf(key,"%p",d); return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0; } -void MemberDef::setSectionList(Definition *d, MemberList *sl) +void MemberDefImpl::setSectionList(Definition *d, MemberList *sl) { - //printf("MemberDef::setSectionList(%p,%p) name=%s\n",d,sl,name().data()); + //printf("MemberDefImpl::setSectionList(%p,%p) name=%s\n",d,sl,name().data()); char key[20]; sprintf(key,"%p",d); if (m_impl->classSectionSDict==0) @@ -3637,7 +4555,7 @@ void MemberDef::setSectionList(Definition *d, MemberList *sl) m_impl->classSectionSDict->append(key,sl); } -Specifier MemberDef::virtualness(int count) const +Specifier MemberDefImpl::virtualness(int count) const { if (count>25) { @@ -3657,7 +4575,7 @@ Specifier MemberDef::virtualness(int count) const return v; } -void MemberDef::writeTagFile(FTextStream &tagFile) +void MemberDefImpl::writeTagFile(FTextStream &tagFile) const { if (!isLinkableInProject()) return; tagFile << " <member kind=\""; @@ -3738,10 +4656,10 @@ void MemberDef::writeTagFile(FTextStream &tagFile) tagFile << " </member>" << endl; } -void MemberDef::_computeIsConstructor() +void MemberDefImpl::_computeIsConstructor() { m_isConstructorCached=1; // FALSE - if (m_impl->classDef) + if (getClassDef()) { if (m_impl->isDMember) // for D { @@ -3766,7 +4684,7 @@ void MemberDef::_computeIsConstructor() } else // for other languages { - QCString locName = m_impl->classDef->localName(); + QCString locName = getClassDef()->localName(); int i=locName.find('<'); if (i==-1) // not a template class { @@ -3781,11 +4699,11 @@ void MemberDef::_computeIsConstructor() } } -bool MemberDef::isConstructor() const +bool MemberDefImpl::isConstructor() const { if (m_isConstructorCached==0) { - MemberDef *that = (MemberDef*)this; + MemberDefImpl *that = (MemberDefImpl*)this; that->_computeIsConstructor(); } ASSERT(m_isConstructorCached>0); @@ -3793,7 +4711,7 @@ bool MemberDef::isConstructor() const } -void MemberDef::_computeIsDestructor() +void MemberDefImpl::_computeIsDestructor() { bool isDestructor; if (m_impl->isDMember) // for D @@ -3822,19 +4740,19 @@ void MemberDef::_computeIsDestructor() m_isDestructorCached = isDestructor ? 2 : 1; } -bool MemberDef::isDestructor() const +bool MemberDefImpl::isDestructor() const { if (m_isDestructorCached==0) { - MemberDef *that=(MemberDef*)this; + MemberDefImpl *that=(MemberDefImpl*)this; that->_computeIsDestructor(); } ASSERT(m_isDestructorCached>0); return m_isDestructorCached==2; } -void MemberDef::writeEnumDeclaration(OutputList &typeDecl, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd) +void MemberDefImpl::writeEnumDeclaration(OutputList &typeDecl, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd) const { int enumMemCount=0; @@ -3862,7 +4780,7 @@ void MemberDef::writeEnumDeclaration(OutputList &typeDecl, if (isLinkableInProject() || hasDocumentedEnumValues()) { //_writeTagData(compoundType); - _addToSearchIndex(); + addToSearchIndex(); writeLink(typeDecl,cd,nd,fd,gd); } else @@ -3913,7 +4831,7 @@ void MemberDef::writeEnumDeclaration(OutputList &typeDecl, if (fmd->hasDocumentation()) // enum value has docs { //fmd->_writeTagData(compoundType); - fmd->_addToSearchIndex(); + fmd->addToSearchIndex(); fmd->writeLink(typeDecl,cd,nd,fd,gd); } else // no docs for this enum value @@ -3957,19 +4875,19 @@ void MemberDef::writeEnumDeclaration(OutputList &typeDecl, } } -void MemberDef::setArgumentList(ArgumentList *al) +void MemberDefImpl::setArgumentList(ArgumentList *al) { if (m_impl->defArgList) delete m_impl->defArgList; m_impl->defArgList = al; } -void MemberDef::setDeclArgumentList(ArgumentList *al) +void MemberDefImpl::setDeclArgumentList(ArgumentList *al) { if (m_impl->declArgList) delete m_impl->declArgList; m_impl->declArgList = al; } -void MemberDef::setTypeConstraints(ArgumentList *al) +void MemberDefImpl::setTypeConstraints(ArgumentList *al) { if (al==0) return; if (m_impl->typeConstraints) delete m_impl->typeConstraints; @@ -3983,53 +4901,53 @@ void MemberDef::setTypeConstraints(ArgumentList *al) } } -void MemberDef::setType(const char *t) +void MemberDefImpl::setType(const char *t) { m_impl->type = t; } -void MemberDef::setAccessorType(ClassDef *cd,const char *t) +void MemberDefImpl::setAccessorType(ClassDef *cd,const char *t) { m_impl->accessorClass = cd; m_impl->accessorType = t; } -ClassDef *MemberDef::accessorClass() const +ClassDef *MemberDefImpl::accessorClass() const { return m_impl->accessorClass; } -void MemberDef::findSectionsInDocumentation() +void MemberDefImpl::findSectionsInDocumentation() { docFindSections(documentation(),this,0,docFile()); } -void MemberDef::enableCallGraph(bool e) +void MemberDefImpl::enableCallGraph(bool e) { m_impl->hasCallGraph=e; if (e) Doxygen::parseSourcesNeeded = TRUE; } -void MemberDef::enableCallerGraph(bool e) +void MemberDefImpl::enableCallerGraph(bool e) { m_impl->hasCallerGraph=e; if (e) Doxygen::parseSourcesNeeded = TRUE; } -void MemberDef::enableReferencedByRelation(bool e) +void MemberDefImpl::enableReferencedByRelation(bool e) { m_impl->hasReferencedByRelation=e; if (e) Doxygen::parseSourcesNeeded = TRUE; } -void MemberDef::enableReferencesRelation(bool e) +void MemberDefImpl::enableReferencesRelation(bool e) { m_impl->hasReferencesRelation=e; if (e) Doxygen::parseSourcesNeeded = TRUE; } #if 0 -bool MemberDef::protectionVisible() const +bool MemberDefImpl::protectionVisible() const { return m_impl->prot==Public || (m_impl->prot==Private && Config_getBool(EXTRACT_PRIVATE)) || @@ -4039,7 +4957,7 @@ bool MemberDef::protectionVisible() const #endif #if 0 -void MemberDef::setInbodyDocumentation(const char *docs, +void MemberDefImpl::setInbodyDocumentation(const char *docs, const char *docFile,int docLine) { m_impl->inbodyDocs = docs; @@ -4049,26 +4967,26 @@ void MemberDef::setInbodyDocumentation(const char *docs, } #endif -bool MemberDef::isObjCMethod() const +bool MemberDefImpl::isObjCMethod() const { - if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isFunction()) return TRUE; + if (getClassDef() && getClassDef()->isObjectiveC() && isFunction()) return TRUE; return FALSE; } -bool MemberDef::isObjCProperty() const +bool MemberDefImpl::isObjCProperty() const { - if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isProperty()) return TRUE; + if (getClassDef() && getClassDef()->isObjectiveC() && isProperty()) return TRUE; return FALSE; } -QCString MemberDef::qualifiedName() const +QCString MemberDefImpl::qualifiedName() const { if (isObjCMethod()) { QCString qm; if (isStatic()) qm="+"; else qm="-"; qm+="["; - qm+=m_impl->classDef->name()+" "; + qm+=getClassDef()->name()+" "; qm+=name(); qm+="]"; return qm; @@ -4081,11 +4999,11 @@ QCString MemberDef::qualifiedName() const } else { - return Definition::qualifiedName(); + return DefinitionImpl::qualifiedName(); } } -void MemberDef::setTagInfo(TagInfo *ti) +void MemberDefImpl::setTagInfo(TagInfo *ti) { if (ti) { @@ -4096,7 +5014,7 @@ void MemberDef::setTagInfo(TagInfo *ti) } } -QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const +QCString MemberDefImpl::objCMethodName(bool localLink,bool showStatic) const { QCString qm; if (showStatic) @@ -4107,461 +5025,471 @@ QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const if (!localLink) // link to method of same class { qm+=" ("; - qm+=m_impl->classDef->name(); + qm+=getClassDef()->name(); qm+=")"; } return qm; } -const char *MemberDef::declaration() const +const char *MemberDefImpl::declaration() const { return m_impl->decl; } -const char *MemberDef::definition() const +const char *MemberDefImpl::definition() const { return m_impl->def; } -const char *MemberDef::extraTypeChars() const +const char *MemberDefImpl::extraTypeChars() const { return m_impl->extraTypeChars; } -const char *MemberDef::typeString() const +const char *MemberDefImpl::typeString() const { return m_impl->type; } -const char *MemberDef::argsString() const +const char *MemberDefImpl::argsString() const { return m_impl->args; } -const char *MemberDef::excpString() const +const char *MemberDefImpl::excpString() const { return m_impl->exception; } -const char *MemberDef::bitfieldString() const +const char *MemberDefImpl::bitfieldString() const { return m_impl->bitfields; } -const QCString &MemberDef::initializer() const +const QCString &MemberDefImpl::initializer() const { return m_impl->initializer; } -int MemberDef::initializerLines() const +int MemberDefImpl::initializerLines() const { return m_impl->initLines; } -uint64 MemberDef::getMemberSpecifiers() const +uint64 MemberDefImpl::getMemberSpecifiers() const { return m_impl->memSpec; } -ClassDef *MemberDef::getClassDef() const +const ClassDef *MemberDefImpl::getClassDef() const +{ + return m_impl->classDef; +} + +ClassDef *MemberDefImpl::getClassDef() { return m_impl->classDef; } -FileDef *MemberDef::getFileDef() const +const FileDef *MemberDefImpl::getFileDef() const +{ + return m_impl->fileDef; +} + +FileDef *MemberDefImpl::getFileDef() { return m_impl->fileDef; } -NamespaceDef* MemberDef::getNamespaceDef() const +const NamespaceDef* MemberDefImpl::getNamespaceDef() const { return m_impl->nspace; } -const char *MemberDef::getReadAccessor() const +NamespaceDef* MemberDefImpl::getNamespaceDef() +{ + return m_impl->nspace; +} + +const char *MemberDefImpl::getReadAccessor() const { return m_impl->read; } -const char *MemberDef::getWriteAccessor() const +const char *MemberDefImpl::getWriteAccessor() const { return m_impl->write; } -GroupDef *MemberDef::getGroupDef() const +const GroupDef *MemberDefImpl::getGroupDef() const { return m_impl->group; } -Grouping::GroupPri_t MemberDef::getGroupPri() const +GroupDef *MemberDefImpl::getGroupDef() +{ + return m_impl->group; +} + +Grouping::GroupPri_t MemberDefImpl::getGroupPri() const { return m_impl->grouppri; } -const char *MemberDef::getGroupFileName() const +const char *MemberDefImpl::getGroupFileName() const { return m_impl->groupFileName; } -int MemberDef::getGroupStartLine() const +int MemberDefImpl::getGroupStartLine() const { return m_impl->groupStartLine; } -bool MemberDef::getGroupHasDocs() const +bool MemberDefImpl::getGroupHasDocs() const { return m_impl->groupHasDocs; } -Protection MemberDef::protection() const +Protection MemberDefImpl::protection() const { return m_impl->prot; } -MemberType MemberDef::memberType() const +MemberType MemberDefImpl::memberType() const { return m_impl->mtype; } -bool MemberDef::isSignal() const +bool MemberDefImpl::isSignal() const { return m_impl->mtype==MemberType_Signal; } -bool MemberDef::isSlot() const +bool MemberDefImpl::isSlot() const { return m_impl->mtype==MemberType_Slot; } -bool MemberDef::isVariable() const +bool MemberDefImpl::isVariable() const { return m_impl->mtype==MemberType_Variable; } -bool MemberDef::isEnumerate() const +bool MemberDefImpl::isEnumerate() const { return m_impl->mtype==MemberType_Enumeration; } -bool MemberDef::isEnumValue() const +bool MemberDefImpl::isEnumValue() const { return m_impl->mtype==MemberType_EnumValue; } -bool MemberDef::isTypedef() const +bool MemberDefImpl::isTypedef() const { return m_impl->mtype==MemberType_Typedef; } -bool MemberDef::isSequence() const +bool MemberDefImpl::isSequence() const { return m_impl->mtype==MemberType_Sequence; } -bool MemberDef::isDictionary() const +bool MemberDefImpl::isDictionary() const { return m_impl->mtype==MemberType_Dictionary; } -bool MemberDef::isFunction() const +bool MemberDefImpl::isFunction() const { return m_impl->mtype==MemberType_Function; } -bool MemberDef::isFunctionPtr() const +bool MemberDefImpl::isFunctionPtr() const { return m_impl->mtype==MemberType_Variable && QCString(argsString()).find(")(")!=-1; } -bool MemberDef::isDefine() const +bool MemberDefImpl::isDefine() const { return m_impl->mtype==MemberType_Define; } -bool MemberDef::isFriend() const +bool MemberDefImpl::isFriend() const { return m_impl->mtype==MemberType_Friend; } -bool MemberDef::isDCOP() const +bool MemberDefImpl::isDCOP() const { return m_impl->mtype==MemberType_DCOP; } -bool MemberDef::isProperty() const +bool MemberDefImpl::isProperty() const { return m_impl->mtype==MemberType_Property; } -bool MemberDef::isEvent() const +bool MemberDefImpl::isEvent() const { return m_impl->mtype==MemberType_Event; } -bool MemberDef::isRelated() const +bool MemberDefImpl::isRelated() const { return m_impl->related == Related; } -bool MemberDef::isForeign() const +bool MemberDefImpl::isForeign() const { return m_impl->related == Foreign; } -bool MemberDef::isStatic() const +bool MemberDefImpl::isStatic() const { return m_impl->stat; } -bool MemberDef::isInline() const +bool MemberDefImpl::isInline() const { return (m_impl->memSpec&Entry::Inline)!=0; } -bool MemberDef::isExplicit() const +bool MemberDefImpl::isExplicit() const { return (m_impl->memSpec&Entry::Explicit)!=0; } -bool MemberDef::isMutable() const +bool MemberDefImpl::isMutable() const { return (m_impl->memSpec&Entry::Mutable)!=0; } -bool MemberDef::isGettable() const +bool MemberDefImpl::isGettable() const { return (m_impl->memSpec&Entry::Gettable)!=0; } -bool MemberDef::isPrivateGettable() const +bool MemberDefImpl::isPrivateGettable() const { return (m_impl->memSpec&Entry::PrivateGettable)!=0; } -bool MemberDef::isProtectedGettable() const +bool MemberDefImpl::isProtectedGettable() const { return (m_impl->memSpec&Entry::ProtectedGettable)!=0; } -bool MemberDef::isSettable() const +bool MemberDefImpl::isSettable() const { return (m_impl->memSpec&Entry::Settable)!=0; } -bool MemberDef::isPrivateSettable() const +bool MemberDefImpl::isPrivateSettable() const { return (m_impl->memSpec&Entry::PrivateSettable)!=0; } -bool MemberDef::isProtectedSettable() const +bool MemberDefImpl::isProtectedSettable() const { return (m_impl->memSpec&Entry::ProtectedSettable)!=0; } -bool MemberDef::isAddable() const +bool MemberDefImpl::isAddable() const { return (m_impl->memSpec&Entry::Addable)!=0; } -bool MemberDef::isRemovable() const +bool MemberDefImpl::isRemovable() const { return (m_impl->memSpec&Entry::Removable)!=0; } -bool MemberDef::isRaisable() const +bool MemberDefImpl::isRaisable() const { return (m_impl->memSpec&Entry::Raisable)!=0; } -bool MemberDef::isReadable() const +bool MemberDefImpl::isReadable() const { return (m_impl->memSpec&Entry::Readable)!=0; } -bool MemberDef::isWritable() const +bool MemberDefImpl::isWritable() const { return (m_impl->memSpec&Entry::Writable)!=0; } -bool MemberDef::isFinal() const +bool MemberDefImpl::isFinal() const { return (m_impl->memSpec&Entry::Final)!=0; } -bool MemberDef::isNew() const +bool MemberDefImpl::isNew() const { return (m_impl->memSpec&Entry::New)!=0; } -bool MemberDef::isSealed() const +bool MemberDefImpl::isSealed() const { return (m_impl->memSpec&Entry::Sealed)!=0; } -bool MemberDef::isOverride() const +bool MemberDefImpl::isOverride() const { return (m_impl->memSpec&Entry::Override)!=0; } -bool MemberDef::isInitonly() const +bool MemberDefImpl::isInitonly() const { return (m_impl->memSpec&Entry::Initonly)!=0; } -bool MemberDef::isAbstract() const +bool MemberDefImpl::isAbstract() const { return (m_impl->memSpec&Entry::Abstract)!=0; } -bool MemberDef::isOptional() const +bool MemberDefImpl::isOptional() const { return (m_impl->memSpec&Entry::Optional)!=0; } -bool MemberDef::isRequired() const +bool MemberDefImpl::isRequired() const { return (m_impl->memSpec&Entry::Required)!=0; } -bool MemberDef::isNonAtomic() const +bool MemberDefImpl::isNonAtomic() const { return (m_impl->memSpec&Entry::NonAtomic)!=0; } -bool MemberDef::isCopy() const +bool MemberDefImpl::isCopy() const { return (m_impl->memSpec&Entry::Copy)!=0; } -bool MemberDef::isAssign() const +bool MemberDefImpl::isAssign() const { return (m_impl->memSpec&Entry::Assign)!=0; } -bool MemberDef::isRetain() const +bool MemberDefImpl::isRetain() const { return (m_impl->memSpec&Entry::Retain)!=0; } -bool MemberDef::isWeak() const +bool MemberDefImpl::isWeak() const { return (m_impl->memSpec&Entry::Weak)!=0; } -bool MemberDef::isStrong() const +bool MemberDefImpl::isStrong() const { return (m_impl->memSpec&Entry::Strong)!=0; } -bool MemberDef::isStrongEnumValue() const +bool MemberDefImpl::isStrongEnumValue() const { return m_impl->mtype==MemberType_EnumValue && m_impl->enumScope && m_impl->enumScope->isStrong(); } -bool MemberDef::isUnretained() const +bool MemberDefImpl::isUnretained() const { return (m_impl->memSpec&Entry::Unretained)!=0; } -bool MemberDef::isAlias() const +bool MemberDefImpl::isTypeAlias() const { return (m_impl->memSpec&Entry::Alias)!=0; } -bool MemberDef::isDefault() const +bool MemberDefImpl::isDefault() const { return (m_impl->memSpec&Entry::Default)!=0; } -bool MemberDef::isDelete() const +bool MemberDefImpl::isDelete() const { return (m_impl->memSpec&Entry::Delete)!=0; } -bool MemberDef::isNoExcept() const +bool MemberDefImpl::isNoExcept() const { return (m_impl->memSpec&Entry::NoExcept)!=0; } -bool MemberDef::isAttribute() const +bool MemberDefImpl::isAttribute() const { return (m_impl->memSpec&Entry::Attribute)!=0; } -bool MemberDef::isUNOProperty() const +bool MemberDefImpl::isUNOProperty() const { return (m_impl->memSpec&Entry::Property)!=0; } -bool MemberDef::isReadonly() const +bool MemberDefImpl::isReadonly() const { return (m_impl->memSpec&Entry::Readonly)!=0; } -bool MemberDef::isBound() const +bool MemberDefImpl::isBound() const { return (m_impl->memSpec&Entry::Bound)!=0; } -bool MemberDef::isConstrained() const +bool MemberDefImpl::isConstrained() const { return (m_impl->memSpec&Entry::Constrained)!=0; } -bool MemberDef::isTransient() const +bool MemberDefImpl::isTransient() const { return (m_impl->memSpec&Entry::Transient)!=0; } -bool MemberDef::isMaybeVoid() const +bool MemberDefImpl::isMaybeVoid() const { return (m_impl->memSpec&Entry::MaybeVoid)!=0; } -bool MemberDef::isMaybeDefault() const +bool MemberDefImpl::isMaybeDefault() const { return (m_impl->memSpec&Entry::MaybeDefault)!=0; } -bool MemberDef::isMaybeAmbiguous() const +bool MemberDefImpl::isMaybeAmbiguous() const { return (m_impl->memSpec&Entry::MaybeAmbiguous)!=0; } -bool MemberDef::isPublished() const +bool MemberDefImpl::isPublished() const { return (m_impl->memSpec&Entry::Published)!=0; } -bool MemberDef::isImplementation() const +bool MemberDefImpl::isImplementation() const { return m_impl->implOnly; } -bool MemberDef::isExternal() const +bool MemberDefImpl::isExternal() const { return m_impl->explExt; } -bool MemberDef::isTemplateSpecialization() const +bool MemberDefImpl::isTemplateSpecialization() const { return m_impl->tspec; } -bool MemberDef::hasDocumentedParams() const -{ - return m_impl->hasDocumentedParams; -} - -bool MemberDef::hasDocumentedReturnType() const -{ - return m_impl->hasDocumentedReturnType; -} - -bool MemberDef::showInCallGraph() const +bool MemberDefImpl::showInCallGraph() const { return isFunction() || isSlot() || @@ -4570,179 +5498,207 @@ bool MemberDef::showInCallGraph() const isObjCMethod(); } -ClassDef *MemberDef::relatedAlso() const +ClassDef *MemberDefImpl::relatedAlso() const { return m_impl->relatedAlso; } -bool MemberDef::hasDocumentedEnumValues() const +bool MemberDefImpl::hasDocumentedEnumValues() const { return m_impl->docEnumValues; } -MemberDef *MemberDef::getAnonymousEnumType() const +const MemberDef *MemberDefImpl::getAnonymousEnumType() const { return m_impl->annEnumType; } -bool MemberDef::isDocsForDefinition() const +bool MemberDefImpl::isDocsForDefinition() const { return m_impl->docsForDefinition; } -MemberDef *MemberDef::getEnumScope() const +const MemberDef *MemberDefImpl::getEnumScope() const { return m_impl->enumScope; } -bool MemberDef::livesInsideEnum() const +bool MemberDefImpl::livesInsideEnum() const { return m_impl->livesInsideEnum; } -bool MemberDef::isSliceLocal() const +bool MemberDefImpl::isSliceLocal() const { return (m_impl->memSpec&Entry::Local)!=0; } -MemberList *MemberDef::enumFieldList() const +bool MemberDefImpl::isConstExpr() const +{ + return (m_impl->memSpec&Entry::ConstExpr)!=0; +} + +const MemberList *MemberDefImpl::enumFieldList() const { return m_impl->enumFields; } -ExampleSDict *MemberDef::getExamples() const +ExampleSDict *MemberDefImpl::getExamples() const { return m_impl->exampleSDict; } -bool MemberDef::isPrototype() const +bool MemberDefImpl::isPrototype() const { return m_impl->proto; } -ArgumentList *MemberDef::argumentList() const +const ArgumentList *MemberDefImpl::argumentList() const { return m_impl->defArgList; } -ArgumentList *MemberDef::declArgumentList() const +ArgumentList *MemberDefImpl::argumentList() +{ + return m_impl->defArgList; +} + +const ArgumentList *MemberDefImpl::declArgumentList() const { return m_impl->declArgList; } -ArgumentList *MemberDef::templateArguments() const +const ArgumentList *MemberDefImpl::templateArguments() const { return m_impl->tArgList; } -QList<ArgumentList> *MemberDef::definitionTemplateParameterLists() const +const QList<ArgumentList> *MemberDefImpl::definitionTemplateParameterLists() const { return m_impl->defTmpArgLists; } -int MemberDef::getMemberGroupId() const +int MemberDefImpl::getMemberGroupId() const { return m_impl->grpId; } -MemberGroup *MemberDef::getMemberGroup() const +MemberGroup *MemberDefImpl::getMemberGroup() const { return m_impl->memberGroup; } -bool MemberDef::fromAnonymousScope() const +bool MemberDefImpl::fromAnonymousScope() const { return m_impl->annScope; } -bool MemberDef::anonymousDeclShown() const +bool MemberDefImpl::anonymousDeclShown() const { return m_impl->annUsed; } -void MemberDef::setAnonymousUsed() +void MemberDefImpl::setAnonymousUsed() const { m_impl->annUsed = TRUE; } -bool MemberDef::hasCallGraph() const +bool MemberDefImpl::hasCallGraph() const { return m_impl->hasCallGraph; } -bool MemberDef::hasCallerGraph() const +bool MemberDefImpl::hasCallerGraph() const { return m_impl->hasCallerGraph; } -bool MemberDef::hasReferencedByRelation() const +bool MemberDefImpl::hasReferencedByRelation() const { return m_impl->hasReferencedByRelation; } -bool MemberDef::hasReferencesRelation() const +bool MemberDefImpl::hasReferencesRelation() const { return m_impl->hasReferencesRelation; } -MemberDef *MemberDef::templateMaster() const +MemberDef *MemberDefImpl::templateMaster() const { return m_impl->templateMaster; } -bool MemberDef::isTypedefValCached() const +bool MemberDefImpl::isTypedefValCached() const { return m_impl->isTypedefValCached; } -ClassDef *MemberDef::getCachedTypedefVal() const +const ClassDef *MemberDefImpl::getCachedTypedefVal() const { return m_impl->cachedTypedefValue; } -QCString MemberDef::getCachedTypedefTemplSpec() const +QCString MemberDefImpl::getCachedTypedefTemplSpec() const { return m_impl->cachedTypedefTemplSpec; } -QCString MemberDef::getCachedResolvedTypedef() const +QCString MemberDefImpl::getCachedResolvedTypedef() const { - //printf("MemberDef::getCachedResolvedTypedef()=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl); + //printf("MemberDefImpl::getCachedResolvedTypedef()=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl); return m_impl->cachedResolvedType; } -MemberDef *MemberDef::memberDefinition() const +MemberDef *MemberDefImpl::memberDefinition() const { return m_impl->memDef; } -MemberDef *MemberDef::memberDeclaration() const +MemberDef *MemberDefImpl::memberDeclaration() const { return m_impl->memDec; } -MemberDef *MemberDef::inheritsDocsFrom() const +MemberDef *MemberDefImpl::inheritsDocsFrom() const { return m_impl->docProvider; } -MemberDef *MemberDef::getGroupAlias() const +const MemberDef *MemberDefImpl::getGroupAlias() const { return m_impl->groupAlias; } -void MemberDef::setMemberType(MemberType t) +QCString MemberDefImpl::getDeclFileName() const +{ + return m_impl->declFileName; +} + +int MemberDefImpl::getDeclLine() const +{ + return m_impl->declLine; +} + +int MemberDefImpl::getDeclColumn() const +{ + return m_impl->declColumn; +} + + +//---------------------------------------------- + +void MemberDefImpl::setMemberType(MemberType t) { m_impl->mtype=t; m_isLinkableCached = 0; } -void MemberDef::setDefinition(const char *d) +void MemberDefImpl::setDefinition(const char *d) { m_impl->def=d; } -void MemberDef::setFileDef(FileDef *fd) +void MemberDefImpl::setFileDef(FileDef *fd) { m_impl->fileDef=fd; m_isLinkableCached = 0; @@ -4750,28 +5706,28 @@ void MemberDef::setFileDef(FileDef *fd) m_isDestructorCached = 0; } -void MemberDef::setProtection(Protection p) +void MemberDefImpl::setProtection(Protection p) { m_impl->prot=p; m_isLinkableCached = 0; } -void MemberDef::setMemberSpecifiers(uint64 s) +void MemberDefImpl::setMemberSpecifiers(uint64 s) { m_impl->memSpec=s; } -void MemberDef::mergeMemberSpecifiers(uint64 s) +void MemberDefImpl::mergeMemberSpecifiers(uint64 s) { m_impl->memSpec|=s; } -void MemberDef::setBitfields(const char *s) +void MemberDefImpl::setBitfields(const char *s) { m_impl->bitfields = QCString(s).simplifyWhiteSpace(); } -void MemberDef::setMaxInitLines(int lines) +void MemberDefImpl::setMaxInitLines(int lines) { if (lines!=-1) { @@ -4779,206 +5735,224 @@ void MemberDef::setMaxInitLines(int lines) } } -void MemberDef::setExplicitExternal(bool b) -{ - m_impl->explExt=b; -} - -void MemberDef::setReadAccessor(const char *r) +void MemberDefImpl::setReadAccessor(const char *r) { m_impl->read=r; } -void MemberDef::setWriteAccessor(const char *w) +void MemberDefImpl::setWriteAccessor(const char *w) { m_impl->write=w; } -void MemberDef::setTemplateSpecialization(bool b) +void MemberDefImpl::setTemplateSpecialization(bool b) { m_impl->tspec=b; } -void MemberDef::makeRelated() +void MemberDefImpl::makeRelated() { m_impl->related = Related; m_isLinkableCached = 0; } -void MemberDef::makeForeign() +void MemberDefImpl::makeForeign() { m_impl->related = Foreign; m_isLinkableCached = 0; } -void MemberDef::setHasDocumentedParams(bool b) -{ - m_impl->hasDocumentedParams = b; -} - -void MemberDef::setHasDocumentedReturnType(bool b) -{ - m_impl->hasDocumentedReturnType = b; -} - -void MemberDef::setInheritsDocsFrom(MemberDef *md) +void MemberDefImpl::setInheritsDocsFrom(MemberDef *md) { m_impl->docProvider = md; } -void MemberDef::setArgsString(const char *as) +void MemberDefImpl::setArgsString(const char *as) { m_impl->args = as; } -void MemberDef::setRelatedAlso(ClassDef *cd) +void MemberDefImpl::setRelatedAlso(ClassDef *cd) { m_impl->relatedAlso=cd; } -void MemberDef::setEnumClassScope(ClassDef *cd) +void MemberDefImpl::setEnumClassScope(ClassDef *cd) { m_impl->classDef = cd; m_isLinkableCached = 0; m_isConstructorCached = 0; } -void MemberDef::setDocumentedEnumValues(bool value) +void MemberDefImpl::setDocumentedEnumValues(bool value) { m_impl->docEnumValues=value; } -void MemberDef::setAnonymousEnumType(MemberDef *md) +void MemberDefImpl::setAnonymousEnumType(const MemberDef *md) { m_impl->annEnumType = md; } -void MemberDef::setPrototype(bool p) +void MemberDefImpl::setPrototype(bool p,const QCString &df,int line,int column) { m_impl->proto=p; + if (p) + { + setDeclFile(df,line,column); + } + else + { + setDefFile(df,line,column); + } } -void MemberDef::setMemberGroupId(int id) +void MemberDefImpl::setExplicitExternal(bool b,const QCString &df,int line,int column) +{ + m_impl->explExt=b; + if (b) + { + setDeclFile(df,line,column); + } + else + { + setDefFile(df,line,column); + } +} + + +void MemberDefImpl::setDeclFile(const QCString &df,int line,int column) +{ + m_impl->declFileName = df; + m_impl->declLine = line; + m_impl->declColumn = column; +} + +void MemberDefImpl::setMemberGroupId(int id) { m_impl->grpId=id; } -void MemberDef::makeImplementationDetail() +void MemberDefImpl::makeImplementationDetail() { m_impl->implOnly=TRUE; } -void MemberDef::setFromAnonymousScope(bool b) +void MemberDefImpl::setFromAnonymousScope(bool b) const { m_impl->annScope=b; } -void MemberDef::setFromAnonymousMember(MemberDef *m) +void MemberDefImpl::setFromAnonymousMember(MemberDef *m) { m_impl->annMemb=m; } -MemberDef *MemberDef::fromAnonymousMember() const +MemberDef *MemberDefImpl::fromAnonymousMember() const { return m_impl->annMemb; } -void MemberDef::setTemplateMaster(MemberDef *mt) +void MemberDefImpl::setTemplateMaster(MemberDef *mt) { m_impl->templateMaster=mt; m_isLinkableCached = 0; } -void MemberDef::setDocsForDefinition(bool b) +void MemberDefImpl::setDocsForDefinition(bool b) { m_impl->docsForDefinition = b; } -void MemberDef::setGroupAlias(MemberDef *md) +void MemberDefImpl::setGroupAlias(const MemberDef *md) { m_impl->groupAlias = md; } -void MemberDef::invalidateTypedefValCache() +void MemberDefImpl::invalidateTypedefValCache() { m_impl->isTypedefValCached=FALSE; } -void MemberDef::setMemberDefinition(MemberDef *md) +void MemberDefImpl::setMemberDefinition(MemberDef *md) { m_impl->memDef=md; } -void MemberDef::setMemberDeclaration(MemberDef *md) +void MemberDefImpl::setMemberDeclaration(MemberDef *md) { m_impl->memDec=md; } -ClassDef *MemberDef::category() const +ClassDef *MemberDefImpl::category() const { return m_impl->category; } -void MemberDef::setCategory(ClassDef *def) +void MemberDefImpl::setCategory(ClassDef *def) { m_impl->category = def; } -MemberDef *MemberDef::categoryRelation() const +MemberDef *MemberDefImpl::categoryRelation() const { return m_impl->categoryRelation; } -void MemberDef::setCategoryRelation(MemberDef *md) +void MemberDefImpl::setCategoryRelation(MemberDef *md) { m_impl->categoryRelation = md; } -void MemberDef::setEnumBaseType(const QCString &type) +void MemberDefImpl::setEnumBaseType(const QCString &type) { m_impl->enumBaseType = type; } -QCString MemberDef::enumBaseType() const +QCString MemberDefImpl::enumBaseType() const { return m_impl->enumBaseType; } -void MemberDef::cacheTypedefVal(ClassDef*val, const QCString & templSpec, const QCString &resolvedType) +void MemberDefImpl::cacheTypedefVal(const ClassDef*val, const QCString & templSpec, const QCString &resolvedType) { m_impl->isTypedefValCached=TRUE; m_impl->cachedTypedefValue=val; m_impl->cachedTypedefTemplSpec=templSpec; m_impl->cachedResolvedType=resolvedType; - //printf("MemberDef::cacheTypedefVal=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl); + //printf("MemberDefImpl::cacheTypedefVal=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl); } -void MemberDef::copyArgumentNames(MemberDef *bmd) +void MemberDefImpl::copyArgumentNames(MemberDef *bmd) { { - ArgumentList *arguments = bmd->argumentList(); + const ArgumentList *arguments = bmd->argumentList(); if (m_impl->defArgList && arguments) { ArgumentListIterator aliDst(*m_impl->defArgList); ArgumentListIterator aliSrc(*arguments); - Argument *argDst, *argSrc; + Argument *argDst; + const Argument *argSrc; for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc) { argDst->name = argSrc->name; + argDst->docs = argSrc->docs; } } } { - ArgumentList *arguments = bmd->declArgumentList(); + const ArgumentList *arguments = bmd->declArgumentList(); if (m_impl->declArgList && arguments) { ArgumentListIterator aliDst(*m_impl->declArgList); ArgumentListIterator aliSrc(*arguments); - Argument *argDst, *argSrc; + Argument *argDst; + const Argument *argSrc; for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc) { argDst->name = argSrc->name; + argDst->docs = argSrc->docs; } } } @@ -4997,30 +5971,30 @@ static void invalidateCachedTypesInArgumentList(ArgumentList *al) } } -void MemberDef::invalidateCachedArgumentTypes() +void MemberDefImpl::invalidateCachedArgumentTypes() { invalidateCachedTypesInArgumentList(m_impl->defArgList); invalidateCachedTypesInArgumentList(m_impl->declArgList); } -void MemberDef::addFlowKeyWord() +void MemberDefImpl::incrementFlowKeyWordCount() { - number_of_flowkw++; + m_impl->numberOfFlowKW++; } -int MemberDef::numberOfFlowKeyWords() +int MemberDefImpl::numberOfFlowKeyWords() const { - return number_of_flowkw; + return m_impl->numberOfFlowKW; } //---------------- -QCString MemberDef::displayName(bool) const +QCString MemberDefImpl::displayName(bool) const { - return Definition::name(); + return DefinitionImpl::name(); } -void MemberDef::_addToSearchIndex() +void MemberDefImpl::addToSearchIndex() const { // write search index info if (Doxygen::searchIndex && isLinkableInProject()) @@ -5086,15 +6060,17 @@ void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef) // mdef, mdef ? mdef->name().data() : "", // mdec, mdec ? mdec->name().data() : ""); + const MemberDef *cmdec = const_cast<const MemberDef*>(mdec); + const MemberDef *cmdef = const_cast<const MemberDef*>(mdef); ArgumentList *mdefAl = mdef->argumentList(); ArgumentList *mdecAl = mdec->argumentList(); - if (matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdefAl, - mdec->getOuterScope(),mdec->getFileDef(),mdecAl, - TRUE - ) + if (matchArguments2(cmdef->getOuterScope(),cmdef->getFileDef(),mdefAl, + cmdec->getOuterScope(),cmdec->getFileDef(),mdecAl, + TRUE + ) ) /* match found */ { - //printf("Found member %s: definition in %s (doc=`%s') and declaration in %s (doc=`%s')\n", + //printf("Found member %s: definition in %s (doc='%s') and declaration in %s (doc='%s')\n", // mn->memberName(), // mdef->getFileDef()->name().data(),mdef->documentation().data(), // mdec->getFileDef()->name().data(),mdec->documentation().data() @@ -5199,14 +6175,14 @@ void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef) mdec->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph()); mdef->enableReferencedByRelation(mdec->hasReferencedByRelation() || mdef->hasReferencedByRelation()); - mdef->enableCallerGraph(mdec->hasReferencesRelation() || mdef->hasReferencesRelation()); + mdef->enableReferencesRelation(mdec->hasReferencesRelation() || mdef->hasReferencesRelation()); mdec->enableReferencedByRelation(mdec->hasReferencedByRelation() || mdef->hasReferencedByRelation()); - mdec->enableCallerGraph(mdec->hasReferencesRelation() || mdef->hasReferencesRelation()); + mdec->enableReferencesRelation(mdec->hasReferencesRelation() || mdef->hasReferencesRelation()); } } } -QCString MemberDef::briefDescription(bool abbr) const +QCString MemberDefImpl::briefDescription(bool abbr) const { if (m_impl->templateMaster) { @@ -5214,11 +6190,11 @@ QCString MemberDef::briefDescription(bool abbr) const } else { - return Definition::briefDescription(abbr); + return DefinitionImpl::briefDescription(abbr); } } -QCString MemberDef::documentation() const +QCString MemberDefImpl::documentation() const { if (m_impl->templateMaster) { @@ -5226,16 +6202,16 @@ QCString MemberDef::documentation() const } else { - return Definition::documentation(); + return DefinitionImpl::documentation(); } } -const ArgumentList *MemberDef::typeConstraints() const +const ArgumentList *MemberDefImpl::typeConstraints() const { return m_impl->typeConstraints; } -bool MemberDef::isFriendToHide() const +bool MemberDefImpl::isFriendToHide() const { static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS); bool isFriendToHide = hideFriendCompounds && @@ -5245,24 +6221,24 @@ bool MemberDef::isFriendToHide() const return isFriendToHide; } -bool MemberDef::isNotFriend() const +bool MemberDefImpl::isNotFriend() const { return !(isFriend() && isFriendToHide()); } -bool MemberDef::isFunctionOrSignalSlot() const +bool MemberDefImpl::isFunctionOrSignalSlot() const { return isFunction() || isSlot() || isSignal(); } -bool MemberDef::isRelatedOrFriend() const +bool MemberDefImpl::isRelatedOrFriend() const { return isRelated() || isForeign() || (isFriend() && !isFriendToHide()); } -bool MemberDef::isReference() const +bool MemberDefImpl::isReference() const { - return Definition::isReference() || + return DefinitionImpl::isReference() || (m_impl->templateMaster && m_impl->templateMaster->isReference()); } diff --git a/src/memberdef.h b/src/memberdef.h index 2c88438..c81af80 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -35,424 +35,397 @@ class OutputList; class GroupDef; class QTextStream; class ArgumentList; -class MemberDefImpl; class QStrList; struct TagInfo; /** A model of a class/file/namespace member symbol. */ -class MemberDef : public Definition +class MemberDef : virtual public Definition { public: - - MemberDef(const char *defFileName,int defLine,int defColumn, - const char *type,const char *name,const char *args, - const char *excp,Protection prot,Specifier virt,bool stat, - Relationship related,MemberType t,const ArgumentList *tal, - const ArgumentList *al,const char *metaData); - ~MemberDef(); - DefType definitionType() const { return TypeMember; } + virtual ~MemberDef() {} + virtual DefType definitionType() const = 0; // move this member into a different scope - MemberDef *deepCopy() const; - void moveTo(Definition *); + virtual MemberDef *deepCopy() const =0; + virtual void moveTo(Definition *) = 0; + + virtual MemberDef *resolveAlias() = 0; + virtual const MemberDef *resolveAlias() const = 0; //----------------------------------------------------------------------------------- // ---- getters ----- //----------------------------------------------------------------------------------- // link id - QCString getOutputFileBase() const; - QCString getReference() const; - QCString anchor() const; - - const char *declaration() const; - const char *definition() const; - const char *typeString() const; - const char *argsString() const; - const char *excpString() const; - const char *bitfieldString() const; - const char *extraTypeChars() const; - const QCString &initializer() const; - int initializerLines() const; - uint64 getMemberSpecifiers() const; - MemberList *getSectionList(Definition *d) const; - QCString displayDefinition() const; + virtual QCString getOutputFileBase() const = 0; + virtual QCString getReference() const = 0; + virtual QCString anchor() const = 0; + + virtual const char *declaration() const = 0; + virtual const char *definition() const = 0; + virtual const char *typeString() const = 0; + virtual const char *argsString() const = 0; + virtual const char *excpString() const = 0; + virtual const char *bitfieldString() const = 0; + virtual const char *extraTypeChars() const = 0; + virtual const QCString &initializer() const = 0; + virtual int initializerLines() const = 0; + virtual uint64 getMemberSpecifiers() const = 0; + virtual const MemberList *getSectionList(const Definition *d) const = 0; + virtual QCString displayDefinition() const = 0; // scope query members - ClassDef *getClassDef() const; - FileDef *getFileDef() const; - NamespaceDef* getNamespaceDef() const; - ClassDef *accessorClass() const; + virtual const ClassDef *getClassDef() const = 0; + virtual ClassDef *getClassDef() = 0; + + virtual const FileDef *getFileDef() const = 0; + virtual FileDef *getFileDef() = 0; + + virtual const NamespaceDef* getNamespaceDef() const = 0; + virtual NamespaceDef* getNamespaceDef() = 0; + + virtual const GroupDef *getGroupDef() const = 0; + virtual GroupDef *getGroupDef() = 0; + + virtual ClassDef *accessorClass() const = 0; // grabbing the property read/write accessor names - const char *getReadAccessor() const; - const char *getWriteAccessor() const; + virtual const char *getReadAccessor() const = 0; + virtual const char *getWriteAccessor() const = 0; // querying the grouping definition - GroupDef *getGroupDef() const; - Grouping::GroupPri_t getGroupPri() const; - const char *getGroupFileName() const; - int getGroupStartLine() const; - bool getGroupHasDocs() const; - QCString qualifiedName() const; - QCString objCMethodName(bool localLink,bool showStatic) const; + virtual Grouping::GroupPri_t getGroupPri() const = 0; + virtual const char *getGroupFileName() const = 0; + virtual int getGroupStartLine() const = 0; + virtual bool getGroupHasDocs() const = 0; + virtual QCString qualifiedName() const = 0; + virtual QCString objCMethodName(bool localLink,bool showStatic) const = 0; // direct kind info - Protection protection() const; - Specifier virtualness(int count=0) const; - MemberType memberType() const; - QCString memberTypeName() const; + virtual Protection protection() const = 0; + virtual Specifier virtualness(int count=0) const = 0; + virtual MemberType memberType() const = 0; + virtual QCString memberTypeName() const = 0; // getter methods - bool isSignal() const; - bool isSlot() const; - bool isVariable() const; - bool isEnumerate() const; - bool isEnumValue() const; - bool isTypedef() const; - bool isSequence() const; - bool isDictionary() const; - bool isFunction() const; - bool isFunctionPtr() const; - bool isDefine() const; - bool isFriend() const; - bool isDCOP() const; - bool isProperty() const; - bool isEvent() const; - bool isRelated() const; - bool isForeign() const; - bool isStatic() const; - bool isInline() const; - bool isExplicit() const; - bool isMutable() const; - bool isGettable() const; - bool isPrivateGettable() const; - bool isProtectedGettable() const; - bool isSettable() const; - bool isPrivateSettable() const; - bool isProtectedSettable() const; - bool isReadable() const; - bool isWritable() const; - bool isAddable() const; - bool isRemovable() const; - bool isRaisable() const; - bool isFinal() const; - bool isAbstract() const; - bool isOverride() const; - bool isInitonly() const; - bool isOptional() const; - bool isRequired() const; - bool isNonAtomic() const; - bool isCopy() const; - bool isAssign() const; - bool isRetain() const; - bool isWeak() const; - bool isStrong() const; - bool isUnretained() const; - bool isNew() const; - bool isSealed() const; - bool isImplementation() const; - bool isExternal() const; - bool isAlias() const; - bool isDefault() const; - bool isDelete() const; - bool isNoExcept() const; - bool isAttribute() const; // UNO IDL attribute - bool isUNOProperty() const; // UNO IDL property - bool isReadonly() const; - bool isBound() const; - bool isConstrained() const; - bool isTransient() const; - bool isMaybeVoid() const; - bool isMaybeDefault() const; - bool isMaybeAmbiguous() const; - bool isPublished() const; // UNO IDL published - bool isTemplateSpecialization() const; - bool hasDocumentedParams() const; - bool hasDocumentedReturnType() const; - bool isObjCMethod() const; - bool isObjCProperty() const; - bool isConstructor() const; - bool isDestructor() const; - bool hasOneLineInitializer() const; - bool hasMultiLineInitializer() const; - bool protectionVisible() const; - bool showInCallGraph() const; - bool isStrongEnumValue() const; - bool livesInsideEnum() const; - bool isSliceLocal() const; - - int numberOfFlowKeyWords(); + virtual bool isSignal() const = 0; + virtual bool isSlot() const = 0; + virtual bool isVariable() const = 0; + virtual bool isEnumerate() const = 0; + virtual bool isEnumValue() const = 0; + virtual bool isTypedef() const = 0; + virtual bool isSequence() const = 0; + virtual bool isDictionary() const = 0; + virtual bool isFunction() const = 0; + virtual bool isFunctionPtr() const = 0; + virtual bool isDefine() const = 0; + virtual bool isFriend() const = 0; + virtual bool isDCOP() const = 0; + virtual bool isProperty() const = 0; + virtual bool isEvent() const = 0; + virtual bool isRelated() const = 0; + virtual bool isForeign() const = 0; + virtual bool isStatic() const = 0; + virtual bool isInline() const = 0; + virtual bool isExplicit() const = 0; + virtual bool isMutable() const = 0; + virtual bool isGettable() const = 0; + virtual bool isPrivateGettable() const = 0; + virtual bool isProtectedGettable() const = 0; + virtual bool isSettable() const = 0; + virtual bool isPrivateSettable() const = 0; + virtual bool isProtectedSettable() const = 0; + virtual bool isReadable() const = 0; + virtual bool isWritable() const = 0; + virtual bool isAddable() const = 0; + virtual bool isRemovable() const = 0; + virtual bool isRaisable() const = 0; + virtual bool isFinal() const = 0; + virtual bool isAbstract() const = 0; + virtual bool isOverride() const = 0; + virtual bool isInitonly() const = 0; + virtual bool isOptional() const = 0; + virtual bool isRequired() const = 0; + virtual bool isNonAtomic() const = 0; + virtual bool isCopy() const = 0; + virtual bool isAssign() const = 0; + virtual bool isRetain() const = 0; + virtual bool isWeak() const = 0; + virtual bool isStrong() const = 0; + virtual bool isUnretained() const = 0; + virtual bool isNew() const = 0; + virtual bool isSealed() const = 0; + virtual bool isImplementation() const = 0; + virtual bool isExternal() const = 0; + virtual bool isTypeAlias() const = 0; + virtual bool isDefault() const = 0; + virtual bool isDelete() const = 0; + virtual bool isNoExcept() const = 0; + virtual bool isAttribute() const = 0; // UNO IDL attribute + virtual bool isUNOProperty() const = 0; // UNO IDL property + virtual bool isReadonly() const = 0; + virtual bool isBound() const = 0; + virtual bool isConstrained() const = 0; + virtual bool isTransient() const = 0; + virtual bool isMaybeVoid() const = 0; + virtual bool isMaybeDefault() const = 0; + virtual bool isMaybeAmbiguous() const = 0; + virtual bool isPublished() const = 0; // UNO IDL published + virtual bool isTemplateSpecialization() const = 0; + virtual bool isObjCMethod() const = 0; + virtual bool isObjCProperty() const = 0; + virtual bool isConstructor() const = 0; + virtual bool isDestructor() const = 0; + virtual bool hasOneLineInitializer() const = 0; + virtual bool hasMultiLineInitializer() const = 0; + virtual bool showInCallGraph() const = 0; + virtual bool isStrongEnumValue() const = 0; + virtual bool livesInsideEnum() const = 0; + virtual bool isSliceLocal() const = 0; + virtual bool isConstExpr() const = 0; + virtual int numberOfFlowKeyWords() const = 0; + // derived getters - bool isFriendToHide() const; - bool isNotFriend() const; - bool isFunctionOrSignalSlot() const; - bool isRelatedOrFriend() const; + virtual bool isFriendToHide() const = 0; + virtual bool isNotFriend() const = 0; + virtual bool isFunctionOrSignalSlot() const = 0; + virtual bool isRelatedOrFriend() const = 0; // output info - bool isLinkableInProject() const; - bool isLinkable() const; - bool hasDocumentation() const; // overrides hasDocumentation in definition.h - //bool hasUserDocumentation() const; // overrides hasUserDocumentation - bool isDeleted() const; - bool isBriefSectionVisible() const; - bool isDetailedSectionVisible(bool inGroup,bool inFile) const; - bool isDetailedSectionLinkable() const; - bool isFriendClass() const; - bool isDocumentedFriendClass() const; - - MemberDef *reimplements() const; - MemberList *reimplementedBy() const; - bool isReimplementedBy(ClassDef *cd) const; - - //int inbodyLine() const; - //QCString inbodyFile() const; - //const QCString &inbodyDocumentation() const; - - ClassDef *relatedAlso() const; - - bool hasDocumentedEnumValues() const; - MemberDef *getAnonymousEnumType() const; - bool isDocsForDefinition() const; - MemberDef *getEnumScope() const; - MemberList *enumFieldList() const; - void setEnumBaseType(const QCString &type); - QCString enumBaseType() const; - - bool hasExamples(); - ExampleSDict *getExamples() const; - bool isPrototype() const; + virtual bool isLinkableInProject() const = 0; + virtual bool isLinkable() const = 0; + virtual bool hasDocumentation() const = 0; // overrides hasDocumentation in definition.h + //bool hasUserDocumentation() const = 0; // overrides hasUserDocumentation + virtual bool isDeleted() const = 0; + virtual bool isBriefSectionVisible() const = 0; + virtual bool isDetailedSectionVisible(bool inGroup,bool inFile) const = 0; + virtual bool isDetailedSectionLinkable() const = 0; + virtual bool isFriendClass() const = 0; + virtual bool isDocumentedFriendClass() const = 0; + + virtual MemberDef *reimplements() const = 0; + virtual MemberList *reimplementedBy() const = 0; + virtual bool isReimplementedBy(const ClassDef *cd) const = 0; + + virtual ClassDef *relatedAlso() const = 0; + + virtual bool hasDocumentedEnumValues() const = 0; + virtual const MemberDef *getAnonymousEnumType() const = 0; + virtual bool isDocsForDefinition() const = 0; + virtual const MemberDef *getEnumScope() const = 0; + virtual const MemberList *enumFieldList() const = 0; + virtual void setEnumBaseType(const QCString &type) = 0; + virtual QCString enumBaseType() const = 0; + + virtual bool hasExamples() const = 0; + virtual ExampleSDict *getExamples() const = 0; + virtual bool isPrototype() const = 0; // argument related members - ArgumentList *argumentList() const; - ArgumentList *declArgumentList() const; - ArgumentList *templateArguments() const; - QList<ArgumentList> *definitionTemplateParameterLists() const; + virtual const ArgumentList *argumentList() const = 0; + virtual ArgumentList *argumentList() = 0; + virtual const ArgumentList *declArgumentList() const = 0; + virtual const ArgumentList *templateArguments() const = 0; + virtual const QList<ArgumentList> *definitionTemplateParameterLists() const = 0; // member group related members - int getMemberGroupId() const; - MemberGroup *getMemberGroup() const; + virtual int getMemberGroupId() const = 0; + virtual MemberGroup *getMemberGroup() const = 0; - bool fromAnonymousScope() const; - bool anonymousDeclShown() const; - MemberDef *fromAnonymousMember() const; + virtual bool fromAnonymousScope() const = 0; + virtual bool anonymousDeclShown() const = 0; + virtual MemberDef *fromAnonymousMember() const = 0; // callgraph related members - bool hasCallGraph() const; - bool hasCallerGraph() const; - bool visibleMemberGroup(bool hideNoHeader); + virtual bool hasCallGraph() const = 0; + virtual bool hasCallerGraph() const = 0; + virtual bool visibleMemberGroup(bool hideNoHeader) const = 0; // refrenced related members - bool hasReferencesRelation() const; - bool hasReferencedByRelation() const; + virtual bool hasReferencesRelation() const = 0; + virtual bool hasReferencedByRelation() const = 0; - MemberDef *templateMaster() const; - QCString getScopeString() const; - ClassDef *getClassDefOfAnonymousType(); + virtual MemberDef *templateMaster() const = 0; + virtual QCString getScopeString() const = 0; + virtual ClassDef *getClassDefOfAnonymousType() const = 0; // cached typedef functions - bool isTypedefValCached() const; - ClassDef *getCachedTypedefVal() const; - QCString getCachedTypedefTemplSpec() const; - QCString getCachedResolvedTypedef() const; + virtual bool isTypedefValCached() const = 0; + virtual const ClassDef *getCachedTypedefVal() const = 0; + virtual QCString getCachedTypedefTemplSpec() const = 0; + virtual QCString getCachedResolvedTypedef() const = 0; - MemberDef *memberDefinition() const; - MemberDef *memberDeclaration() const; - MemberDef *inheritsDocsFrom() const; - MemberDef *getGroupAlias() const; + virtual MemberDef *memberDefinition() const = 0; + virtual MemberDef *memberDeclaration() const = 0; + virtual MemberDef *inheritsDocsFrom() const = 0; + virtual const MemberDef *getGroupAlias() const = 0; - ClassDef *category() const; - MemberDef *categoryRelation() const; + virtual ClassDef *category() const = 0; + virtual MemberDef *categoryRelation() const = 0; - QCString displayName(bool=TRUE) const; - QCString getDeclType() const; - void getLabels(QStrList &sl,Definition *container) const; + virtual QCString displayName(bool=TRUE) const = 0; + virtual QCString getDeclType() const = 0; + virtual void getLabels(QStrList &sl,const Definition *container) const = 0; - const ArgumentList *typeConstraints() const; + virtual const ArgumentList *typeConstraints() const = 0; // overrules - QCString documentation() const; - QCString briefDescription(bool abbr=FALSE) const; - QCString fieldType() const; - bool isReference() const; + virtual QCString documentation() const = 0; + virtual QCString briefDescription(bool abbr=FALSE) const = 0; + virtual QCString fieldType() const = 0; + virtual bool isReference() const = 0; + virtual QCString getDeclFileName() const = 0; + virtual int getDeclLine() const = 0; + virtual int getDeclColumn() const = 0; //----------------------------------------------------------------------------------- // ---- setters ----- //----------------------------------------------------------------------------------- - void addFlowKeyWord(); // set functions - void setMemberType(MemberType t); - void setDefinition(const char *d); - void setFileDef(FileDef *fd); - void setAnchor(); - void setProtection(Protection p); - void setMemberSpecifiers(uint64 s); - void mergeMemberSpecifiers(uint64 s); - void setInitializer(const char *i); - void setBitfields(const char *s); - void setMaxInitLines(int lines); - void setMemberClass(ClassDef *cd); - void setSectionList(Definition *d,MemberList *sl); - void setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, + virtual void setMemberType(MemberType t) = 0; + virtual void setDefinition(const char *d) = 0; + virtual void setFileDef(FileDef *fd) = 0; + virtual void setAnchor() = 0; + virtual void setProtection(Protection p) = 0; + virtual void setMemberSpecifiers(uint64 s) = 0; + virtual void mergeMemberSpecifiers(uint64 s) = 0; + virtual void setInitializer(const char *i) = 0; + virtual void setBitfields(const char *s) = 0; + virtual void setMaxInitLines(int lines) = 0; + virtual void setMemberClass(ClassDef *cd) = 0; + virtual void setSectionList(Definition *d,MemberList *sl) = 0; + virtual void setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, const QCString &fileName,int startLine,bool hasDocs, - MemberDef *member=0); - void setExplicitExternal(bool b); - void setReadAccessor(const char *r); - void setWriteAccessor(const char *w); - void setTemplateSpecialization(bool b); - - void makeRelated(); - void makeForeign(); - void setHasDocumentedParams(bool b); - void setHasDocumentedReturnType(bool b); - void setInheritsDocsFrom(MemberDef *md); - void setTagInfo(TagInfo *i); - void setArgsString(const char *as); + MemberDef *member=0) = 0; + virtual void setReadAccessor(const char *r) = 0; + virtual void setWriteAccessor(const char *w) = 0; + virtual void setTemplateSpecialization(bool b) = 0; + + virtual void makeRelated() = 0; + virtual void makeForeign() = 0; + virtual void setInheritsDocsFrom(MemberDef *md) = 0; + virtual void setTagInfo(TagInfo *i) = 0; + virtual void setArgsString(const char *as) = 0; + virtual void incrementFlowKeyWordCount() = 0; // relation to other members - void setReimplements(MemberDef *md); - void insertReimplementedBy(MemberDef *md); - - // in-body documentation - //void setInbodyDocumentation(const char *docs,const char *file,int line); + virtual void setReimplements(MemberDef *md) = 0; + virtual void insertReimplementedBy(MemberDef *md) = 0; - void setRelatedAlso(ClassDef *cd); + virtual void setRelatedAlso(ClassDef *cd) = 0; // enumeration specific members - void insertEnumField(MemberDef *md); - void setEnumScope(MemberDef *md,bool livesInsideEnum=FALSE); - void setEnumClassScope(ClassDef *cd); - void setDocumentedEnumValues(bool value); - void setAnonymousEnumType(MemberDef *md); + virtual void insertEnumField(MemberDef *md) = 0; + virtual void setEnumScope(MemberDef *md,bool livesInsideEnum=FALSE) = 0; + virtual void setEnumClassScope(ClassDef *cd) = 0; + virtual void setDocumentedEnumValues(bool value) = 0; + virtual void setAnonymousEnumType(const MemberDef *md) = 0; // example related members - bool addExample(const char *anchor,const char *name,const char *file); + virtual bool addExample(const char *anchor,const char *name,const char *file) = 0; // prototype related members - void setPrototype(bool p); + virtual void setPrototype(bool p,const QCString &df,int line, int column) = 0; + virtual void setExplicitExternal(bool b,const QCString &df,int line,int column) = 0; + virtual void setDeclFile(const QCString &df,int line,int column) = 0; // argument related members - void setArgumentList(ArgumentList *al); - void setDeclArgumentList(ArgumentList *al); - void setDefinitionTemplateParameterLists(QList<ArgumentList> *lists); - void setTypeConstraints(ArgumentList *al); - void setType(const char *t); - void setAccessorType(ClassDef *cd,const char *t); + virtual void setArgumentList(ArgumentList *al) = 0; + virtual void setDeclArgumentList(ArgumentList *al) = 0; + virtual void setDefinitionTemplateParameterLists(QList<ArgumentList> *lists) = 0; + virtual void setTypeConstraints(ArgumentList *al) = 0; + virtual void setType(const char *t) = 0; + virtual void setAccessorType(ClassDef *cd,const char *t) = 0; // namespace related members - void setNamespace(NamespaceDef *nd); + virtual void setNamespace(NamespaceDef *nd) = 0; // member group related members - void setMemberGroup(MemberGroup *grp); - void setMemberGroupId(int id); - void makeImplementationDetail(); + virtual void setMemberGroup(MemberGroup *grp) = 0; + virtual void setMemberGroupId(int id) = 0; + virtual void makeImplementationDetail() = 0; // anonymous scope members - void setFromAnonymousScope(bool b); - void setFromAnonymousMember(MemberDef *m); + virtual void setFromAnonymousMember(MemberDef *m) = 0; - void enableCallGraph(bool e); - void enableCallerGraph(bool e); + virtual void enableCallGraph(bool e) = 0; + virtual void enableCallerGraph(bool e) = 0; - void enableReferencedByRelation(bool e); - void enableReferencesRelation(bool e); + virtual void enableReferencedByRelation(bool e) = 0; + virtual void enableReferencesRelation(bool e) = 0; - void setTemplateMaster(MemberDef *mt); - void addListReference(Definition *d); - void setDocsForDefinition(bool b); - void setGroupAlias(MemberDef *md); + virtual void setTemplateMaster(MemberDef *mt) = 0; + virtual void addListReference(Definition *d) = 0; + virtual void setDocsForDefinition(bool b) = 0; + virtual void setGroupAlias(const MemberDef *md) = 0; - void cacheTypedefVal(ClassDef *val,const QCString &templSpec,const QCString &resolvedType); - void invalidateTypedefValCache(); + virtual void cacheTypedefVal(const ClassDef *val,const QCString &templSpec,const QCString &resolvedType) = 0; + virtual void invalidateTypedefValCache() = 0; + + virtual void invalidateCachedArgumentTypes() = 0; - void invalidateCachedArgumentTypes(); - // declaration <-> definition relation - void setMemberDefinition(MemberDef *md); - void setMemberDeclaration(MemberDef *md); - - void setAnonymousUsed(); - void copyArgumentNames(MemberDef *bmd); + virtual void setMemberDefinition(MemberDef *md) = 0; + virtual void setMemberDeclaration(MemberDef *md) = 0; + + virtual void copyArgumentNames(MemberDef *bmd) = 0; - void setCategory(ClassDef *); - void setCategoryRelation(MemberDef *); + virtual void setCategory(ClassDef *) = 0; + virtual void setCategoryRelation(MemberDef *) = 0; - void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE); - void setBriefDescription(const char *b,const char *briefFile,int briefLine); - void setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine); + virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE) = 0; + virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine) = 0; + virtual void setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine) = 0; - void setHidden(bool b); + virtual void setHidden(bool b) = 0; //----------------------------------------------------------------------------------- // --- actions ---- //----------------------------------------------------------------------------------- - // output generation - void writeDeclaration(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, - bool inGroup, ClassDef *inheritFrom=0,const char *inheritId=0); - void writeDocumentation(MemberList *ml,int memCount,int memTotal,OutputList &ol, - const char *scopeName,Definition *container, - bool inGroup,bool showEnumValues=FALSE,bool - showInline=FALSE); - void writeMemberDocSimple(OutputList &ol,Definition *container); - void writeEnumDeclaration(OutputList &typeDecl, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd); - void writeTagFile(FTextStream &); - void warnIfUndocumented(); - void warnIfUndocumentedParams(); - - MemberDef *createTemplateInstanceMember(ArgumentList *formalArgs, - ArgumentList *actualArgs); + virtual MemberDef *createTemplateInstanceMember(ArgumentList *formalArgs, + ArgumentList *actualArgs) const = 0; + virtual void findSectionsInDocumentation() = 0; + virtual void addToSearchIndex() const = 0; + + //----------------------------------------------------------------------------------- + // --- write output ---- + //----------------------------------------------------------------------------------- + + virtual void writeDeclaration(OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + bool inGroup, const ClassDef *inheritFrom=0,const char *inheritId=0) const = 0; + virtual void writeDocumentation(const MemberList *ml,int memCount,int memTotal,OutputList &ol, + const char *scopeName,const Definition *container, + bool inGroup,bool showEnumValues=FALSE,bool + showInline=FALSE) const = 0; + virtual void writeMemberDocSimple(OutputList &ol,const Definition *container) const = 0; + virtual void writeEnumDeclaration(OutputList &typeDecl, const ClassDef *cd, + const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd) const = 0; + virtual void writeTagFile(FTextStream &) const = 0; + virtual void writeLink(OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + bool onlyText=FALSE) const = 0; + + // write helpers + virtual void warnIfUndocumented() const = 0; + virtual void warnIfUndocumentedParams() const = 0; + virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const = 0; + virtual void setAnonymousUsed() const = 0; + virtual void setFromAnonymousScope(bool b) const = 0; - void findSectionsInDocumentation(); - - bool visited; - - protected: - void flushToDisk() const; - void loadFromDisk() const; - private: - void lock() const; - void unlock() const; - void saveToDisk() const; - void makeResident() const; - void _computeLinkableInProject(); - void _computeIsConstructor(); - void _computeIsDestructor(); - void _writeGroupInclude(OutputList &ol,bool inGroup); - void _writeCallGraph(OutputList &ol); - void _writeCallerGraph(OutputList &ol); - void _writeReimplements(OutputList &ol); - void _writeReimplementedBy(OutputList &ol); - void _writeExamples(OutputList &ol); - void _writeTypeConstraints(OutputList &ol); - void _writeEnumValues(OutputList &ol,Definition *container, - const QCString &cfname,const QCString &ciname, - const QCString &cname); - void _writeCategoryRelation(OutputList &ol); - void _writeTagData(const DefType); - void _addToSearchIndex(); - - static int s_indentLevel; - - int number_of_flowkw; - - // disable copying of member defs - MemberDef(const MemberDef &); - MemberDef &operator=(const MemberDef &); - - void writeLink(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, - bool onlyText=FALSE); - - MemberDefImpl *m_impl; - uchar m_isLinkableCached; // 0 = not cached, 1=FALSE, 2=TRUE - uchar m_isConstructorCached; // 0 = not cached, 1=FALSE, 2=TRUE - uchar m_isDestructorCached; // 0 = not cached, 1=FALSE, 2=TRUE }; +/** Factory method to create a new instance of a MemberDef */ +MemberDef *createMemberDef(const char *defFileName,int defLine,int defColumn, + const char *type,const char *name,const char *args, + const char *excp,Protection prot,Specifier virt,bool stat, + Relationship related,MemberType t,const ArgumentList *tal, + const ArgumentList *al,const char *metaData); + +MemberDef *createMemberDefAlias(const Definition *newScope,const MemberDef *aliasMd); + void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef); #endif diff --git a/src/membergroup.cpp b/src/membergroup.cpp index 5ee47ab..a5852e4 100644 --- a/src/membergroup.cpp +++ b/src/membergroup.cpp @@ -26,7 +26,6 @@ #include "groupdef.h" #include "doxygen.h" #include "docparser.h" -#include "marshal.h" #include "entry.h" #include "md5.h" @@ -41,15 +40,17 @@ MemberGroup::MemberGroup() { } -MemberGroup::MemberGroup(Definition *parent, +MemberGroup::MemberGroup(const Definition *parent, int id,const char *hdr,const char *d,const char *docFile,int docLine) { + static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); + //printf("New member group id=%d header=%s desc=%s\n",id,hdr,d); memberList = new MemberList(MemberListType_memberGroup); + memberList->setNeedsSorting(sortBriefDocs); // detailed sections are already sorted elsewhere. grpId = id; grpHeader = hdr; doc = d; - scope = 0; inSameSection = TRUE; inDeclSection = 0; m_numDecMembers = -1; @@ -58,7 +59,7 @@ MemberGroup::MemberGroup(Definition *parent, m_docFile = docFile; m_docLine = docLine; m_xrefListItems = 0; - //printf("Member group docs=`%s'\n",doc.data()); + //printf("Member group docs='%s'\n",doc.data()); } MemberGroup::~MemberGroup() @@ -84,14 +85,14 @@ void MemberGroup::insertMember(MemberDef *md) } else if (inDeclSection==0) { - inDeclSection = md->getSectionList(m_parent); + inDeclSection = const_cast<MemberList*>(md->getSectionList(m_parent)); //printf("inDeclSection=%p type=%d\n",inDeclSection,inDeclSection->listType()); } memberList->append(md); // copy the group of the first member in the memberGroup GroupDef *gd; - if (firstMd && (gd=firstMd->getGroupDef())) + if (firstMd && (gd=const_cast<GroupDef*>(firstMd->getGroupDef()))) { md->setGroupDef(gd, firstMd->getGroupPri(), firstMd->getGroupFileName(), firstMd->getGroupStartLine(), @@ -107,8 +108,8 @@ void MemberGroup::setAnchors() } void MemberGroup::writeDeclarations(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, - bool showInline) + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + bool showInline) const { //printf("MemberGroup::writeDeclarations() %s\n",grpHeader.data()); QCString ldoc = doc; @@ -117,29 +118,34 @@ void MemberGroup::writeDeclarations(OutputList &ol, } void MemberGroup::writePlainDeclarations(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, - ClassDef *inheritedFrom,const char *inheritId - ) + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + const ClassDef *inheritedFrom,const char *inheritId + ) const { //printf("MemberGroup::writePlainDeclarations() memberList->count()=%d\n",memberList->count()); memberList->writePlainDeclarations(ol,cd,nd,fd,gd,inheritedFrom,inheritId); } void MemberGroup::writeDocumentation(OutputList &ol,const char *scopeName, - Definition *container,bool showEnumValues,bool showInline) + const Definition *container,bool showEnumValues,bool showInline) const { memberList->writeDocumentation(ol,scopeName,container,0,showEnumValues,showInline); } void MemberGroup::writeDocumentationPage(OutputList &ol,const char *scopeName, - Definition *container) + const Definition *container) const { memberList->writeDocumentationPage(ol,scopeName,container); } -void MemberGroup::addGroupedInheritedMembers(OutputList &ol,ClassDef *cd, +void MemberGroup::setAnonymousEnumType() +{ + memberList->setAnonymousEnumType(); +} + +void MemberGroup::addGroupedInheritedMembers(OutputList &ol,const ClassDef *cd, MemberListType lt, - ClassDef *inheritedFrom,const QCString &inheritId) + const ClassDef *inheritedFrom,const QCString &inheritId) const { //printf("** addGroupedInheritedMembers()\n"); MemberListIterator li(*memberList); @@ -147,11 +153,12 @@ void MemberGroup::addGroupedInheritedMembers(OutputList &ol,ClassDef *cd, for (li.toFirst();(md=li.current());++li) { //printf("matching %d == %d\n",lt,md->getSectionList(m_parent)->listType()); - MemberList *ml = md->getSectionList(m_parent); + const MemberList *ml = md->getSectionList(m_parent); if (ml && lt==ml->listType()) { MemberList ml(lt); ml.append(md); + ml.countDecMembers(); ml.writePlainDeclarations(ol,cd,0,0,0,inheritedFrom,inheritId); } } @@ -166,7 +173,7 @@ int MemberGroup::countGroupedInheritedMembers(MemberListType lt) for (li.toFirst();(md=li.current());++li) { //printf("matching %d == %d\n",lt,md->getSectionList(m_parent)->listType()); - MemberList *ml = md->getSectionList(m_parent); + const MemberList *ml = md->getSectionList(m_parent); if (ml && lt==ml->listType()) { count++; @@ -183,33 +190,24 @@ void MemberGroup::addToDeclarationSection() { if (inDeclSection) { - //printf("Adding group %p to list %p (type=%d)\n",this, - // inDeclSection,inDeclSection->listType()); + //printf("Adding group %p to list %p (type=%d) memberList=%p\n",this, + // inDeclSection,inDeclSection->listType(),memberList); inDeclSection->addMemberGroup(this); } } -int MemberGroup::countDecMembers(GroupDef *gd) +void MemberGroup::countDecMembers() { - if (m_numDecMembers==-1) /* number of member not cached */ - { - memberList->countDecMembers(gd); - m_numDecMembers = memberList->numDecMembers(); - } - return m_numDecMembers; + memberList->countDecMembers(); } -int MemberGroup::countDocMembers() +void MemberGroup::countDocMembers() { - if (m_numDocMembers==-1) - { - memberList->countDocMembers(); - m_numDocMembers = memberList->numDocMembers(); - } - return m_numDocMembers; + memberList->countDocMembers(); } -int MemberGroup::countInheritableMembers(ClassDef *inheritedFrom) const + +int MemberGroup::countInheritableMembers(const ClassDef *inheritedFrom) const { return memberList->countInheritableMembers(inheritedFrom); } @@ -253,6 +251,7 @@ void MemberGroup::distributeMemberGroupDocumentation() } } +#if 0 int MemberGroup::varCount() const { return memberList->varCount(); @@ -302,15 +301,26 @@ int MemberGroup::friendCount() const { return memberList->friendCount(); } +#endif -int MemberGroup::numDecMembers() const -{ - return memberList->numDecMembers(); +int MemberGroup::numDecMembers() const +{ + return memberList->numDecMembers(); } -int MemberGroup::numDocMembers() const -{ - return memberList->numDocMembers(); +int MemberGroup::numDecEnumValues() const +{ + return memberList->numDecEnumValues(); +} + +int MemberGroup::numDocMembers() const +{ + return memberList->numDocMembers(); +} + +int MemberGroup::numDocEnumValues() const +{ + return memberList->numDocEnumValues(); } void MemberGroup::setInGroup(bool b) @@ -318,6 +328,7 @@ void MemberGroup::setInGroup(bool b) memberList->setInGroup(b); } + QCString MemberGroup::anchor() const { uchar md5_sig[16]; @@ -349,40 +360,6 @@ void MemberGroup::findSectionsInDocumentation() memberList->findSectionsInDocumentation(); } -void MemberGroup::marshal(StorageIntf *s) -{ - marshalMemberList(s,memberList); - marshalObjPointer(s,inDeclSection); // reference only - marshalInt(s,grpId); - marshalQCString(s,grpHeader); - marshalQCString(s,fileName); - marshalObjPointer(s,scope); - marshalQCString(s,doc); - marshalBool(s,inSameSection); - marshalInt(s,m_numDecMembers); - marshalInt(s,m_numDocMembers); - marshalObjPointer(s,m_parent); - marshalQCString(s,m_docFile); - marshalItemInfoList (Doxygen::symbolStorage,m_xrefListItems); -} - -void MemberGroup::unmarshal(StorageIntf *s) -{ - memberList = unmarshalMemberList(s); - inDeclSection = (MemberList *)unmarshalObjPointer(s); - grpId = unmarshalInt(s); - grpHeader = unmarshalQCString(s); - fileName = unmarshalQCString(s); - scope = (Definition *)unmarshalObjPointer(s); - doc = unmarshalQCString(s); - inSameSection = unmarshalBool(s); - m_numDecMembers = unmarshalInt(s); - m_numDocMembers = unmarshalInt(s); - m_parent = (Definition *)unmarshalObjPointer(s); - m_docFile = unmarshalQCString(s); - m_xrefListItems = unmarshalItemInfoList (Doxygen::symbolStorage); -} - void MemberGroup::setRefItems(const QList<ListItemInfo> *sli) { if (sli) diff --git a/src/membergroup.h b/src/membergroup.h index b590d48..c07d025 100644 --- a/src/membergroup.h +++ b/src/membergroup.h @@ -41,7 +41,7 @@ class MemberGroup { public: MemberGroup(); - MemberGroup(Definition *parent,int id,const char *header, + MemberGroup(const Definition *parent,int id,const char *header, const char *docs,const char *docFile,int docLine); ~MemberGroup(); QCString header() const { return grpHeader; } @@ -49,28 +49,30 @@ class MemberGroup void insertMember(MemberDef *md); void setAnchors(); void writePlainDeclarations(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, - ClassDef *inheritedFrom,const char *inheritId); + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + const ClassDef *inheritedFrom,const char *inheritId) const; void writeDeclarations(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, - bool showInline=FALSE); + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + bool showInline=FALSE) const; void writeDocumentation(OutputList &ol,const char *scopeName, - Definition *container,bool showEnumValues,bool showInline); + const Definition *container,bool showEnumValues,bool showInline) const; void writeDocumentationPage(OutputList &ol,const char *scopeName, - Definition *container); + const Definition *container) const; void writeTagFile(FTextStream &); - void addGroupedInheritedMembers(OutputList &ol,ClassDef *cd, + void addGroupedInheritedMembers(OutputList &ol,const ClassDef *cd, MemberListType lt, - ClassDef *inheritedFrom,const QCString &inheritId); + const ClassDef *inheritedFrom,const QCString &inheritId) const; + void setAnonymousEnumType(); const QCString &documentation() const { return doc; } bool allMembersInSameSection() const { return inSameSection; } void addToDeclarationSection(); - int countDecMembers(GroupDef *gd=0); - int countDocMembers(); + void countDecMembers(); + void countDocMembers(); int countGroupedInheritedMembers(MemberListType lt); void distributeMemberGroupDocumentation(); void findSectionsInDocumentation(); + /* int varCount() const; int funcCount() const; int enumCount() const; @@ -81,34 +83,34 @@ class MemberGroup int protoCount() const; int defineCount() const; int friendCount() const; + */ int numDecMembers() const; + int numDecEnumValues() const; int numDocMembers() const; - int countInheritableMembers(ClassDef *inheritedFrom) const; + int numDocEnumValues() const; + + int countInheritableMembers(const ClassDef *inheritedFrom) const; void setInGroup(bool b); void addListReferences(Definition *d); void setRefItems(const QList<ListItemInfo> *sli); MemberList *members() const { return memberList; } - Definition *parent() const { return m_parent; } + const Definition *parent() const { return m_parent; } QCString anchor() const; QCString docFile() const { return m_docFile; } int docLine() const { return m_docLine; } - void marshal(StorageIntf *s); - void unmarshal(StorageIntf *s); - private: MemberList *memberList; // list of all members in the group MemberList *inDeclSection; int grpId; QCString grpHeader; QCString fileName; // base name of the generated file - Definition *scope; QCString doc; bool inSameSection; int m_numDecMembers; int m_numDocMembers; - Definition *m_parent; + const Definition *m_parent; QCString m_docFile; int m_docLine; QList<ListItemInfo> *m_xrefListItems; diff --git a/src/memberlist.cpp b/src/memberlist.cpp index abb8aff..1869808 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -25,7 +25,6 @@ #include "doxygen.h" #include "outputlist.h" #include "groupdef.h" -#include "marshal.h" #include "vhdldocgen.h" #include "namespacedef.h" #include "filedef.h" @@ -35,19 +34,12 @@ MemberList::MemberList() : m_listType(MemberListType_pubMethods) { + //printf("%p: MemberList::MemberList()\n",this); memberGroupList=0; - m_varCnt=0; - m_funcCnt=0; - m_enumCnt=0; - m_enumValCnt=0; - m_typeCnt=0; - m_seqCnt=0; - m_dictCnt=0; - m_protoCnt=0; - m_defCnt=0; - m_friendCnt=0; m_numDecMembers=-1; // special value indicating that value needs to be computed + m_numDecEnumValues=0; m_numDocMembers=-1; // special value indicating that value needs to be computed + m_numDocEnumValues=0; m_inGroup=FALSE; m_inFile=FALSE; m_needsSorting=FALSE; @@ -55,19 +47,12 @@ MemberList::MemberList() : m_listType(MemberListType_pubMethods) MemberList::MemberList(MemberListType lt) : m_listType(lt) { + //printf("%p: MemberList::MemberList(%d)\n",this,lt); memberGroupList=0; - m_varCnt=0; - m_funcCnt=0; - m_enumCnt=0; - m_enumValCnt=0; - m_typeCnt=0; - m_seqCnt=0; - m_dictCnt=0; - m_protoCnt=0; - m_defCnt=0; - m_friendCnt=0; m_numDecMembers=-1; // special value indicating that value needs to be computed + m_numDecEnumValues=0; m_numDocMembers=-1; // special value indicating that value needs to be computed + m_numDocEnumValues=0; m_inGroup=FALSE; m_inFile=FALSE; m_needsSorting=FALSE; @@ -90,14 +75,15 @@ int MemberList::compareValues(const MemberDef *c1, const MemberDef *c2) const return 1; } int cmp = qstricmp(c1->name(),c2->name()); + if (cmp==0) cmp = qstricmp(c1->argsString(),c2->argsString()); return cmp!=0 ? cmp : c1->getDefLine()-c2->getDefLine(); } -int MemberList::countInheritableMembers(ClassDef *inheritedFrom) const +int MemberList::countInheritableMembers(const ClassDef *inheritedFrom) const { int count=0; QListIterator<MemberDef> mli(*this); - MemberDef *md; + const MemberDef *md; for (mli.toFirst();(md=mli.current());++mli) { if (md->isBriefSectionVisible()) @@ -137,13 +123,15 @@ int MemberList::countInheritableMembers(ClassDef *inheritedFrom) const /*! Count the number of members in this list that are visible in * the declaration part of a compound's documentation page. */ -void MemberList::countDecMembers(bool countEnumValues,GroupDef *gd) +void MemberList::countDecMembers() { - if (m_numDecMembers!=-1) return; - + if (m_numDecMembers!=-1) return; + //printf("----- countDecMembers count=%d ----\n",count()); + /* m_varCnt=m_funcCnt=m_enumCnt=m_enumValCnt=0; m_typeCnt=m_seqCnt=m_dictCnt=m_protoCnt=m_defCnt=m_friendCnt=0; + */ m_numDecMembers=0; QListIterator<MemberDef> mli(*this); MemberDef *md; @@ -156,7 +144,8 @@ void MemberList::countDecMembers(bool countEnumValues,GroupDef *gd) { case MemberType_Variable: // fall through case MemberType_Event: // fall through - case MemberType_Property: m_varCnt++,m_numDecMembers++; + case MemberType_Property: /*m_varCnt++,*/ + m_numDecMembers++; break; // apparently necessary to get this to show up in declarations section? case MemberType_Interface: // fall through @@ -165,26 +154,36 @@ void MemberList::countDecMembers(bool countEnumValues,GroupDef *gd) case MemberType_Signal: // fall through case MemberType_DCOP: // fall through case MemberType_Slot: if (!md->isRelated() || md->getClassDef()) - m_funcCnt++,m_numDecMembers++; + /*m_funcCnt++,*/ + m_numDecMembers++; + break; + case MemberType_Enumeration: /*m_enumCnt++,*/ + m_numDecMembers++; + break; + case MemberType_EnumValue: m_numDecEnumValues++; + m_numDecMembers++; break; - case MemberType_Enumeration: m_enumCnt++,m_numDecMembers++; break; - case MemberType_EnumValue: if (countEnumValues) - m_enumValCnt++,m_numDecMembers++; + case MemberType_Typedef: /*m_typeCnt++,*/ + m_numDecMembers++; + break; + case MemberType_Sequence: /*m_seqCnt++,*/ + m_numDecMembers++; + break; + case MemberType_Dictionary: /*m_dictCnt++,*/ + m_numDecMembers++; break; - case MemberType_Typedef: m_typeCnt++,m_numDecMembers++; break; - case MemberType_Sequence: m_seqCnt++,m_numDecMembers++; break; - case MemberType_Dictionary: m_dictCnt++,m_numDecMembers++; break; //case MemberType_Prototype: m_protoCnt++,m_numDecMembers++; break; - case MemberType_Define: if (Config_getBool(EXTRACT_ALL) || - md->argsString() || + case MemberType_Define: if (Config_getBool(EXTRACT_ALL) || + md->argsString() || !md->initializer().isEmpty() || - md->hasDocumentation() - ) m_defCnt++,m_numDecMembers++; + md->hasDocumentation() + ) /*m_defCnt++,*/ m_numDecMembers++; break; - case MemberType_Friend: m_friendCnt++,m_numDecMembers++; + case MemberType_Friend: /*m_friendCnt++,*/ + m_numDecMembers++; break; default: - err("Unknown member type found for member `%s'\n!",md->name().data()); + err("Unknown member type found for member '%s'\n!",md->name().data()); } } } @@ -194,7 +193,8 @@ void MemberList::countDecMembers(bool countEnumValues,GroupDef *gd) MemberGroup *mg; for (;(mg=mgli.current());++mgli) { - mg->countDecMembers(gd); + mg->countDecMembers(); + /* m_varCnt+=mg->varCount(); m_funcCnt+=mg->funcCount(); m_enumCnt+=mg->enumCount(); @@ -205,7 +205,9 @@ void MemberList::countDecMembers(bool countEnumValues,GroupDef *gd) m_protoCnt+=mg->protoCount(); m_defCnt+=mg->defineCount(); m_friendCnt+=mg->friendCount(); + */ m_numDecMembers+=mg->numDecMembers(); + m_numDecEnumValues+=mg->numDecEnumValues(); } } //printf("----- end countDecMembers ----\n"); @@ -213,7 +215,7 @@ void MemberList::countDecMembers(bool countEnumValues,GroupDef *gd) //printf("MemberList::countDecMembers()=%d\n",m_numDecMembers); } -void MemberList::countDocMembers(bool countEnumValues) +void MemberList::countDocMembers() { if (m_numDocMembers!=-1) return; // used cached value m_numDocMembers=0; @@ -221,11 +223,14 @@ void MemberList::countDocMembers(bool countEnumValues) MemberDef *md; for (mli.toFirst();(md=mli.current());++mli) { - if (md->isDetailedSectionVisible(m_inGroup,m_inFile)) + if (md->isDetailedSectionVisible(m_inGroup,m_inFile) && !md->isAlias()) { // do not count enum values, since they do not produce entries of their own - if (countEnumValues || md->memberType()!=MemberType_EnumValue) - m_numDocMembers++; + if (md->memberType()==MemberType_EnumValue) + { + m_numDocEnumValues++; + } + m_numDocMembers++; } } if (memberGroupList) @@ -236,6 +241,7 @@ void MemberList::countDocMembers(bool countEnumValues) { mg->countDocMembers(); m_numDocMembers+=mg->numDocMembers(); + m_numDocEnumValues+=mg->numDocEnumValues(); } } //printf("MemberList::countDocMembers()=%d memberGroupList=%p\n",m_numDocMembers,memberGroupList); @@ -286,36 +292,74 @@ MemberListIterator::MemberListIterator(const MemberList &l) : { } -int MemberList::countEnumValues(MemberDef *md,bool setAnonEnumType) const +void MemberList::setAnonymousEnumType() { - int enumVars=0; + //printf("MemberList(%p)::setAnonymousEnumType()\n",this); + MemberListIterator mli(*this); + const MemberDef *md; + for ( ; (md=mli.current()); ++mli ) + { + if (md->isBriefSectionVisible()) + { + QCString name(md->name()); + int i=name.findRev("::"); + if (i!=-1) name=name.right(name.length()-i-2); + if (md->memberType()==MemberType_Enumeration && name[0]=='@') + { + const MemberList *mfl = md->enumFieldList(); + if (mfl) + { + MemberListIterator vmli(*mfl); + MemberDef *vmd; + for ( ; (vmd=vmli.current()) ; ++vmli) + { + QCString vtype=vmd->typeString(); + if ((vtype.find(name))!=-1) + { + vmd->setAnonymousEnumType(md); + } + } + } + } + } + } + if (memberGroupList) + { + MemberGroupListIterator mgli(*memberGroupList); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + mg->setAnonymousEnumType(); + } + } +} + +int MemberList::countEnumValues(const MemberDef *md) const +{ + int numEnumValues=0; MemberListIterator vmli(*this); - MemberDef *vmd; + const MemberDef *vmd; QCString name(md->name()); int i=name.findRev("::"); - if (i!=-1) name=name.right(name.length()-i-2); // strip scope (TODO: is this needed?) - if (name[0]=='@') // anonymous enum => append variables + if (i!=-1) name=name.right(name.length()-i-2); + if (name[0]=='@') { for ( ; (vmd=vmli.current()) ; ++vmli) { QCString vtype=vmd->typeString(); - if ((vtype.find(name))!=-1) + if ((vtype.find(name))!=-1) { - enumVars++; - if (setAnonEnumType) - { - vmd->setAnonymousEnumType(md); - } + numEnumValues++; } } } - return enumVars; + return numEnumValues; } bool MemberList::declVisible() const { MemberListIterator mli(*this); - MemberDef *md; + const MemberDef *md; for ( ; (md=mli.current()); ++mli ) { if (md->isBriefSectionVisible()) @@ -340,7 +384,7 @@ bool MemberList::declVisible() const { // if this is an anonymous enum and there are variables of this // enum type (i.e. enumVars>0), then we do not show the enum here. - if (countEnumValues(md,FALSE)==0) // show enum here + if (countEnumValues(md)==0) // show enum here { return TRUE; } @@ -363,14 +407,18 @@ bool MemberList::declVisible() const } void MemberList::writePlainDeclarations(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd, - GroupDef *gd,ClassDef *inheritedFrom,const char *inheritId - ) + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd, + const GroupDef *gd,const ClassDef *inheritedFrom,const char *inheritId + ) const { //printf("----- writePlainDeclaration() ----\n"); static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); - countDecMembers(); - if (numDecMembers()==0) + if (numDecMembers()==-1) + { + err("MemberList::numDecMembers()==-1, so the members of this list have not been counted. Please report as a bug.\n"); + abort(); + } + if (numDecMembers()<=numDecEnumValues()) { //printf(" --> no members!\n"); return; // no members in this list @@ -381,11 +429,11 @@ void MemberList::writePlainDeclarations(OutputList &ol, ol.pushGeneratorState(); bool first=TRUE; - MemberDef *md; + const MemberDef *md; MemberListIterator mli(*this); for ( ; (md=mli.current()); ++mli ) { - //printf(">>> Member `%s' type=%d visible=%d\n", + //printf(">>> Member '%s' type=%d visible=%d\n", // md->name().data(),md->memberType(),md->isBriefSectionVisible()); if ((inheritedFrom==0 || !md->isReimplementedBy(inheritedFrom)) && md->isBriefSectionVisible()) @@ -416,7 +464,7 @@ void MemberList::writePlainDeclarations(OutputList &ol, { // if this is an anonymous enum and there are variables of this // enum type (i.e. enumVars>0), then we do not show the enum here. - if (countEnumValues(md,TRUE)==0) // show enum here + if (countEnumValues(md)==0) // show enum here { //printf("Enum!!\n"); if (first) @@ -549,9 +597,9 @@ void MemberList::writePlainDeclarations(OutputList &ol, * @param lt Type of list that is inherited from. */ void MemberList::writeDeclarations(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, const char *title,const char *subtitle, bool showEnumValues, - bool showInline,ClassDef *inheritedFrom,MemberListType lt) + bool showInline,const ClassDef *inheritedFrom,MemberListType lt) const { (void)showEnumValues; // unused @@ -559,16 +607,16 @@ void MemberList::writeDeclarations(OutputList &ol, static bool optimizeVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL); QCString inheritId; - countDecMembers(/*showEnumValues*/FALSE,gd); // count members shown in this section - Definition *ctx = cd; + const Definition *ctx = cd; if (ctx==0 && nd) ctx = nd; if (ctx==0 && gd) ctx = gd; if (ctx==0 && fd) ctx = fd; - //printf("%p: MemberList::writeDeclaration(title=`%s',subtitle=`%s')=%d inheritedFrom=%p\n", + //printf("%p: MemberList::writeDeclaration(title='%s',subtitle='%s')=%d inheritedFrom=%p\n", // this,title,subtitle,numDecMembers(),inheritedFrom); int num = numDecMembers(); + int numEnumValues = numDecEnumValues(); if (inheritedFrom) { //if ( cd && !optimizeVhdl && countInheritableMembers(inheritedFrom)>0 ) @@ -588,7 +636,7 @@ void MemberList::writeDeclarations(OutputList &ol, ol.popGeneratorState(); } } - else if (num>0) + else if (num>numEnumValues) { if (title) { @@ -622,7 +670,7 @@ void MemberList::writeDeclarations(OutputList &ol, } } } - if (num>0) + if (num>numEnumValues) { // TODO: Two things need to be worked out for proper VHDL output: // 1. Signals and types under the group need to be @@ -685,13 +733,17 @@ void MemberList::writeDeclarations(OutputList &ol, } void MemberList::writeDocumentation(OutputList &ol, - const char *scopeName, Definition *container, - const char *title,bool showEnumValues,bool showInline) + const char *scopeName, const Definition *container, + const char *title,bool showEnumValues,bool showInline) const { - //printf("MemberList::writeDocumentation()\n"); + if (numDocMembers()==-1) + { + err("MemberList::numDocMembers()==-1, so the members of this list have not been counted. Please report as a bug.\n"); + abort(); + } - countDocMembers(showEnumValues); if (numDocMembers()==0) return; + if (!showEnumValues && numDocMembers()<=numDocEnumValues()) return; if (title) { @@ -706,7 +758,7 @@ void MemberList::writeDocumentation(OutputList &ol, ol.startMemberDocList(); MemberListIterator mli(*this); - MemberDef *md; + const MemberDef *md; // count the number of overloaded members QDict<uint> overloadTotalDict(67); @@ -758,20 +810,19 @@ void MemberList::writeDocumentation(OutputList &ol, // members in a table void MemberList::writeSimpleDocumentation(OutputList &ol, - Definition *container) + const Definition *container) const { - countDocMembers(FALSE); - //printf("MemberList count=%d\n",numDocMembers()); - if (numDocMembers()==0) return; + //printf("MemberList count=%d enumValues=%d\n",numDocMembers(),numDocEnumValues()); + if (numDocMembers()<=numDocEnumValues()) return; // only enum values and they should be excluded - ClassDef *cd = 0; + const ClassDef *cd = 0; if (container && container->definitionType()==Definition::TypeClass) { - cd = (ClassDef*)container; + cd = dynamic_cast<const ClassDef*>(container); } ol.startMemberDocSimple(cd && cd->isJavaEnum()); MemberListIterator mli(*this); - MemberDef *md; + const MemberDef *md; for ( ; (md=mli.current()) ; ++mli) { md->writeMemberDocSimple(ol,container); @@ -781,7 +832,7 @@ void MemberList::writeSimpleDocumentation(OutputList &ol, // separate member pages void MemberList::writeDocumentationPage(OutputList &ol, - const char *scopeName, Definition *container) + const char *scopeName, const Definition *container) const { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); @@ -791,7 +842,7 @@ void MemberList::writeDocumentationPage(OutputList &ol, overloadTotalDict.setAutoDelete(TRUE); overloadCountDict.setAutoDelete(TRUE); MemberListIterator mli(*this); - MemberDef *md; + const MemberDef *md; for (mli.toFirst() ; (md=mli.current()) ; ++mli) { if (md->isDetailedSectionLinkable()) @@ -882,10 +933,10 @@ void MemberList::addListReferences(Definition *def) MemberDef *md; for ( ; (md=mli.current()) ; ++mli) { - if (md->getGroupDef()==0 || def->definitionType()==Definition::TypeGroup) + if (!md->isAlias() && (md->getGroupDef()==0 || def->definitionType()==Definition::TypeGroup)) { md->addListReference(def); - MemberList *enumFields = md->enumFieldList(); + const MemberList *enumFields = md->enumFieldList(); if (md->memberType()==MemberType_Enumeration && enumFields) { //printf(" Adding enum values!\n"); @@ -929,75 +980,6 @@ void MemberList::findSectionsInDocumentation() } } -void MemberList::marshal(StorageIntf *s) -{ - marshalInt(s,(int)m_listType); - marshalInt(s,m_varCnt); - marshalInt(s,m_funcCnt); - marshalInt(s,m_enumCnt); - marshalInt(s,m_enumValCnt); - marshalInt(s,m_typeCnt); - marshalInt(s,m_seqCnt); - marshalInt(s,m_dictCnt); - marshalInt(s,m_protoCnt); - marshalInt(s,m_defCnt); - marshalInt(s,m_friendCnt); - marshalInt(s,m_numDecMembers); - marshalInt(s,m_numDocMembers); - marshalBool(s,m_inGroup); - marshalBool(s,m_inFile); - marshalBool(s,m_needsSorting); - if (memberGroupList==0) - { - marshalUInt(s,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(s,memberGroupList->count()); - QListIterator<MemberGroup> mgi(*memberGroupList); - MemberGroup *mg=0; - for (mgi.toFirst();(mg=mgi.current());++mgi) - { - mg->marshal(s); - } - } -} - -void MemberList::unmarshal(StorageIntf *s) -{ - m_listType = (MemberListType)unmarshalInt(s); - m_varCnt = unmarshalInt(s); - m_funcCnt = unmarshalInt(s); - m_enumCnt = unmarshalInt(s); - m_enumValCnt = unmarshalInt(s); - m_typeCnt = unmarshalInt(s); - m_seqCnt = unmarshalInt(s); - m_dictCnt = unmarshalInt(s); - m_protoCnt = unmarshalInt(s); - m_defCnt = unmarshalInt(s); - m_friendCnt = unmarshalInt(s); - m_numDecMembers = unmarshalInt(s); - m_numDocMembers = unmarshalInt(s); - m_inGroup = unmarshalBool(s); - m_inFile = unmarshalBool(s); - m_needsSorting = unmarshalBool(s); - uint i,count = unmarshalUInt(s); - if (count==NULL_LIST) // empty list - { - memberGroupList = 0; - } - else // add member groups - { - memberGroupList = new MemberGroupList; - for (i=0;i<count;i++) - { - MemberGroup *mg = new MemberGroup; - mg->unmarshal(s); - memberGroupList->append(mg); - } - } -} - void MemberList::setNeedsSorting(bool b) { m_needsSorting = b; diff --git a/src/memberlist.h b/src/memberlist.h index a96f61f..3c227be 100644 --- a/src/memberlist.h +++ b/src/memberlist.h @@ -49,7 +49,7 @@ class MemberList : private QList<MemberDef> MemberDef *getFirst() const; MemberDef *take(uint index); - +/* int varCount() const { ASSERT(m_numDecMembers!=-1); return m_varCnt; } int funcCount() const { ASSERT(m_numDecMembers!=-1); return m_funcCnt; } int enumCount() const { ASSERT(m_numDecMembers!=-1); return m_enumCnt; } @@ -60,25 +60,29 @@ class MemberList : private QList<MemberDef> int protoCount() const { ASSERT(m_numDecMembers!=-1); return m_protoCnt; } int defineCount() const { ASSERT(m_numDecMembers!=-1); return m_defCnt; } int friendCount() const { ASSERT(m_numDecMembers!=-1); return m_friendCnt; } +*/ int numDecMembers() const { ASSERT(m_numDecMembers!=-1); return m_numDecMembers; } + int numDecEnumValues() const { return m_numDecEnumValues; } int numDocMembers() const { ASSERT(m_numDocMembers!=-1); return m_numDocMembers; } + int numDocEnumValues() const { return m_numDocEnumValues; } bool needsSorting() const { return m_needsSorting; } - void countDecMembers(bool countEnumValues=FALSE,GroupDef *gd=0); - void countDocMembers(bool countEnumValues=FALSE); - int countInheritableMembers(ClassDef *inheritedFrom) const; + void countDecMembers(); + void countDocMembers(); + int countInheritableMembers(const ClassDef *inheritedFrom) const; void writePlainDeclarations(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd, GroupDef *gd, - ClassDef *inheritedFrom,const char *inheritId); + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd, const GroupDef *gd, + const ClassDef *inheritedFrom,const char *inheritId) const; void writeDeclarations(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, const char *title,const char *subtitle, bool showEnumValues=FALSE,bool showInline=FALSE, - ClassDef *inheritedFrom=0,MemberListType lt=MemberListType_pubMethods); + const ClassDef *inheritedFrom=0,MemberListType lt=MemberListType_pubMethods) const; void writeDocumentation(OutputList &ol,const char *scopeName, - Definition *container,const char *title,bool showEnumValues=FALSE,bool showInline=FALSE); - void writeSimpleDocumentation(OutputList &ol,Definition *container); + const Definition *container,const char *title, + bool showEnumValues=FALSE,bool showInline=FALSE) const; + void writeSimpleDocumentation(OutputList &ol,const Definition *container) const; void writeDocumentationPage(OutputList &ol, - const char *scopeName, Definition *container); + const char *scopeName, const Definition *container) const; void writeTagFile(FTextStream &); bool declVisible() const; void addMemberGroup(MemberGroup *mg); @@ -88,25 +92,26 @@ class MemberList : private QList<MemberDef> void findSectionsInDocumentation(); void setNeedsSorting(bool b); MemberGroupList *getMemberGroupList() const { return memberGroupList; } - - void marshal(StorageIntf *s); - void unmarshal(StorageIntf *s); + void setAnonymousEnumType(); private: int compareValues(const MemberDef *item1,const MemberDef *item2) const; - int countEnumValues(MemberDef *md,bool setAnonEnumType) const; + int countEnumValues(const MemberDef *md) const; + /* int m_varCnt; int m_funcCnt; int m_enumCnt; - int m_enumValCnt; int m_typeCnt; int m_seqCnt; int m_dictCnt; int m_protoCnt; int m_defCnt; int m_friendCnt; + */ int m_numDecMembers; // number of members in the brief part of the memberlist + int m_numDecEnumValues; int m_numDocMembers; // number of members in the detailed part of the memberlist + int m_numDocEnumValues; MemberGroupList *memberGroupList; bool m_inGroup; // is this list part of a group definition bool m_inFile; // is this list part of a file definition diff --git a/src/membername.cpp b/src/membername.cpp index a5248c3..72809b3 100644 --- a/src/membername.cpp +++ b/src/membername.cpp @@ -32,10 +32,10 @@ MemberName::~MemberName() int MemberName::compareValues(const MemberDef *m1, const MemberDef *m2) const { - ClassDef *c1=m1->getClassDef(); - ClassDef *c2=m2->getClassDef(); - FileDef *f1=m1->getFileDef(); - FileDef *f2=m2->getFileDef(); + const ClassDef *c1=m1->getClassDef(); + const ClassDef *c2=m2->getClassDef(); + const FileDef *f1=m1->getFileDef(); + const FileDef *f2=m2->getFileDef(); if (c1 && c2) return qstrcmp(c1->name(),c2->name()); else if (f1 && f2) @@ -52,10 +52,10 @@ MemberNameInfo::MemberNameInfo(const char *n) : QList<MemberInfo>() int MemberNameInfo::compareValues(const MemberInfo *m1,const MemberInfo *m2) const { - ClassDef *c1=m1->memberDef->getClassDef(); - ClassDef *c2=m2->memberDef->getClassDef(); - FileDef *f1=m1->memberDef->getFileDef(); - FileDef *f2=m2->memberDef->getFileDef(); + const ClassDef *c1=m1->memberDef->getClassDef(); + const ClassDef *c2=m2->memberDef->getClassDef(); + const FileDef *f1=m1->memberDef->getFileDef(); + const FileDef *f2=m2->memberDef->getFileDef(); if (c1 && c2) return qstrcmp(c1->name(),c2->name()); else if (f1 && f2) diff --git a/src/message.cpp b/src/message.cpp index 2f3a06f..ddf757a 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -167,17 +167,29 @@ static void format_warn(const char *file,int line,const char *text) static void do_warn(bool enabled, const char *file, int line, const char *prefix, const char *fmt, va_list args) { if (!enabled) return; // warning type disabled - const int bufSize = 40960; - char text[bufSize]; + + va_list argsCopy; + va_copy(argsCopy, args); + int l=0; if (prefix) { - qstrncpy(text,prefix,bufSize); l=strlen(prefix); } - vsnprintf(text+l, bufSize-l, fmt, args); + // determine needed buffersize based on: + // format + arguments + // prefix + // 1 position for `\0` + int bufSize = vsnprintf(NULL, 0, fmt, args) + l + 1; + char *text = (char *)malloc(sizeof(char) * bufSize); + if (prefix) + { + qstrncpy(text,prefix,bufSize); + } + vsnprintf(text+l, bufSize-l, fmt, argsCopy); text[bufSize-1]='\0'; format_warn(file,line,text); + free(text); } void warn(const char *file,int line,const char *fmt, ...) diff --git a/src/msc.cpp b/src/msc.cpp index 29f96ac..51e23fa 100644 --- a/src/msc.cpp +++ b/src/msc.cpp @@ -24,6 +24,7 @@ #include "index.h" #include "util.h" #include "ftextstream.h" +#include "mscgen_api.h" #include <qdir.h> @@ -50,7 +51,7 @@ static bool convertMapFile(FTextStream &t,const char *mapName,const QCString rel bool isRef = FALSE; int numBytes = f.readLine(buf,maxLineLen); buf[numBytes-1]='\0'; - //printf("ReadLine `%s'\n",buf); + //printf("ReadLine '%s'\n",buf); if (qstrncmp(buf,"rect",4)==0) { // obtain the url and the coordinates in the order used by graphviz-1.5 @@ -97,50 +98,38 @@ void writeMscGraphFromFile(const char *inFile,const char *outDir, absOutFile+=portable_pathSeparator(); absOutFile+=outFile; - // chdir to the output dir, so dot can find the font file. - QCString oldDir = QDir::currentDirPath().utf8(); - // go to the html output directory (i.e. path) - QDir::setCurrent(outDir); - //printf("Going to dir %s\n",QDir::currentDirPath().data()); - QCString mscExe = Config_getString(MSCGEN_PATH)+"mscgen"+portable_commandExtension(); - QCString mscArgs; - QCString imgName = outFile; + mscgen_format_t msc_format; + QCString imgName = absOutFile; switch (format) { case MSC_BITMAP: - mscArgs+="-T png"; + msc_format = mscgen_format_png; imgName+=".png"; break; case MSC_EPS: - mscArgs+="-T eps"; + msc_format = mscgen_format_eps; imgName+=".eps"; break; case MSC_SVG: - mscArgs+="-T svg"; + msc_format = mscgen_format_svg; imgName+=".svg"; break; default: - goto error; // I am not very fond of goto statements, but when in Rome... + return; } - mscArgs+=" -i \""; - mscArgs+=inFile; - - mscArgs+="\" -o \""; - mscArgs+=imgName+"\""; - int exitCode; -// printf("*** running: %s %s outDir:%s %s\n",mscExe.data(),mscArgs.data(),outDir,outFile); - portable_sysTimerStart(); - if ((exitCode=portable_system(mscExe,mscArgs,FALSE))!=0) + int code; + if ((code=mscgen_generate(inFile,imgName,msc_format))!=0) { - portable_sysTimerStop(); - goto error; + err("Problems generating msc output (error=%s). Look for typos in you msc file %s\n", + mscgen_error2str(code),inFile); + return; } - portable_sysTimerStop(); + if ( (format==MSC_EPS) && (Config_getBool(USE_PDFLATEX)) ) { QCString epstopdfArgs(maxCmdLine); epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"", - outFile,outFile); + absOutFile.data(),absOutFile.data()); portable_sysTimerStart(); if (portable_system("epstopdf",epstopdfArgs)!=0) { @@ -151,45 +140,28 @@ void writeMscGraphFromFile(const char *inFile,const char *outDir, Doxygen::indexList->addImageFile(imgName); -error: - QDir::setCurrent(oldDir); } -QCString getMscImageMapFromFile(const QCString& inFile, const QCString& outDir, - const QCString& relPath,const QCString& context) +static QCString getMscImageMapFromFile(const QCString& inFile, const QCString& outDir, + const QCString& relPath,const QCString& context, + bool writeSVGMap) { QCString outFile = inFile + ".map"; - - //printf("*** running:getMscImageMapFromFile \n"); - // chdir to the output dir, so dot can find the font file. - QCString oldDir = QDir::currentDirPath().utf8(); - // go to the html output directory (i.e. path) - QDir::setCurrent(outDir); - //printf("Going to dir %s\n",QDir::currentDirPath().data()); - - QCString mscExe = Config_getString(MSCGEN_PATH)+"mscgen"+portable_commandExtension(); - QCString mscArgs = "-T ismap -i \""; - mscArgs+=inFile; - mscArgs+="\" -o \""; - mscArgs+=outFile + "\""; - - int exitCode; - portable_sysTimerStart(); - if ((exitCode=portable_system(mscExe,mscArgs,FALSE))!=0) + int code; + if ((code=mscgen_generate(inFile,outFile, + writeSVGMap ? mscgen_format_svgmap : mscgen_format_pngmap))!=0) { - portable_sysTimerStop(); - QDir::setCurrent(oldDir); + err("Problems generating msc output (error=%s). Look for typos in you msc file %s\n", + mscgen_error2str(code),inFile.data()); return ""; } - portable_sysTimerStop(); - + QGString result; FTextStream tmpout(&result); convertMapFile(tmpout, outFile, relPath, context); QDir().remove(outFile); - QDir::setCurrent(oldDir); return result.data(); } @@ -217,7 +189,7 @@ void writeMscImageMapFromFile(FTextStream &t,const QCString &inFile, default: t << "unknown"; } - QCString imap = getMscImageMapFromFile(inFile,outDir,relPath,context); + QCString imap = getMscImageMapFromFile(inFile,outDir,relPath,context,format==MSC_SVG); if (!imap.isEmpty()) { t << "\" alt=\"" diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index bc8bb47..38e5c04 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -30,14 +30,237 @@ #include "layout.h" #include "membergroup.h" #include "config.h" +#include "definitionimpl.h" +#include "membername.h" //------------------------------------------------------------------ -NamespaceDef::NamespaceDef(const char *df,int dl,int dc, +class NamespaceDefImpl : public DefinitionImpl, public NamespaceDef +{ + public: + NamespaceDefImpl(const char *defFileName,int defLine,int defColumn, + const char *name,const char *ref=0, + const char *refFile=0,const char*type=0, + bool isPublished=false); + virtual ~NamespaceDefImpl(); + virtual DefType definitionType() const { return TypeNamespace; } + virtual QCString getOutputFileBase() const; + virtual QCString anchor() const { return QCString(); } + virtual void insertUsedFile(FileDef *fd); + virtual void writeDocumentation(OutputList &ol); + virtual void writeMemberPages(OutputList &ol); + virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const; + virtual void writeTagFile(FTextStream &); + virtual void insertClass(const ClassDef *cd); + virtual void insertNamespace(const NamespaceDef *nd); + virtual void insertMember(MemberDef *md); + virtual void computeAnchors(); + virtual void countMembers(); + virtual int numDocMembers() const; + virtual void addUsingDirective(const NamespaceDef *nd); + virtual const NamespaceSDict *getUsedNamespaces() const; + virtual void addUsingDeclaration(const Definition *def); + virtual const SDict<Definition> *getUsedClasses() const { return usingDeclList; } + virtual void combineUsingRelations(); + virtual QCString displayName(bool=TRUE) const; + virtual QCString localName() const; + virtual void setInline(bool isInline) { m_inline = isInline; } + virtual bool isConstantGroup() const { return CONSTANT_GROUP == m_type; } + virtual bool isModule() const { return MODULE == m_type; } + virtual bool isLibrary() const { return LIBRARY == m_type; } + virtual bool isInline() const { return m_inline; } + virtual bool isLinkableInProject() const; + virtual bool isLinkable() const; + virtual bool hasDetailedDescription() const; + virtual void addMembersToMemberGroup(); + virtual void distributeMemberGroupDocumentation(); + virtual void findSectionsInDocumentation(); + virtual void sortMemberLists(); + virtual Definition *findInnerCompound(const char *name) const; + virtual void addInnerCompound(const Definition *d); + virtual void addListReferences(); + virtual void setFileName(const QCString &fn); + virtual bool subGrouping() const { return m_subGrouping; } + virtual MemberList *getMemberList(MemberListType lt) const; + virtual const QList<MemberList> &getMemberLists() const { return m_memberLists; } + virtual MemberDef *getMemberByName(const QCString &) const; + virtual MemberGroupSDict *getMemberGroupSDict() const { return memberGroupSDict; } + virtual ClassSDict *getClassSDict() const { return classSDict; } + virtual ClassSDict *getInterfaceSDict() const { return interfaceSDict; } + virtual ClassSDict *getStructSDict() const { return structSDict; } + virtual ClassSDict *getExceptionSDict() const { return exceptionSDict; } + virtual const NamespaceSDict *getNamespaceSDict() const { return namespaceSDict; } + + virtual QCString title() const; + virtual QCString compoundTypeString() const; + + virtual void setMetaData(const QCString &m); + void setVisited(bool v) { m_visited = v; } + bool isVisited() const { return m_visited; } + + private: + bool m_visited; + MemberList *createMemberList(MemberListType lt); + void addMemberToList(MemberListType lt,MemberDef *md); + void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title); + void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title); + void writeDetailedDescription(OutputList &ol,const QCString &title); + void writeBriefDescription(OutputList &ol); + void startMemberDeclarations(OutputList &ol); + void endMemberDeclarations(OutputList &ol); + void writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d); + void writeInlineClasses(OutputList &ol); + void writeMemberGroups(OutputList &ol); + void writeAuthorSection(OutputList &ol); + void startMemberDocumentation(OutputList &ol); + void endMemberDocumentation(OutputList &ol); + void writeSummaryLinks(OutputList &ol) const; + void addNamespaceAttributes(OutputList &ol); + void writeClassesToTagFile(FTextStream &,ClassSDict *d); + + void writeNamespaceDeclarations(OutputList &ol,const QCString &title, + bool isConstantGroup=false); + + QCString fileName; + FileList files; + + NamespaceSDict *usingDirList; + SDict<Definition> *usingDeclList; + SDict<Definition> *m_innerCompounds; + + MemberSDict *m_allMembersDict; + QList<MemberList> m_memberLists; + MemberGroupSDict *memberGroupSDict; + ClassSDict *classSDict; + ClassSDict *interfaceSDict; + ClassSDict *structSDict; + ClassSDict *exceptionSDict; + NamespaceSDict *namespaceSDict; + bool m_subGrouping; + enum { NAMESPACE, MODULE, CONSTANT_GROUP, LIBRARY } m_type; + bool m_isPublished; + QCString metaData; + bool m_inline; +}; + +NamespaceDef *createNamespaceDef(const char *defFileName,int defLine,int defColumn, + const char *name,const char *ref, + const char *refFile,const char*type, + bool isPublished) +{ + return new NamespaceDefImpl(defFileName,defLine,defColumn,name,ref,refFile,type,isPublished); +} + +//------------------------------------------------------------------ + +class NamespaceDefAliasImpl : public DefinitionAliasImpl, public NamespaceDef +{ + public: + NamespaceDefAliasImpl(const Definition *newScope,const NamespaceDef *nd) : DefinitionAliasImpl(newScope,nd) {} + virtual ~NamespaceDefAliasImpl() {} + virtual DefType definitionType() const { return TypeNamespace; } + + const NamespaceDef *getNSAlias() const { return dynamic_cast<const NamespaceDef*>(getAlias()); } + + // ---- getters + virtual QCString getOutputFileBase() const + { return getNSAlias()->getOutputFileBase(); } + virtual QCString anchor() const + { return getNSAlias()->anchor(); } + virtual int numDocMembers() const + { return getNSAlias()->numDocMembers(); } + virtual void addUsingDirective(const NamespaceDef *nd) {} + virtual const NamespaceSDict *getUsedNamespaces() const + { return getNSAlias()->getUsedNamespaces(); } + virtual void addUsingDeclaration(const Definition *def) {} + virtual const SDict<Definition> *getUsedClasses() const + { return getNSAlias()->getUsedClasses(); } + virtual void combineUsingRelations() {} + virtual QCString displayName(bool b=TRUE) const + { return getNSAlias()->displayName(b); } + virtual QCString localName() const + { return getNSAlias()->localName(); } + virtual void setInline(bool isInline) { } + virtual bool isConstantGroup() const + { return getNSAlias()->isConstantGroup(); } + virtual bool isModule() const + { return getNSAlias()->isModule(); } + virtual bool isLibrary() const + { return getNSAlias()->isLibrary(); } + virtual bool isInline() const + { return getNSAlias()->isInline(); } + virtual bool isLinkableInProject() const + { return getNSAlias()->isLinkableInProject(); } + virtual bool isLinkable() const + { return getNSAlias()->isLinkable(); } + virtual bool hasDetailedDescription() const + { return getNSAlias()->hasDetailedDescription(); } + virtual Definition *findInnerCompound(const char *name) const + { return getNSAlias()->findInnerCompound(name); } + virtual bool subGrouping() const + { return getNSAlias()->subGrouping(); } + virtual MemberList *getMemberList(MemberListType lt) const + { return getNSAlias()->getMemberList(lt); } + virtual const QList<MemberList> &getMemberLists() const + { return getNSAlias()->getMemberLists(); } + virtual MemberDef *getMemberByName(const QCString &name) const + { return getNSAlias()->getMemberByName(name); } + virtual MemberGroupSDict *getMemberGroupSDict() const + { return getNSAlias()->getMemberGroupSDict(); } + virtual ClassSDict *getClassSDict() const + { return getNSAlias()->getClassSDict(); } + virtual ClassSDict *getInterfaceSDict() const + { return getNSAlias()->getInterfaceSDict(); } + virtual ClassSDict *getStructSDict() const + { return getNSAlias()->getStructSDict(); } + virtual ClassSDict *getExceptionSDict() const + { return getNSAlias()->getExceptionSDict(); } + virtual const NamespaceSDict *getNamespaceSDict() const + { return getNSAlias()->getNamespaceSDict(); } + virtual QCString title() const + { return getNSAlias()->title(); } + virtual QCString compoundTypeString() const + { return getNSAlias()->compoundTypeString(); } + + // --- setters/actions + virtual void setMetaData(const QCString &m) {} + virtual void insertUsedFile(FileDef *fd) { } + virtual void writeDocumentation(OutputList &ol) {} + virtual void writeMemberPages(OutputList &ol) {} + virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const {} + virtual void writeTagFile(FTextStream &) {} + virtual void insertClass(const ClassDef *cd) {} + virtual void insertNamespace(const NamespaceDef *nd) {} + virtual void insertMember(MemberDef *md) {} + virtual void computeAnchors() {} + virtual void countMembers() {} + virtual void addMembersToMemberGroup() {} + virtual void distributeMemberGroupDocumentation() {} + virtual void findSectionsInDocumentation() {} + virtual void sortMemberLists() {} + virtual void addInnerCompound(const Definition *d) {} + virtual void addListReferences() {} + virtual void setFileName(const QCString &fn) {} + + void setVisited(bool v) { m_visited = v; } + bool isVisited() const { return m_visited; } + + private: + bool m_visited; +}; + +NamespaceDef *createNamespaceDefAlias(const Definition *newScope,const NamespaceDef *nd) +{ + return new NamespaceDefAliasImpl(newScope,nd); +} + +//------------------------------------------------------------------ + +NamespaceDefImpl::NamespaceDefImpl(const char *df,int dl,int dc, const char *name,const char *lref, const char *fName, const char*type, bool isPublished) : - Definition(df,dl,dc,name) + DefinitionImpl(df,dl,dc,name) ,m_isPublished(isPublished) { if (fName) @@ -67,7 +290,8 @@ NamespaceDef::NamespaceDef(const char *df,int dl,int dc, setReference(lref); memberGroupSDict = new MemberGroupSDict; memberGroupSDict->setAutoDelete(TRUE); - visited=FALSE; + m_visited=FALSE; + m_inline=FALSE; m_subGrouping=Config_getBool(SUBGROUPING); if (type && !strcmp("module", type)) { @@ -87,7 +311,7 @@ NamespaceDef::NamespaceDef(const char *df,int dl,int dc, } } -NamespaceDef::~NamespaceDef() +NamespaceDefImpl::~NamespaceDefImpl() { delete classSDict; delete interfaceSDict; @@ -101,7 +325,7 @@ NamespaceDef::~NamespaceDef() delete m_allMembersDict; } -void NamespaceDef::setFileName(const QCString &fn) +void NamespaceDefImpl::setFileName(const QCString &fn) { if (isReference()) { @@ -113,7 +337,7 @@ void NamespaceDef::setFileName(const QCString &fn) } } -void NamespaceDef::distributeMemberGroupDocumentation() +void NamespaceDefImpl::distributeMemberGroupDocumentation() { MemberGroupSDict::Iterator mgli(*memberGroupSDict); MemberGroup *mg; @@ -123,7 +347,7 @@ void NamespaceDef::distributeMemberGroupDocumentation() } } -void NamespaceDef::findSectionsInDocumentation() +void NamespaceDefImpl::findSectionsInDocumentation() { docFindSections(documentation(),this,0,docFile()); MemberGroupSDict::Iterator mgli(*memberGroupSDict); @@ -143,7 +367,7 @@ void NamespaceDef::findSectionsInDocumentation() } } -void NamespaceDef::insertUsedFile(FileDef *fd) +void NamespaceDefImpl::insertUsedFile(FileDef *fd) { if (fd==0) return; if (files.find(fd)==-1) @@ -155,20 +379,20 @@ void NamespaceDef::insertUsedFile(FileDef *fd) } } -void NamespaceDef::addInnerCompound(Definition *d) +void NamespaceDefImpl::addInnerCompound(const Definition *d) { m_innerCompounds->append(d->localName(),d); if (d->definitionType()==Definition::TypeNamespace) { - insertNamespace((NamespaceDef *)d); + insertNamespace(dynamic_cast<const NamespaceDef *>(d)); } else if (d->definitionType()==Definition::TypeClass) { - insertClass((ClassDef *)d); + insertClass(dynamic_cast<const ClassDef *>(d)); } } -void NamespaceDef::insertClass(ClassDef *cd) +void NamespaceDefImpl::insertClass(const ClassDef *cd) { ClassSDict *d = classSDict; @@ -201,7 +425,7 @@ void NamespaceDef::insertClass(ClassDef *cd) } } -void NamespaceDef::insertNamespace(NamespaceDef *nd) +void NamespaceDefImpl::insertNamespace(const NamespaceDef *nd) { if (namespaceSDict->find(nd->name())==0) { @@ -213,7 +437,7 @@ void NamespaceDef::insertNamespace(NamespaceDef *nd) } -void NamespaceDef::addMembersToMemberGroup() +void NamespaceDefImpl::addMembersToMemberGroup() { QListIterator<MemberList> mli(m_memberLists); MemberList *ml; @@ -241,8 +465,9 @@ void NamespaceDef::addMembersToMemberGroup() } } -void NamespaceDef::insertMember(MemberDef *md) +void NamespaceDefImpl::insertMember(MemberDef *md) { + //printf("%s::insertMember(%s)\n",qPrint(name()),qPrint(md->name())); if (md->isHidden()) return; MemberList *allMemberList = getMemberList(MemberListType_allMembersList); if (allMemberList==0) @@ -292,28 +517,62 @@ void NamespaceDef::insertMember(MemberDef *md) addMemberToList(MemberListType_docDefineMembers,md); break; default: - err("NamespaceDef::insertMembers(): " - "member `%s' with class scope `%s' inserted in namespace scope `%s'!\n", + err("NamespaceDefImpl::insertMembers(): " + "member '%s' with class scope '%s' inserted in namespace scope '%s'!\n", md->name().data(), md->getClassDef() ? md->getClassDef()->name().data() : "", name().data()); } + // if this is an inline namespace, then insert an alias of this member in the outer scope. + if (isInline()) + { + Definition *outerScope = getOuterScope(); + if (outerScope) + { + MemberDef *aliasMd = 0; + if (outerScope->definitionType()==Definition::TypeNamespace) + { + aliasMd = createMemberDefAlias(outerScope,md); + dynamic_cast<NamespaceDef*>(outerScope)->insertMember(aliasMd); + } + else if (outerScope->definitionType()==Definition::TypeFile) + { + aliasMd = createMemberDefAlias(outerScope,md); + dynamic_cast<FileDef*>(outerScope)->insertMember(aliasMd); + } + if (aliasMd) + { + MemberName *mn; + QCString name = md->name(); + if ((mn=Doxygen::functionNameSDict->find(name))) + { + mn->append(aliasMd); + } + else + { + mn = new MemberName(name); + mn->append(aliasMd); + Doxygen::functionNameSDict->append(name,mn); + } + } + } + } } -void NamespaceDef::computeAnchors() +void NamespaceDefImpl::computeAnchors() { MemberList *allMemberList = getMemberList(MemberListType_allMembersList); if (allMemberList) setAnchors(allMemberList); } -bool NamespaceDef::hasDetailedDescription() const +bool NamespaceDefImpl::hasDetailedDescription() const { static bool repeatBrief = Config_getBool(REPEAT_BRIEF); return ((!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty()); } -void NamespaceDef::writeTagFile(FTextStream &tagFile) +void NamespaceDefImpl::writeTagFile(FTextStream &tagFile) { tagFile << " <compound kind=\"namespace\">" << endl; tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; @@ -401,7 +660,7 @@ void NamespaceDef::writeTagFile(FTextStream &tagFile) tagFile << " </compound>" << endl; } -void NamespaceDef::writeDetailedDescription(OutputList &ol,const QCString &title) +void NamespaceDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title) { if (hasDetailedDescription()) { @@ -443,7 +702,7 @@ void NamespaceDef::writeDetailedDescription(OutputList &ol,const QCString &title } } -void NamespaceDef::writeBriefDescription(OutputList &ol) +void NamespaceDefImpl::writeBriefDescription(OutputList &ol) { if (hasBriefDescription()) { @@ -465,7 +724,7 @@ void NamespaceDef::writeBriefDescription(OutputList &ol) if (hasDetailedDescription()) { ol.disableAllBut(OutputGenerator::Html); - ol.startTextLink(0,"details"); + ol.startTextLink(getOutputFileBase(),"details"); ol.parseText(theTranslator->trMore()); ol.endTextLink(); } @@ -501,17 +760,17 @@ void NamespaceDef::writeBriefDescription(OutputList &ol) ol.writeSynopsis(); } -void NamespaceDef::startMemberDeclarations(OutputList &ol) +void NamespaceDefImpl::startMemberDeclarations(OutputList &ol) { ol.startMemberSections(); } -void NamespaceDef::endMemberDeclarations(OutputList &ol) +void NamespaceDefImpl::endMemberDeclarations(OutputList &ol) { ol.endMemberSections(); } -void NamespaceDef::startMemberDocumentation(OutputList &ol) +void NamespaceDefImpl::startMemberDocumentation(OutputList &ol) { if (Config_getBool(SEPARATE_MEMBER_PAGES)) { @@ -520,7 +779,7 @@ void NamespaceDef::startMemberDocumentation(OutputList &ol) } } -void NamespaceDef::endMemberDocumentation(OutputList &ol) +void NamespaceDefImpl::endMemberDocumentation(OutputList &ol) { if (Config_getBool(SEPARATE_MEMBER_PAGES)) { @@ -529,23 +788,23 @@ void NamespaceDef::endMemberDocumentation(OutputList &ol) } } -void NamespaceDef::writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d) +void NamespaceDefImpl::writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d) { if (d) d->writeDeclaration(ol,0,title,TRUE); } -void NamespaceDef::writeInlineClasses(OutputList &ol) +void NamespaceDefImpl::writeInlineClasses(OutputList &ol) { if (classSDict) classSDict->writeDocumentation(ol,this); } -void NamespaceDef::writeNamespaceDeclarations(OutputList &ol,const QCString &title, +void NamespaceDefImpl::writeNamespaceDeclarations(OutputList &ol,const QCString &title, bool const isConstantGroup) { if (namespaceSDict) namespaceSDict->writeDeclaration(ol,title,isConstantGroup,TRUE); } -void NamespaceDef::writeMemberGroups(OutputList &ol) +void NamespaceDefImpl::writeMemberGroups(OutputList &ol) { /* write user defined member groups */ if (memberGroupSDict) @@ -564,7 +823,7 @@ void NamespaceDef::writeMemberGroups(OutputList &ol) } } -void NamespaceDef::writeAuthorSection(OutputList &ol) +void NamespaceDefImpl::writeAuthorSection(OutputList &ol) { // write Author section (Man only) ol.pushGeneratorState(); @@ -576,7 +835,7 @@ void NamespaceDef::writeAuthorSection(OutputList &ol) ol.popGeneratorState(); } -void NamespaceDef::writeSummaryLinks(OutputList &ol) +void NamespaceDefImpl::writeSummaryLinks(OutputList &ol) const { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -640,7 +899,7 @@ void NamespaceDef::writeSummaryLinks(OutputList &ol) ol.popGeneratorState(); } -void NamespaceDef::addNamespaceAttributes(OutputList &ol) +void NamespaceDefImpl::addNamespaceAttributes(OutputList &ol) { // UNO IDL constant groups may be published if (getLanguage()==SrcLangExt_IDL && isConstantGroup() && m_isPublished) @@ -654,7 +913,7 @@ void NamespaceDef::addNamespaceAttributes(OutputList &ol) } } -void NamespaceDef::writeClassesToTagFile(FTextStream &tagFile,ClassSDict *d) +void NamespaceDefImpl::writeClassesToTagFile(FTextStream &tagFile,ClassSDict *d) { SDict<ClassDef>::Iterator ci(*d); ClassDef *cd; @@ -668,7 +927,7 @@ void NamespaceDef::writeClassesToTagFile(FTextStream &tagFile,ClassSDict *d) } } -void NamespaceDef::writeDocumentation(OutputList &ol) +void NamespaceDefImpl::writeDocumentation(OutputList &ol) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); //static bool outputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA); @@ -838,7 +1097,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) } } -void NamespaceDef::writeMemberPages(OutputList &ol) +void NamespaceDefImpl::writeMemberPages(OutputList &ol) { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -855,7 +1114,7 @@ void NamespaceDef::writeMemberPages(OutputList &ol) ol.popGeneratorState(); } -void NamespaceDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const +void NamespaceDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const { static bool createSubDirs=Config_getBool(CREATE_SUBDIRS); @@ -898,15 +1157,34 @@ void NamespaceDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) co ol.writeString(" </div>\n"); } -int NamespaceDef::countMembers() +void NamespaceDefImpl::countMembers() +{ + QListIterator<MemberList> mli(m_memberLists); + MemberList *ml; + for (mli.toFirst();(ml=mli.current());++mli) + { + ml->countDecMembers(); + ml->countDocMembers(); + } + if (memberGroupSDict) + { + MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + mg->countDecMembers(); + mg->countDocMembers(); + } + } +} + +int NamespaceDefImpl::numDocMembers() const { MemberList *allMemberList = getMemberList(MemberListType_allMembersList); - if (allMemberList) allMemberList->countDocMembers(); - return (allMemberList ? allMemberList->numDocMembers() : 0) + - classSDict->count() + interfaceSDict->count() + structSDict->count() + exceptionSDict->count(); + return (allMemberList ? allMemberList->numDocMembers() : 0) + m_innerCompounds->count(); } -void NamespaceDef::addUsingDirective(NamespaceDef *nd) +void NamespaceDefImpl::addUsingDirective(const NamespaceDef *nd) { if (usingDirList==0) { @@ -916,16 +1194,16 @@ void NamespaceDef::addUsingDirective(NamespaceDef *nd) { usingDirList->append(nd->qualifiedName(),nd); } - //printf("%p: NamespaceDef::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count()); + //printf("%p: NamespaceDefImpl::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count()); } -NamespaceSDict *NamespaceDef::getUsedNamespaces() const +const NamespaceSDict *NamespaceDefImpl::getUsedNamespaces() const { - //printf("%p: NamespaceDef::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0); + //printf("%p: NamespaceDefImpl::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0); return usingDirList; } -void NamespaceDef::addUsingDeclaration(Definition *d) +void NamespaceDefImpl::addUsingDeclaration(const Definition *d) { if (usingDeclList==0) { @@ -937,12 +1215,12 @@ void NamespaceDef::addUsingDeclaration(Definition *d) } } -QCString NamespaceDef::getOutputFileBase() const +QCString NamespaceDefImpl::getOutputFileBase() const { return fileName; } -Definition *NamespaceDef::findInnerCompound(const char *n) const +Definition *NamespaceDefImpl::findInnerCompound(const char *n) const { if (n==0) return 0; Definition *d = m_innerCompounds->find(n); @@ -960,7 +1238,7 @@ Definition *NamespaceDef::findInnerCompound(const char *n) const return d; } -void NamespaceDef::addListReferences() +void NamespaceDefImpl::addListReferences() { //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); { @@ -992,7 +1270,7 @@ void NamespaceDef::addListReferences() } } -QCString NamespaceDef::displayName(bool includeScope) const +QCString NamespaceDefImpl::displayName(bool includeScope) const { QCString result=includeScope ? name() : localName(); SrcLangExt lang = getLanguage(); @@ -1001,11 +1279,11 @@ QCString NamespaceDef::displayName(bool includeScope) const { result = substitute(result,"::",sep); } - //printf("NamespaceDef::displayName() %s->%s lang=%d\n",name().data(),result.data(),lang); + //printf("NamespaceDefImpl::displayName() %s->%s lang=%d\n",name().data(),result.data(),lang); return result; } -QCString NamespaceDef::localName() const +QCString NamespaceDefImpl::localName() const { QCString result=name(); int i=result.findRev("::"); @@ -1016,10 +1294,10 @@ QCString NamespaceDef::localName() const return result; } -void NamespaceDef::combineUsingRelations() +void NamespaceDefImpl::combineUsingRelations() { - if (visited) return; // already done - visited=TRUE; + if (m_visited) return; // already done + m_visited=TRUE; if (usingDirList) { NamespaceSDict::Iterator nli(*usingDirList); @@ -1152,7 +1430,7 @@ void NamespaceSDict::writeDeclaration(OutputList &ol,const char *title, ol.endMemberList(); } -MemberList *NamespaceDef::createMemberList(MemberListType lt) +MemberList *NamespaceDefImpl::createMemberList(MemberListType lt) { m_memberLists.setAutoDelete(TRUE); QListIterator<MemberList> mli(m_memberLists); @@ -1170,7 +1448,7 @@ MemberList *NamespaceDef::createMemberList(MemberListType lt) return ml; } -void NamespaceDef::addMemberToList(MemberListType lt,MemberDef *md) +void NamespaceDefImpl::addMemberToList(MemberListType lt,MemberDef *md) { static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS); static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS); @@ -1180,17 +1458,13 @@ void NamespaceDef::addMemberToList(MemberListType lt,MemberDef *md) ((ml->listType()&MemberListType_documentationLists) && sortMemberDocs)); ml->append(md); -#if 0 - if (ml->needsSorting()) - ml->inSort(md); - else - ml->append(md); -#endif - - if (ml->listType()&MemberListType_declarationLists) md->setSectionList(this,ml); + if (ml->listType()&MemberListType_declarationLists) + { + md->setSectionList(this,ml); + } } -void NamespaceDef::sortMemberLists() +void NamespaceDefImpl::sortMemberLists() { QListIterator<MemberList> mli(m_memberLists); MemberList *ml; @@ -1220,7 +1494,7 @@ void NamespaceDef::sortMemberLists() } } -MemberList *NamespaceDef::getMemberList(MemberListType lt) const +MemberList *NamespaceDefImpl::getMemberList(MemberListType lt) const { QListIterator<MemberList> mli(m_memberLists); MemberList *ml; @@ -1234,20 +1508,20 @@ MemberList *NamespaceDef::getMemberList(MemberListType lt) const return 0; } -void NamespaceDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title) +void NamespaceDefImpl::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title) { MemberList * ml = getMemberList(lt); if (ml) ml->writeDeclarations(ol,0,this,0,0,title,0); } -void NamespaceDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title) +void NamespaceDefImpl::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title) { MemberList * ml = getMemberList(lt); if (ml) ml->writeDocumentation(ol,displayName(),this,title); } -bool NamespaceDef::isLinkableInProject() const +bool NamespaceDefImpl::isLinkableInProject() const { int i = name().findRev("::"); if (i==-1) i=0; else i+=2; @@ -1265,12 +1539,12 @@ bool NamespaceDef::isLinkableInProject() const !isArtificial(); // or artificial } -bool NamespaceDef::isLinkable() const +bool NamespaceDefImpl::isLinkable() const { return isLinkableInProject() || isReference(); } -MemberDef * NamespaceDef::getMemberByName(const QCString &n) const +MemberDef * NamespaceDefImpl::getMemberByName(const QCString &n) const { MemberDef *md = 0; if (m_allMembersDict && !n.isEmpty()) @@ -1281,7 +1555,7 @@ MemberDef * NamespaceDef::getMemberByName(const QCString &n) const return md; } -QCString NamespaceDef::title() const +QCString NamespaceDefImpl::title() const { SrcLangExt lang = getLanguage(); QCString pageTitle; @@ -1306,7 +1580,7 @@ QCString NamespaceDef::title() const return pageTitle; } -QCString NamespaceDef::compoundTypeString() const +QCString NamespaceDefImpl::compoundTypeString() const { SrcLangExt lang = getLanguage(); if (lang==SrcLangExt_Java) @@ -1343,7 +1617,7 @@ QCString NamespaceDef::compoundTypeString() const return ""; } -void NamespaceDef::setMetaData(const QCString &m) +void NamespaceDefImpl::setMetaData(const QCString &m) { metaData = m; } diff --git a/src/namespacedef.h b/src/namespacedef.h index b46d074..3be54f2 100644 --- a/src/namespacedef.h +++ b/src/namespacedef.h @@ -26,137 +26,102 @@ class MemberList; class ClassDef; -class ClassList; class OutputList; class ClassSDict; class MemberDef; -class NamespaceList; class MemberGroupSDict; class NamespaceSDict; class FTextStream; -/** A model of a namespace symbol. */ -class NamespaceDef : public Definition +/** An abstract interface of a namespace symbol. */ +class NamespaceDef : virtual public Definition { public: - NamespaceDef(const char *defFileName,int defLine,int defColumn, - const char *name,const char *ref=0, - const char *refFile=0,const char*type=0, - bool isPublished=false); - ~NamespaceDef(); - DefType definitionType() const { return TypeNamespace; } - QCString getOutputFileBase() const; - QCString anchor() const { return QCString(); } - void insertUsedFile(FileDef *fd); - - void writeDocumentation(OutputList &ol); - void writeMemberPages(OutputList &ol); - void writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const; - void writeTagFile(FTextStream &); - - void insertClass(ClassDef *cd); - void insertNamespace(NamespaceDef *nd); - void insertMember(MemberDef *md); - - void computeAnchors(); - int countMembers(); - void addUsingDirective(NamespaceDef *nd); - NamespaceSDict *getUsedNamespaces() const; - void addUsingDeclaration(Definition *def); - SDict<Definition> *getUsedClasses() const { return usingDeclList; } - void combineUsingRelations(); - QCString displayName(bool=TRUE) const; - QCString localName() const; - - bool isConstantGroup() const { return CONSTANT_GROUP == m_type; } - bool isModule() const { return MODULE == m_type; } - bool isLibrary() const { return LIBRARY == m_type; } - - bool isLinkableInProject() const; - bool isLinkable() const; - bool hasDetailedDescription() const; - void addMembersToMemberGroup(); - void distributeMemberGroupDocumentation(); - void findSectionsInDocumentation(); - void sortMemberLists(); - - virtual Definition *findInnerCompound(const char *name) const; - void addInnerCompound(Definition *d); - void addListReferences(); - void setFileName(const QCString &fn); - - bool subGrouping() const { return m_subGrouping; } - - MemberList *getMemberList(MemberListType lt) const; - const QList<MemberList> &getMemberLists() const { return m_memberLists; } - MemberDef *getMemberByName(const QCString &) const; + virtual ~NamespaceDef() {} + virtual DefType definitionType() const = 0; + virtual QCString getOutputFileBase() const = 0; + virtual QCString anchor() const = 0; + virtual void insertUsedFile(FileDef *fd) = 0; + + virtual void writeDocumentation(OutputList &ol) = 0; + virtual void writeMemberPages(OutputList &ol) = 0; + virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const = 0; + virtual void writeTagFile(FTextStream &) = 0; + + virtual void insertClass(const ClassDef *cd) = 0; + virtual void insertNamespace(const NamespaceDef *nd) = 0; + virtual void insertMember(MemberDef *md) = 0; // md cannot be const, since setSectionList is called on it + + virtual void computeAnchors() = 0; + virtual void countMembers() = 0; + virtual int numDocMembers() const = 0; + virtual void addUsingDirective(const NamespaceDef *nd) = 0; + virtual const NamespaceSDict *getUsedNamespaces() const = 0; + virtual void addUsingDeclaration(const Definition *def) = 0; + virtual const SDict<Definition> *getUsedClasses() const = 0; + virtual void combineUsingRelations() = 0; + virtual QCString displayName(bool=TRUE) const = 0; + virtual QCString localName() const = 0; + virtual void setInline(bool isInline) = 0; + + virtual bool isConstantGroup() const = 0; + virtual bool isModule() const = 0; + virtual bool isLibrary() const = 0; + virtual bool isInline() const = 0; + + virtual bool isLinkableInProject() const = 0; + virtual bool isLinkable() const = 0; + virtual bool hasDetailedDescription() const = 0; + virtual void addMembersToMemberGroup() = 0; + virtual void distributeMemberGroupDocumentation() = 0; + virtual void findSectionsInDocumentation() = 0; + virtual void sortMemberLists() = 0; + + virtual Definition *findInnerCompound(const char *name) const = 0; + virtual void addInnerCompound(const Definition *d) = 0; + virtual void addListReferences() = 0; + virtual void setFileName(const QCString &fn) = 0; + + virtual bool subGrouping() const = 0; + + virtual MemberList *getMemberList(MemberListType lt) const = 0; + virtual const QList<MemberList> &getMemberLists() const = 0; + virtual MemberDef *getMemberByName(const QCString &) const = 0; /*! Returns the user defined member groups */ - MemberGroupSDict *getMemberGroupSDict() const { return memberGroupSDict; } + virtual MemberGroupSDict *getMemberGroupSDict() const = 0; /*! Returns the classes contained in this namespace */ - ClassSDict *getClassSDict() const { return classSDict; } + virtual ClassSDict *getClassSDict() const = 0; /*! Returns the Slice interfaces contained in this namespace */ - ClassSDict *getInterfaceSDict() const { return interfaceSDict; } + virtual ClassSDict *getInterfaceSDict() const = 0; /*! Returns the Slice structs contained in this namespace */ - ClassSDict *getStructSDict() const { return structSDict; } + virtual ClassSDict *getStructSDict() const = 0; /*! Returns the Slice exceptions contained in this namespace */ - ClassSDict *getExceptionSDict() const { return exceptionSDict; } + virtual ClassSDict *getExceptionSDict() const = 0; /*! Returns the namespaces contained in this namespace */ - NamespaceSDict *getNamespaceSDict() const { return namespaceSDict; } + virtual const NamespaceSDict *getNamespaceSDict() const = 0; - QCString title() const; - QCString compoundTypeString() const; + virtual QCString title() const = 0; + virtual QCString compoundTypeString() const = 0; - void setMetaData(const QCString &m); + virtual void setMetaData(const QCString &m) = 0; + virtual void setVisited(bool v) = 0; + virtual bool isVisited() const = 0; +}; - bool visited; +/** Factory method to create new NamespaceDef instance */ +NamespaceDef *createNamespaceDef(const char *defFileName,int defLine,int defColumn, + const char *name,const char *ref=0, + const char *refFile=0,const char*type=0, + bool isPublished=false); - private: - MemberList *createMemberList(MemberListType lt); - void addMemberToList(MemberListType lt,MemberDef *md); - void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title); - void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title); - void writeDetailedDescription(OutputList &ol,const QCString &title); - void writeBriefDescription(OutputList &ol); - void startMemberDeclarations(OutputList &ol); - void endMemberDeclarations(OutputList &ol); - void writeClassDeclarations(OutputList &ol,const QCString &title,ClassSDict *d); - void writeInlineClasses(OutputList &ol); - void writeNamespaceDeclarations(OutputList &ol,const QCString &title, - bool isConstantGroup=false); - void writeMemberGroups(OutputList &ol); - void writeAuthorSection(OutputList &ol); - void startMemberDocumentation(OutputList &ol); - void endMemberDocumentation(OutputList &ol); - void writeSummaryLinks(OutputList &ol); - void addNamespaceAttributes(OutputList &ol); - void writeClassesToTagFile(FTextStream &,ClassSDict *d); - - QCString fileName; - FileList files; - - NamespaceSDict *usingDirList; - SDict<Definition> *usingDeclList; - SDict<Definition> *m_innerCompounds; - - MemberSDict *m_allMembersDict; - QList<MemberList> m_memberLists; - MemberGroupSDict *memberGroupSDict; - ClassSDict *classSDict; - ClassSDict *interfaceSDict; - ClassSDict *structSDict; - ClassSDict *exceptionSDict; - NamespaceSDict *namespaceSDict; - bool m_subGrouping; - enum { NAMESPACE, MODULE, CONSTANT_GROUP, LIBRARY } m_type; - bool m_isPublished; - QCString metaData; -}; +/** Factory method to create an alias of an existing namespace. Used for inline namespaces. */ +NamespaceDef *createNamespaceDefAlias(const Definition *newScope, const NamespaceDef *nd); /** A list of NamespaceDef objects. */ class NamespaceList : public QList<NamespaceDef> diff --git a/src/outputgen.h b/src/outputgen.h index a99cff3..322f4b7 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -124,7 +124,7 @@ class CodeOutputInterface */ virtual void writeCodeAnchor(const char *name) = 0; - virtual void setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile) = 0; + virtual void setCurrentDoc(const Definition *context,const char *anchor,bool isSourceFile) = 0; virtual void addWord(const char *word,bool hiPriority) = 0; }; @@ -150,7 +150,7 @@ class BaseOutputDocInterface : public CodeOutputInterface Examples }; - virtual bool parseText(const QCString &s) { return s.isEmpty(); } + virtual void parseText(const QCString &s) {} /*! Start of a bullet list: e.g. \c \<ul\> in html. startItemListItem() is * Used for the bullet items. @@ -346,7 +346,7 @@ class OutputGenerator : public BaseOutputDocInterface //void setEncoding(const QCString &enc) { encoding = enc; } //virtual void postProcess(QByteArray &) { } - virtual void writeDoc(DocNode *,Definition *ctx,MemberDef *md) = 0; + virtual void writeDoc(DocNode *,const Definition *ctx,const MemberDef *md) = 0; /////////////////////////////////////////////////////////////// // structural output interface @@ -428,16 +428,16 @@ class OutputGenerator : public BaseOutputDocInterface virtual void startClassDiagram() = 0; virtual void endClassDiagram(const ClassDiagram &,const char *,const char *) = 0; virtual void startDotGraph() = 0; - virtual void endDotGraph(const DotClassGraph &g) = 0; + virtual void endDotGraph(DotClassGraph &g) = 0; virtual void startInclDepGraph() = 0; - virtual void endInclDepGraph(const DotInclDepGraph &g) = 0; + virtual void endInclDepGraph(DotInclDepGraph &g) = 0; virtual void startGroupCollaboration() = 0; - virtual void endGroupCollaboration(const DotGroupCollaboration &g) = 0; + virtual void endGroupCollaboration(DotGroupCollaboration &g) = 0; virtual void startCallGraph() = 0; - virtual void endCallGraph(const DotCallGraph &g) = 0; + virtual void endCallGraph(DotCallGraph &g) = 0; virtual void startDirDepGraph() = 0; - virtual void endDirDepGraph(const DotDirDeps &g) = 0; - virtual void writeGraphicalHierarchy(const DotGfxHierarchyTable &g) = 0; + virtual void endDirDepGraph(DotDirDeps &g) = 0; + virtual void writeGraphicalHierarchy(DotGfxHierarchyTable &g) = 0; virtual void startQuickIndices() = 0; virtual void endQuickIndices() = 0; virtual void writeSplitBar(const char *) = 0; diff --git a/src/outputlist.cpp b/src/outputlist.cpp index 93a1b6e..daf3270 100644 --- a/src/outputlist.cpp +++ b/src/outputlist.cpp @@ -128,14 +128,14 @@ void OutputList::popGeneratorState() } } -bool OutputList::generateDoc(const char *fileName,int startLine, - Definition *ctx,MemberDef * md, +void OutputList::generateDoc(const char *fileName,int startLine, + const Definition *ctx,const MemberDef * md, const QCString &docStr,bool indexWords, bool isExample,const char *exampleName, bool singleLine,bool linkFromIndex) { int count=0; - if (docStr.isEmpty()) return TRUE; + if (docStr.isEmpty()) return; QListIterator<OutputGenerator> it(m_outputs); OutputGenerator *og; @@ -143,23 +143,20 @@ bool OutputList::generateDoc(const char *fileName,int startLine, { if (og->isEnabled()) count++; } - if (count==0) return TRUE; // no output formats enabled. + // we want to validate irrespective of the number of output formats + // specified as: + // - when only XML format there should be warnings as well (XML has its own write routines) + // - no formats there should be warnings as well DocRoot *root=0; root = validatingParseDoc(fileName,startLine, ctx,md,docStr,indexWords,isExample,exampleName, singleLine,linkFromIndex); - - writeDoc(root,ctx,md); - - bool isEmpty = root->isEmpty(); - + if (count>0) writeDoc(root,ctx,md); delete root; - - return isEmpty; } -void OutputList::writeDoc(DocRoot *root,Definition *ctx,MemberDef *md) +void OutputList::writeDoc(DocRoot *root,const Definition *ctx,const MemberDef *md) { QListIterator<OutputGenerator> it(m_outputs); OutputGenerator *og; @@ -172,7 +169,7 @@ void OutputList::writeDoc(DocRoot *root,Definition *ctx,MemberDef *md) VhdlDocGen::setFlowMember(0); } -bool OutputList::parseText(const QCString &textStr) +void OutputList::parseText(const QCString &textStr) { int count=0; QListIterator<OutputGenerator> it(m_outputs); @@ -181,20 +178,22 @@ bool OutputList::parseText(const QCString &textStr) { if (og->isEnabled()) count++; } - if (count==0) return TRUE; // no output formats enabled. + // we want to validate irrespective of the number of output formats + // specified as: + // - when only XML format there should be warnings as well (XML has its own write routines) + // - no formats there should be warnings as well DocText *root = validatingParseText(textStr); - for (it.toFirst();(og=it.current());++it) + if (count>0) { - if (og->isEnabled()) og->writeDoc(root,0,0); + for (it.toFirst();(og=it.current());++it) + { + if (og->isEnabled()) og->writeDoc(root,0,0); + } } - bool isEmpty = root->isEmpty(); - delete root; - - return isEmpty; } @@ -316,12 +315,12 @@ void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4,a5,a6,a7,a8),a FORALL1(const char *a1,a1) FORALL1(char a1,a1) FORALL1(int a1,a1) -FORALL1(const DotClassGraph &a1,a1) -FORALL1(const DotInclDepGraph &a1,a1) -FORALL1(const DotCallGraph &a1,a1) -FORALL1(const DotDirDeps &a1,a1) -FORALL1(const DotGfxHierarchyTable &a1,a1) -FORALL1(const DotGroupCollaboration &a1,a1) +FORALL1(DotClassGraph &a1,a1) +FORALL1(DotInclDepGraph &a1,a1) +FORALL1(DotCallGraph &a1,a1) +FORALL1(DotDirDeps &a1,a1) +FORALL1(DotGfxHierarchyTable &a1,a1) +FORALL1(DotGroupCollaboration &a1,a1) FORALL1(SectionTypes a1,a1) #if defined(HAS_BOOL_TYPE) || defined(Q_HAS_BOOL_TYPE) FORALL1(bool a1,a1) @@ -345,7 +344,7 @@ FORALL3(const char *a1,const char *a2,bool a3,a1,a2,a3) FORALL3(const char *a1,int a2,const char *a3,a1,a2,a3) FORALL3(const char *a1,const char *a2,SectionInfo::SectionType a3,a1,a2,a3) FORALL3(uchar a1,uchar a2,uchar a3,a1,a2,a3) -FORALL3(Definition *a1,const char *a2,bool a3,a1,a2,a3) +FORALL3(const Definition *a1,const char *a2,bool a3,a1,a2,a3) FORALL4(SectionTypes a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4) FORALL4(const char *a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4) FORALL4(const char *a1,const char *a2,const char *a3,int a4,a1,a2,a3,a4) diff --git a/src/outputlist.h b/src/outputlist.h index 5fd8017..2a83020 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -74,13 +74,12 @@ class OutputList : public OutputDocInterface // OutputDocInterface implementation ////////////////////////////////////////////////// - bool generateDoc(const char *fileName,int startLine, - Definition *ctx,MemberDef *md,const QCString &docStr, + void generateDoc(const char *fileName,int startLine, + const Definition *ctx,const MemberDef *md,const QCString &docStr, bool indexWords,bool isExample,const char *exampleName=0, bool singleLine=FALSE,bool linkFromIndex=FALSE); - void writeDoc(DocRoot *root,Definition *ctx,MemberDef *md); - bool parseText(const QCString &textStr); - + void writeDoc(DocRoot *root,const Definition *ctx,const MemberDef *md); + void parseText(const QCString &textStr); void startIndexSection(IndexSections is) { forall(&OutputGenerator::startIndexSection,is); } @@ -391,25 +390,25 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::endDescTableData); } void startDotGraph() { forall(&OutputGenerator::startDotGraph); } - void endDotGraph(const DotClassGraph &g) + void endDotGraph(DotClassGraph &g) { forall(&OutputGenerator::endDotGraph,g); } void startInclDepGraph() { forall(&OutputGenerator::startInclDepGraph); } - void endInclDepGraph(const DotInclDepGraph &g) + void endInclDepGraph(DotInclDepGraph &g) { forall(&OutputGenerator::endInclDepGraph,g); } void startCallGraph() { forall(&OutputGenerator::startCallGraph); } - void endCallGraph(const DotCallGraph &g) + void endCallGraph(DotCallGraph &g) { forall(&OutputGenerator::endCallGraph,g); } void startDirDepGraph() { forall(&OutputGenerator::startDirDepGraph); } - void endDirDepGraph(const DotDirDeps &g) + void endDirDepGraph(DotDirDeps &g) { forall(&OutputGenerator::endDirDepGraph,g); } void startGroupCollaboration() { forall(&OutputGenerator::startGroupCollaboration); } - void endGroupCollaboration(const DotGroupCollaboration &g) + void endGroupCollaboration(DotGroupCollaboration &g) { forall(&OutputGenerator::endGroupCollaboration,g); } - void writeGraphicalHierarchy(const DotGfxHierarchyTable &g) + void writeGraphicalHierarchy(DotGfxHierarchyTable &g) { forall(&OutputGenerator::writeGraphicalHierarchy,g); } void startTextBlock(bool dense=FALSE) { forall(&OutputGenerator::startTextBlock,dense); } @@ -487,7 +486,7 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::endFontClass); } void writeCodeAnchor(const char *name) { forall(&OutputGenerator::writeCodeAnchor,name); } - void setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile) + void setCurrentDoc(const Definition *context,const char *anchor,bool isSourceFile) { forall(&OutputGenerator::setCurrentDoc,context,anchor,isSourceFile); } void addWord(const char *word,bool hiPriority) { forall(&OutputGenerator::addWord,word,hiPriority); } @@ -520,12 +519,12 @@ class OutputList : public OutputDocInterface FORALLPROTO1(char); FORALLPROTO1(IndexSections); FORALLPROTO1(int); - FORALLPROTO1(const DotClassGraph &); - FORALLPROTO1(const DotInclDepGraph &); - FORALLPROTO1(const DotCallGraph &); - FORALLPROTO1(const DotGroupCollaboration &); - FORALLPROTO1(const DotDirDeps &); - FORALLPROTO1(const DotGfxHierarchyTable &); + FORALLPROTO1(DotClassGraph &); + FORALLPROTO1(DotInclDepGraph &); + FORALLPROTO1(DotCallGraph &); + FORALLPROTO1(DotGroupCollaboration &); + FORALLPROTO1(DotDirDeps &); + FORALLPROTO1(DotGfxHierarchyTable &); FORALLPROTO1(SectionTypes); #if defined(HAS_BOOL_TYPE) || defined(Q_HAS_BOOL_TYPE) FORALLPROTO1(bool); @@ -548,7 +547,7 @@ class OutputList : public OutputDocInterface FORALLPROTO3(uchar,uchar,uchar); FORALLPROTO3(const char *,const char *,const char *); FORALLPROTO3(const ClassDiagram &,const char *,const char *); - FORALLPROTO3(Definition*,const char *,bool); + FORALLPROTO3(const Definition*,const char *,bool); FORALLPROTO4(SectionTypes,const char *,const char *,const char *); FORALLPROTO4(const char *,const char *,const char *,const char *); FORALLPROTO4(const char *,const char *,const char *,bool); diff --git a/src/pagedef.cpp b/src/pagedef.cpp index 79a78d3..9f11eb0 100644 --- a/src/pagedef.cpp +++ b/src/pagedef.cpp @@ -25,10 +25,64 @@ #include "language.h" #include "namespacedef.h" #include "reflist.h" +#include "definitionimpl.h" -PageDef::PageDef(const char *f,int l,const char *n, +//------------------------------------------------------------------------------------------ + +class PageDefImpl : public DefinitionImpl, public PageDef +{ + public: + PageDefImpl(const char *f,int l,const char *n,const char *d,const char *t); + virtual ~PageDefImpl(); + + virtual void setFileName(const char *name); + virtual void setLocalToc(const LocalToc &tl); + virtual void setShowLineNo(bool); + virtual DefType definitionType() const { return TypePage; } + virtual bool isLinkableInProject() const { return /*hasDocumentation() &&*/ !isReference(); } + virtual bool isLinkable() const { return isLinkableInProject() || isReference(); } + virtual QCString getOutputFileBase() const; + virtual QCString anchor() const { return QCString(); } + virtual void findSectionsInDocumentation(); + virtual QCString title() const { return m_title; } + virtual GroupDef * getGroupDef() const; + virtual PageSDict * getSubPages() const { return m_subPageDict; } + virtual void addInnerCompound(Definition *d); + virtual bool visibleInIndex() const; + virtual bool documentedPage() const; + virtual bool hasSubPages() const; + virtual bool hasParentPage() const; + virtual bool hasTitle() const; + virtual LocalToc localToc() const { return m_localToc; } + virtual void setPageScope(Definition *d){ m_pageScope = d; } + virtual Definition *getPageScope() const { return m_pageScope; } + virtual QCString displayName(bool=TRUE) const { return hasTitle() ? m_title : DefinitionImpl::name(); } + virtual bool showLineNo() const; + virtual void writeDocumentation(OutputList &ol); + virtual void writeTagFile(FTextStream &); + virtual void setNestingLevel(int l); + virtual void writePageDocumentation(OutputList &ol); + + private: + QCString m_fileName; + QCString m_title; + PageSDict *m_subPageDict; // list of pages in the group + Definition *m_pageScope; + int m_nestingLevel; + LocalToc m_localToc; + bool m_showLineNo; +}; + +PageDef *createPageDef(const char *f,int l,const char *n,const char *d,const char *t) +{ + return new PageDefImpl(f,l,n,d,t); +} + +//------------------------------------------------------------------------------------------ + +PageDefImpl::PageDefImpl(const char *f,int l,const char *n, const char *d,const char *t) - : Definition(f,l,1,n), m_title(t) + : DefinitionImpl(f,l,1,n), m_title(t) { setDocumentation(d,f,l); m_subPageDict = new PageSDict(7); @@ -38,23 +92,23 @@ PageDef::PageDef(const char *f,int l,const char *n, m_showLineNo = FALSE; } -PageDef::~PageDef() +PageDefImpl::~PageDefImpl() { delete m_subPageDict; } -void PageDef::findSectionsInDocumentation() +void PageDefImpl::findSectionsInDocumentation() { docFindSections(documentation(),this,0,docFile()); } -GroupDef *PageDef::getGroupDef() const +GroupDef *PageDefImpl::getGroupDef() const { GroupList *groups = partOfGroups(); return groups!=0 ? groups->getFirst() : 0; } -QCString PageDef::getOutputFileBase() const +QCString PageDefImpl::getOutputFileBase() const { if (getGroupDef()) return getGroupDef()->getOutputFileBase(); @@ -62,16 +116,16 @@ QCString PageDef::getOutputFileBase() const return m_fileName; } -void PageDef::setFileName(const char *name) +void PageDefImpl::setFileName(const char *name) { m_fileName = name; } -void PageDef::addInnerCompound(Definition *def) +void PageDefImpl::addInnerCompound(Definition *def) { if (def->definitionType()==Definition::TypePage) { - PageDef *pd = (PageDef*)def; + PageDef *pd = dynamic_cast<PageDef*>(def); m_subPageDict->append(pd->name(),pd); def->setOuterScope(this); if (this==Doxygen::mainPage) @@ -85,13 +139,13 @@ void PageDef::addInnerCompound(Definition *def) } } -bool PageDef::hasParentPage() const +bool PageDefImpl::hasParentPage() const { return getOuterScope() && getOuterScope()->definitionType()==Definition::TypePage; } -void PageDef::writeTagFile(FTextStream &tagFile) +void PageDefImpl::writeTagFile(FTextStream &tagFile) { bool found = name()=="citelist"; QDictIterator<RefList> rli(*Doxygen::xrefLists); @@ -115,7 +169,7 @@ void PageDef::writeTagFile(FTextStream &tagFile) } } -void PageDef::writeDocumentation(OutputList &ol) +void PageDefImpl::writeDocumentation(OutputList &ol) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); @@ -124,7 +178,7 @@ void PageDef::writeDocumentation(OutputList &ol) pageName = escapeCharsInString(name(),FALSE,TRUE); manPageName = escapeCharsInString(name(),TRUE,TRUE); - //printf("PageDef::writeDocumentation: %s\n",getOutputFileBase().data()); + //printf("PageDefImpl::writeDocumentation: %s\n",getOutputFileBase().data()); ol.pushGeneratorState(); //1.{ @@ -190,7 +244,7 @@ void PageDef::writeDocumentation(OutputList &ol) ol.disable(OutputGenerator::Docbook); ol.disable(OutputGenerator::RTF); ol.disable(OutputGenerator::Man); - if (!title().isEmpty() && !name().isEmpty() && si!=0) + if (hasTitle() && !name().isEmpty() && si!=0) { ol.startPageDoc(si->title); //ol.startSection(si->label,si->title,si->type); @@ -214,16 +268,16 @@ void PageDef::writeDocumentation(OutputList &ol) } writePageDocumentation(ol); + ol.endContents(); ol.endPageDoc(); if (generateTreeView && getOuterScope()!=Doxygen::globalScope && !Config_getBool(DISABLE_INDEX)) { - ol.endContents(); endFileWithNavPath(getOuterScope(),ol); } else { - endFile(ol); + endFile(ol,FALSE,TRUE); } ol.popGeneratorState(); @@ -232,7 +286,7 @@ void PageDef::writeDocumentation(OutputList &ol) Doxygen::indexList->addIndexItem(this,0,0,filterTitle(title())); } -void PageDef::writePageDocumentation(OutputList &ol) +void PageDefImpl::writePageDocumentation(OutputList &ol) { bool markdownEnabled = Doxygen::markdownSupport; @@ -300,7 +354,7 @@ void PageDef::writePageDocumentation(OutputList &ol) } } -bool PageDef::visibleInIndex() const +bool PageDefImpl::visibleInIndex() const { static bool externalPages = Config_getBool(EXTERNAL_PAGES); return // not part of a group @@ -310,7 +364,7 @@ bool PageDef::visibleInIndex() const ; } -bool PageDef::documentedPage() const +bool PageDefImpl::documentedPage() const { return // not part of a group !getGroupDef() && @@ -318,27 +372,33 @@ bool PageDef::documentedPage() const !isReference(); } -bool PageDef::hasSubPages() const +bool PageDefImpl::hasSubPages() const { return m_subPageDict->count()>0; } -void PageDef::setNestingLevel(int l) +void PageDefImpl::setNestingLevel(int l) { m_nestingLevel = l; } -void PageDef::setLocalToc(const LocalToc <) +void PageDefImpl::setLocalToc(const LocalToc <) { m_localToc = lt; } -void PageDef::setShowLineNo(bool b) +void PageDefImpl::setShowLineNo(bool b) { m_showLineNo = b; } -bool PageDef::showLineNo() const +bool PageDefImpl::showLineNo() const { return m_showLineNo; } + +bool PageDefImpl::hasTitle() const +{ + return !m_title.isEmpty() && m_title.lower()!="notitle"; +} + diff --git a/src/pagedef.h b/src/pagedef.h index a0c3acb..f0b68d1 100644 --- a/src/pagedef.h +++ b/src/pagedef.h @@ -26,61 +26,47 @@ class OutputList; class FTextStream; /** @brief A model of a page symbol. */ -class PageDef : public Definition +class PageDef : virtual public Definition { public: - PageDef(const char *f,int l,const char *n,const char *d,const char *t); - ~PageDef(); + virtual ~PageDef() {} // setters - void setFileName(const char *name); - void setLocalToc(const LocalToc &tl); - void setShowLineNo(bool); + virtual void setFileName(const char *name) = 0; + virtual void setLocalToc(const LocalToc &tl) = 0; + virtual void setShowLineNo(bool) = 0; // getters - DefType definitionType() const { return TypePage; } - bool isLinkableInProject() const - { - return /*hasDocumentation() &&*/ !isReference(); - } - bool isLinkable() const - { - return isLinkableInProject() || isReference(); - } - - // functions to get a uniform interface with Definitions - QCString getOutputFileBase() const; - QCString anchor() const { return QCString(); } - void findSectionsInDocumentation(); - QCString title() const { return m_title; } - GroupDef * getGroupDef() const; - PageSDict * getSubPages() const { return m_subPageDict; } - void addInnerCompound(Definition *d); - bool visibleInIndex() const; - bool documentedPage() const; - bool hasSubPages() const; - bool hasParentPage() const; - LocalToc localToc() const { return m_localToc; } - void setPageScope(Definition *d){ m_pageScope = d; } - Definition *getPageScope() const { return m_pageScope; } - QCString displayName(bool=TRUE) const { return !m_title.isEmpty() ? m_title : Definition::name(); } - bool showLineNo() const; + virtual DefType definitionType() const = 0; + virtual bool isLinkableInProject() const = 0; + virtual bool isLinkable() const = 0; + virtual QCString getOutputFileBase() const = 0; + virtual QCString anchor() const = 0; + virtual void findSectionsInDocumentation() = 0; + virtual QCString title() const = 0; + virtual GroupDef * getGroupDef() const = 0; + virtual PageSDict * getSubPages() const = 0; + virtual void addInnerCompound(Definition *d) = 0; + virtual bool visibleInIndex() const = 0; + virtual bool documentedPage() const = 0; + virtual bool hasSubPages() const = 0; + virtual bool hasParentPage() const = 0; + virtual bool hasTitle() const = 0; + virtual LocalToc localToc() const = 0; + virtual void setPageScope(Definition *d) = 0; + virtual Definition *getPageScope() const = 0; + virtual QCString displayName(bool=TRUE) const = 0; + virtual bool showLineNo() const = 0; - void writeDocumentation(OutputList &ol); - void writeTagFile(FTextStream &); + virtual void writeDocumentation(OutputList &ol) = 0; + virtual void writeTagFile(FTextStream &) = 0; + virtual void setNestingLevel(int l) = 0; + virtual void writePageDocumentation(OutputList &ol) = 0; - private: - void setNestingLevel(int l); - void writePageDocumentation(OutputList &ol); - QCString m_fileName; - QCString m_title; - PageSDict *m_subPageDict; // list of pages in the group - Definition *m_pageScope; - int m_nestingLevel; - LocalToc m_localToc; - bool m_showLineNo; }; +PageDef *createPageDef(const char *f,int l,const char *n,const char *d,const char *t); + class PageSDict : public SDict<PageDef> { public: diff --git a/src/parserintf.h b/src/parserintf.h index 0942106..f03aac7 100644 --- a/src/parserintf.h +++ b/src/parserintf.h @@ -110,9 +110,9 @@ class ParserInterface int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, - MemberDef *memberDef=0, + const MemberDef *memberDef=0, bool showLineNumbers=TRUE, - Definition *searchCtx=0, + const Definition *searchCtx=0, bool collectXRefs=TRUE ) = 0; diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp index fcc7ef5..a288e0e 100644 --- a/src/perlmodgen.cpp +++ b/src/perlmodgen.cpp @@ -388,8 +388,6 @@ public: void visitPost(DocXRefItem *); void visitPre(DocInternalRef *); void visitPost(DocInternalRef *); - void visitPre(DocCopy *); - void visitPost(DocCopy *); void visitPre(DocText *); void visitPost(DocText *); void visitPre(DocHtmlBlockQuote *); @@ -642,7 +640,9 @@ void PerlModDocVisitor::visit(DocStyleChange *s) { case DocStyleChange::Bold: style = "bold"; break; case DocStyleChange::Strike: style = "strike"; break; + case DocStyleChange::Del: style = "del"; break; case DocStyleChange::Underline: style = "underline"; break; + case DocStyleChange::Ins: style = "ins"; break; case DocStyleChange::Italic: style = "italic"; break; case DocStyleChange::Code: style = "code"; break; case DocStyleChange::Subscript: style = "subscript"; break; @@ -729,6 +729,7 @@ void PerlModDocVisitor::visit(DocInclude *inc) #endif return; case DocInclude::DontInclude: return; + case DocInclude::DontIncWithLines: return; case DocInclude::HtmlInclude: type = "htmlonly"; break; case DocInclude::LatexInclude: type = "latexonly"; break; case DocInclude::VerbInclude: type = "preformatted"; break; @@ -748,7 +749,7 @@ void PerlModDocVisitor::visit(DocInclude *inc) void PerlModDocVisitor::visit(DocIncOperator *) { #if 0 - //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n", + //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", // op->type(),op->isFirst(),op->isLast(),op->text().data()); if (op->isFirst()) { @@ -1384,14 +1385,6 @@ void PerlModDocVisitor::visitPost(DocInternalRef *) closeItem(); } -void PerlModDocVisitor::visitPre(DocCopy *) -{ -} - -void PerlModDocVisitor::visitPost(DocCopy *) -{ -} - void PerlModDocVisitor::visitPre(DocText *) { } @@ -1461,7 +1454,7 @@ static void addMemberTemplateLists(MemberDef *md,PerlModOutput &output) } #endif -static void addTemplateList(ClassDef *cd,PerlModOutput &output) +static void addTemplateList(const ClassDef *cd,PerlModOutput &output) { addTemplateArgumentList(cd->templateArguments(),output,cd->name()); } @@ -1470,8 +1463,8 @@ static void addPerlModDocBlock(PerlModOutput &output, const char *name, const QCString &fileName, int lineNr, - Definition *scope, - MemberDef *md, + const Definition *scope, + const MemberDef *md, const QCString &text) { QCString stext = text.stripWhiteSpace(); @@ -1542,14 +1535,14 @@ public: inline PerlModGenerator(bool pretty) : m_output(pretty) { } - void generatePerlModForMember(MemberDef *md, Definition *); - void generatePerlModSection(Definition *d, MemberList *ml, + void generatePerlModForMember(const MemberDef *md, const Definition *); + void generatePerlModSection(const Definition *d, MemberList *ml, const char *name, const char *header=0); - void addListOfAllMembers(ClassDef *cd); - void generatePerlModForClass(ClassDef *cd); - void generatePerlModForNamespace(NamespaceDef *nd); - void generatePerlModForFile(FileDef *fd); - void generatePerlModForGroup(GroupDef *gd); + void addListOfAllMembers(const ClassDef *cd); + void generatePerlModForClass(const ClassDef *cd); + void generatePerlModForNamespace(const NamespaceDef *nd); + void generatePerlModForFile(const FileDef *fd); + void generatePerlModForGroup(const GroupDef *gd); void generatePerlModForPage(PageDef *pi); bool createOutputFile(QFile &f, const char *s); @@ -1566,7 +1559,7 @@ public: void generate(); }; -void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) +void PerlModGenerator::generatePerlModForMember(const MemberDef *md,const Definition *) { // + declaration/definition arg lists // + reimplements @@ -1616,23 +1609,23 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) md->memberType()!=MemberType_Enumeration) m_output.addFieldQuotedString("type", md->typeString()); - ArgumentList *al = md->argumentList(); + const ArgumentList *al = md->argumentList(); if (isFunc) //function { m_output.addFieldBoolean("const", al!=0 && al->constSpecifier) .addFieldBoolean("volatile", al!=0 && al->volatileSpecifier); m_output.openList("parameters"); - ArgumentList *declAl = md->declArgumentList(); - ArgumentList *defAl = md->argumentList(); + const ArgumentList *declAl = md->declArgumentList(); + const ArgumentList *defAl = md->argumentList(); if (declAl && defAl && declAl->count()>0) { ArgumentListIterator declAli(*declAl); ArgumentListIterator defAli(*defAl); - Argument *a; + const Argument *a; for (declAli.toFirst();(a=declAli.current());++declAli) { - Argument *defArg = defAli.current(); + const Argument *defArg = defAli.current(); m_output.openHash(); if (!a->name.isEmpty()) @@ -1664,7 +1657,7 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) { m_output.openList("parameters"); ArgumentListIterator ali(*al); - Argument *a; + const Argument *a; for (ali.toFirst();(a=ali.current());++ali) { m_output.openHash() @@ -1686,12 +1679,12 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) if (md->memberType()==MemberType_Enumeration) // enum { - MemberList *enumFields = md->enumFieldList(); + const MemberList *enumFields = md->enumFieldList(); if (enumFields) { m_output.openList("values"); MemberListIterator emli(*enumFields); - MemberDef *emd; + const MemberDef *emd; for (emli.toFirst();(emd=emli.current());++emli) { m_output.openHash() @@ -1710,7 +1703,7 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) } } - MemberDef *rmd = md->reimplements(); + const MemberDef *rmd = md->reimplements(); if (rmd) m_output.openHash("reimplements") .addFieldQuotedString("name", rmd->name()) @@ -1731,7 +1724,7 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) m_output.closeHash(); } -void PerlModGenerator::generatePerlModSection(Definition *d, +void PerlModGenerator::generatePerlModSection(const Definition *d, MemberList *ml,const char *name,const char *header) { if (ml==0) return; // empty list @@ -1743,7 +1736,7 @@ void PerlModGenerator::generatePerlModSection(Definition *d, m_output.openList("members"); MemberListIterator mli(*ml); - MemberDef *md; + const MemberDef *md; for (mli.toFirst();(md=mli.current());++mli) { generatePerlModForMember(md,d); @@ -1752,7 +1745,7 @@ void PerlModGenerator::generatePerlModSection(Definition *d, .closeHash(); } -void PerlModGenerator::addListOfAllMembers(ClassDef *cd) +void PerlModGenerator::addListOfAllMembers(const ClassDef *cd) { m_output.openList("all_members"); if (cd->memberNameInfoSDict()) @@ -1765,9 +1758,9 @@ void PerlModGenerator::addListOfAllMembers(ClassDef *cd) MemberInfo *mi; for (mii.toFirst();(mi=mii.current());++mii) { - MemberDef *md=mi->memberDef; - ClassDef *cd=md->getClassDef(); - Definition *d=md->getGroupDef(); + const MemberDef *md=mi->memberDef; + const ClassDef *cd=md->getClassDef(); + const Definition *d=md->getGroupDef(); if (d==0) d = cd; m_output.openHash() @@ -1786,7 +1779,7 @@ void PerlModGenerator::addListOfAllMembers(ClassDef *cd) m_output.closeList(); } -void PerlModGenerator::generatePerlModForClass(ClassDef *cd) +void PerlModGenerator::generatePerlModForClass(const ClassDef *cd) { // + brief description // + detailed description @@ -1844,7 +1837,7 @@ void PerlModGenerator::generatePerlModForClass(ClassDef *cd) { m_output.openList("inner"); ClassSDict::Iterator cli(*cl); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) m_output.openHash() .addFieldQuotedString("name", cd->name()) @@ -1936,7 +1929,7 @@ void PerlModGenerator::generatePerlModForClass(ClassDef *cd) m_output.closeHash(); } -void PerlModGenerator::generatePerlModForNamespace(NamespaceDef *nd) +void PerlModGenerator::generatePerlModForNamespace(const NamespaceDef *nd) { // + contained class definitions // + contained namespace definitions @@ -1957,7 +1950,7 @@ void PerlModGenerator::generatePerlModForNamespace(NamespaceDef *nd) { m_output.openList("classes"); ClassSDict::Iterator cli(*cl); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) m_output.openHash() .addFieldQuotedString("name", cd->name()) @@ -1965,12 +1958,12 @@ void PerlModGenerator::generatePerlModForNamespace(NamespaceDef *nd) m_output.closeList(); } - NamespaceSDict *nl = nd->getNamespaceSDict(); + const NamespaceSDict *nl = nd->getNamespaceSDict(); if (nl) { m_output.openList("namespaces"); NamespaceSDict::Iterator nli(*nl); - NamespaceDef *nd; + const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) m_output.openHash() .addFieldQuotedString("name", nd->name()) @@ -1981,7 +1974,7 @@ void PerlModGenerator::generatePerlModForNamespace(NamespaceDef *nd) if (nd->getMemberGroupSDict()) { MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict()); - MemberGroup *mg; + const MemberGroup *mg; for (;(mg=mgli.current());++mgli) generatePerlModSection(nd,mg->members(),"user-defined",mg->header()); } @@ -1999,7 +1992,7 @@ void PerlModGenerator::generatePerlModForNamespace(NamespaceDef *nd) m_output.closeHash(); } -void PerlModGenerator::generatePerlModForFile(FileDef *fd) +void PerlModGenerator::generatePerlModForFile(const FileDef *fd) { // + includes files // + includedby files @@ -2068,7 +2061,7 @@ void PerlModGenerator::generatePerlModForFile(FileDef *fd) m_output.closeHash(); } -void PerlModGenerator::generatePerlModForGroup(GroupDef *gd) +void PerlModGenerator::generatePerlModForGroup(const GroupDef *gd) { // + members // + member groups @@ -2093,7 +2086,7 @@ void PerlModGenerator::generatePerlModForGroup(GroupDef *gd) { m_output.openList("files"); QListIterator<FileDef> fli(*fl); - FileDef *fd; + const FileDef *fd; for (fli.toFirst();(fd=fli.current());++fli) m_output.openHash() .addFieldQuotedString("name", fd->name()) @@ -2106,7 +2099,7 @@ void PerlModGenerator::generatePerlModForGroup(GroupDef *gd) { m_output.openList("classes"); ClassSDict::Iterator cli(*cl); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) m_output.openHash() .addFieldQuotedString("name", cd->name()) @@ -2119,7 +2112,7 @@ void PerlModGenerator::generatePerlModForGroup(GroupDef *gd) { m_output.openList("namespaces"); NamespaceSDict::Iterator nli(*nl); - NamespaceDef *nd; + const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) m_output.openHash() .addFieldQuotedString("name", nd->name()) @@ -2145,7 +2138,7 @@ void PerlModGenerator::generatePerlModForGroup(GroupDef *gd) { m_output.openList("groups"); GroupListIterator gli(*gl); - GroupDef *sgd; + const GroupDef *sgd; for (gli.toFirst();(sgd=gli.current());++gli) m_output.openHash() .addFieldQuotedString("title", sgd->groupTitle()) @@ -2206,14 +2199,14 @@ bool PerlModGenerator::generatePerlModOutput() m_output.openList("classes"); ClassSDict::Iterator cli(*Doxygen::classSDict); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) generatePerlModForClass(cd); m_output.closeList(); m_output.openList("namespaces"); NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); - NamespaceDef *nd; + const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) generatePerlModForNamespace(nd); m_output.closeList(); @@ -2224,7 +2217,7 @@ bool PerlModGenerator::generatePerlModOutput() for (;(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); - FileDef *fd; + const FileDef *fd; for (;(fd=fni.current());++fni) generatePerlModForFile(fd); } @@ -2232,7 +2225,7 @@ bool PerlModGenerator::generatePerlModOutput() m_output.openList("groups"); GroupSDict::Iterator gli(*Doxygen::groupSDict); - GroupDef *gd; + const GroupDef *gd; for (;(gd=gli.current());++gli) { generatePerlModForGroup(gd); @@ -2282,13 +2275,13 @@ bool PerlModGenerator::createOutputDir(QDir &perlModDir) dir.setPath(QDir::currentDirPath()); if (!dir.mkdir(outputDirectory)) { - err("tag OUTPUT_DIRECTORY: Output directory `%s' does not " + err("tag OUTPUT_DIRECTORY: Output directory '%s' does not " "exist and cannot be created\n",outputDirectory.data()); exit(1); } else { - msg("Notice: Output directory `%s' does not exist. " + msg("Notice: Output directory '%s' does not exist. " "I have created it for you.\n", outputDirectory.data()); } dir.cd(outputDirectory); diff --git a/src/plantuml.cpp b/src/plantuml.cpp index ada035b..ff4ebd3 100644 --- a/src/plantuml.cpp +++ b/src/plantuml.cpp @@ -14,23 +14,32 @@ */ #include "plantuml.h" +#include "util.h" #include "portable.h" #include "config.h" #include "doxygen.h" #include "index.h" #include "message.h" +#include "debug.h" #include <qdir.h> +#include <qdict.h> +#include <qlist.h> -static const int maxCmdLine = 40960; -QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content) +QCString PlantumlManager::writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content,OutputFormat format) { - QCString baseName(4096); + QCString baseName; + QCString puName; + QCString imgName; static int umlindex=1; + Debug::print(Debug::Plantuml,0,"*** %s fileName: %s\n","writePlantUMLSource",qPrint(fileName)); + Debug::print(Debug::Plantuml,0,"*** %s outDir: %s\n","writePlantUMLSource",qPrint(outDir)); + if (fileName.isEmpty()) // generate name { + puName = "inline_umlgraph_"+QCString().setNum(umlindex); baseName = outDir+"/inline_umlgraph_"+QCString().setNum(umlindex++); } else // user specified name @@ -38,29 +47,158 @@ QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,con baseName = fileName; int i=baseName.findRev('.'); if (i!=-1) baseName = baseName.left(i); + puName = baseName; baseName.prepend(outDir+"/"); } - QFile file(baseName+".pu"); - if (!file.open(IO_WriteOnly)) + + switch (format) { - err("Could not open file %s for writing\n",baseName.data()); + case PUML_BITMAP: + imgName =puName+".png"; + break; + case PUML_EPS: + imgName =puName+".eps"; + break; + case PUML_SVG: + imgName =puName+".svg"; + break; } - QCString text = "@startuml\n"; + + Debug::print(Debug::Plantuml,0,"*** %s baseName: %s\n","writePlantUMLSource",qPrint(baseName)); + Debug::print(Debug::Plantuml,0,"*** %s puName: %s\n","writePlantUMLSource",qPrint(puName)); + Debug::print(Debug::Plantuml,0,"*** %s imgName: %s\n","writePlantUMLSource",qPrint(imgName)); + + QCString text = "@startuml "+imgName+"\n"; text+=content; text+="\n@enduml\n"; - file.writeBlock( text, text.length() ); - file.close(); + + QCString qcOutDir(outDir); + uint pos = qcOutDir.findRev("/"); + QCString generateType(qcOutDir.right(qcOutDir.length() - (pos + 1)) ); + Debug::print(Debug::Plantuml,0,"*** %s generateType: %s\n","writePlantUMLSource",qPrint(generateType)); + PlantumlManager::instance()->insert(generateType,puName,format,text); + Debug::print(Debug::Plantuml,0,"*** %s generateType: %s\n","writePlantUMLSource",qPrint(generateType)); + return baseName; } -void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutputFormat format) +void PlantumlManager::generatePlantUMLOutput(const char *baseName,const char *outDir,OutputFormat format) +{ + QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH); + QCString plantumlConfigFile = Config_getString(PLANTUML_CFG_FILE); + QCString dotPath = Config_getString(DOT_PATH); + + QCString imgName = baseName; + // The basename contains path, we need to strip the path from the filename in order + // to create the image file name which should be included in the index.qhp (Qt help index file). + int i; + if ((i=imgName.findRev('/'))!=-1) // strip path + { + imgName=imgName.right(imgName.length()-i-1); + } + switch (format) + { + case PUML_BITMAP: + imgName+=".png"; + break; + case PUML_EPS: + imgName+=".eps"; + break; + case PUML_SVG: + imgName+=".svg"; + break; + } + + Doxygen::indexList->addImageFile(imgName); +} + +//-------------------------------------------------------------------- + +PlantumlManager *PlantumlManager::m_theInstance = 0; + +PlantumlManager *PlantumlManager::instance() +{ + if (!m_theInstance) + { + m_theInstance = new PlantumlManager; + QCString outputFilename = Config_getString(OUTPUT_DIRECTORY) + "/" + CACHE_FILENAME; + QFileInfo fi(outputFilename); + if (fi.exists()) + { + m_theInstance->m_cachedPlantumlAllContent = fileToString(outputFilename); + } + else + { + m_theInstance->m_cachedPlantumlAllContent = ""; + } + Debug::print(Debug::Plantuml,0,"*** instance() : m_cachedPlantumlAllContent = [%s]\n",qPrint(m_theInstance->m_cachedPlantumlAllContent)); + m_theInstance->m_pngPlantumlContent.clear(); + m_theInstance->m_svgPlantumlContent.clear(); + m_theInstance->m_epsPlantumlContent.clear(); + } + return m_theInstance; +} + +PlantumlManager::PlantumlManager() { - static QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH); - static QCString plantumlConfigFile = Config_getString(PLANTUML_CFG_FILE); - static QCString dotPath = Config_getString(DOT_PATH); +} + +PlantumlManager::~PlantumlManager() +{ + { + QDictIterator< QList<QCString> > it( m_pngPlantumlFiles); // See QDictIterator + QList<QCString> *list; + for (it.toFirst();(list=it.current());++it) + { + (*list).clear(); + } + m_pngPlantumlFiles.clear(); + m_pngPlantumlContent.clear(); + } + { + QDictIterator< QList<QCString> > it( m_epsPlantumlFiles); // See QDictIterator + QList<QCString> *list; + for (it.toFirst();(list=it.current());++it) + { + (*list).clear(); + } + m_epsPlantumlFiles.clear(); + m_epsPlantumlContent.clear(); + } + { + QDictIterator< QList<QCString> > it( m_svgPlantumlFiles); // See QDictIterator + QList<QCString> *list; + for (it.toFirst();(list=it.current());++it) + { + (*list).clear(); + } + m_svgPlantumlFiles.clear(); + m_svgPlantumlContent.clear(); + } +} + +static void runPlantumlContent(const QDict< QList <QCString> > &plantumlFiles, + const QDict< QCString > &plantumlContent, + PlantumlManager::OutputFormat format) +{ + /* example : running: java -Djava.awt.headless=true + -jar "/usr/local/bin/plantuml.jar" + -o "test_doxygen/DOXYGEN_OUTPUT/html" + -tpng + "test_doxygen/DOXYGEN_OUTPUT/html/A.pu" + -charset UTF-8 + outDir:test_doxygen/DOXYGEN_OUTPUT/html + test_doxygen/DOXYGEN_OUTPUT/html/A + */ + int exitCode; + QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH); + QCString plantumlConfigFile = Config_getString(PLANTUML_CFG_FILE); + QCString dotPath = Config_getString(DOT_PATH); QCString pumlExe = "java"; QCString pumlArgs = ""; + QCString pumlType = ""; + QCString pumlOutDir = ""; QStrList &pumlIncludePathList = Config_getList(PLANTUML_INCLUDE_PATH); char *s=pumlIncludePathList.first(); @@ -92,61 +230,211 @@ void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutp pumlArgs += portable_commandExtension(); pumlArgs += "\" "; } - pumlArgs+="-o \""; - pumlArgs+=outDir; - pumlArgs+="\" "; - QCString imgName = baseName; - // The basename contains path, we need to strip the path from the filename in order - // to create the image file name which should be included in the index.qhp (Qt help index file). - int i; - if ((i=imgName.findRev('/'))!=-1) // strip path - { - imgName=imgName.right(imgName.length()-i-1); - } switch (format) { - case PUML_BITMAP: - pumlArgs+="-tpng"; - imgName+=".png"; + case PlantumlManager::PUML_BITMAP: + pumlType="png"; break; - case PUML_EPS: - pumlArgs+="-teps"; - imgName+=".eps"; + case PlantumlManager::PUML_EPS: + pumlType="eps"; break; - case PUML_SVG: - pumlArgs+="-tsvg"; - imgName+=".svg"; + case PlantumlManager::PUML_SVG: + pumlType="svg"; break; } - pumlArgs+=" \""; - pumlArgs+=baseName; - pumlArgs+=".pu\" "; - pumlArgs+="-charset UTF-8 "; - int exitCode; - //printf("*** running: %s %s outDir:%s %s\n",pumlExe.data(),pumlArgs.data(),outDir,baseName); - msg("Running PlantUML on generated file %s.pu\n",baseName); - portable_sysTimerStart(); - if ((exitCode=portable_system(pumlExe,pumlArgs,TRUE))!=0) + { - err("Problems running PlantUML. Verify that the command 'java -jar \"%splantuml.jar\" -h' works from the command line. Exit code: %d\n", - plantumlJarPath.data(),exitCode); + QDictIterator< QCString > it( plantumlContent); // See QDictIterator + QCString *nb; + for (it.toFirst();(nb=it.current());++it) + { + QCString pumlArguments(pumlArgs); + msg("Generating PlantUML %s Files in %s\n",qPrint(pumlType),qPrint(it.currentKey())); + pumlArguments+="-o \""; + pumlArguments+=Config_getString(OUTPUT_DIRECTORY); + pumlArguments+="/"; + pumlArguments+=it.currentKey(); + pumlArguments+="\" "; + pumlArguments+="-charset UTF-8 -t"; + pumlArguments+=pumlType; + pumlArguments+=" "; + + QCString puFileName(""); + puFileName+=Config_getString(OUTPUT_DIRECTORY); + puFileName+="/"; + puFileName+=it.currentKey(); + puFileName+="/"; + pumlOutDir=puFileName; + puFileName+="inline_umlgraph_"; + puFileName+=pumlType; + puFileName+=it.currentKey(); + puFileName+=".pu"; + + pumlArguments+="\""; + pumlArguments+=puFileName; + pumlArguments+="\" "; + + QFile file(puFileName); + if (!file.open(IO_WriteOnly)) + { + err("Could not open file %s for writing\n",puFileName.data()); + } + file.writeBlock( *nb, nb->length() ); + file.close(); + Debug::print(Debug::Plantuml,0,"*** %s Running Plantuml arguments:%s\n","PlantumlManager::runPlantumlContent",qPrint(pumlArguments)); + + portable_sysTimerStart(); + if ((exitCode=portable_system(pumlExe,pumlArguments,TRUE))!=0) + { + err("Problems running PlantUML. Verify that the command 'java -jar \"%splantuml.jar\" -h' works from the command line. Exit code: %d\n", + plantumlJarPath.data(),exitCode); + } + else if (Config_getBool(DOT_CLEANUP)) + { + Debug::print(Debug::Plantuml,0,"*** %s Remove %s file\n","PlantumlManager::runPlantumlContent",qPrint(puFileName)); + file.remove(); + } + portable_sysTimerStop(); + + if ( (format==PlantumlManager::PUML_EPS) && (Config_getBool(USE_PDFLATEX)) ) + { + Debug::print(Debug::Plantuml,0,"*** %s Running epstopdf\n","PlantumlManager::runPlantumlContent"); + QList<QCString> *list = plantumlFiles[it.currentKey()]; + if (list) + { + QListIterator<QCString> li(*list); + QCString *nb; + for (li.toFirst();(nb=li.current());++li) + { + const int maxCmdLine = 40960; + QCString epstopdfArgs(maxCmdLine); + epstopdfArgs.sprintf("\"%s%s.eps\" --outfile=\"%s%s.pdf\"",qPrint(pumlOutDir),qPrint(*nb),qPrint(pumlOutDir),qPrint(*nb)); + portable_sysTimerStart(); + if ((exitCode=portable_system("epstopdf",epstopdfArgs))!=0) + { + err("Problems running epstopdf. Check your TeX installation! Exit code: %d\n",exitCode); + } + portable_sysTimerStop(); + } + } + } + } } - else if (Config_getBool(DOT_CLEANUP)) +} + +void PlantumlManager::run() +{ + Debug::print(Debug::Plantuml,0,"*** %s\n","PlantumlManager::run"); + if (m_currentPlantumlAllContent.isEmpty()) return; + runPlantumlContent(m_pngPlantumlFiles, m_pngPlantumlContent, PUML_BITMAP); + runPlantumlContent(m_svgPlantumlFiles, m_svgPlantumlContent, PUML_SVG); + runPlantumlContent(m_epsPlantumlFiles, m_epsPlantumlContent, PUML_EPS); + QCString outputFilename = Config_getString(OUTPUT_DIRECTORY) + "/" + CACHE_FILENAME; + QFile file(outputFilename); + if (!file.open(IO_WriteOnly)) { - QFile(QCString(baseName)+".pu").remove(); + err("Could not open file %s for writing\n",CACHE_FILENAME); } - portable_sysTimerStop(); - if ( (format==PUML_EPS) && (Config_getBool(USE_PDFLATEX)) ) + file.writeBlock( m_currentPlantumlAllContent, m_currentPlantumlAllContent.length() ); + file.close(); +} + +static void print(const QDict< QList <QCString> > &plantumlFiles) +{ + if (Debug::isFlagSet(Debug::Plantuml)) { - QCString epstopdfArgs(maxCmdLine); - epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",baseName,baseName); - portable_sysTimerStart(); - if ((exitCode=portable_system("epstopdf",epstopdfArgs))!=0) + QDictIterator< QList<QCString> > it( plantumlFiles); // See QDictIterator + QList<QCString> *list; + for (it.toFirst();(list=it.current());++it) { - err("Problems running epstopdf. Check your TeX installation! Exit code: %d\n",exitCode); + Debug::print(Debug::Plantuml,0,"*** %s PlantumlFiles key:%s size:%d\n","PlantumlManager::print Files",qPrint(it.currentKey()),(*list).count()); + QListIterator<QCString> li(*list); + QCString *nb; + for (li.toFirst();(nb=li.current());++li) + { + Debug::print(Debug::Plantuml,0,"*** %s list:%s\n","PlantumlManager::print",qPrint(*nb)); + } } - portable_sysTimerStop(); } - Doxygen::indexList->addImageFile(imgName); } +static void print(const QDict<QCString> &plantumlContent) +{ + if (Debug::isFlagSet(Debug::Plantuml)) + { + QDictIterator< QCString > it( plantumlContent); // See QDictIterator + QCString *nb; + for (it.toFirst();(nb=it.current());++it) + { + Debug::print(Debug::Plantuml,0,"*** %s PlantumlContent key:%s\n","PlantumlManager::print Content",qPrint(it.currentKey())); + Debug::print(Debug::Plantuml,0,"*** %s Content :%s\n","PlantumlManager::print",qPrint(*nb)); + } + } +} + +static void addPlantumlFiles(QDict< QList<QCString> > &plantumlFiles, + const QCString &key , const QCString &value) +{ + QList<QCString> *list = plantumlFiles.find(key); + if (list==0) + { + list = new QList<QCString>; + plantumlFiles.insert(key,list); + } + list->append(new QCString(value)); +} + +static void addPlantumlContent(QDict< QCString > &plantumlContent, + const QCString &key, const QCString &puContent) +{ + QCString* content = plantumlContent.find(key); + if (content == 0) + { + content = new QCString(""); + plantumlContent.insert(key,content); + } + (*content)+=puContent; +} + + + +void PlantumlManager::insert(const QCString &key, const QCString &value, + OutputFormat format,const QCString &puContent) +{ + int find; + + Debug::print(Debug::Plantuml,0,"*** %s key:%s ,value:%s\n","PlantumlManager::insert",qPrint(key),qPrint(value)); + + m_currentPlantumlAllContent+=puContent; + + find = m_cachedPlantumlAllContent.find(puContent); + Debug::print(Debug::Plantuml,0,"*** %s find: %d\n","PlantumlManager::addPlantumlContent",find); + if (find >=0) + { // matched in cache. so we skip to run java for this plantuml + return ; + } + + switch (format) + { + case PUML_BITMAP: + addPlantumlFiles(m_pngPlantumlFiles,key,value); + print(m_pngPlantumlFiles); + addPlantumlContent(m_pngPlantumlContent,key,puContent); + print(m_pngPlantumlContent); + break; + case PUML_EPS: + addPlantumlFiles(m_epsPlantumlFiles,key,value); + print(m_epsPlantumlFiles); + addPlantumlContent(m_epsPlantumlContent,key,puContent); + print(m_epsPlantumlContent); + break; + case PUML_SVG: + addPlantumlFiles(m_svgPlantumlFiles,key,value); + print(m_svgPlantumlFiles); + addPlantumlContent(m_svgPlantumlContent,key,puContent); + print(m_svgPlantumlContent); + break; + } +} + +//-------------------------------------------------------------------- diff --git a/src/plantuml.h b/src/plantuml.h index 54ab8a2..6c99eba 100644 --- a/src/plantuml.h +++ b/src/plantuml.h @@ -16,25 +16,60 @@ #ifndef PLANTUML_H #define PLANTUML_H +#include <qdict.h> +#include <qlist.h> + +#define CACHE_FILENAME "inline_umlgraph_cache_all.pu" +#define DIVIDE_COUNT 4 +#define MIN_PLANTUML_COUNT 8 + class QCString; -/** Plant UML output image formats */ -enum PlantUMLOutputFormat { PUML_BITMAP, PUML_EPS, PUML_SVG }; +/** Singleton that manages plantuml relation actions */ +class PlantumlManager +{ + public: + /** Plant UML output image formats */ + enum OutputFormat { PUML_BITMAP, PUML_EPS, PUML_SVG }; -/** Write a PlantUML compatible file. - * @param[in] outDir the output directory to write the file to. - * @param[in] fileName the name of the file. If empty a name will be chosen automatically. - * @param[in] content the contents of the PlantUML file. - * @returns The name of the generated file. - */ -QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content); + static PlantumlManager *instance(); -/** Convert a PlantUML file to an image. - * @param[in] baseName the name of the generated file (as returned by writePlantUMLSource()) - * @param[in] outDir the directory to write the resulting image into. - * @param[in] format the image format to generate. - */ -void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutputFormat format); + /** Run plant UML tool for all images */ + void run(); + + /** Write a PlantUML compatible file. + * @param[in] outDir the output directory to write the file to. + * @param[in] fileName the name of the file. If empty a name will be chosen automatically. + * @param[in] content the contents of the PlantUML file. + * @param[in] format the image format to generate. + * @returns The name of the generated file. + */ + QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content, OutputFormat format); + + /** Convert a PlantUML file to an image. + * @param[in] baseName the name of the generated file (as returned by writePlantUMLSource()) + * @param[in] outDir the directory to write the resulting image into. + * @param[in] format the image format to generate. + */ + void generatePlantUMLOutput(const char *baseName,const char *outDir,OutputFormat format); + + private: + PlantumlManager(); + ~PlantumlManager(); + void insert(const QCString &key, + const QCString &value, + OutputFormat format, + const QCString &puContent); + static PlantumlManager *m_theInstance; + QDict< QList<QCString> > m_pngPlantumlFiles; + QDict< QList<QCString> > m_svgPlantumlFiles; + QDict< QList<QCString> > m_epsPlantumlFiles; + QDict< QCString > m_pngPlantumlContent; // use circular queue for using multi-proecessor (multi threading) + QDict< QCString > m_svgPlantumlContent; + QDict< QCString > m_epsPlantumlContent; + QCString m_cachedPlantumlAllContent; // read from CACHE_FILENAME file + QCString m_currentPlantumlAllContent; // processing plantuml then write it into CACHE_FILENAME to reuse the next time as cache information +}; #endif diff --git a/src/portable.cpp b/src/portable.cpp index 3dccaed..3d64638 100644 --- a/src/portable.cpp +++ b/src/portable.cpp @@ -396,7 +396,7 @@ const char *portable_commandExtension() bool portable_fileSystemIsCaseSensitive() { -#if defined(_WIN32) || defined(macintosh) || defined(__MACOSX__) || defined(__APPLE__) +#if defined(_WIN32) || defined(macintosh) || defined(__MACOSX__) || defined(__APPLE__) || defined(__CYGWIN__) return FALSE; #else return TRUE; @@ -463,7 +463,18 @@ void portable_correct_path(void) { #if defined(_WIN32) && !defined(__CYGWIN__) const char *p = portable_getenv("PATH"); + if (!p) return; // no path nothing to correct QCString result = substitute(p,'/','\\'); if (result!=p) portable_setenv("PATH",result.data()); #endif } + +void portable_unlink(const char *fileName) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + _unlink(fileName); +#else + unlink(fileName); +#endif +} + diff --git a/src/portable.h b/src/portable.h index c5578a3..83f90ef 100644 --- a/src/portable.h +++ b/src/portable.h @@ -23,6 +23,7 @@ void portable_unsetenv(const char *variable); portable_off_t portable_fseek(FILE *f,portable_off_t offset, int whence); portable_off_t portable_ftell(FILE *f); FILE * portable_fopen(const char *fileName,const char *mode); +void portable_unlink(const char *fileName); char portable_pathSeparator(); char portable_pathListSeparator(); const char * portable_ghostScriptCommand(); @@ -73,9 +73,10 @@ struct CondCtx struct FileState { - FileState(int size) : lineNr(1), fileBuf(size), + FileState(int size) : lineNr(1), curlyCount(0),fileBuf(size), oldFileBuf(0), oldFileBufPos(0), bufState(0) {} int lineNr; + int curlyCount; BufStr fileBuf; BufStr *oldFileBuf; int oldFileBufPos; @@ -693,7 +694,7 @@ static QCString stringize(const QCString &s) } } } - //printf("stringize `%s'->`%s'\n",s.data(),result.data()); + //printf("stringize '%s'->'%s'\n",s.data(),result.data()); return result; } @@ -704,19 +705,19 @@ static QCString stringize(const QCString &s) */ static void processConcatOperators(QCString &expr) { - //printf("processConcatOperators: in=`%s'\n",expr.data()); + //printf("processConcatOperators: in='%s'\n",expr.data()); QRegExp r("[ \\t\\n]*##[ \\t\\n]*"); int l,n,i=0; if (expr.isEmpty()) return; while ((n=r.match(expr,i,&l))!=-1) { - //printf("Match: `%s'\n",expr.data()+i); + //printf("Match: '%s'\n",expr.data()+i); if (n+l+1<(int)expr.length() && expr.at(n+l)=='@' && expr.at(n+l+1)=='-') { // remove no-rescan marker after ID l+=2; } - //printf("found `%s'\n",expr.mid(n,l).data()); + //printf("found '%s'\n",expr.mid(n,l).data()); // remove the ## operator and the surrounding whitespace expr=expr.left(n)+expr.right(expr.length()-n-l); int k=n-1; @@ -729,7 +730,7 @@ static void processConcatOperators(QCString &expr) } i=n; } - //printf("processConcatOperators: out=`%s'\n",expr.data()); + //printf("processConcatOperators: out='%s'\n",expr.data()); } static void yyunput (int c,char *buf_ptr ); @@ -774,7 +775,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int unputChar(expr,rest,j,' '); return FALSE; } - getNextChar(expr,rest,j); // eat the `(' character + getNextChar(expr,rest,j); // eat the '(' character QDict<QCString> argTable; // list of arguments argTable.setAutoDelete(TRUE); @@ -882,6 +883,21 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int arg+=c; } } + else if (c=='/') // possible start of a comment + { + char prevChar = '\0'; + arg+=c; + if ((cc=getCurrentChar(expr,rest,j)) == '*') // we have a comment + { + while ((cc=getNextChar(expr,rest,j))!=EOF && cc!=0) + { + c=(char)cc; + arg+=c; + if (c == '/' && prevChar == '*') break; // we have an end of comment + prevChar = c; + } + } + } else // append other characters { arg+=c; @@ -939,13 +955,13 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int if (key.length()>1 && (subst=argTable[key])) { QCString substArg=*subst; - //printf("substArg=`%s'\n",substArg.data()); + //printf("substArg='%s'\n",substArg.data()); // only if no ## operator is before or after the argument // marker we do macro expansion. if (!hash) expandExpression(substArg,0,0); if (inString) { - //printf("`%s'=stringize(`%s')\n",stringize(*subst).data(),subst->data()); + //printf("'%s'=stringize('%s')\n",stringize(*subst).data(),subst->data()); // if the marker is inside a string (because a # was put // before the macro name) we must escape " and \ characters @@ -984,7 +1000,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int } len=j-pos; result=resExpr; - //printf("result after substitution `%s' expr=`%s'\n", + //printf("result after substitution '%s' expr='%s'\n", // result.data(),expr.mid(pos,len).data()); return TRUE; } @@ -1073,7 +1089,12 @@ static void expandExpression(QCString &expr,QCString *rest,int pos) if (g_expandedDict->find(macroName)==0) // expand macro { Define *def=DefineManager::instance().isDefined(macroName); - if (definedTest) // macro name was found after defined + if (macroName=="defined") + { + //printf("found defined inside macro definition '%s'\n",expr.right(expr.length()-p).data()); + definedTest=TRUE; + } + else if (definedTest) // macro name was found after defined { if (def) expMacro = " 1 "; else expMacro = " 0 "; replaced=TRUE; @@ -1083,7 +1104,7 @@ static void expandExpression(QCString &expr,QCString *rest,int pos) else if (def && def->nargs==-1) // simple macro { // substitute the definition of the macro - //printf("macro `%s'->`%s'\n",macroName.data(),def->definition.data()); + //printf("macro '%s'->'%s'\n",macroName.data(),def->definition.data()); if (g_nospaces) { expMacro=def->definition.stripWhiteSpace(); @@ -1095,23 +1116,17 @@ static void expandExpression(QCString &expr,QCString *rest,int pos) //expMacro=def->definition.stripWhiteSpace(); replaced=TRUE; len=l; - //printf("simple macro expansion=`%s'->`%s'\n",macroName.data(),expMacro.data()); + //printf("simple macro expansion='%s'->'%s'\n",macroName.data(),expMacro.data()); } else if (def && def->nargs>=0) // function macro { replaced=replaceFunctionMacro(expr,rest,p+l,len,def,expMacro); len+=l; } - else if (macroName=="defined") - { - //printf("found defined inside macro definition '%s'\n",expr.right(expr.length()-p).data()); - definedTest=TRUE; - } if (replaced) // expand the macro and rescan the expression { - - //printf("replacing `%s'->`%s'\n",expr.mid(p,len).data(),expMacro.data()); + //printf("replacing '%s'->'%s'\n",expr.mid(p,len).data(),expMacro.data()); QCString resultExpr=expMacro; QCString restExpr=expr.right(expr.length()-len-p); processConcatOperators(resultExpr); @@ -1147,6 +1162,44 @@ static void expandExpression(QCString &expr,QCString *rest,int pos) } } +/*! @brief Process string or character literal. + * + * \a inputStr should point to the start of a string or character literal. + * the routine will return a pointer to just after the end of the literal + * the character making up the literal will be added to \a result. + */ +const char *processUntilMatchingTerminator(const char *inputStr,QCString &result) +{ + if (inputStr==0) return inputStr; + char term = *inputStr; // capture start character of the literal + if (term!='\'' && term!='"') return inputStr; // not a valid literal + char c=term; + // output start character + result+=c; + inputStr++; + while ((c=*inputStr)) // while inside the literal + { + if (c==term) // found end marker of the literal + { + // output end character and stop + result+=c; + inputStr++; + break; + } + else if (c=='\\') // escaped character, process next character + // as well without checking for end marker. + { + result+=c; + inputStr++; + c=*inputStr; + if (c==0) break; // unexpected end of string after escape character + } + result+=c; + inputStr++; + } + return inputStr; +} + /*! replaces all occurrences of @@@@ in \a s by @@ * and removes all occurrences of @@E. * All identifiers found are replaced by 0L @@ -1180,7 +1233,11 @@ QCString removeIdsAndMarkers(const char *s) p++; inNum=TRUE; } - else if (c=='d' && !inNum) // identifier starting with a `d' + else if (c=='\'') // quoted character + { + p = processUntilMatchingTerminator(p,result); + } + else if (c=='d' && !inNum) // identifier starting with a 'd' { if (qstrncmp(p,"defined ",8)==0 || qstrncmp(p,"defined(",8)==0) // defined keyword @@ -1199,6 +1256,7 @@ QCString removeIdsAndMarkers(const char *s) result+="0L"; p++; while ((c=*p) && isId(c)) p++; + while ((c=*p) && isspace((uchar)c)) p++; if (*p=='(') // undefined function macro { p++; @@ -1306,30 +1364,8 @@ QCString removeMarkers(const char *s) } break; case '"': // skip string literals - { - result+=c; - char pc=c; - c=*++p; - while (*p && (c!='"' || pc=='\\')) // no end quote - { - result+=c; - c=*++p; - } - if (*p) result+=c,p++; - } - break; case '\'': // skip char literals - { - result+=c; - char pc=c; - c=*++p; - while (*p && (c!='\'' || pc=='\\')) // no end quote - { - result+=c; - c=*++p; - } - if (*p) result+=c,p++; - } + p = processUntilMatchingTerminator(p,result); break; default: { @@ -1352,10 +1388,10 @@ bool computeExpression(const QCString &expr) { QCString e=expr; expandExpression(e,0,0); - //printf("after expansion `%s'\n",e.data()); + //printf("after expansion '%s'\n",e.data()); e = removeIdsAndMarkers(e); if (e.isEmpty()) return FALSE; - //printf("parsing `%s'\n",e.data()); + //printf("parsing '%s'\n",e.data()); return parseconstexp(g_yyFileName,g_yyLineNr,e); } @@ -1368,7 +1404,7 @@ QCString expandMacro(const QCString &name) QCString n=name; expandExpression(n,0,0); n=removeMarkers(n); - //printf("expandMacro `%s'->`%s'\n",name.data(),n.data()); + //printf("expandMacro '%s'->'%s'\n",name.data(),n.data()); return n; } @@ -1385,7 +1421,7 @@ Define *newDefine() def->varArgs = g_defVarArgs; //printf("newDefine: %s %s file: %s\n",def->name.data(),def->definition.data(), // def->fileDef ? def->fileDef->name().data() : def->fileName.data()); - //printf("newDefine: `%s'->`%s'\n",def->name.data(),def->definition.data()); + //printf("newDefine: '%s'->'%s'\n",def->name.data(),def->definition.data()); if (!def->name.isEmpty() && Doxygen::expandAsDefinedDict[def->name]) { def->isPredefined=TRUE; @@ -1402,18 +1438,18 @@ void addDefine() //printf("addDefine %s %s\n",g_defName.data(),g_defArgsStr.data()); //ArgumentList *al = new ArgumentList; //stringToArgumentList(g_defArgsStr,al); - MemberDef *md=new MemberDef( + MemberDef *md=createMemberDef( g_yyFileName,g_yyLineNr-g_yyMLines,g_yyColNr, "#define",g_defName,g_defArgsStr,0, Public,Normal,FALSE,Member,MemberType_Define,0,0,""); if (!g_defArgsStr.isEmpty()) { ArgumentList *argList = new ArgumentList; - //printf("addDefine() g_defName=`%s' g_defArgsStr=`%s'\n",g_defName.data(),g_defArgsStr.data()); + //printf("addDefine() g_defName='%s' g_defArgsStr='%s'\n",g_defName.data(),g_defArgsStr.data()); stringToArgumentList(g_defArgsStr,argList); md->setArgumentList(argList); } - //printf("Setting initializer for `%s' to `%s'\n",g_defName.data(),g_defText.data()); + //printf("Setting initializer for '%s' to '%s'\n",g_defName.data(),g_defText.data()); int l=g_defLitText.find('\n'); if (l>0 && g_defLitText.left(l).stripWhiteSpace()=="\\") { @@ -1493,7 +1529,7 @@ static void readIncludeFile(const QCString &inc) QCString oldFileName = g_yyFileName; FileDef *oldFileDef = g_yyFileDef; int oldLineNr = g_yyLineNr; - //printf("Searching for `%s'\n",incFileName.data()); + //printf("Searching for '%s'\n",incFileName.data()); // absIncFileName avoids difficulties for incFileName starting with "../" (bug 641336) QCString absIncFileName = incFileName; @@ -1571,6 +1607,8 @@ static void readIncludeFile(const QCString &inc) fs->bufState = YY_CURRENT_BUFFER; fs->lineNr = oldLineNr; fs->fileName = oldFileName; + fs->curlyCount = g_curlyCount; + g_curlyCount = 0; // push the state on the stack g_includeStack.push(fs); // set the scanner to the include file @@ -1982,7 +2020,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) if (g_roundCount==0) { QCString result=expandMacro(g_defArgsStr); - //printf("g_defArgsStr=`%s'->`%s'\n",g_defArgsStr.data(),result.data()); + //printf("g_defArgsStr='%s'->'%s'\n",g_defArgsStr.data(),result.data()); if (g_findDefArgContext==CopyLine) { outputArray(result,result.length()); @@ -2056,6 +2094,8 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <ReadString>"//"|"/*" { g_defArgsStr+=yytext; } +<ReadString>\\/\r?\n { // line continuation + } <ReadString>\\. { g_defArgsStr+=yytext; } @@ -2185,10 +2225,11 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) BEGIN(DefinedExpr1); } <Guard>{ID} { g_guardExpr+=yytext; } +<Guard>"@" { g_guardExpr+="@@"; } <Guard>. { g_guardExpr+=*yytext; } <Guard>\n { unput(*yytext); - //printf("Guard: `%s'\n", + //printf("Guard: '%s'\n", // g_guardExpr.data()); bool guard=computeExpression(g_guardExpr); setCaseDone(guard); @@ -2342,7 +2383,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <EndImport>. { } <DefName>{ID}/("\\\n")*"(" { // define with argument - //printf("Define() `%s'\n",yytext); + //printf("Define() '%s'\n",yytext); delete g_argDict; g_argDict = new QDict<int>(31); g_argDict->setAutoDelete(TRUE); @@ -2356,7 +2397,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) BEGIN(DefineArg); } <DefName>{ID}{B}+"1"/[ \r\t\n] { // special case: define with 1 -> can be "guard" - //printf("Define `%s'\n",yytext); + //printf("Define '%s'\n",yytext); delete g_argDict; g_argDict=0; g_defArgs = -1; g_defArgsStr.resize(0); @@ -2414,7 +2455,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) g_expectGuard=FALSE; } <DefName>{ID}/{B}* { // define with content - //printf("Define `%s'\n",yytext); + //printf("Define '%s'\n",yytext); delete g_argDict; g_argDict=0; g_defArgs = -1; g_defArgsStr.resize(0); @@ -2816,7 +2857,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } outputChar('\n'); Define *def=0; - //printf("Define name=`%s' text=`%s' litTexti=`%s'\n",g_defName.data(),g_defText.data(),g_defLitText.data()); + //printf("Define name='%s' text='%s' litTexti='%s'\n",g_defName.data(),g_defText.data(),g_defLitText.data()); if (g_includeStack.isEmpty() || g_curlyCount>0) { addDefine(); @@ -2913,6 +2954,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) //preYYin = fs->oldYYin; g_inputBuf = fs->oldFileBuf; g_inputBufPos = fs->oldFileBufPos; + g_curlyCount = fs->curlyCount; setFileName(fs->fileName); DBG_CTX((stderr,"######## FileName %s\n",g_yyFileName.data())); @@ -3162,7 +3204,7 @@ void preprocessFile(const char *fileName,BufStr &input,BufStr &output) DefineManager::instance().addDefine(g_yyFileName,def); } - //printf("#define `%s' `%s' #nargs=%d\n", + //printf("#define '%s' '%s' #nargs=%d\n", // def->name.data(),def->definition.data(),def->nargs); } else if ((i_obrace==-1 || i_obrace>i_equals) && @@ -3197,7 +3239,7 @@ void preprocessFile(const char *fileName,BufStr &input,BufStr &output) delete def; } - //printf("#define `%s' `%s' #nargs=%d\n", + //printf("#define '%s' '%s' #nargs=%d\n", // def->name.data(),def->definition.data(),def->nargs); } } diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h index 8d375fc..6b9bd75 100644 --- a/src/printdocvisitor.h +++ b/src/printdocvisitor.h @@ -108,9 +108,15 @@ class PrintDocVisitor : public DocVisitor case DocStyleChange::Strike: if (s->enable()) printf("<strike>"); else printf("</strike>"); break; + case DocStyleChange::Del: + if (s->enable()) printf("<del>"); else printf("</del>"); + break; case DocStyleChange::Underline: if (s->enable()) printf("<underline>"); else printf("</underline>"); break; + case DocStyleChange::Ins: + if (s->enable()) printf("<ins>"); else printf("</ins>"); + break; case DocStyleChange::Italic: if (s->enable()) printf("<italic>"); else printf("</italic>"); break; @@ -187,6 +193,7 @@ class PrintDocVisitor : public DocVisitor case DocInclude::Include: printf("include"); break; case DocInclude::IncWithLines: printf("incwithlines"); break; case DocInclude::DontInclude: printf("dontinclude"); break; + case DocInclude::DontIncWithLines: printf("dontinwithlines"); break; case DocInclude::HtmlInclude: printf("htmlinclude"); if (inc->isBlock()) printf(" block=\"yes\""); @@ -615,16 +622,24 @@ class PrintDocVisitor : public DocVisitor //const char *s; DocNode *param; printf("<parameters>"); - for (sli.toFirst();(param=sli.current());++sli) + if (sli.count() > 0) { printf("<param>"); - if (param->kind()==DocNode::Kind_Word) + for (sli.toFirst();(param=sli.current());++sli) { - visit((DocWord*)param); - } - else if (param->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)param); + if (param->kind()==DocNode::Kind_Word) + { + visit((DocWord*)param); + } + else if (param->kind()==DocNode::Kind_LinkedWord) + { + visit((DocLinkedWord*)param); + } + else if (param->kind()==DocNode::Kind_Sep) + { + printf("</param>"); + printf("<param>"); + } } printf("</param>"); } @@ -675,16 +690,6 @@ class PrintDocVisitor : public DocVisitor indent_post(); printf("</internalref>\n"); } - void visitPre(DocCopy *c) - { - indent_pre(); - printf("<copy link=\"%s\">\n",c->link().data()); - } - void visitPost(DocCopy *) - { - indent_post(); - printf("</copy>\n"); - } void visitPre(DocText *) { indent_pre(); diff --git a/src/pycode.h b/src/pycode.h index 9817c39..de0a8a9 100644 --- a/src/pycode.h +++ b/src/pycode.h @@ -36,7 +36,7 @@ class Definition; extern void parsePythonCode(CodeOutputInterface &,const char *,const QCString &, bool ,const char *,FileDef *fd, int startLine,int endLine,bool inlineFragment, - MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx, + const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, bool collectXRefs); extern void resetPythonCodeParserState(); diff --git a/src/pycode.l b/src/pycode.l index d9c9f01..0f04baa 100644 --- a/src/pycode.l +++ b/src/pycode.l @@ -63,7 +63,7 @@ static const char * g_inputString; //!< the code fragment as text static int g_inputPosition; //!< read offset during parsing static const char * g_currentFontClass; static bool g_needsTermination; -static Definition *g_searchCtx; +static const Definition *g_searchCtx; static bool g_collectXRefs; static int g_inputLines; //!< number of line in the code fragment static int g_yyLineNr; //!< current line number @@ -162,7 +162,7 @@ void PyVariableContext::addVariable(const QCString &type,const QCString &name) QCString lname = name.simplifyWhiteSpace(); Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast(); - ClassDef *varType; + const ClassDef *varType; if ( (varType=g_codeClassSDict[ltype]) || // look for class definitions inside the code block (varType=getResolvedClass(g_currentDefinition,g_sourceFileDef,ltype)) // look for global class definitions @@ -212,7 +212,7 @@ class PyCallContext Ctx() : name(g_name), type(g_type), cd(0) {} QCString name; QCString type; - ClassDef *cd; + const ClassDef *cd; }; PyCallContext() @@ -223,7 +223,7 @@ class PyCallContext virtual ~PyCallContext() {} - void setClass(ClassDef *cd) + void setClass(const ClassDef *cd) { Ctx *ctx = m_classList.getLast(); if (ctx) @@ -259,7 +259,7 @@ class PyCallContext m_classList.append(new Ctx); } - ClassDef *getClass() const + const ClassDef *getClass() const { Ctx *ctx = m_classList.getLast(); @@ -320,7 +320,7 @@ static void addToSearchIndex(const char *text) } -static ClassDef *stripClassName(const char *s,Definition *d=g_currentDefinition) +static const ClassDef *stripClassName(const char *s,Definition *d=g_currentDefinition) { int pos=0; QCString type = s; @@ -330,7 +330,7 @@ static ClassDef *stripClassName(const char *s,Definition *d=g_currentDefinition) { QCString clName=className+templSpec; - ClassDef *cd=0; + const ClassDef *cd=0; if (!g_classScope.isEmpty()) { cd=getResolvedClass(d,g_sourceFileDef,g_classScope+"::"+clName); @@ -376,7 +376,7 @@ static void startCodeLine() g_searchingForBody = TRUE; g_realScope = d->name().copy(); g_classScope = d->name().copy(); - //printf("Real scope: `%s'\n",g_realScope.data()); + //printf("Real scope: '%s'\n",g_realScope.data()); g_bodyCurlyCount = 0; QCString lineAnchor; lineAnchor.sprintf("l%05d",g_yyLineNr); @@ -437,7 +437,7 @@ static void nextCodeLine() * split into multiple links with the same destination, one for each line. */ static void writeMultiLineCodeLink(CodeOutputInterface &ol, - Definition *d, + const Definition *d, const char *text) { static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); @@ -544,20 +544,20 @@ static bool getLinkInScope(const QCString &c, // scope const char *text ) { - MemberDef *md; - ClassDef *cd; - FileDef *fd; - NamespaceDef *nd; - GroupDef *gd; - //printf("Trying `%s'::`%s'\n",c.data(),m.data()); + const MemberDef *md = 0; + const ClassDef *cd = 0; + const FileDef *fd = 0; + const NamespaceDef *nd = 0; + const GroupDef *gd = 0; + //printf("Trying '%s'::'%s'\n",c.data(),m.data()); if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,g_sourceFileDef) && md->isLinkable()) { //Definition *d=0; //if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd; - Definition *d = md->getOuterScope()==Doxygen::globalScope ? - md->getBodyDef() : md->getOuterScope(); + const Definition *d = md->getOuterScope()==Doxygen::globalScope ? + md->getBodyDef() : md->getOuterScope(); //printf("Found! d=%s\n",d?d->name().data():"<none>"); if (md->getGroupDef()) d = md->getGroupDef(); if (d && d->isLinkable()) @@ -569,9 +569,9 @@ static bool getLinkInScope(const QCString &c, // scope if (g_currentDefinition && g_currentMemberDef && md!=g_currentMemberDef && g_collectXRefs) { - addDocCrossReference(g_currentMemberDef,md); + addDocCrossReference(g_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()); + //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()); writeMultiLineCodeLink(ol,md, text ? text : memberText); addToSearchIndex(text ? text : memberText); @@ -616,8 +616,8 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, DBG_CTX((stderr,"generateClassOrGlobalLink(className=%s)\n",className.data())); - ClassDef *cd=0,*lcd=0; /** Class def that we may find */ - MemberDef *md=0; /** Member def that we may find */ + const ClassDef *cd=0,*lcd=0; /** Class def that we may find */ + const MemberDef *md=0; /** Member def that we may find */ //bool isLocal=FALSE; if ((lcd=g_theVarContext.findVariable(className))==0) // not a local variable @@ -634,7 +634,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, if (cd==0 && md==0) // also see if it is variable or enum or enum value { - NamespaceDef *nd = getResolvedNamespace(scope); + const NamespaceDef *nd = getResolvedNamespace(scope); if (nd) { writeMultiLineCodeLink(ol,nd,clName); @@ -663,13 +663,13 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, addToSearchIndex(className); if (md) { - Definition *d = md->getOuterScope()==Doxygen::globalScope ? - md->getBodyDef() : md->getOuterScope(); + const Definition *d = md->getOuterScope()==Doxygen::globalScope ? + md->getBodyDef() : md->getOuterScope(); if (md->getGroupDef()) d = md->getGroupDef(); if (d && d->isLinkable() && md->isLinkable() && g_currentMemberDef && g_collectXRefs) { - addDocCrossReference(g_currentMemberDef,md); + addDocCrossReference(g_currentMemberDef,const_cast<MemberDef*>(md)); } } } @@ -690,8 +690,8 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope())); writeMultiLineCodeLink(ol,md,clName); addToSearchIndex(className); - Definition *d = md->getOuterScope()==Doxygen::globalScope ? - md->getBodyDef() : md->getOuterScope(); + const Definition *d = md->getOuterScope()==Doxygen::globalScope ? + md->getBodyDef() : md->getOuterScope(); if (md->getGroupDef()) d = md->getGroupDef(); if (d && d->isLinkable() && md->isLinkable() && g_currentMemberDef && g_collectXRefs) @@ -703,7 +703,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, } else // check namespace as well { - NamespaceDef *mnd = getResolvedNamespace(scope); + const NamespaceDef *mnd = getResolvedNamespace(scope); if (mnd) { MemberDef *md=mnd->getMemberByName(locName); @@ -713,8 +713,8 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope())); writeMultiLineCodeLink(ol,md,clName); addToSearchIndex(className); - Definition *d = md->getOuterScope()==Doxygen::globalScope ? - md->getBodyDef() : md->getOuterScope(); + const Definition *d = md->getOuterScope()==Doxygen::globalScope ? + md->getBodyDef() : md->getOuterScope(); if (md->getGroupDef()) d = md->getGroupDef(); if (d && d->isLinkable() && md->isLinkable() && g_currentMemberDef && g_collectXRefs) @@ -753,7 +753,7 @@ static void generateFunctionLink(CodeOutputInterface &ol,char *funcName) locScope=locFunc.left(i); locFunc=locFunc.right(locFunc.length()-i-2).stripWhiteSpace(); } - //printf("generateFunctionLink(%s) classScope=`%s'\n",locFunc.data(),locScope.data()); + //printf("generateFunctionLink(%s) classScope='%s'\n",locFunc.data(),locScope.data()); if (!locScope.isEmpty() && (ccd=g_codeClassSDict[locScope])) { //printf("using classScope %s\n",g_classScope.data()); @@ -786,13 +786,13 @@ static bool findMemberLink(CodeOutputInterface &ol,Definition *sym,const char *s sym->getOuterScope()->definitionType()==Definition::TypeClass && g_currentDefinition->definitionType()==Definition::TypeClass) { - ClassDef *cd = (ClassDef*)sym->getOuterScope(); - ClassDef *thisCd = (ClassDef *)g_currentDefinition; + ClassDef *cd = dynamic_cast<ClassDef*>(sym->getOuterScope()); + ClassDef *thisCd = dynamic_cast<ClassDef *>(g_currentDefinition); if (sym->definitionType()==Definition::TypeMember) { if (g_currentMemberDef && g_collectXRefs) { - addDocCrossReference(g_currentMemberDef,(MemberDef*)sym); + addDocCrossReference(g_currentMemberDef,dynamic_cast<MemberDef*>(sym)); } } DBG_CTX((stderr,"cd=%s thisCd=%s\n",cd?cd->name().data():"<none>",thisCd?thisCd->name().data():"<none>")); @@ -1086,12 +1086,12 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT // Push a class scope - ClassDef *classDefToAdd = new ClassDef("<code>",1,1,g_curClassName,ClassDef::Class,0,0,FALSE); + ClassDef *classDefToAdd = createClassDef("<code>",1,1,g_curClassName,ClassDef::Class,0,0,FALSE); g_codeClassSDict.append(g_curClassName,classDefToAdd); char *s=g_curClassBases.first(); while (s) { - ClassDef *baseDefToAdd=g_codeClassSDict[s]; + const ClassDef *baseDefToAdd=g_codeClassSDict[s]; // Try to find class in global // scope @@ -1102,7 +1102,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT if (baseDefToAdd && baseDefToAdd!=classDefToAdd) { - classDefToAdd->insertBaseClass(baseDefToAdd,s,Public,Normal); + classDefToAdd->insertBaseClass(const_cast<ClassDef*>(baseDefToAdd),s,Public,Normal); } s=g_curClassBases.next(); @@ -1173,6 +1173,10 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT } {FLOWKW} { + if (g_currentMemberDef && g_currentMemberDef->isFunction()) + { + g_currentMemberDef->incrementFlowKeyWordCount(); + } startFontClass("keywordflow"); codify(yytext); endFontClass(); @@ -1210,6 +1214,10 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUT } {FLOWKW} { + if (g_currentMemberDef && g_currentMemberDef->isFunction()) + { + g_currentMemberDef->incrementFlowKeyWordCount(); + } startFontClass("keywordflow"); codifyLines(yytext); endFontClass(); @@ -1560,7 +1568,7 @@ static void adjustScopesAndSuites(unsigned indentLength) void parsePythonCode(CodeOutputInterface &od,const char * /*className*/, const QCString &s,bool exBlock, const char *exName, FileDef *fd,int startLine,int endLine,bool inlineFragment, - MemberDef *,bool,Definition *searchCtx,bool collectXRefs) + const MemberDef *,bool,const Definition *searchCtx,bool collectXRefs) { //printf("***parseCode()\n"); @@ -1569,7 +1577,6 @@ void parsePythonCode(CodeOutputInterface &od,const char * /*className*/, if (s.isEmpty()) return; printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL); g_codeClassSDict.setAutoDelete(TRUE); - TooltipManager::instance()->clearTooltips(); g_code = &od; g_inputString = s; g_inputPosition = 0; @@ -1595,7 +1602,7 @@ void parsePythonCode(CodeOutputInterface &od,const char * /*className*/, if (exBlock && fd==0) { // create a dummy filedef for the example - g_sourceFileDef = new FileDef("",(exName?exName:"generated")); + g_sourceFileDef = createFileDef("",(exName?exName:"generated")); cleanupSourceDef = TRUE; } if (g_sourceFileDef) @@ -1620,10 +1627,6 @@ void parsePythonCode(CodeOutputInterface &od,const char * /*className*/, { endCodeLine(); } - if (fd) - { - TooltipManager::instance()->writeTooltips(*g_code); - } if (cleanupSourceDef) { // delete the temporary file definition used for this example diff --git a/src/pyscanner.h b/src/pyscanner.h index affa7ca..01235ee 100644 --- a/src/pyscanner.h +++ b/src/pyscanner.h @@ -53,9 +53,9 @@ class PythonLanguageScanner : public ParserInterface int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, - MemberDef *memberDef=0, + const MemberDef *memberDef=0, bool showLineNumbers=TRUE, - Definition *searchCtx=0, + const Definition *searchCtx=0, bool collectXrefs=TRUE ); void resetCodeParserState(); diff --git a/src/pyscanner.l b/src/pyscanner.l index 1596b9d..3fe66f2 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -95,6 +95,7 @@ static int g_stringContext; static QGString * g_copyString; static int g_indent = 0; static int g_curIndent = 0; +static bool g_importTuple; static QDict<QCString> g_packageNameCache(257); @@ -102,6 +103,7 @@ static char g_atomStart; static char g_atomEnd; static int g_atomCount; + //static bool g_insideConstructor; static QCString g_moduleScope; @@ -143,7 +145,7 @@ static void initEntry() current->stat = gstat; current->lang = SrcLangExt_Python; current->setParent(current_root); - initGroupInfo(current); + Doxygen::docGroup.initGroupInfo(current); gstat = FALSE; } @@ -230,6 +232,17 @@ static QCString findPackageScope(const char *fileName) return findPackageScopeFromPath(fi.dirPath(TRUE).data()); } +static void addFrom(bool all) +{ + QCString item=all ? g_packageName : g_packageName+"."+yytext; + current->name=removeRedundantWhiteSpace(substitute(item,".","::")); + current->fileName = yyFileName; + //printf("Adding using declaration: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data()); + current->section=all ? Entry::USINGDIR_SEC : Entry::USINGDECL_SEC; + current_root->addSubEntry(current); + current = new Entry ; + initEntry(); +} //----------------------------------------------------------------------------- static void lineCount() @@ -324,11 +337,12 @@ static void handleCommentBlock(const QCString &doc,bool brief) int position = 0; bool needsEntry; int lineNr = brief ? current->briefLine : current->docLine; + QCString processedDoc = preprocessCommentBlock(doc,yyFileName,lineNr); while (parseCommentBlock( g_thisParser, (docBlockInBody && previous) ? previous : current, - doc, // text - yyFileName, // file + processedDoc, // text + yyFileName, // file lineNr, docBlockInBody ? FALSE : brief, docBlockJavaStyle, // javadoc style // or FALSE, @@ -536,6 +550,8 @@ STARTDOCSYMS "##" %x SingleQuoteString %x DoubleQuoteString %x TripleString +%x SingleQuoteStringIgnore +%x DoubleQuoteStringIgnore /* import */ %x FromMod @@ -699,45 +715,43 @@ STARTDOCSYMS "##" <FromModItem>{ "*" { // import all - QCString item=g_packageName; - current->name=removeRedundantWhiteSpace(substitute(item,".","::")); - current->fileName = yyFileName; - //printf("Adding using directive: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data()); - current->section=Entry::USINGDIR_SEC; - current_root->addSubEntry(current); - current = new Entry ; - initEntry(); + addFrom(TRUE); BEGIN(Search); } {IDENTIFIER}/{B}","{B} { - QCString item=g_packageName+"."+yytext; - current->name=removeRedundantWhiteSpace(substitute(item,".","::")); - current->fileName = yyFileName; - //printf("Adding using declaration: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data()); - current->section=Entry::USINGDECL_SEC; - current_root->addSubEntry(current); - current = new Entry ; - initEntry(); + addFrom(FALSE); } + {IDENTIFIER}/{B}")" { + addFrom(FALSE); + } {IDENTIFIER} { - QCString item=g_packageName+"."+yytext; - current->name=removeRedundantWhiteSpace(substitute(item,".","::")); - current->fileName = yyFileName; - //printf("Adding using declaration: found:%s:%d name=%s\n",yyFileName.data(),yyLineNr,current->name.data()); - current->section=Entry::USINGDECL_SEC; - current_root->addSubEntry(current); - current = new Entry ; - initEntry(); - BEGIN(Search); + addFrom(FALSE); + if (!g_importTuple) + { + BEGIN(Search); + } } \n { incLineNr(); - BEGIN(Search); + if (!g_importTuple) + { + BEGIN(Search); + } } {B} { } - "," { + "(" { + g_importTuple=TRUE; + } + ")" { + g_importTuple=FALSE; + BEGIN(Search); + } + "," { } + "\\"{B}\n { // line continuation + incLineNr(); + } . { unput(*yytext); BEGIN(Search); @@ -1281,8 +1295,28 @@ STARTDOCSYMS "##" ); //Has base class-do stuff } + "'" { // start of a single quoted string + g_stringContext=YY_START; + BEGIN( SingleQuoteStringIgnore ); + } + "\"" { // start of a double quoted string + g_stringContext=YY_START; + BEGIN( DoubleQuoteStringIgnore ); + } } +<SingleQuoteStringIgnore>{ + "'" { // end of a single quoted string + BEGIN(g_stringContext); + } + . { } +} +<DoubleQuoteStringIgnore>{ + "\"" { // end of a double quoted string + BEGIN(g_stringContext); + } + . { } +} <ClassCaptureIndent>{ "\n"|({BB}"\n") { @@ -1701,6 +1735,10 @@ STARTDOCSYMS "##" lineCount(); } +<*>"'" { + fprintf(stderr,"Quote: %d\n",YY_START); + } + <*>. { //printf("[pyscanner] '%s' [ state %d ] [line %d] no match\n", // yytext, YY_START, yyLineNr); @@ -1745,14 +1783,14 @@ static void parseCompounds(Entry *rt) current = new Entry; initEntry(); - groupEnterCompound(yyFileName,yyLineNr,ce->name); + Doxygen::docGroup.enterCompound(yyFileName,yyLineNr,ce->name); pyscannerYYlex() ; g_lexInit=TRUE; delete current; current=0; ce->program.resize(0); - groupLeaveCompound(yyFileName,yyLineNr,ce->name); + Doxygen::docGroup.leaveCompound(yyFileName,yyLineNr,ce->name); } parseCompounds(ce); @@ -1812,7 +1850,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) initParser(); current = new Entry; - groupEnterFile(yyFileName,yyLineNr); + Doxygen::docGroup.enterFile(yyFileName,yyLineNr); current->reset(); initEntry(); @@ -1821,7 +1859,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt) pyscannerYYlex(); g_lexInit=TRUE; - groupLeaveFile(yyFileName,yyLineNr); + Doxygen::docGroup.leaveFile(yyFileName,yyLineNr); current_root->program.resize(0); delete current; current=0; @@ -1925,9 +1963,9 @@ void PythonLanguageScanner::parseCode(CodeOutputInterface &codeOutIntf, int startLine, int endLine, bool inlineFragment, - MemberDef *memberDef, + const MemberDef *memberDef, bool showLineNumbers, - Definition *searchCtx, + const Definition *searchCtx, bool collectXRefs ) { diff --git a/src/qhp.cpp b/src/qhp.cpp index 6ce6b06..6260d09 100644 --- a/src/qhp.cpp +++ b/src/qhp.cpp @@ -193,7 +193,7 @@ void Qhp::addContentsItem(bool /*isDir*/, const char * name, const char * /*ref*/, const char * file, const char *anchor, bool /* separateIndex */, bool /* addToNavIndex */, - Definition * /*def*/) + const Definition * /*def*/) { //printf("Qhp::addContentsItem(%s) %d\n",name,m_sectionLevel); // Backup difference before modification @@ -214,7 +214,7 @@ void Qhp::addContentsItem(bool /*isDir*/, const char * name, } } -void Qhp::addIndexItem(Definition *context,MemberDef *md, +void Qhp::addIndexItem(const Definition *context,const MemberDef *md, const char *sectionAnchor,const char *word) { (void)word; @@ -34,8 +34,8 @@ class Qhp : public IndexIntf void addContentsItem(bool isDir, const char * name, const char * ref, const char * file, const char * anchor, bool separateIndex,bool addToNavIndex, - Definition *def); - void addIndexItem(Definition *context, MemberDef *md, + const Definition *def); + void addIndexItem(const Definition *context, const MemberDef *md, const char *sectionAnchor, const char *title); void addIndexFile(const char * name); void addImageFile(const char * name); diff --git a/src/resourcemgr.cpp b/src/resourcemgr.cpp index ab7422a..8cb831e 100644 --- a/src/resourcemgr.cpp +++ b/src/resourcemgr.cpp @@ -144,7 +144,7 @@ bool ResourceMgr::copyResourceAs(const char *name,const char *targetDir,const ch } else { - t << substitute(buf,"$doxygenversion",versionString); + t << substitute(buf,"$doxygenversion",getVersion()); } return TRUE; } diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index f2edf8b..43ac362 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -236,9 +236,11 @@ void RTFDocVisitor::visit(DocStyleChange *s) if (s->enable()) m_t << "{\\b "; else m_t << "} "; break; case DocStyleChange::Strike: + case DocStyleChange::Del: if (s->enable()) m_t << "{\\strike "; else m_t << "} "; break; case DocStyleChange::Underline: + case DocStyleChange::Ins: if (s->enable()) m_t << "{\\ul "; else m_t << "} "; break; case DocStyleChange::Italic: @@ -383,7 +385,7 @@ void RTFDocVisitor::visit(DocVerbatim *s) case DocVerbatim::PlantUML: { static QCString rtfOutput = Config_getString(RTF_OUTPUT); - QCString baseName = writePlantUMLSource(rtfOutput,s->exampleFile(),s->text()); + QCString baseName = PlantumlManager::instance()->writePlantUMLSource(rtfOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_BITMAP); writePlantUMLFile(baseName, s->hasCaption()); visitCaption(this, s->children()); @@ -429,20 +431,21 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), inc->exampleFile(), - &fd, // fileDef, + fd, // fileDef, -1, // start line -1, // end line FALSE, // inline fragment 0, // memberDef TRUE // show line numbers ); + delete fd; m_t << "\\par"; m_t << "}" << endl; } @@ -465,10 +468,9 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "\\par"; m_t << "}" << endl; break; - case DocInclude::DontInclude: - break; - case DocInclude::HtmlInclude: - break; + case DocInclude::DontInclude: + case DocInclude::DontIncWithLines: + case DocInclude::HtmlInclude: case DocInclude::LatexInclude: break; case DocInclude::VerbInclude: @@ -496,7 +498,7 @@ void RTFDocVisitor::visit(DocInclude *inc) case DocInclude::SnipWithLines: { QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); m_t << "{" << endl; if (!m_lastIsPara) m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); @@ -507,13 +509,14 @@ void RTFDocVisitor::visit(DocInclude *inc) langExt, inc->isExample(), inc->exampleFile(), - &fd, + fd, lineBlock(inc->text(),inc->blockId()), -1, // endLine FALSE, // inlineFragment 0, // memberDef TRUE // show line number ); + delete fd; m_t << "}"; } break; @@ -528,10 +531,12 @@ void RTFDocVisitor::visit(DocInclude *inc) void RTFDocVisitor::visit(DocIncOperator *op) { - //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n", + //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", // op->type(),op->isFirst(),op->isLast(),op->text().data()); DBG_RTF("{\\comment RTFDocVisitor::visit(DocIncOperator)}\n"); - SrcLangExt langExt = getLanguageFromFileName(m_langExt); + QCString locLangExt = getFileNameExtension(op->includeFileName()); + if (locLangExt.isEmpty()) locLangExt = m_langExt; + SrcLangExt langExt = getLanguageFromFileName(locLangExt); if (op->isFirst()) { if (!m_hide) @@ -548,9 +553,24 @@ void RTFDocVisitor::visit(DocIncOperator *op) popEnabled(); if (!m_hide) { - Doxygen::parserManager->getParser(m_langExt) + FileDef *fd = 0; + if (!op->includeFileName().isEmpty()) + { + QFileInfo cfi( op->includeFileName() ); + fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + } + + Doxygen::parserManager->getParser(locLangExt) ->parseCode(m_ci,op->context(),op->text(),langExt, - op->isExample(),op->exampleFile()); + op->isExample(),op->exampleFile(), + fd, // fileDef + op->line(), // startLine + -1, // endLine + FALSE, // inline fragment + 0, // memberDef + op->showLineNo() // show line numbers + ); + if (fd) delete fd; } pushEnabled(); m_hide=TRUE; @@ -766,21 +786,22 @@ void RTFDocVisitor::visitPre(DocSimpleSect *s) // special case 1: user defined title if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs) { - m_t << ":"; m_t << "\\par"; m_t << "}"; // end bold incIndentLevel(); m_t << rtf_Style_Reset << getStyle("DescContinue"); + m_t << "{\\s17 \\sa60 \\sb30\n"; } m_lastIsPara=FALSE; } -void RTFDocVisitor::visitPost(DocSimpleSect *) +void RTFDocVisitor::visitPost(DocSimpleSect *s) { if (m_hide) return; DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleSect)}\n"); if (!m_lastIsPara) m_t << "\\par" << endl; decIndentLevel(); + if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs) m_t << "}"; m_t << "}"; // end desc m_lastIsPara=TRUE; } @@ -1359,7 +1380,6 @@ void RTFDocVisitor::visitPre(DocParamSect *s) default: ASSERT(0); } - m_t << ":"; m_t << "\\par"; m_t << "}" << endl; bool useTable = s->type()==DocParamSect::Param || @@ -1475,10 +1495,8 @@ void RTFDocVisitor::visitPre(DocParamList *pl) } QListIterator<DocNode> li(pl->paramTypes()); DocNode *type; - bool first=TRUE; for (li.toFirst();(type=li.current());++li) { - if (!first) m_t << " | "; else first=FALSE; if (type->kind()==DocNode::Kind_Word) { visit((DocWord*)type); @@ -1487,6 +1505,10 @@ void RTFDocVisitor::visitPre(DocParamList *pl) { visit((DocLinkedWord*)type); } + else if (type->kind()==DocNode::Kind_Sep) + { + m_t << " " << ((DocSeparator *)type)->chars() << " "; + } } if (useTable) { @@ -1637,18 +1659,6 @@ void RTFDocVisitor::visitPost(DocInternalRef *) m_t << " "; } -void RTFDocVisitor::visitPre(DocCopy *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocCopy)}\n"); -} - -void RTFDocVisitor::visitPost(DocCopy *) -{ - if (m_hide) return; - DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocCopy)}\n"); -} - void RTFDocVisitor::visitPre(DocText *) { if (m_hide) return; @@ -1868,6 +1878,6 @@ void RTFDocVisitor::writePlantUMLFile(const QCString &fileName, bool hasCaption) baseName=baseName.right(baseName.length()-i-1); } QCString outDir = Config_getString(RTF_OUTPUT); - generatePlantUMLOutput(fileName,outDir,PUML_BITMAP); + PlantumlManager::instance()->generatePlantUMLOutput(fileName,outDir,PlantumlManager::PUML_BITMAP); includePicturePreRTF(baseName + ".png", true, hasCaption); } diff --git a/src/rtfdocvisitor.h b/src/rtfdocvisitor.h index b7cc3ea..82e4453 100644 --- a/src/rtfdocvisitor.h +++ b/src/rtfdocvisitor.h @@ -126,8 +126,6 @@ class RTFDocVisitor : public DocVisitor void visitPost(DocXRefItem *); void visitPre(DocInternalRef *); void visitPost(DocInternalRef *); - void visitPre(DocCopy *); - void visitPost(DocCopy *); void visitPre(DocText *); void visitPost(DocText *); void visitPre(DocHtmlBlockQuote *); diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index 2e67c26..229a817 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -31,6 +31,10 @@ #include "diagram.h" #include "language.h" #include "dot.h" +#include "dotcallgraph.h" +#include "dotclassgraph.h" +#include "dotdirdeps.h" +#include "dotincldepgraph.h" #include "version.h" #include "pagedef.h" #include "rtfstyle.h" @@ -44,6 +48,8 @@ #include "filename.h" #include "namespacedef.h" +static bool DoxyCodeLineOpen = FALSE; + //#define DBG_RTF(x) x; #define DBG_RTF(x) @@ -96,7 +102,7 @@ RTFGenerator::~RTFGenerator() void RTFGenerator::writeStyleSheetFile(QFile &file) { FTextStream t(&file); - t << "# Generated by doxygen " << versionString << "\n\n"; + t << "# Generated by doxygen " << getVersion() << "\n\n"; t << "# This file describes styles used for generating RTF output.\n"; t << "# All text after a hash (#) is considered a comment and will be ignored.\n"; t << "# Remove a hash to activate a line.\n\n"; @@ -113,7 +119,7 @@ void RTFGenerator::writeStyleSheetFile(QFile &file) void RTFGenerator::writeExtensionsFile(QFile &file) { FTextStream t(&file); - t << "# Generated by doxygen " << versionString << "\n\n"; + t << "# Generated by doxygen " << getVersion() << "\n\n"; t << "# This file describes extensions used for generating RTF output.\n"; t << "# All text after a hash (#) is considered a comment and will be ignored.\n"; t << "# Remove a hash to activate a line.\n\n"; @@ -665,7 +671,7 @@ void RTFGenerator::endIndexSection(IndexSections is) break; case isMainPage: t << "\\par " << rtf_Style_Reset << endl; - if (!Doxygen::mainPage || Doxygen::mainPage->title().isEmpty()) + if (!mainPageHasTitle()) { t << "{\\tc \\v " << theTranslator->trMainPage() << "}"<< endl; } @@ -1532,7 +1538,7 @@ void RTFGenerator::startMemberDoc(const char *clname, t << rtf_Style_Reset << rtf_Style[showInline ? "Heading5" : "Heading4"]->reference; //styleStack.push(rtf_Style_Heading4); t << "{" << endl; - //printf("RTFGenerator::startMemberDoc() `%s'\n",rtf_Style["Heading4"]->reference); + //printf("RTFGenerator::startMemberDoc() '%s'\n",rtf_Style["Heading4"]->reference); startBold(); t << endl; } @@ -1541,7 +1547,7 @@ void RTFGenerator::endMemberDoc(bool) { DBG_RTF(t << "{\\comment endMemberDoc}" << endl) //const char *style = styleStack.pop(); - //printf("RTFGenerator::endMemberDoc() `%s'\n",style); + //printf("RTFGenerator::endMemberDoc() '%s'\n",style); //ASSERT(style==rtf_Style["Heading4"]->reference); endBold(); t << "}" << endl; @@ -1948,6 +1954,9 @@ void RTFGenerator::endCodeFragment() //styleStack.pop(); //printf("RTFGenerator::endCodeFrament() top=%s\n",styleStack.top()); //t << rtf_Style_Reset << styleStack.top() << endl; + //endCodeLine checks is there is still an open code line, if so closes it. + endCodeLine(); + DBG_RTF(t << "{\\comment (endCodeFragment) }" << endl) t << "}" << endl; m_omitParagraph = TRUE; @@ -2497,7 +2506,7 @@ void RTFGenerator::startDotGraph() DBG_RTF(t << "{\\comment (startDotGraph)}" << endl) } -void RTFGenerator::endDotGraph(const DotClassGraph &g) +void RTFGenerator::endDotGraph(DotClassGraph &g) { newParagraph(); @@ -2521,7 +2530,7 @@ void RTFGenerator::startInclDepGraph() DBG_RTF(t << "{\\comment (startInclDepGraph)}" << endl) } -void RTFGenerator::endInclDepGraph(const DotInclDepGraph &g) +void RTFGenerator::endInclDepGraph(DotInclDepGraph &g) { newParagraph(); @@ -2543,7 +2552,7 @@ void RTFGenerator::startGroupCollaboration() { } -void RTFGenerator::endGroupCollaboration(const DotGroupCollaboration &) +void RTFGenerator::endGroupCollaboration(DotGroupCollaboration &) { } @@ -2552,7 +2561,7 @@ void RTFGenerator::startCallGraph() DBG_RTF(t << "{\\comment (startCallGraph)}" << endl) } -void RTFGenerator::endCallGraph(const DotCallGraph &g) +void RTFGenerator::endCallGraph(DotCallGraph &g) { newParagraph(); @@ -2575,7 +2584,7 @@ void RTFGenerator::startDirDepGraph() DBG_RTF(t << "{\\comment (startDirDepGraph)}" << endl) } -void RTFGenerator::endDirDepGraph(const DotDirDeps &g) +void RTFGenerator::endDirDepGraph(DotDirDeps &g) { newParagraph(); @@ -2803,7 +2812,7 @@ void RTFGenerator::exceptionEntry(const char* prefix,bool closeBracket) t << " "; } -void RTFGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *) +void RTFGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *) { RTFDocVisitor *visitor = new RTFDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString("")); n->accept(visitor); @@ -3037,6 +3046,22 @@ void RTFGenerator::endInlineMemberDoc() t << "\\cell }{\\row }" << endl; } +void RTFGenerator::writeLineNumber(const char *,const char *,const char *,int l) +{ + DoxyCodeLineOpen = TRUE; + t << QString("%1").arg(l,5) << " "; +} +void RTFGenerator::startCodeLine(bool) +{ + DoxyCodeLineOpen = TRUE; + col=0; +} +void RTFGenerator::endCodeLine() +{ + if (DoxyCodeLineOpen) lineBreak(); + DoxyCodeLineOpen = FALSE; +} + void RTFGenerator::startLabels() { } diff --git a/src/rtfgen.h b/src/rtfgen.h index b6b32c7..b5f06f0 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -41,7 +41,7 @@ class RTFGenerator : public OutputGenerator bool isEnabled(OutputType o) { return (o==RTF && active); } OutputGenerator *get(OutputType o) { return (o==RTF) ? this : 0; } - void writeDoc(DocNode *,Definition *,MemberDef *); + void writeDoc(DocNode *,const Definition *,const MemberDef *); void startFile(const char *name,const char *manName,const char *title); void writeSearchInfo() {} @@ -127,9 +127,9 @@ class RTFGenerator : public OutputGenerator void writeAnchor(const char *fileName,const char *name); void startCodeFragment(); void endCodeFragment(); - void writeLineNumber(const char *,const char *,const char *,int l) { t << QString("%1").arg(l,5) << " "; } - void startCodeLine(bool) { col=0; } - void endCodeLine() { lineBreak(); } + void writeLineNumber(const char *,const char *,const char *,int l); + void startCodeLine(bool); + void endCodeLine(); void startEmphasis() { t << "{\\i "; } void endEmphasis() { t << "}"; } void startBold() { t << "{\\b "; } @@ -202,16 +202,16 @@ class RTFGenerator : public OutputGenerator void endDescTableData(); void startDotGraph(); - void endDotGraph(const DotClassGraph &); + void endDotGraph(DotClassGraph &); void startInclDepGraph(); - void endInclDepGraph(const DotInclDepGraph &); + void endInclDepGraph(DotInclDepGraph &); void startGroupCollaboration(); - void endGroupCollaboration(const DotGroupCollaboration &g); + void endGroupCollaboration(DotGroupCollaboration &g); void startCallGraph(); - void endCallGraph(const DotCallGraph &); + void endCallGraph(DotCallGraph &); void startDirDepGraph(); - void endDirDepGraph(const DotDirDeps &g); - void writeGraphicalHierarchy(const DotGfxHierarchyTable &) {} + void endDirDepGraph(DotDirDeps &g); + void writeGraphicalHierarchy(DotGfxHierarchyTable &) {} void startMemberGroupHeader(bool); void endMemberGroupHeader(); @@ -262,7 +262,7 @@ class RTFGenerator : public OutputGenerator void endFontClass(); void writeCodeAnchor(const char *) {} - void setCurrentDoc(Definition *,const char *,bool) {} + void setCurrentDoc(const Definition *,const char *,bool) {} void addWord(const char *,bool) {} static bool preProcessFileInplace(const char *path,const char *name); diff --git a/src/scanner.h b/src/scanner.h index ac574e2..c0d3dff 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -48,9 +48,9 @@ class CLanguageScanner : public ParserInterface int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, - MemberDef *memberDef=0, + const MemberDef *memberDef=0, bool showLineNumbers=TRUE, - Definition *searchCtx=0, + const Definition *searchCtx=0, bool collectXRefs=TRUE ); void resetCodeParserState(); diff --git a/src/scanner.l b/src/scanner.l index 7559e0b..970b1e8 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -78,6 +78,7 @@ static int lastHereDocContext; static int lastDefineContext; static int lastAlignAsContext; static int lastC11AttributeContext; +static int lastModifierContext; static Protection protection; static Protection baseProt; static int sharpCount = 0 ; @@ -246,7 +247,7 @@ static void initEntry() // //printf("Appending group %s\n",autoGroupStack.top()->groupname.data()); // current->groups->append(new Grouping(*autoGroupStack.top())); //} - initGroupInfo(current); + Doxygen::docGroup.initGroupInfo(current); isTypedef=FALSE; } @@ -613,6 +614,7 @@ PRE [pP][rR][eE] CODE [cC][oO][dD][eE] CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] +PHPUSEKW ("public"|"private"|"protected") IDLATTR ("["[^\]]*"]"){BN}* TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"(" @@ -766,6 +768,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) /** Slice states */ +%x SliceOptional %x SliceMetadata %x SliceSequence %x SliceSequenceName @@ -865,12 +868,6 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <FindMembersPHP>. { // Non-PHP code text, ignore } -<FindMembers>"?>"|"</script>" { // PHP code end - if (insidePHP) - BEGIN( FindMembersPHP ); - else - REJECT; - } <FindMembers>{PHPKW} { if (insidePHP) BEGIN( NextSemi ); else @@ -1146,9 +1143,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <ObjCReturnType>")" { BEGIN( ObjCMethod ); } -<ObjCParams>({ID})?":" { // Keyword of parameter +<ObjCParams>({ID})?{BN}*":" { // Keyword of parameter QCString keyw = yytext; - keyw=keyw.left(keyw.length()-1); // strip : + keyw=keyw.left(keyw.length()-1).stripWhiteSpace(); // strip : if (keyw.isEmpty()) { current->name += " :"; @@ -1390,10 +1387,26 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->explicitExternal = TRUE; lineCount(); } +<FindMembers>{B}*"const"{BN}+ { current->type += " const "; + if (insideCS) current->stat = TRUE; + lineCount(); + } <FindMembers>{B}*"virtual"{BN}+ { current->type += " virtual "; current->virt = Virtual; lineCount(); } +<FindMembers>{B}*"constexpr"{BN}+ { + if (insideCpp) + { + current->type += " constexpr "; + current->spec |= Entry::ConstExpr; + lineCount(); + } + else + { + REJECT; + } + } <FindMembers>{B}*"published"{BN}+ { // UNO IDL published keyword if (insideIDL) { @@ -1994,11 +2007,16 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <PHPUseAs>{BN}+"as"{BN}+ { lineCount(); } +<PHPUseAs>{PHPUSEKW} { + } <PHPUseAs>{ID} { //printf("PHP: adding use as relation: %s->%s\n",yytext,aliasName.data()); - Doxygen::namespaceAliasDict.insert(yytext, - new QCString(removeRedundantWhiteSpace( - substitute(aliasName,"\\","::")))); + if (!aliasName.isEmpty()) + { + Doxygen::namespaceAliasDict.insert(yytext, + new QCString(removeRedundantWhiteSpace( + substitute(aliasName,"\\","::")))); + } aliasName.resize(0); } <PHPUse,PHPUseAs>[,;] { @@ -2298,6 +2316,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <CopyHereDocEnd>\n { *pCopyHereDocGString += yytext; } +<CopyHereDocEnd>{ID} { + *pCopyHereDocGString += yytext; + } <CopyHereDocEnd>. { *pCopyHereDocGString += yytext; } @@ -2423,6 +2444,19 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type+=yytext; BEGIN(DeclType); } + else if (insideSlice && qstrcmp(yytext,"optional")==0) + { + if (current->type.isEmpty()) + { + current->type = "optional"; + } + else + { + current->type += " optional"; + } + lastModifierContext = YY_START; + BEGIN(SliceOptional); + } else { if (YY_START==FindMembers) @@ -2438,6 +2472,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->protection = Protected; } + else if ((insideCS || insideD || insidePHP || insideJS) && qstrcmp(yytext,"internal")==0) + { + current->protection = Package; + } else if (javaLike && qstrcmp(yytext,"private")==0) { current->protection = Private; @@ -2639,7 +2677,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } */ <Define>{ID} { - //printf("Define `%s' without args\n",yytext); + //printf("Define '%s' without args\n",yytext); if (insideCpp || insideObjC) { current->id = ClangParser::instance()->lookup(yyLineNr,yytext); @@ -2814,17 +2852,17 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } -<FindMembers,FindFields>("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") { +<FindMembers,FindFields>("//"([!/]){B}*{CMD}"{")|("/*"([!*]){B}*{CMD}"{") { //handleGroupStartCommand(current->name); if (previous && previous->section==Entry::GROUPDOC_SEC) { // link open command to the group defined in the previous entry - openGroup(previous,yyFileName,yyLineNr); + Doxygen::docGroup.open(previous,yyFileName,yyLineNr); } else { // link open command to the current entry - openGroup(current,yyFileName,yyLineNr); + Doxygen::docGroup.open(current,yyFileName,yyLineNr); } //current = tmp; initEntry(); @@ -2866,9 +2904,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } } -<FindMembers,FindFields,ReadInitializer>"//"([!/]?){B}*{CMD}"}".*|"/*"([!*]?){B}*{CMD}"}"[^*]*"*/" { +<FindMembers,FindFields,ReadInitializer>"//"([!/]){B}*{CMD}"}".*|"/*"([!*]){B}*{CMD}"}"[^*]*"*/" { bool insideEnum = YY_START==FindFields || (YY_START==ReadInitializer && lastInitializerContext==FindFields); // see bug746226 - closeGroup(current,yyFileName,yyLineNr,insideEnum); + Doxygen::docGroup.close(current,yyFileName,yyLineNr,insideEnum); } <FindMembers>"=" { // in PHP code this could also be due to "<?=" current->bodyLine = yyLineNr; @@ -2910,7 +2948,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) BEGIN(GCopyCurly); } <ReadInitializer>[;,] { - //printf(">> initializer `%s' <<\n",current->initializer.data()); + //printf(">> initializer '%s' <<\n",current->initializer.data()); if (*yytext==';' && (current_root->spec&Entry::Enum)) { current->fileName = yyFileName; @@ -3573,6 +3611,20 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) BEGIN (lastSquareContext); } } +<SliceOptional>"(" { + current->type += "("; + roundCount++; + } +<SliceOptional>[0-9]+ { + current->type += yytext; + } +<SliceOptional>")" { + current->type += ")"; + if(--roundCount<=0) + { + BEGIN (lastModifierContext); + } + } <IDLAttribute>"]" { // end of IDL function attribute if (--squareCount<=0) @@ -3804,7 +3856,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <SkipRemainder>[^\n]* <FindFields>"," { - //printf("adding `%s' `%s' `%s' to enum `%s' (mGrpId=%d)\n", + //printf("adding '%s' '%s' '%s' to enum '%s' (mGrpId=%d)\n", // current->type.data(), current->name.data(), // current->args.data(), current_root->name.data(),current->mGrpId); if (!current->name.isEmpty()) @@ -3925,6 +3977,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { current->endBodyLine = yyLineNr; + Entry * original_root = current_root; // save root this namespace is in if (current->section == Entry::NAMESPACE_SEC && current->type == "namespace") { int split_point; @@ -3949,7 +4002,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } QCString &cn = current->name; QCString rn = current_root->name.copy(); - //printf("cn=`%s' rn=`%s' isTypedef=%d\n",cn.data(),rn.data(),isTypedef); + //printf("cn='%s' rn='%s' isTypedef=%d\n",cn.data(),rn.data(),isTypedef); if (!cn.isEmpty() && !rn.isEmpty()) { prependScope(); @@ -3970,7 +4023,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // was: current->args.simplifyWhiteSpace(); current->type = current->type.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); - //printf("adding `%s' `%s' `%s' brief=%s insideObjC=%d %x\n",current->type.data(),current->name.data(),current->args.data(),current->brief.data(),insideObjC,current->section); + //printf("adding '%s' '%s' '%s' brief=%s insideObjC=%d %x\n",current->type.data(),current->name.data(),current->args.data(),current->brief.data(),insideObjC,current->section); if (insideObjC && ((current->spec&Entry::Interface) || (current->spec==Entry::Category)) ) // method definition follows @@ -3989,6 +4042,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) ) { // namespaces and interfaces and java classes ends with a closing bracket without semicolon current->reset(); + current_root = original_root; // restore scope from before namespace descent initEntry(); memspecEntry = 0; BEGIN( FindMembers ) ; @@ -4115,7 +4169,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { // see if the compound does not have a name or is inside another // anonymous compound. If so we insert a - // special `anonymous' variable. + // special 'anonymous' variable. //Entry *p=current_root; Entry *p=current; while (p) @@ -4123,7 +4177,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // only look for class scopes, not namespace scopes if ((p->section & Entry::COMPOUND_MASK) && !p->name.isEmpty()) { - //printf("Trying scope `%s'\n",p->name.data()); + //printf("Trying scope '%s'\n",p->name.data()); int i=p->name.findRev("::"); int pi = (i==-1) ? 0 : i+2; if (p->name.at(pi)=='@') @@ -4208,7 +4262,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } - //printf("Add: type=`%s',name=`%s',args=`%s' brief=%s doc=%s\n", + //printf("Add: type='%s',name='%s',args='%s' brief=%s doc=%s\n", // varEntry->type.data(),varEntry->name.data(), // varEntry->args.data(),varEntry->brief.data(),varEntry->doc.data()); current_root->addSubEntry(varEntry); @@ -4310,7 +4364,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } <FuncPtr>. { - //printf("error: FuncPtr `%c' unexpected at line %d of %s\n",*yytext,yyLineNr,yyFileName); + //printf("error: FuncPtr '%c' unexpected at line %d of %s\n",*yytext,yyLineNr,yyFileName); } <FuncPtrOperator>"("{BN}*")"{BN}*/"(" { current->name += yytext; @@ -4564,7 +4618,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) BEGIN( SkipCxxComment ); } */ - /* `)' followed by a special comment */ + /* ')' followed by a special comment */ <ReadFuncArgType>")"{BN}*("/*"[*!]|"//"[/!])"<" { lineCount(); if (currentArgumentContext==DefineEnd) @@ -4609,7 +4663,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) unput(lastCopyArgChar); BEGIN( lastCommentInArgContext ); } -<CopyArgCommentLine>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9] { // verbatim command (which could contain nested comments!) +<CopyArgCommentLine>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!) docBlockName=&yytext[1]; fullArgString+=yytext; BEGIN(CopyArgVerbatim); @@ -4627,7 +4681,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) fullArgString+=yytext; BEGIN(CopyArgVerbatim); } -<CopyArgVerbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"enddot"|"endcode"|"f$"|"f]"|"f}")/[^a-z_A-Z0-9] { // end of verbatim block +<CopyArgVerbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"enddot"|"endcode"|"f$"|"f]"|"f}")/[^a-z_A-Z0-9\-] { // end of verbatim block fullArgString+=yytext; if (yytext[1]=='f') // end of formula { @@ -5095,7 +5149,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) if (!current->type.isEmpty() && (!isFunction || current->type.left(8)=="typedef ")) { - //printf("Scanner.l: found in class variable: `%s' `%s' `%s'\n", current->type.data(),current->name.data(),current->args.data()); + //printf("Scanner.l: found in class variable: '%s' '%s' '%s'\n", current->type.data(),current->name.data(),current->args.data()); if (isTypedef && current->type.left(8)!="typedef ") { current->type.prepend("typedef "); @@ -5104,14 +5158,14 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - //printf("Scanner.l: found in class function: `%s' `%s' `%s'\n", current->type.data(),current->name.data(),current->args.data()); + //printf("Scanner.l: found in class function: '%s' '%s' '%s'\n", current->type.data(),current->name.data(),current->args.data()); current->section = Entry::FUNCTION_SEC ; current->proto = *yytext==';'; } } else // a global function prototype or function variable { - //printf("Scanner.l: prototype? type=`%s' name=`%s' args=`%s'\n",current->type.data(),current->name.data(),current->args.data()); + //printf("Scanner.l: prototype? type='%s' name='%s' args='%s'\n",current->type.data(),current->name.data(),current->args.data()); if (!current->type.isEmpty() && (current->type.find(re,0)!=-1 || current->type.left(8)=="typedef ")) { @@ -5129,7 +5183,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->proto = TRUE; } } - //printf("Adding entry `%s'\n",current->name.data()); + //printf("Adding entry '%s'\n",current->name.data()); if ( insidePHP) { if (findAndRemoveWord(current->type,"final")) @@ -5326,7 +5380,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) lineCount(); //addToBody(yytext); } -<SkipCurly,SkipCurlyCpp>"<<<" { +<SkipCurly,SkipCurlyCpp,ReadInitializer>"<<<" { if (!insidePHP) { REJECT; @@ -5537,7 +5591,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name=current->name.left(current->name.length()-1).stripWhiteSpace(); //printf("template class declaration for %s!\n",current->name.data()); QCString rn = current_root->name.copy(); - //printf("cn=`%s' rn=`%s' isTypedef=%d\n",cn.data(),rn.data(),isTypedef); + //printf("cn='%s' rn='%s' isTypedef=%d\n",cn.data(),rn.data(),isTypedef); if (!current->name.isEmpty() && !rn.isEmpty()) { prependScope(); @@ -6236,6 +6290,43 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) startCommentBlock(FALSE); BEGIN( DocBlock ); } +<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>"/**"[*]+{BL} { + + static bool javadocBanner = Config_getBool(JAVADOC_BANNER); + + if( javadocBanner ) { + lastDocContext = YY_START; + + //printf("Found comment banner at %s:%d\n",yyFileName,yyLineNr); + if (current_root->section & Entry::SCOPE_MASK) + { + current->inside = current_root->name+"::"; + } + current->docLine = yyLineNr; + current->docFile = yyFileName; + docBlockContext = YY_START; + docBlockInBody = YY_START==SkipCurly; + static bool javadocAutoBrief = Config_getBool(JAVADOC_AUTOBRIEF); + docBlockAutoBrief = javadocAutoBrief; + + QCString indent; + indent.fill(' ',computeIndent(yytext,g_column)); + docBlock=indent; + + if (docBlockAutoBrief) + { + current->briefLine = yyLineNr; + current->briefFile = yyFileName; + } + startCommentBlock(FALSE); + BEGIN( DocBlock ); + } else { + current->program += yytext ; + lastContext = YY_START ; + BEGIN( Comment ) ; + } + + } <FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>("//"{B}*)?"/**"/[^/*] { removeSlashes=(yytext[1]=='/'); lastDocContext = YY_START; @@ -6526,7 +6617,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // middle of a comment block docBlock+=yytext; } -<DocBlock>("@@"|"\\\\"){ID}/[^a-z_A-Z0-9] { // escaped command +<DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command docBlock+=yytext; } <DocBlock>{CMD}("f$"|"f["|"f{") { @@ -6547,7 +6638,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) g_nestedComment=FALSE; BEGIN(DocCopyBlock); } -<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9] { // verbatim command (which could contain nested comments!) +<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"dot"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!) docBlock+=yytext; docBlockName=&yytext[1]; g_fencedSize=0; @@ -6635,7 +6726,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) docBlock+=indent; } } -<DocCopyBlock>^{B}*"*"+/{BN}+"*"{BN}* { // start of a comment line with two *'s +<DocCopyBlock>^{B}*"*"+/{B}+"*"{BN}* { // start of a comment line with two *'s if (docBlockName=="code") { QCString indent; @@ -6716,7 +6807,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <DocCopyBlock><<EOF>> { warn(yyFileName,yyLineNr, - "reached end of file while inside a %s block!\n" + "reached end of file while inside a '%s' block!\n" "The command that should end the block seems to be missing!\n", docBlockName.data()); yyterminate(); @@ -6794,7 +6885,6 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } - /* ------------ Generic rules -------------- */ <SkipCxxComment>.*"\\\n" { // line continuation @@ -6812,7 +6902,18 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <SkipComment>[^\*\n]+ + /* ------------ Generic rules -------------- */ + +<*>"?>"|"</script>" { // PHP code end + if (insidePHP) + BEGIN( FindMembersPHP ); + else + REJECT; + } + <*>"[[" { // C++11 attribute + if (!insideCpp) REJECT; + if (YY_START == CopyGString || YY_START == CopyGString) REJECT; lastC11AttributeContext = YY_START; BEGIN( SkipC11Attribute ); } @@ -6908,12 +7009,10 @@ static void newEntry() static void handleCommentBlock(const QCString &doc,bool brief) { static bool hideInBodyDocs = Config_getBool(HIDE_IN_BODY_DOCS); - int position=0; - bool needsEntry=FALSE; if (docBlockInBody && hideInBodyDocs) return; //printf("parseCommentBlock [%s] brief=%d\n",doc.data(),brief); int lineNr = brief ? current->briefLine : current->docLine; // line of block start - + // fill in inbodyFile && inbodyLine the first time, see bug 633891 Entry *docEntry = docBlockInBody && previous ? previous : current; if (docBlockInBody && docEntry && docEntry->inbodyLine==-1) @@ -6922,12 +7021,15 @@ static void handleCommentBlock(const QCString &doc,bool brief) docEntry->inbodyLine = lineNr; } + int position=0; + bool needsEntry=FALSE; + QCString processedDoc = preprocessCommentBlock(stripIndentation(doc),yyFileName,lineNr); while (parseCommentBlock( g_thisParser, docBlockInBody && previous ? previous : current, - stripIndentation(doc), // text - yyFileName, // file - lineNr, // line of block start + processedDoc, // text + yyFileName, // file + lineNr, // line of block start docBlockInBody ? FALSE : brief, // isBrief docBlockInBody ? FALSE : docBlockAutoBrief, // isJavaDocStyle docBlockInBody, // isInBody @@ -6935,7 +7037,7 @@ static void handleCommentBlock(const QCString &doc,bool brief) position, needsEntry ) - ) + ) { //printf("parseCommentBlock position=%d [%s]\n",position,doc.data()+position); if (needsEntry) @@ -6968,6 +7070,7 @@ static void handleParametersCommentBlocks(ArgumentList *al) //printf(" Param %s docs=%s\n",a->name.data(),a->docs.data()); if (!a->docs.isEmpty()) { + if (!a->name && a->type == "...") a->name= "..."; int position=0; bool needsEntry; @@ -7115,13 +7218,13 @@ static void parseCompounds(Entry *rt) //memberGroupId = DOX_NOGROUP; //memberGroupRelates.resize(0); //memberGroupInside.resize(0); - groupEnterCompound(yyFileName,yyLineNr,ce->name); + Doxygen::docGroup.enterCompound(yyFileName,yyLineNr,ce->name); scannerYYlex() ; g_lexInit=TRUE; //forceEndGroup(); - groupLeaveCompound(yyFileName,yyLineNr,ce->name); + Doxygen::docGroup.leaveCompound(yyFileName,yyLineNr,ce->name); delete current; current=0; ce->program.resize(0); @@ -7181,7 +7284,7 @@ static void parseMain(const char *fileName, current_root = rt ; initParser(); - groupEnterFile(yyFileName,yyLineNr); + Doxygen::docGroup.enterFile(yyFileName,yyLineNr); current = new Entry; //printf("current=%p current_root=%p\n",current,current_root); int sec=guessSection(yyFileName); @@ -7213,7 +7316,7 @@ static void parseMain(const char *fileName, } //forceEndGroup(); - groupLeaveFile(yyFileName,yyLineNr); + Doxygen::docGroup.leaveFile(yyFileName,yyLineNr); //if (depthIf>0) //{ @@ -7348,9 +7451,9 @@ void CLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf, int startLine, int endLine, bool inlineFragment, - MemberDef *memberDef, + const MemberDef *memberDef, bool showLineNumbers, - Definition *searchCtx, + const Definition *searchCtx, bool collectXRefs ) { @@ -7365,7 +7468,7 @@ bool CLanguageScanner::needsPreprocessing(const QCString &extension) SrcLangExt lang = getLanguageFromFileName(extension); return (SrcLangExt_Cpp == lang) || !( fe==".java" || fe==".as" || fe==".d" || fe==".php" || - fe==".php4" || fe==".inc" || fe==".phtml" + fe==".php4" || fe==".inc" || fe==".phtml"|| fe==".php5" ); } diff --git a/src/searchindex.cpp b/src/searchindex.cpp index 5859d67..b21d587 100644 --- a/src/searchindex.cpp +++ b/src/searchindex.cpp @@ -86,12 +86,12 @@ SearchIndex::SearchIndex() : SearchIndexIntf(Internal), for (i=0;i<numIndexEntries;i++) m_index.insert(i,new QList<IndexWord>); } -void SearchIndex::setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile) +void SearchIndex::setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile) { if (ctx==0) return; assert(!isSourceFile || ctx->definitionType()==Definition::TypeFile); //printf("SearchIndex::setCurrentDoc(%s,%s,%s)\n",name,baseName,anchor); - QCString url=isSourceFile ? ((FileDef*)ctx)->getSourceFileBase() : ctx->getOutputFileBase(); + QCString url=isSourceFile ? (dynamic_cast<const FileDef*>(ctx))->getSourceFileBase() : ctx->getOutputFileBase(); url+=Config_getString(HTML_FILE_EXTENSION); QCString baseUrl = url; if (anchor) url+=QCString("#")+anchor; @@ -99,7 +99,7 @@ void SearchIndex::setCurrentDoc(Definition *ctx,const char *anchor,bool isSource QCString name=ctx->qualifiedName(); if (ctx->definitionType()==Definition::TypeMember) { - MemberDef *md = (MemberDef *)ctx; + const MemberDef *md = dynamic_cast<const MemberDef *>(ctx); name.prepend((md->getLanguage()==SrcLangExt_Fortran ? theTranslator->trSubprogram(TRUE,TRUE) : theTranslator->trMember(TRUE,TRUE))+" "); @@ -116,8 +116,8 @@ void SearchIndex::setCurrentDoc(Definition *ctx,const char *anchor,bool isSource { case Definition::TypePage: { - PageDef *pd = (PageDef *)ctx; - if (!pd->title().isEmpty()) + const PageDef *pd = dynamic_cast<const PageDef *>(ctx); + if (pd->hasTitle()) { name = theTranslator->trPage(TRUE,TRUE)+" "+pd->title(); } @@ -129,7 +129,7 @@ void SearchIndex::setCurrentDoc(Definition *ctx,const char *anchor,bool isSource break; case Definition::TypeClass: { - ClassDef *cd = (ClassDef *)ctx; + const ClassDef *cd = dynamic_cast<const ClassDef *>(ctx); name.prepend(cd->compoundTypeString()+" "); } break; @@ -151,7 +151,7 @@ void SearchIndex::setCurrentDoc(Definition *ctx,const char *anchor,bool isSource break; case Definition::TypeGroup: { - GroupDef *gd = (GroupDef *)ctx; + const GroupDef *gd = dynamic_cast<const GroupDef *>(ctx); if (gd->groupTitle()) { name = theTranslator->trGroup(TRUE,TRUE)+" "+gd->groupTitle(); @@ -442,11 +442,11 @@ SearchIndexExternal::~SearchIndexExternal() delete p; } -static QCString definitionToName(Definition *ctx) +static QCString definitionToName(const Definition *ctx) { if (ctx && ctx->definitionType()==Definition::TypeMember) { - MemberDef *md = (MemberDef*)ctx; + const MemberDef *md = dynamic_cast<const MemberDef*>(ctx); if (md->isFunction()) return "function"; else if (md->isSlot()) @@ -477,7 +477,7 @@ static QCString definitionToName(Definition *ctx) switch(ctx->definitionType()) { case Definition::TypeClass: - return ((ClassDef*)ctx)->compoundTypeString(); + return (dynamic_cast<const ClassDef*>(ctx))->compoundTypeString(); case Definition::TypeFile: return "file"; case Definition::TypeNamespace: @@ -497,10 +497,10 @@ static QCString definitionToName(Definition *ctx) return "unknown"; } -void SearchIndexExternal::setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile) +void SearchIndexExternal::setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile) { QCString extId = stripPath(Config_getString(EXTERNAL_SEARCH_ID)); - QCString baseName = isSourceFile ? ((FileDef*)ctx)->getSourceFileBase() : ctx->getOutputFileBase(); + 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; @@ -514,7 +514,7 @@ void SearchIndexExternal::setCurrentDoc(Definition *ctx,const char *anchor,bool e->name = ctx->qualifiedName(); if (ctx->definitionType()==Definition::TypeMember) { - e->args = ((MemberDef*)ctx)->argsString(); + e->args = (dynamic_cast<const MemberDef*>(ctx))->argsString(); } e->extId = extId; e->url = url; @@ -585,14 +585,14 @@ void SearchIndexExternal::write(const char *fileName) static SearchIndexInfo g_searchIndexInfo[NUM_SEARCH_INDICES]; -static void addMemberToSearchIndex(MemberDef *md) +static void addMemberToSearchIndex(const MemberDef *md) { static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS); bool isLinkable = md->isLinkable(); - ClassDef *cd=0; - NamespaceDef *nd=0; - FileDef *fd=0; - GroupDef *gd=0; + const ClassDef *cd=0; + const NamespaceDef *nd=0; + const FileDef *fd=0; + const GroupDef *gd=0; if (isLinkable && ( ((cd=md->getClassDef()) && cd->isLinkable() && cd->templateMaster()==0) || @@ -956,6 +956,7 @@ void createJavascriptSearchIndex() void writeJavascriptSearchIndex() { int i; + int cnt = 0; // write index files QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search"; @@ -983,7 +984,7 @@ void writeJavascriptSearchIndex() " \"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl; t << "<html><head><title></title>" << endl; t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>" << endl; - t << "<meta name=\"generator\" content=\"Doxygen " << versionString << "\"/>" << endl; + t << "<meta name=\"generator\" content=\"Doxygen " << getVersion() << "\"/>" << endl; t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>" << endl; t << "<script type=\"text/javascript\" src=\"" << baseName << ".js\"></script>" << endl; t << "<script type=\"text/javascript\" src=\"search.js\"></script>" << endl; @@ -1043,13 +1044,11 @@ void writeJavascriptSearchIndex() } firstEntry=FALSE; - ti << " ['" << dl->id() << "',['" << convertToXML(dl->name()) << "',["; + ti << " ['" << dl->id() << "_" << cnt++ << "',['" << convertToXML(dl->name()) << "',["; if (dl->count()==1) // item with a unique name { - MemberDef *md = 0; - bool isMemberDef = d->definitionType()==Definition::TypeMember; - if (isMemberDef) md = (MemberDef*)d; + MemberDef *md = dynamic_cast<MemberDef*>(d); QCString anchor = d->anchor(); ti << "'" << externalRef("../",d->getReference(),TRUE) @@ -1076,7 +1075,7 @@ void writeJavascriptSearchIndex() } else if (md) { - FileDef *fd = md->getBodyDef(); + const FileDef *fd = md->getBodyDef(); if (fd==0) fd = md->getFileDef(); if (fd) { @@ -1101,9 +1100,7 @@ void writeJavascriptSearchIndex() Definition *scope = d->getOuterScope(); Definition *next = di.current(); Definition *nextScope = 0; - MemberDef *md = 0; - bool isMemberDef = d->definitionType()==Definition::TypeMember; - if (isMemberDef) md = (MemberDef*)d; + MemberDef *md = dynamic_cast<MemberDef*>(d); if (next) nextScope = next->getOuterScope(); QCString anchor = d->anchor(); @@ -1147,20 +1144,20 @@ void writeJavascriptSearchIndex() QCString name; if (d->definitionType()==Definition::TypeClass) { - name = convertToXML(((ClassDef*)d)->displayName()); + name = convertToXML((dynamic_cast<ClassDef*>(d))->displayName()); found = TRUE; } else if (d->definitionType()==Definition::TypeNamespace) { - name = convertToXML(((NamespaceDef*)d)->displayName()); + name = convertToXML((dynamic_cast<NamespaceDef*>(d))->displayName()); found = TRUE; } else if (scope==0 || scope==Doxygen::globalScope) // in global scope { if (md) { - FileDef *fd = md->getBodyDef(); - if (fd==0) fd = md->getFileDef(); + const FileDef *fd = md->getBodyDef(); + if (fd==0) fd = md->resolveAlias()->getFileDef(); if (fd) { if (!prefix.isEmpty()) prefix+=": "; @@ -1169,7 +1166,7 @@ void writeJavascriptSearchIndex() } } } - else if (md && (md->getClassDef() || md->getNamespaceDef())) + else if (md && (md->resolveAlias()->getClassDef() || md->resolveAlias()->getNamespaceDef())) // member in class or namespace scope { SrcLangExt lang = md->getLanguage(); @@ -1319,7 +1316,7 @@ SearchIndexList::~SearchIndexList() { } -void SearchIndexList::append(Definition *d) +void SearchIndexList::append(const Definition *d) { QCString dispName = d->localName(); SearchDefinitionList *l = find(dispName); @@ -1327,11 +1324,11 @@ void SearchIndexList::append(Definition *d) { if (d->definitionType()==Definition::TypeGroup) { - dispName = ((GroupDef*)d)->groupTitle(); + dispName = (dynamic_cast<const GroupDef*>(d))->groupTitle(); } else if (d->definitionType()==Definition::TypePage) { - dispName = ((PageDef*)d)->title(); + dispName = (dynamic_cast<const PageDef*>(d))->title(); } l=new SearchDefinitionList(searchId(dispName),dispName); SDict< SearchDefinitionList >::append(dispName,l); diff --git a/src/searchindex.h b/src/searchindex.h index 0345b41..9a612ad 100644 --- a/src/searchindex.h +++ b/src/searchindex.h @@ -72,7 +72,7 @@ class SearchIndexIntf enum Kind { Internal, External }; SearchIndexIntf(Kind k) : m_kind(k) {} virtual ~SearchIndexIntf() {} - virtual void setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile) = 0; + virtual void setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile) = 0; virtual void addWord(const char *word,bool hiPriority) = 0; virtual void write(const char *file) = 0; Kind kind() const { return m_kind; } @@ -84,7 +84,7 @@ class SearchIndex : public SearchIndexIntf { public: SearchIndex(); - void setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile); + void setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile); void addWord(const char *word,bool hiPriority); void write(const char *file); private: @@ -103,7 +103,7 @@ class SearchIndexExternal : public SearchIndexIntf public: SearchIndexExternal(); ~SearchIndexExternal(); - void setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile); + void setCurrentDoc(const Definition *ctx,const char *anchor,bool isSourceFile); void addWord(const char *word,bool hiPriority); void write(const char *file); private: @@ -148,10 +148,10 @@ class SearchDefinitionList : public QList<Definition> class SearchIndexList : public SDict< SearchDefinitionList > { public: - typedef Definition ElementType; + typedef const Definition ElementType; SearchIndexList(uint letter); ~SearchIndexList(); - void append(Definition *d); + void append(const Definition *d); uint letter() const; private: int compareValues(const SearchDefinitionList *md1, const SearchDefinitionList *md2) const; diff --git a/src/sqlcode.h b/src/sqlcode.h index 9c1f7e0..d8a09b7 100644 --- a/src/sqlcode.h +++ b/src/sqlcode.h @@ -30,7 +30,7 @@ class Definition; extern void parseSqlCode(CodeOutputInterface &,const char *,const QCString &, bool ,const char *,FileDef *fd, int startLine,int endLine,bool inlineFragment, - MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx, + const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, bool collectXRefs); extern void resetSqlCodeParserState(); diff --git a/src/sqlcode.l b/src/sqlcode.l index fd0f11e..eec9732 100644 --- a/src/sqlcode.l +++ b/src/sqlcode.l @@ -15,6 +15,10 @@ %option never-interactive %option prefix="sqlcodeYY" +%option noyywrap +%option nounput +%option reentrant +%option extra-type="struct sqlcodeYY_state *" %{ @@ -31,133 +35,261 @@ #include "config.h" #include "filedef.h" #include "tooltip.h" +#include "message.h" #define YY_NEVER_INTERACTIVE 1 #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 -static CodeOutputInterface * g_code; -static QCString g_curClassName; -static QCString g_parmType; -static QCString g_parmName; -static const char * g_inputString; //!< the code fragment as text -static int g_inputPosition; //!< read offset during parsing -static int g_inputLines; //!< number of line in the code fragment -static int g_yyLineNr; //!< current line number -static bool g_needsTermination; -static Definition *g_searchCtx; - -static bool g_exampleBlock; -static QCString g_exampleName; -static QCString g_exampleFile; - -static QCString g_type; -static QCString g_name; -static QCString g_args; -static QCString g_classScope; - -static QCString g_CurrScope; - -static FileDef * g_sourceFileDef; -static Definition * g_currentDefinition; -static MemberDef * g_currentMemberDef; -static bool g_includeCodeFragment; -static const char * g_currentFontClass; - -static void codify(const char* text) +struct sqlcodeYY_state +{ + CodeOutputInterface * code; + const char *inputString; //!< the code fragment as text + int inputPosition; //!< read offset during parsing + int inputLines; //!< number of line in the code fragment + int yyLineNr; //!< current line number + bool needsTermination; + const Definition *searchCtx; + + bool exampleBlock; + QCString exampleName; + QCString classScope; + + FileDef *sourceFileDef; + Definition *currentDefinition; + MemberDef *currentMemberDef; + bool includeCodeFragment; + const char *currentFontClass; +}; + +static void codify(const char* text); +static void setCurrentDoc(const QCString &anchor,yyscan_t yyscanner); +static void startCodeLine(yyscan_t yyscanner); +static void endFontClass(yyscan_t yyscanner); +static void endCodeLine(yyscan_t yyscanner); +static void nextCodeLine(yyscan_t yyscanner); +static void codifyLines(char *text,yyscan_t yyscanner); +static void startFontClass(const char *s,yyscan_t yyscanner); +static int countLines(yyscan_t yyscanner); +static int yyread(char *buf,int max_size,yyscan_t yyscanner); + +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size,yyscanner); + +%} + +nl (\r\n|\r|\n) +ws [ \t]+ +idchar [A-Za-z0-9\-_]+ +keywords1 ("ADD"|"ALL"|"ALLOCATE"|"ALTER"|"AND"|"ANY"|"ARE"|"AS"|"ASENSITIVE"|"ASYMMETRIC"|"AT"|"ATOMIC"|"AUTHORIZATION"|"BETWEEN"|"BOTH"|"BY"|"CALL"|"CALLED"|"CASCADED"|"CAST") +keywords2 ("CHECK"|"CLOSE"|"COLLATE"|"COLUMN"|"COMMIT"|"CONNECT"|"CONSTRAINT"|"CONTINUE"|"CORRESPONDING"|"CREATE"|"CROSS"|"CUBE"|"CURRENT"|"CURRENT_DATE"|"CURRENT_DEFAULT_TRANSFORM_GROUP") +keywords3 ("CURRENT_PATH"|"CURRENT_ROLE"|"CURRENT_TIME"|"CURRENT_TIMESTAMP"|"CURRENT_TRANSFORM_GROUP_FOR_TYPE"|"CURRENT_USER") +keywords4 ("CURSOR"|"CYCLE"|"DAY"|"DEALLOCATE"|"DECLARE"|"DEFAULT"|"DELETE"|"DEREF"|"DESCRIBE"|"DETERMINISTIC"|"DISCONNECT"|"DISTINCT"|"DROP"|"DYNAMIC") +keywords5 ("EACH"|"ELEMENT"|"END-EXEC"|"ESCAPE"|"EXCEPT"|"EXEC"|"EXECUTE"|"EXISTS"|"EXTERNAL"|"FETCH"|"FILTER"|"FOR"|"FOREIGN"|"FREE"|"FROM"|"FULL"|"FUNCTION") +keywords6 ("GET"|"GLOBAL"|"GRANT"|"GROUP"|"GROUPING"|"HAVING"|"HOLD"|"HOUR"|"IDENTITY"|"IMMEDIATE"|"IN"|"INDICATOR"|"INNER"|"INOUT"|"INPUT"|"INSENSITIVE"|"INSERT"|"INTERSECT") +keywords7 ("INTERVAL"|"INTO"|"IS"|"ISOLATION"|"JOIN"|"LANGUAGE"|"LARGE"|"LATERAL"|"LEADING"|"LEFT"|"LIKE"|"LOCAL"|"LOCALTIME"|"LOCALTIMESTAMP"|"MATCH"|"MEMBER"|"MERGE"|"METHOD"|"MINUTE") +keywords8 ("MODIFIES"|"MODULE"|"MONTH"|"MULTISET"|"NATIONAL"|"NATURAL"|"NEW"|"NO"|"NONE"|"NOT"|"OF"|"OLD"|"ON"|"ONLY"|"OPEN"|"OR"|"ORDER"|"OUT"|"OUTER"|"OUTPUT") +keywords9 ("OVER"|"OVERLAPS"|"PARAMETER"|"PARTITION"|"PRECISION"|"PREPARE"|"PRIMARY"|"PROCEDURE"|"RANGE"|"READS"|"RECURSIVE"|"REF"|"REFERENCES"|"REFERENCING"|"REGR_AVGX"|"REGR_AVGY") +keywords10 ("REGR_COUNT"|"REGR_INTERCEPT"|"REGR_R2"|"REGR_SLOPE"|"REGR_SXX"|"REGR_SXY"|"REGR_SYY"|"RELEASE"|"RESULT"|"RETURN"|"RETURNS"|"REVOKE"|"RIGHT"|"ROLLBACK"|"ROLLUP"|"ROW"|"ROWS"|"SAVEPOINT") +keywords11 ("SCROLL"|"SEARCH"|"SECOND"|"SELECT"|"SENSITIVE"|"SESSION_USER"|"SET"|"SIMILAR"|"SOME"|"SPECIFIC"|"SPECIFICTYPE"|"SQL"|"SQLEXCEPTION"|"SQLSTATE"|"SQLWARNING"|"START"|"STATIC") +keywords12 ("SUBMULTISET"|"SYMMETRIC"|"SYSTEM"|"SYSTEM_USER"|"TABLE"|"THEN"|"TIMEZONE_HOUR"|"TIMEZONE_MINUTE"|"TO"|"TRAILING"|"TRANSLATION"|"TREAT"|"TRIGGER"|"UESCAPE"|"UNION") +keywords13 ("UNIQUE"|"UNNEST"|"UPDATE"|"UPPER"|"USER"|"USING"|"VALUE"|"VALUES"|"VAR_POP"|"VAR_SAMP"|"VARYING"|"WHEN"|"WHENEVER"|"WHERE"|"WIDTH_BUCKET"|"WINDOW"|"WITH"|"WITHIN"|"WITHOUT"|"YEAR") + +/* Need multiple keyword definitions due to max length */ +keyword (?i:{keywords1}|{keywords2}|{keywords3}|{keywords4}|{keywords5}|{keywords6}|{keywords7}|{keywords8}|{keywords9}|{keywords10}|{keywords11}|{keywords12}|{keywords13}) + +typekeyword (?i:"ARRAY"|"BIGINT"|"BINARY"|"BLOB"|"BOOLEAN"|"CHAR"|"CHARACTER"|"CLOB"|"DATE"|"DEC"|"DECIMAL"|"DOUBLE"|"FLOAT"|"INT"|"INTEGER"|"NCHAR"|"NCLOB"|"NUMERIC"|"NVARCHAR"|"REAL"|"SMALLINT"|"TIME"|"TIMESTAMP"|"VARCHAR") + +flowkeyword (?i:"CASE"|"IF"|"ELSE"|"BEGIN"|"END"|"WHILE") + +literalkeyword (?i:"FALSE"|"TRUE"|"NULL"|"UNKNOWN") +stringliteral (\"[^"]*\")|('[^']*') +number [0-9]+ +literals ({literalkeyword}|{stringliteral}|{number}) + +variable @{idchar}+ + +simplecomment --.* +commentopen "/\*" +commentclose "\*/" + +%x COMMENT + +%% + +{literals} { + startFontClass("stringliteral",yyscanner); + codifyLines(yytext,yyscanner); + endFontClass(yyscanner); + } + + +{keyword} { + startFontClass("keyword",yyscanner); + codifyLines(yytext,yyscanner); + endFontClass(yyscanner); + } + +{flowkeyword} { + startFontClass("keywordflow",yyscanner); + codifyLines(yytext,yyscanner); + endFontClass(yyscanner); + } + +{typekeyword} { + startFontClass("keywordtype",yyscanner); + codifyLines(yytext,yyscanner); + endFontClass(yyscanner); + } + +{variable} { + startFontClass("preprocessor",yyscanner); + codifyLines(yytext,yyscanner); + endFontClass(yyscanner); + } + +{simplecomment} { + startFontClass("comment",yyscanner); + codifyLines(yytext,yyscanner); + endFontClass(yyscanner); + } + +{commentopen} { + startFontClass("comment",yyscanner); + codifyLines(yytext,yyscanner); + BEGIN(COMMENT); + } + +<COMMENT>. { + codifyLines(yytext,yyscanner); + + } +<COMMENT>{nl} { + codifyLines(yytext,yyscanner); + } + +<COMMENT>{commentclose} { + codifyLines(yytext,yyscanner); + endFontClass(yyscanner); + BEGIN(INITIAL); + } + +{idchar} { + codifyLines(yytext,yyscanner); + } + +{nl} { + codifyLines(yytext,yyscanner); + } + +. { + codifyLines(yytext,yyscanner); + } + +%% + + +static void codify(const char* text, yyscan_t yyscanner) { - g_code->codify(text); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->code->codify(text); } -static void setCurrentDoc(const QCString &anchor) +static void setCurrentDoc(const QCString &anchor, yyscan_t yyscanner) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (Doxygen::searchIndex) { - if (g_searchCtx) + if (yyextra->searchCtx) { - Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE); + Doxygen::searchIndex->setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),FALSE); } else { - Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE); + Doxygen::searchIndex->setCurrentDoc(yyextra->sourceFileDef,anchor,TRUE); } } } -/*! start a new line of code, inserting a line number if g_sourceFileDef +/*! start a new line of code, inserting a line number if yyextra->sourceFileDef * is TRUE. If a definition starts at the current line, then the line * number is linked to the documentation of that definition. */ -static void startCodeLine() +static void startCodeLine(yyscan_t yyscanner) { - if (g_sourceFileDef) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->sourceFileDef) { - Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr); + Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr); - if (!g_includeCodeFragment && d && d->isLinkableInProject()) + if (!yyextra->includeCodeFragment && d && d->isLinkableInProject()) { - g_currentDefinition = d; - g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr); - g_classScope = d->name().copy(); + yyextra->currentDefinition = d; + yyextra->currentMemberDef = yyextra->sourceFileDef->getSourceMember(yyextra->yyLineNr); + yyextra->classScope = d->name().copy(); QCString lineAnchor; - lineAnchor.sprintf("l%05d",g_yyLineNr); - if (g_currentMemberDef) + lineAnchor.sprintf("l%05d",yyextra->yyLineNr); + if (yyextra->currentMemberDef) { - g_code->writeLineNumber(g_currentMemberDef->getReference(), - g_currentMemberDef->getOutputFileBase(), - g_currentMemberDef->anchor(),g_yyLineNr); - setCurrentDoc(lineAnchor); + yyextra->code->writeLineNumber(yyextra->currentMemberDef->getReference(), + yyextra->currentMemberDef->getOutputFileBase(), + yyextra->currentMemberDef->anchor(),yyextra->yyLineNr); + setCurrentDoc(lineAnchor,yyscanner); } else { - g_code->writeLineNumber(d->getReference(), + yyextra->code->writeLineNumber(d->getReference(), d->getOutputFileBase(), - 0,g_yyLineNr); - setCurrentDoc(lineAnchor); + 0,yyextra->yyLineNr); + setCurrentDoc(lineAnchor,yyscanner); } } else { - g_code->writeLineNumber(0,0,0,g_yyLineNr); + yyextra->code->writeLineNumber(0,0,0,yyextra->yyLineNr); } } - g_code->startCodeLine(g_sourceFileDef); + yyextra->code->startCodeLine(yyextra->sourceFileDef); - if (g_currentFontClass) + if (yyextra->currentFontClass) { - g_code->startFontClass(g_currentFontClass); + yyextra->code->startFontClass(yyextra->currentFontClass); } } -static void endFontClass() +static void endFontClass(yyscan_t yyscanner) { - if (g_currentFontClass) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->currentFontClass) { - g_code->endFontClass(); - g_currentFontClass=0; + yyextra->code->endFontClass(); + yyextra->currentFontClass=0; } } -static void endCodeLine() +static void endCodeLine(yyscan_t yyscanner) { - endFontClass(); - g_code->endCodeLine(); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + endFontClass(yyscanner); + yyextra->code->endCodeLine(); } -static void nextCodeLine() +static void nextCodeLine(yyscan_t yyscanner) { - const char *fc = g_currentFontClass; - endCodeLine(); - if (g_yyLineNr<g_inputLines) + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + const char *fc = yyextra->currentFontClass; + endCodeLine(yyscanner); + if (yyextra->yyLineNr<yyextra->inputLines) { - g_currentFontClass = fc; - startCodeLine(); + yyextra->currentFontClass = fc; + startCodeLine(yyscanner); } } -static void codifyLines(char *text) +static void codifyLines(char *text,yyscan_t yyscanner) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; char *p=text,*sp=p; char c; bool done=FALSE; @@ -170,30 +302,32 @@ static void codifyLines(char *text) if (c=='\n') { - g_yyLineNr++; + yyextra->yyLineNr++; *(p-1)='\0'; - g_code->codify(sp); - nextCodeLine(); + yyextra->code->codify(sp); + nextCodeLine(yyscanner); } else { - g_code->codify(sp); + yyextra->code->codify(sp); done=TRUE; } } } -static void startFontClass(const char *s) +static void startFontClass(const char *s,yyscan_t yyscanner) { - endFontClass(); - g_code->startFontClass(s); - g_currentFontClass=s; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + endFontClass(yyscanner); + yyextra->code->startFontClass(s); + yyextra->currentFontClass=s; } /*! counts the number of lines in the input */ -static int countLines() +static int countLines(yyscan_t yyscanner) { - const char *p=g_inputString; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + const char *p=yyextra->inputString; char c; int count=1; while ((c=*p)) @@ -201,142 +335,31 @@ static int countLines() p++ ; if (c=='\n') count++; } - if (p>g_inputString && *(p-1)!='\n') + if (p>yyextra->inputString && *(p-1)!='\n') { // last line does not end with a \n, so we add an extra // line and explicitly terminate the line after parsing. count++, - g_needsTermination=TRUE; + yyextra->needsTermination=TRUE; } return count; } -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); - -static int yyread(char *buf,int max_size) +static int yyread(char *buf,int max_size,yyscan_t yyscanner) { + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; int c=0; - while( c < max_size && g_inputString[g_inputPosition] ) + while( c < max_size && yyextra->inputString[yyextra->inputPosition] ) { - *buf = g_inputString[g_inputPosition++] ; + *buf = yyextra->inputString[yyextra->inputPosition++] ; c++; buf++; } return c; } -%} - -nl (\r\n|\r|\n) -ws [ \t]+ -idchar [A-Za-z0-9\-_]+ -keywords1 ("ADD"|"ALL"|"ALLOCATE"|"ALTER"|"AND"|"ANY"|"ARE"|"AS"|"ASENSITIVE"|"ASYMMETRIC"|"AT"|"ATOMIC"|"AUTHORIZATION"|"BETWEEN"|"BOTH"|"BY"|"CALL"|"CALLED"|"CASCADED"|"CAST") -keywords2 ("CHECK"|"CLOSE"|"COLLATE"|"COLUMN"|"COMMIT"|"CONNECT"|"CONSTRAINT"|"CONTINUE"|"CORRESPONDING"|"CREATE"|"CROSS"|"CUBE"|"CURRENT"|"CURRENT_DATE"|"CURRENT_DEFAULT_TRANSFORM_GROUP") -keywords3 ("CURRENT_PATH"|"CURRENT_ROLE"|"CURRENT_TIME"|"CURRENT_TIMESTAMP"|"CURRENT_TRANSFORM_GROUP_FOR_TYPE"|"CURRENT_USER") -keywords4 ("CURSOR"|"CYCLE"|"DAY"|"DEALLOCATE"|"DECLARE"|"DEFAULT"|"DELETE"|"DEREF"|"DESCRIBE"|"DETERMINISTIC"|"DISCONNECT"|"DISTINCT"|"DROP"|"DYNAMIC") -keywords5 ("EACH"|"ELEMENT"|"END-EXEC"|"ESCAPE"|"EXCEPT"|"EXEC"|"EXECUTE"|"EXISTS"|"EXTERNAL"|"FETCH"|"FILTER"|"FOR"|"FOREIGN"|"FREE"|"FROM"|"FULL"|"FUNCTION") -keywords6 ("GET"|"GLOBAL"|"GRANT"|"GROUP"|"GROUPING"|"HAVING"|"HOLD"|"HOUR"|"IDENTITY"|"IMMEDIATE"|"IN"|"INDICATOR"|"INNER"|"INOUT"|"INPUT"|"INSENSITIVE"|"INSERT"|"INTERSECT") -keywords7 ("INTERVAL"|"INTO"|"IS"|"ISOLATION"|"JOIN"|"LANGUAGE"|"LARGE"|"LATERAL"|"LEADING"|"LEFT"|"LIKE"|"LOCAL"|"LOCALTIME"|"LOCALTIMESTAMP"|"MATCH"|"MEMBER"|"MERGE"|"METHOD"|"MINUTE") -keywords8 ("MODIFIES"|"MODULE"|"MONTH"|"MULTISET"|"NATIONAL"|"NATURAL"|"NEW"|"NO"|"NONE"|"NOT"|"OF"|"OLD"|"ON"|"ONLY"|"OPEN"|"OR"|"ORDER"|"OUT"|"OUTER"|"OUTPUT") -keywords9 ("OVER"|"OVERLAPS"|"PARAMETER"|"PARTITION"|"PRECISION"|"PREPARE"|"PRIMARY"|"PROCEDURE"|"RANGE"|"READS"|"RECURSIVE"|"REF"|"REFERENCES"|"REFERENCING"|"REGR_AVGX"|"REGR_AVGY") -keywords10 ("REGR_COUNT"|"REGR_INTERCEPT"|"REGR_R2"|"REGR_SLOPE"|"REGR_SXX"|"REGR_SXY"|"REGR_SYY"|"RELEASE"|"RESULT"|"RETURN"|"RETURNS"|"REVOKE"|"RIGHT"|"ROLLBACK"|"ROLLUP"|"ROW"|"ROWS"|"SAVEPOINT") -keywords11 ("SCROLL"|"SEARCH"|"SECOND"|"SELECT"|"SENSITIVE"|"SESSION_USER"|"SET"|"SIMILAR"|"SOME"|"SPECIFIC"|"SPECIFICTYPE"|"SQL"|"SQLEXCEPTION"|"SQLSTATE"|"SQLWARNING"|"START"|"STATIC") -keywords12 ("SUBMULTISET"|"SYMMETRIC"|"SYSTEM"|"SYSTEM_USER"|"TABLE"|"THEN"|"TIMEZONE_HOUR"|"TIMEZONE_MINUTE"|"TO"|"TRAILING"|"TRANSLATION"|"TREAT"|"TRIGGER"|"UESCAPE"|"UNION") -keywords13 ("UNIQUE"|"UNNEST"|"UPDATE"|"UPPER"|"USER"|"USING"|"VALUE"|"VALUES"|"VAR_POP"|"VAR_SAMP"|"VARYING"|"WHEN"|"WHENEVER"|"WHERE"|"WIDTH_BUCKET"|"WINDOW"|"WITH"|"WITHIN"|"WITHOUT"|"YEAR") - -/* Need multiple keyword definitions due to max length */ -keyword (?i:{keywords1}|{keywords2}|{keywords3}|{keywords4}|{keywords5}|{keywords6}|{keywords7}|{keywords8}|{keywords9}|{keywords10}|{keywords11}|{keywords12}|{keywords13}) - -typekeyword (?i:"ARRAY"|"BIGINT"|"BINARY"|"BLOB"|"BOOLEAN"|"CHAR"|"CHARACTER"|"CLOB"|"DATE"|"DEC"|"DECIMAL"|"DOUBLE"|"FLOAT"|"INT"|"INTEGER"|"NCHAR"|"NCLOB"|"NUMERIC"|"NVARCHAR"|"REAL"|"SMALLINT"|"TIME"|"TIMESTAMP"|"VARCHAR") -flowkeyword (?i:"CASE"|"IF"|"ELSE"|"BEGIN"|"END"|"WHILE") - -literalkeyword (?i:"FALSE"|"TRUE"|"NULL"|"UNKNOWN") -stringliteral (\"[^"]*\")|('[^']*') -number [0-9]+ -literals ({literalkeyword}|{stringliteral}|{number}) - -variable @{idchar}+ - -simplecomment --.* -commentopen "/\*" -commentclose "\*/" - -%option noyywrap -%option nounput - -%x COMMENT - -%% - -{literals} { - startFontClass("stringliteral"); - codifyLines(yytext); - endFontClass(); - } - - -{keyword} { - startFontClass("keyword"); - codifyLines(yytext); - endFontClass(); - } - -{flowkeyword} { - startFontClass("keywordflow"); - codifyLines(yytext); - endFontClass(); - } - -{typekeyword} { - startFontClass("keywordtype"); - codifyLines(yytext); - endFontClass(); - } - -{variable} { - startFontClass("preprocessor"); - codifyLines(yytext); - endFontClass(); - } - -{simplecomment} { - startFontClass("comment"); - codifyLines(yytext); - endFontClass(); - } - -{commentopen} { - startFontClass("comment"); - codifyLines(yytext); - BEGIN(COMMENT); - } - -<COMMENT>. { - codifyLines(yytext); - } -<COMMENT>{nl} { - codifyLines(yytext); - } - -<COMMENT>{commentclose} { - codifyLines(yytext); - endFontClass(); - BEGIN(INITIAL); - } - -{idchar} { - codifyLines(yytext); - } - -{nl} { - codifyLines(yytext); - } - -. { - codifyLines(yytext); - } - -%% +// public interface ----------------------------------------------------------- +static yyscan_t yyscanner; +static struct sqlcodeYY_state sqlcode_extra; void parseSqlCode( CodeOutputInterface &od, @@ -348,80 +371,86 @@ void parseSqlCode( int startLine, int endLine, bool inlineFragment, - MemberDef *, - bool,Definition *searchCtx, + const MemberDef *, + bool,const Definition *searchCtx, bool /*collectXRefs*/ ) { if (s.isEmpty()) return; + + sqlcodeYYlex_init_extra(&sqlcode_extra, &yyscanner); + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + +#ifdef FLEX_DEBUG + yyset_debug(1,yyscanner); +#endif + + printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL); - TooltipManager::instance()->clearTooltips(); - - g_code = &od; - g_inputString = s; - g_inputPosition = 0; - g_currentFontClass = 0; - g_needsTermination = FALSE; - g_searchCtx=searchCtx; + yyextra->code = &od; + yyextra->inputString = s; + yyextra->inputPosition = 0; + yyextra->currentFontClass = 0; + yyextra->needsTermination = FALSE; + yyextra->searchCtx=searchCtx; if (startLine!=-1) - g_yyLineNr = startLine; + yyextra->yyLineNr = startLine; else - g_yyLineNr = 1; + yyextra->yyLineNr = 1; if (endLine!=-1) - g_inputLines = endLine+1; + yyextra->inputLines = endLine+1; else - g_inputLines = g_yyLineNr + countLines() - 1; + yyextra->inputLines = yyextra->yyLineNr + countLines(yyscanner) - 1; - g_exampleBlock = exBlock; - g_exampleName = exName; - g_sourceFileDef = fd; + yyextra->exampleBlock = exBlock; + yyextra->exampleName = exName; + yyextra->sourceFileDef = fd; bool cleanupSourceDef = FALSE; if (exBlock && fd==0) { // create a dummy filedef for the example - g_sourceFileDef = new FileDef("",(exName?exName:"generated")); + yyextra->sourceFileDef = createFileDef("",(exName?exName:"generated")); cleanupSourceDef = TRUE; } - if (g_sourceFileDef) + if (yyextra->sourceFileDef) { - setCurrentDoc("l00001"); + setCurrentDoc("l00001",yyscanner); } - g_includeCodeFragment = inlineFragment; + yyextra->includeCodeFragment = inlineFragment; // Starts line 1 on the output - startCodeLine(); + startCodeLine(yyscanner); - sqlcodeYYrestart( sqlcodeYYin ); + sqlcodeYYrestart( yyin,yyscanner ); - sqlcodeYYlex(); + sqlcodeYYlex(yyscanner); - if (g_needsTermination) - { - endCodeLine(); - } - if (fd) + if (yyextra->needsTermination) { - TooltipManager::instance()->writeTooltips(*g_code); + endCodeLine(yyscanner); } if (cleanupSourceDef) { // delete the temporary file definition used for this example - delete g_sourceFileDef; - g_sourceFileDef=0; + delete yyextra->sourceFileDef; + yyextra->sourceFileDef=0; } + printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL); + sqlcodeYYlex_destroy(yyscanner); return; } void resetSqlCodeParserState() { - g_currentDefinition = 0; - g_currentMemberDef = 0; + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + yyextra->currentDefinition = 0; + yyextra->currentMemberDef = 0; } #if !defined(YY_FLEX_SUBMINOR_VERSION) diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp index a7b8dbb..012a0c0 100644 --- a/src/sqlite3gen.cpp +++ b/src/sqlite3gen.cpp @@ -924,7 +924,7 @@ static int insertPath(QCString name, bool local=TRUE, bool found=TRUE, int type= static void recordMetadata() { - bindTextParameter(meta_insert,":doxygen_version",versionString); + bindTextParameter(meta_insert,":doxygen_version",getVersion()); bindTextParameter(meta_insert,":schema_version","0.2.0"); //TODO: this should be a constant somewhere; not sure where bindTextParameter(meta_insert,":generated_at",dateToString(TRUE), FALSE); bindTextParameter(meta_insert,":generated_on",dateToString(FALSE), FALSE); @@ -1015,16 +1015,16 @@ static void insertMemberReference(const MemberDef *src, const MemberDef *dst, co static void insertMemberFunctionParams(int memberdef_id, const MemberDef *md, const Definition *def) { - ArgumentList *declAl = md->declArgumentList(); - ArgumentList *defAl = md->argumentList(); + const ArgumentList *declAl = md->declArgumentList(); + const ArgumentList *defAl = md->argumentList(); if (declAl!=0 && defAl!=0 && declAl->count()>0) { ArgumentListIterator declAli(*declAl); ArgumentListIterator defAli(*defAl); - Argument *a; + const Argument *a; for (declAli.toFirst();(a=declAli.current());++declAli) { - Argument *defArg = defAli.current(); + const Argument *defArg = defAli.current(); if (!a->attrib.isEmpty()) { @@ -1410,7 +1410,7 @@ static void writeTemplateArgumentList(const ArgumentList * al, static void writeMemberTemplateLists(const MemberDef *md) { - ArgumentList *templMd = md->templateArguments(); + const ArgumentList *templMd = md->templateArguments(); if (templMd) // function template prefix { writeTemplateArgumentList(templMd,md->getClassDef(),md->getFileDef()); @@ -1434,7 +1434,7 @@ QCString getSQLDocBlock(const Definition *scope, fileName, lineNr, const_cast<Definition*>(scope), - const_cast<MemberDef*>(reinterpret_cast<const MemberDef*>(def)), + dynamic_cast<const MemberDef*>(def), doc, FALSE, FALSE @@ -1675,7 +1675,7 @@ static void generateSqlite3ForMember(const MemberDef *md, struct Refid scope_ref if (isFunc) { - ArgumentList *al = md->argumentList(); + const ArgumentList *al = md->argumentList(); if (al!=0) { bindIntParameter(memberdef_insert,":const",al->constSpecifier); @@ -2009,7 +2009,11 @@ static void generateSqlite3ForClass(const ClassDef *cd) if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName(); if (!nm.isEmpty()) { - int header_id=insertPath(ii->fileDef->absFilePath(),!ii->fileDef->isReference()); + int header_id=-1; + if (ii->fileDef) + { + insertPath(ii->fileDef->absFilePath(),!ii->fileDef->isReference()); + } DBG_CTX(("-----> ClassDef includeInfo for %s\n", nm.data())); DBG_CTX((" local : %d\n", ii->local)); DBG_CTX((" imported : %d\n", ii->imported)); @@ -2478,7 +2482,7 @@ static void generateSqlite3ForPage(const PageDef *pd,bool isExample) QCString title; if (pd==Doxygen::mainPage) // main page is special { - if (!pd->title().isEmpty() && pd->title().lower()!="notitle") + if (mainPageHasTitle()) { title = filterTitle(convertCharEntitiesToUTF8(Doxygen::mainPage->title())); } diff --git a/src/sqlscanner.h b/src/sqlscanner.h index 7afa869..3ca6fe3 100644 --- a/src/sqlscanner.h +++ b/src/sqlscanner.h @@ -41,9 +41,9 @@ public: int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, - MemberDef *memberDef=0, + const MemberDef *memberDef=0, bool showLineNumbers=TRUE, - Definition *searchCtx=0, + const Definition *searchCtx=0, bool collectXRefs=TRUE ) { diff --git a/src/store.cpp b/src/store.cpp deleted file mode 100644 index c09dcfb..0000000 --- a/src/store.cpp +++ /dev/null @@ -1,484 +0,0 @@ -/****************************************************************************** - * - * - * - * - * 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 - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ - -#include "store.h" -#include "portable.h" - - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <assert.h> -#include <ctype.h> - -#define BLOCK_SIZE 512 // should be >8 and a power of 2 -#define BLOCK_POINTER_SIZE sizeof(portable_off_t) - - -#define ASSERTS_ENABLED - -#ifdef ASSERTS_ENABLED -#define STORE_ASSERT(x) assert(x) -#else -#define STORE_ASSERT(x) -#endif - -// Decide to use ftell or keep track of the current file pointer ourselves. -// Since valgrind shows that calling ftell has the unwanted side-effect of -// writing some uninitialized bytes (!) it might be better (and faster) to keep track -// of the current pointer ourselves. -#define USE_FTELL 0 - -//------------------------------------------------------------------------------------ - -Store::Store() -{ - m_file = 0; - m_front = 0; - m_cur = 0; - m_head = 0; - m_state = Init; - m_reads = 0; - m_writes = 0; -} - -Store::~Store() -{ - if (m_file) fclose(m_file); - - // clean up free list - while (m_head) - { - Node *node = m_head; - m_head = node->next; - delete node; - } -} - -int Store::open(const char *name) -{ - int i; - STORE_ASSERT(m_state==Init); - if (m_file) return 0; // already open - m_file = portable_fopen(name,"w+b"); - if (m_file==0) return -1; - - // first block serves as header, so offset=0 can be used as the end of the list. - for (i=0;i<BLOCK_SIZE/8;i++) - { - fputc('D',m_file); - fputc('O',m_file); - fputc('X',m_file); - fputc('Y',m_file); - fputc('G',m_file); - fputc('E',m_file); - fputc('N',m_file); - fputc(0,m_file); - } - m_front = BLOCK_SIZE; - m_cur = BLOCK_SIZE; - m_head = 0; - m_state = Reading; - return 0; -} - -void Store::close() -{ - if (m_file) fclose(m_file); - m_file=0; - m_state = Init; -} - -portable_off_t Store::alloc() -{ - STORE_ASSERT(m_state==Reading); - m_state=Writing; - portable_off_t pos; - if (m_head==0) // allocate new block - { - //printf("alloc: new block, pos=%lld\n",(long long)m_front); - if (portable_fseek(m_file,0,SEEK_END)==-1) // go to end of the file - { - fprintf(stderr,"Store::alloc: Error seeking to end of file: %s\n",strerror(errno)); - exit(1); - } -#if USE_FTELL - pos = portable_ftell(m_file); - STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 ); - m_front = pos + BLOCK_SIZE; // move front to end of this block -#else - m_cur = m_front; - pos = m_cur; - STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 ); - m_front = pos + BLOCK_SIZE; -#endif - } - else // reuse freed block - { - //printf("alloc: reuse block: pos=%lld\n",(long long)m_head->pos); - Node *node = m_head; - pos = node->pos; - // point head to next free item - m_head = node->next; - delete node; - // move to start of the block - if (portable_fseek(m_file,pos,SEEK_SET)==-1) - { - fprintf(stderr,"Store::alloc: Error seeking to position %d: %s\n", - (int)pos,strerror(errno)); - exit(1); - } - m_cur = pos; - STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 ); - } - //printf("%x: Store::alloc\n",(int)pos); - return pos; -} - -int Store::write(const char *buf,uint size) -{ - STORE_ASSERT(m_state==Writing); - //printf("%x: Store::write\n",(int)portable_ftell(m_file)); - do - { -#if USE_FTELL - portable_off_t curPos = portable_ftell(m_file); -#else - portable_off_t curPos = m_cur; -#endif - int bytesInBlock = (int)(BLOCK_SIZE - BLOCK_POINTER_SIZE - (curPos & (BLOCK_SIZE-1))); - int bytesLeft = bytesInBlock<(int)size ? (int)size-bytesInBlock : 0; - int numBytes = size - bytesLeft; - STORE_ASSERT(bytesInBlock>=0); - STORE_ASSERT(numBytes<=(int)(BLOCK_SIZE-BLOCK_POINTER_SIZE)); - if (numBytes>0) - { - if ((int)fwrite(buf,1,numBytes,m_file)!=numBytes) - { - fprintf(stderr,"Error writing: %s\n",strerror(errno)); - exit(1); - } - m_cur+=numBytes; - m_writes++; - } - if (bytesLeft>0) // still more bytes to write - { -#if USE_FTELL - STORE_ASSERT(((portable_ftell(m_file)+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0); -#else - STORE_ASSERT(((m_cur+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0); -#endif - // allocate new block - if (m_head==0) // no free blocks to reuse - { - //printf("%x: Store::write: new: pos=%x\n",(int)m_front,(int)portable_ftell(m_file)); - // write pointer to next block - if (fwrite(&m_front,BLOCK_POINTER_SIZE,1,m_file)!=1) - { - fprintf(stderr,"Error writing to store: %s\n",strerror(errno)); - exit(1); - } - m_cur+=BLOCK_POINTER_SIZE; -#if USE_FTELL - STORE_ASSERT(portable_ftell(m_file)==(curPos&~(BLOCK_SIZE-1))+BLOCK_SIZE); -#else - STORE_ASSERT(m_cur==(curPos&~(BLOCK_SIZE-1))+BLOCK_SIZE); -#endif - // move to next block - if (portable_fseek(m_file,0,SEEK_END)==-1) // go to end of the file - { - fprintf(stderr,"Store::alloc: Error seeking to end of file: %s\n",strerror(errno)); - exit(1); - } - m_cur=m_front; -#if USE_FTELL - STORE_ASSERT(portable_ftell(m_file)==m_front); -#else - STORE_ASSERT(m_cur==m_front); -#endif - // move front to the next of the block - m_front+=BLOCK_SIZE; - } - else // reuse block from the free list - { - // write pointer to next block - if (fwrite(&m_head->pos,BLOCK_POINTER_SIZE,1,m_file)!=1) - { - fprintf(stderr,"Error writing to store: %s\n",strerror(errno)); - exit(1); - } - Node *node = m_head; - portable_off_t pos = node->pos; - // point head to next free item - m_head = node->next; - delete node; - // move to start of the block - if (portable_fseek(m_file,pos,SEEK_SET)==-1) - { - fprintf(stderr,"Store::write: Error seeking to position %d: %s\n", - (int)pos,strerror(errno)); - exit(1); - } - m_cur = pos; - //printf("%x: Store::write: reuse\n",(int)pos); - } - } - size-=numBytes; - buf+=numBytes; - } - while (size>0); - return size; -} - -void Store::end() -{ - STORE_ASSERT(m_state==Writing); -#if USE_FTELL - portable_off_t curPos = portable_ftell(m_file); -#else - portable_off_t curPos = m_cur; -#endif - int bytesInBlock = (int)(BLOCK_SIZE - (curPos & (BLOCK_SIZE-1))); - //printf("%x: Store::end erasing %x bytes\n",(int)curPos&~(BLOCK_SIZE-1),bytesInBlock); - //printf("end: bytesInBlock=%x\n",bytesInBlock); - // zero out rest of the block - int i; - for (i=0;i<bytesInBlock;i++) - { - fputc(0,m_file); - } - m_state=Reading; -} - -void Store::release(portable_off_t pos) -{ - STORE_ASSERT(m_state==Reading); - //printf("release: block pos=%lld\n",(long long)pos); - STORE_ASSERT(pos>0 && (pos & (BLOCK_SIZE-1))==0); - // goto end of the block - portable_off_t cur = pos, next; - while (1) - { - // add new node to the free list - Node *node = new Node; - node->next = m_head; - node->pos = cur; - - m_head = node; - // goto the end of cur block - if (portable_fseek(m_file,cur+BLOCK_SIZE-BLOCK_POINTER_SIZE,SEEK_SET)==-1) - { - fprintf(stderr,"Store::release: Error seeking to position %d: %s\n", - (int)(cur+BLOCK_SIZE-BLOCK_POINTER_SIZE),strerror(errno)); - exit(1); - } - // read pointer to next block - if (fread(&next,BLOCK_POINTER_SIZE,1,m_file)!=1) - { - fprintf(stderr,"Store::release: Error reading from store: %s\n",strerror(errno)); - exit(1); - } - m_cur = cur+BLOCK_SIZE; - if (next==0) break; // found end of list -> cur is last element - STORE_ASSERT((next & (BLOCK_SIZE-1))==0); - cur = next; - //printf("%x: Store::release\n",(int)cur); - } -} - -void Store::seek(portable_off_t pos) -{ - STORE_ASSERT(m_state==Reading); - //printf("%x: Store::seek\n",(int)pos); - if (portable_fseek(m_file,pos,SEEK_SET)==-1) - { - fprintf(stderr,"Store::seek: Error seeking to position %d: %s\n", - (int)pos,strerror(errno)); - exit(1); - } - m_cur = pos; - STORE_ASSERT((pos&(BLOCK_SIZE-1))==0); -} - -int Store::read(char *buf,uint size) -{ - STORE_ASSERT(m_state==Reading); - //printf("%x: Store::read total=%d\n",(int)portable_ftell(m_file),size); - do - { -#if USE_FTELL - portable_off_t curPos = portable_ftell(m_file); -#else - portable_off_t curPos = m_cur; -#endif - int bytesInBlock = (int)(BLOCK_SIZE - BLOCK_POINTER_SIZE - (curPos & (BLOCK_SIZE-1))); - int bytesLeft = bytesInBlock<(int)size ? (int)size-bytesInBlock : 0; - int numBytes = size - bytesLeft; - //printf(" Store::read: pos=%x num=%d left=%d\n",(int)curPos,numBytes,bytesLeft); - - if (numBytes>0) - { - //printf("%x: Store::read: %d out of %d bytes\n",(int)portable_ftell(m_file),numBytes,size); - if ((int)fread(buf,1,numBytes,m_file)!=numBytes) - { - fprintf(stderr,"Error reading from store: %s\n",strerror(errno)); - exit(1); - } - m_cur+=numBytes; - m_reads++; - } - if (bytesLeft>0) - { - portable_off_t newPos; - // read offset of the next block -#if USE_FTELL - STORE_ASSERT(((portable_ftell(m_file)+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0); -#else - STORE_ASSERT(((m_cur+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0); -#endif - if (fread((char *)&newPos,BLOCK_POINTER_SIZE,1,m_file)!=1) - { - fprintf(stderr,"Error reading from store: %s\n",strerror(errno)); - exit(1); - } - //printf("%x: Store::read: continue in next block, %d bytes to go\n",(int)newPos,bytesLeft); - //printf(" Store::read: next block=%x\n",(int)newPos); - STORE_ASSERT(newPos!=0); - STORE_ASSERT((newPos&(BLOCK_SIZE-1))==0); - curPos = newPos; - // move to next block - if (portable_fseek(m_file,curPos,SEEK_SET)==-1) - { - fprintf(stderr,"Store::read: Error seeking to position %d: %s\n", - (int)curPos,strerror(errno)); - exit(1); - } - m_cur = curPos; - } - - size-=numBytes; - buf+=numBytes; - } - while (size>0); - return size; -} - -void Store::printFreeList() -{ - printf("FreeList: "); - while (m_head) - { - portable_off_t pos = m_head->pos; - printf("%x ",(int)pos); - m_head = m_head->next; - } - printf("\n"); -} - -void Store::printStats() -{ - printf("ObjStore: block size %d bytes, total size %ld blocks, wrote %d blocks, read %d blocks\n", - BLOCK_SIZE,(long)(m_front/BLOCK_SIZE),m_reads,m_writes); -} - -void Store::dumpBlock(portable_off_t s,portable_off_t e) -{ - portable_fseek(m_file,s,SEEK_SET); - int size = (int)(e-s); - uchar *buf = new uchar[size]; - if (fread(buf,size,1,m_file)==(size_t)size) - { - int i,j; - for (i=0;i<size;i+=16) - { - printf("%08x: ",(int)s+i); - for (j=i;j<QMIN(size,i+16);j++) - { - printf("%02x ",buf[i+j]); - } - printf(" "); - for (j=i;j<QMIN(size,i+16);j++) - { - printf("%c",(buf[i+j]>=32 && buf[i+j]<128)?buf[i+j]:'.'); - } - printf("\n"); - } - } - delete[] buf; - portable_fseek(m_file,m_cur,SEEK_SET); -} - -#ifdef STORE_TEST - -int main() -{ - printf("sizeof(portable_off_t)=%d\n",(int)sizeof(portable_off_t)); - Store s; - if (s.open("test.db")==0) - { - const char *str1 = "This is a test message... "; - const char *str2 = "Another message. "; - - int i,j; - for (j=0;j<5;j++) - { - char buf[100]; - - portable_off_t handle = s.alloc(); - for (i=0;i<1000000000;i++) - { - s.write(str1,strlen(str1)+1); - } - s.end(); - portable_off_t handle2 = s.alloc(); - for (i=0;i<10;i++) - { - s.write(str2,strlen(str2)+1); - } - s.end(); - - s.seek(handle); - for (i=0;i<3;i++) - { - s.read(buf,strlen(str1)+1); - printf("i=%d Read: %s\n",i,buf); - } - - s.release(handle); - - s.seek(handle2); - for (i=0;i<3;i++) - { - s.read(buf,strlen(str2)+1); - printf("i=%d Read: %s\n",i,buf); - } - - s.release(handle2); - } - - s.close(); - } - else - { - printf("Open failed! %s\n",strerror(errno)); - } -} - -#endif - diff --git a/src/store.h b/src/store.h deleted file mode 100644 index 39917df..0000000 --- a/src/store.h +++ /dev/null @@ -1,123 +0,0 @@ -/****************************************************************************** - * - * - * - * 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 - * 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 STORE_H -#define STORE_H - -#include <qglobal.h> -#include <stdio.h> - -#include "portable.h" - -/*! @brief Abstract interface for file based memory storage operations */ -class StorageIntf -{ - public: - /*! Required by gcc */ - virtual ~StorageIntf() {} - /*! Read \a size bytes from the store into \a buf. */ - virtual int read(char *buf,uint size) = 0; - /*! Write \a size bytes from \a buf into the store. */ - virtual int write(const char *buf,uint size) = 0; -}; - -/*! @brief The Store is a file based memory manager. - * - * You can open the store using open(). Then obtain a handle via alloc() - * followed by a sequence of write() commands to store information, - * and finalize it using end(). - * - * Later on you locate the information - * with seek() using the handle obtained with alloc(), and then use a - * sequence of read() calls to read the information back. - * - * If no longer needed the storage space can be freed using release(). - * - * The store will dynamically grow the file on disk if needed. - */ -class Store : public StorageIntf -{ - public: - /*! Creates a store. */ - Store(); - - /*! Releases the store object. Will close the underlying file if opened. */ - ~Store(); - - /*! Opens the file underlying the store using \a name as the file name. - * Returns 0 upon success, or -1 otherwise. - */ - int open(const char *name); - - /*! Allocates a handle to write to and read from. */ - portable_off_t alloc(); - - /*! Writes \a size bytes in array \a buf to the store. - * First alloc() has to be called. - * \note The information can only be read after end() has been called. - */ - int write(const char *buf,uint size); - - /*! Ends the sequence of writes. - * \note After this call, first alloc() has to be called - * before new writes can be done. - */ - void end(); - - /*! Releases the memory corresponding to the handle returned with alloc() */ - void release(portable_off_t handle); - - /*! Closes the store */ - void close(); - - /*! Goes to the start of information corresponding to handle \a pos */ - void seek(portable_off_t handle); - - /*! Reads \a size bytes from the store into the array pointed to be \a buf. - * \note Before reading seek() has to be called to set the right start of the store. - */ - int read(char *buf,uint size); - - void printStats(); - - portable_off_t pos() const { return m_cur; } - - void dumpBlock(portable_off_t start,portable_off_t end); - - private: - enum State - { - Init, - Reading, - Writing - }; - struct Node - { - portable_off_t pos; - struct Node *next; - }; - void printFreeList(); - FILE *m_file; - portable_off_t m_front; - portable_off_t m_cur; - Node *m_head; - State m_state; - int m_reads; - int m_writes; -}; - -#endif diff --git a/src/tagreader.cpp b/src/tagreader.cpp index 45543de..56dbe7d 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -384,7 +384,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unknown compound attribute `%s' found!",kind.data()); + warn("Unknown compound attribute '%s' found!",kind.data()); m_state = Invalid; } if (isObjC=="yes" && m_curClass) @@ -412,7 +412,7 @@ class TagFileParser : public QXmlDefaultHandler case InPackage: m_tagFilePackages.append(m_curPackage); m_curPackage=0; break; default: - warn("tag `compound' was not expected!"); + warn("tag 'compound' was not expected!"); } } @@ -458,7 +458,7 @@ class TagFileParser : public QXmlDefaultHandler case InNamespace: m_curNamespace->members.append(m_curMember); break; case InGroup: m_curGroup->members.append(m_curMember); break; case InPackage: m_curPackage->members.append(m_curMember); break; - default: warn("Unexpected tag `member' found"); break; + default: warn("Unexpected tag 'member' found"); break; } } @@ -476,7 +476,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Found `enumvalue' tag outside of member tag"); + warn("Found 'enumvalue' tag outside of member tag"); } } @@ -504,7 +504,7 @@ class TagFileParser : public QXmlDefaultHandler case InMember: m_curMember->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break; case InPackage: m_curPackage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break; case InDir: m_curDir->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break; - default: warn("Unexpected tag `docanchor' found"); break; + default: warn("Unexpected tag 'docanchor' found"); break; } } @@ -517,7 +517,7 @@ class TagFileParser : public QXmlDefaultHandler case InNamespace: m_curNamespace->classList.append(m_curString); break; case InGroup: m_curGroup->classList.append(m_curString); break; case InPackage: m_curPackage->classList.append(m_curString); break; - default: warn("Unexpected tag `class' found"); break; + default: warn("Unexpected tag 'class' found"); break; } } @@ -528,7 +528,7 @@ class TagFileParser : public QXmlDefaultHandler case InNamespace: m_curNamespace->classList.append(m_curString); break; case InFile: m_curFile->namespaceList.append(m_curString); break; case InGroup: m_curGroup->namespaceList.append(m_curString); break; - default: warn("Unexpected tag `namespace' found"); break; + default: warn("Unexpected tag 'namespace' found"); break; } } @@ -538,7 +538,7 @@ class TagFileParser : public QXmlDefaultHandler { case InGroup: m_curGroup->fileList.append(m_curString); break; case InDir: m_curDir->fileList.append(m_curString); break; - default: warn("Unexpected tag `file' found"); break; + default: warn("Unexpected tag 'file' found"); break; } } @@ -547,7 +547,7 @@ class TagFileParser : public QXmlDefaultHandler switch(m_state) { case InGroup: m_curGroup->fileList.append(m_curString); break; - default: warn("Unexpected tag `page' found"); break; + default: warn("Unexpected tag 'page' found"); break; } } @@ -556,7 +556,7 @@ class TagFileParser : public QXmlDefaultHandler switch(m_state) { case InDir: m_curDir->subdirList.append(m_curString); break; - default: warn("Unexpected tag `dir' found"); break; + default: warn("Unexpected tag 'dir' found"); break; } } @@ -580,7 +580,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `type' found"); + warn("Unexpected tag 'type' found"); } } @@ -596,7 +596,7 @@ class TagFileParser : public QXmlDefaultHandler case InDir: m_curDir->name = m_curString; break; case InMember: m_curMember->name = m_curString; break; case InPackage: m_curPackage->name = m_curString; break; - default: warn("Unexpected tag `name' found"); break; + default: warn("Unexpected tag 'name' found"); break; } } @@ -630,7 +630,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `base' found"); + warn("Unexpected tag 'base' found"); } } @@ -642,7 +642,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `base' found"); + warn("Unexpected tag 'base' found"); } } @@ -659,7 +659,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `includes' found"); + warn("Unexpected tag 'includes' found"); } m_curString=""; } @@ -682,7 +682,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `templarg' found"); + warn("Unexpected tag 'templarg' found"); } } @@ -697,7 +697,7 @@ class TagFileParser : public QXmlDefaultHandler case InPage: m_curPage->filename = m_curString; break; case InPackage: m_curPackage->filename = m_curString; break; case InDir: m_curDir->filename = m_curString; break; - default: warn("Unexpected tag `filename' found"); break; + default: warn("Unexpected tag 'filename' found"); break; } } @@ -707,7 +707,7 @@ class TagFileParser : public QXmlDefaultHandler { case InFile: m_curFile->path = m_curString; break; case InDir: m_curDir->path = m_curString; break; - default: warn("Unexpected tag `path' found"); break; + default: warn("Unexpected tag 'path' found"); break; } } @@ -723,7 +723,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `anchor' found"); + warn("Unexpected tag 'anchor' found"); } } @@ -743,7 +743,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `clangid' found"); + warn("Unexpected tag 'clangid' found"); } } @@ -757,7 +757,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `anchorfile' found"); + warn("Unexpected tag 'anchorfile' found"); } } @@ -769,7 +769,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `arglist' found"); + warn("Unexpected tag 'arglist' found"); } } void endTitle() @@ -778,7 +778,7 @@ class TagFileParser : public QXmlDefaultHandler { case InGroup: m_curGroup->title = m_curString; break; case InPage: m_curPage->title = m_curString; break; - default: warn("Unexpected tag `title' found"); break; + default: warn("Unexpected tag 'title' found"); break; } } @@ -790,7 +790,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unexpected tag `subgroup' found"); + warn("Unexpected tag 'subgroup' found"); } } @@ -877,7 +877,7 @@ class TagFileParser : public QXmlDefaultHandler bool startElement( const QString&, const QString&, const QString&name, const QXmlAttributes& attrib ) { - //printf("startElement `%s'\n",name.data()); + //printf("startElement '%s'\n",name.data()); StartElementHandler *handler = m_startElementHandlers[name.utf8()]; if (handler) { @@ -885,14 +885,14 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unknown tag `%s' found!",name.data()); + warn("Unknown tag '%s' found!",name.data()); } return TRUE; } bool endElement( const QString&, const QString&, const QString& name ) { - //printf("endElement `%s'\n",name.data()); + //printf("endElement '%s'\n",name.data()); EndElementHandler *handler = m_endElementHandlers[name.utf8()]; if (handler) { @@ -900,7 +900,7 @@ class TagFileParser : public QXmlDefaultHandler } else { - warn("Unknown tag `%s' found!",name.data()); + warn("Unknown tag '%s' found!",name.data()); } return TRUE; } @@ -986,8 +986,8 @@ void TagFileParser::dump() TagClassInfo *cd; for (;(cd=lci.current());++lci) { - msg("class `%s'\n",cd->name.data()); - msg(" filename `%s'\n",cd->filename.data()); + msg("class '%s'\n",cd->name.data()); + msg(" filename '%s'\n",cd->filename.data()); if (cd->bases) { QListIterator<BaseInfo> bii(*cd->bases); @@ -1003,10 +1003,10 @@ void TagFileParser::dump() for (;(md=mci.current());++mci) { msg(" member:\n"); - msg(" kind: `%s'\n",md->kind.data()); - msg(" name: `%s'\n",md->name.data()); - msg(" anchor: `%s'\n",md->anchor.data()); - msg(" arglist: `%s'\n",md->arglist.data()); + msg(" kind: '%s'\n",md->kind.data()); + msg(" name: '%s'\n",md->name.data()); + msg(" anchor: '%s'\n",md->anchor.data()); + msg(" arglist: '%s'\n",md->arglist.data()); } } //============== NAMESPACES @@ -1014,8 +1014,8 @@ void TagFileParser::dump() TagNamespaceInfo *nd; for (;(nd=lni.current());++lni) { - msg("namespace `%s'\n",nd->name.data()); - msg(" filename `%s'\n",nd->filename.data()); + msg("namespace '%s'\n",nd->name.data()); + msg(" filename '%s'\n",nd->filename.data()); QCStringList::Iterator it; for ( it = nd->classList.begin(); it != nd->classList.end(); ++it ) @@ -1028,10 +1028,10 @@ void TagFileParser::dump() for (;(md=mci.current());++mci) { msg(" member:\n"); - msg(" kind: `%s'\n",md->kind.data()); - msg(" name: `%s'\n",md->name.data()); - msg(" anchor: `%s'\n",md->anchor.data()); - msg(" arglist: `%s'\n",md->arglist.data()); + msg(" kind: '%s'\n",md->kind.data()); + msg(" name: '%s'\n",md->name.data()); + msg(" anchor: '%s'\n",md->anchor.data()); + msg(" arglist: '%s'\n",md->arglist.data()); } } //============== FILES @@ -1039,8 +1039,8 @@ void TagFileParser::dump() TagFileInfo *fd; for (;(fd=lfi.current());++lfi) { - msg("file `%s'\n",fd->name.data()); - msg(" filename `%s'\n",fd->filename.data()); + msg("file '%s'\n",fd->name.data()); + msg(" filename '%s'\n",fd->filename.data()); QCStringList::Iterator it; for ( it = fd->namespaceList.begin(); it != fd->namespaceList.end(); ++it ) @@ -1058,10 +1058,10 @@ void TagFileParser::dump() for (;(md=mci.current());++mci) { msg(" member:\n"); - msg(" kind: `%s'\n",md->kind.data()); - msg(" name: `%s'\n",md->name.data()); - msg(" anchor: `%s'\n",md->anchor.data()); - msg(" arglist: `%s'\n",md->arglist.data()); + msg(" kind: '%s'\n",md->kind.data()); + msg(" name: '%s'\n",md->name.data()); + msg(" anchor: '%s'\n",md->anchor.data()); + msg(" arglist: '%s'\n",md->arglist.data()); } QListIterator<TagIncludeInfo> mii(fd->includes); @@ -1077,8 +1077,8 @@ void TagFileParser::dump() TagGroupInfo *gd; for (;(gd=lgi.current());++lgi) { - msg("group `%s'\n",gd->name.data()); - msg(" filename `%s'\n",gd->filename.data()); + msg("group '%s'\n",gd->name.data()); + msg(" filename '%s'\n",gd->filename.data()); QCStringList::Iterator it; for ( it = gd->namespaceList.begin(); it != gd->namespaceList.end(); ++it ) @@ -1111,10 +1111,10 @@ void TagFileParser::dump() for (;(md=mci.current());++mci) { msg(" member:\n"); - msg(" kind: `%s'\n",md->kind.data()); - msg(" name: `%s'\n",md->name.data()); - msg(" anchor: `%s'\n",md->anchor.data()); - msg(" arglist: `%s'\n",md->arglist.data()); + msg(" kind: '%s'\n",md->kind.data()); + msg(" name: '%s'\n",md->name.data()); + msg(" anchor: '%s'\n",md->anchor.data()); + msg(" arglist: '%s'\n",md->arglist.data()); } } //============== PAGES @@ -1122,17 +1122,17 @@ void TagFileParser::dump() TagPageInfo *pd; for (;(pd=lpi.current());++lpi) { - msg("page `%s'\n",pd->name.data()); - msg(" title `%s'\n",pd->title.data()); - msg(" filename `%s'\n",pd->filename.data()); + msg("page '%s'\n",pd->name.data()); + msg(" title '%s'\n",pd->title.data()); + msg(" filename '%s'\n",pd->filename.data()); } //============== DIRS QListIterator<TagDirInfo> ldi(m_tagFileDirs); TagDirInfo *dd; for (;(dd=ldi.current());++ldi) { - msg("dir `%s'\n",dd->name.data()); - msg(" path `%s'\n",dd->path.data()); + msg("dir '%s'\n",dd->name.data()); + msg(" path '%s'\n",dd->path.data()); QCStringList::Iterator it; for ( it = dd->fileList.begin(); it != dd->fileList.end(); ++it ) @@ -1393,8 +1393,8 @@ void TagFileParser::buildLists(Entry *root) QCString fullName = m_tagName+":"+tfi->path+stripPath(tfi->name); fe->fileName = fullName; - //printf("new FileDef() filename=%s\n",tfi->filename.data()); - FileDef *fd = new FileDef(m_tagName+":"+tfi->path, + //printf("createFileDef() filename=%s\n",tfi->filename.data()); + FileDef *fd = createFileDef(m_tagName+":"+tfi->path, tfi->name,m_tagName, tfi->filename ); @@ -1527,7 +1527,7 @@ void TagFileParser::addIncludes() TagIncludeInfo *ii; for (;(ii=mii.current());++mii) { - //printf("ii->name=`%s'\n",ii->name.data()); + //printf("ii->name='%s'\n",ii->name.data()); FileName *ifn = Doxygen::inputNameDict->find(ii->name); ASSERT(ifn!=0); if (ifn) diff --git a/src/tclscanner.h b/src/tclscanner.h index aa1673c..0e56bdd 100644 --- a/src/tclscanner.h +++ b/src/tclscanner.h @@ -47,9 +47,9 @@ class TclLanguageScanner : public ParserInterface int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, - MemberDef *memberDef=0, + const MemberDef *memberDef=0, bool showLineNumbers=TRUE, - Definition *searchCtx=0, + const Definition *searchCtx=0, bool collectXRefs=TRUE ); void resetCodeParserState(); diff --git a/src/tclscanner.l b/src/tclscanner.l index ca5294b..88bd474 100644 --- a/src/tclscanner.l +++ b/src/tclscanner.l @@ -456,7 +456,7 @@ static struct QAsciiDict<Entry> fn; // all read function entries QList<Entry> entry; // list of all created entries, will be deleted after codifying Protection protection; // current protections state - MemberDef *memberdef; // contain current MemberDef when codifying + const MemberDef *memberdef; // contain current MemberDef when codifying bool collectXRefs; } tcl; @@ -486,7 +486,7 @@ Entry* tcl_entry_new() // myEntry->stat = FALSE; myEntry->fileName = tcl.file_name; myEntry->lang = SrcLangExt_Tcl; - initGroupInfo(myEntry); + Doxygen::docGroup.initGroupInfo(myEntry); // collect entries if (!tcl.code) { @@ -1049,7 +1049,7 @@ D tcl.string_commentcodify = ""; tcl.string_commentline = ""; tcl.line_body1=yylineno; - tcl_command(-1,""); + tcl_command(-1,yytext); } <COMMAND>{ws}*; { D @@ -1507,6 +1507,7 @@ tcl_inf("-> %s\n",(const char *)tcl.string_comment); myO.shrink(myO.curPos()-2); myO.addChar('\0'); QCString myDoc = myO.data(); + QCString processedDoc; if (what==99) { // inbody comment file or namespace or class or proc/method int myPos0; @@ -1526,14 +1527,16 @@ tcl_inf("-> %s\n",(const char *)tcl.string_comment); myPos0=myPos; myLine0=myLine; - while (parseCommentBlock(tcl.this_parser, &myEntry0, myDoc, tcl.file_name, + processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine); + while (parseCommentBlock(tcl.this_parser, &myEntry0, processedDoc, tcl.file_name, myLine, FALSE, tcl.config_autobrief, FALSE, myProt, myPos, myNew)) { if (myNew) { // we need a new entry in this case myNew=0; myEntry = tcl_entry_new(); - parseCommentBlock(tcl.this_parser, myEntry, myDoc, tcl.file_name, + processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine0); + parseCommentBlock(tcl.this_parser, myEntry, processedDoc, tcl.file_name, myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); tcl.entry_inside->addSubEntry(myEntry); } @@ -1543,7 +1546,8 @@ tcl_inf("-> %s\n",(const char *)tcl.string_comment); { myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns); } - parseCommentBlock(tcl.this_parser, myEntry1, myDoc, tcl.file_name, + processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine0); + parseCommentBlock(tcl.this_parser, myEntry1, processedDoc, tcl.file_name, myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); } myPos0=myPos; @@ -1553,7 +1557,8 @@ tcl_inf("-> %s\n",(const char *)tcl.string_comment); { // we need a new entry myNew=0; myEntry = tcl_entry_new(); - parseCommentBlock(tcl.this_parser, myEntry, myDoc, tcl.file_name, + processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine0); + parseCommentBlock(tcl.this_parser, myEntry, processedDoc, tcl.file_name, myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); tcl.entry_inside->addSubEntry(myEntry); } @@ -1563,14 +1568,16 @@ tcl_inf("-> %s\n",(const char *)tcl.string_comment); { myEntry1=tcl_entry_namespace(tcl.scan.at(0)->ns); } - parseCommentBlock(tcl.this_parser, myEntry1, myDoc, tcl.file_name, + processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine0); + parseCommentBlock(tcl.this_parser, myEntry1, processedDoc, tcl.file_name, myLine0, FALSE, tcl.config_autobrief, FALSE, myProt, myPos0, myNew); } } else { // new entry tcl.entry_current = tcl_entry_new(); - while (parseCommentBlock(tcl.this_parser, tcl.entry_current, myDoc, + processedDoc = preprocessCommentBlock(myDoc,tcl.file_name,myLine); + while (parseCommentBlock(tcl.this_parser, tcl.entry_current, processedDoc, tcl.file_name, myLine, FALSE, tcl.config_autobrief, FALSE, myProt, myPos, myNew)) { @@ -1715,7 +1722,7 @@ static void tcl_codify_link(QCString name) if (tcl.memberdef) { myDef->addSourceReferencedBy(tcl.memberdef); - tcl.memberdef->addSourceReferences(myDef); + //tcl.memberdef->addSourceReferences(myDef); } else { Entry* callerEntry; unsigned int i; @@ -2267,21 +2274,22 @@ D } //! Handle \c namespace statements. -static void tcl_command_NAMESPACE() +static bool tcl_command_NAMESPACE() { D QCString myNs, myName, myStr; //Entry *myEntryNs=NULL; tcl_scan *myScan = tcl.scan.at(0); + tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)),myNs,myName); + if (myName.isEmpty()) return false; // not a namespace tcl_codify_cmd("keyword",0); tcl_codify_cmd(NULL,1); tcl_codify_cmd("keyword",2); tcl_codify_cmd(NULL,3); tcl_codify_cmd(NULL,4); tcl_codify_cmd(NULL,5); - tcl_name(myScan->ns,(*tcl.list_commandwords.at(4)),myNs,myName); - if (myNs.length()) + if (!myNs.isEmpty()) { myName = myNs+"::"+myName; } @@ -2303,6 +2311,7 @@ D tcl.word_is=' '; } myScan = tcl_scan_start(tcl.word_is,myStr, myName, NULL, NULL); + return true; } //! Handle \c itcl::class statements. @@ -2629,11 +2638,16 @@ tcl_inf("->\n"); if ((*tcl.list_commandwords.at(2))=="eval") { if (tcl.list_commandwords.count() < 7) {myLine=__LINE__;goto command_warn;} - tcl_command_NAMESPACE(); + if (tcl_command_NAMESPACE()) + { + goto command_end; + } + } + else + { + tcl_command_OTHER(); goto command_end; } - tcl_command_OTHER(); - goto command_end; } if (myStr=="itcl::class") { @@ -2943,7 +2957,7 @@ tcl_inf("%s\n",fileName); printlex(yy_flex_debug, TRUE, __FILE__, fileName); msg("Parsing %s...\n",fileName); - groupEnterFile(fileName,yylineno); + Doxygen::docGroup.enterFile(fileName,yylineno); tcl_init(); tcl.code = NULL; @@ -2951,7 +2965,7 @@ tcl_inf("%s\n",fileName); tcl.this_parser = this; tcl.entry_main = root; /* toplevel entry */ tcl_parse("",""); - groupLeaveFile(tcl.file_name,yylineno); + Doxygen::docGroup.leaveFile(tcl.file_name,yylineno); root->program.resize(0); myFile.close(); printlex(yy_flex_debug, FALSE, __FILE__, fileName); @@ -2968,9 +2982,9 @@ void TclLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf, int startLine, int endLine, bool inlineFragment, - MemberDef *memberDef, + const MemberDef *memberDef, bool showLineNumbers, - Definition *searchCtx, + const Definition *searchCtx, bool collectXRefs ) { diff --git a/src/template.cpp b/src/template.cpp index b1435ce..228da4d 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -2832,7 +2832,7 @@ template<class T> class TemplateNodeCreator : public TemplateNode rootDir.setPath(QDir::currentDirPath()); if (!rootDir.mkdir(outputDir)) { - err("tag OUTPUT_DIRECTORY: Output directory `%s' does not " + err("tag OUTPUT_DIRECTORY: Output directory '%s' does not " "exist and cannot be created\n",outputDir.data()); return; } diff --git a/src/textdocvisitor.h b/src/textdocvisitor.h index bbc70e8..c4ba3d7 100644 --- a/src/textdocvisitor.h +++ b/src/textdocvisitor.h @@ -125,8 +125,6 @@ class TextDocVisitor : public DocVisitor void visitPost(DocXRefItem *) {} void visitPre(DocInternalRef *) {} void visitPost(DocInternalRef *) {} - void visitPre(DocCopy *) {} - void visitPost(DocCopy *) {} void visitPre(DocText *) {} void visitPost(DocText *) {} void visitPre(DocHtmlBlockQuote *) {} diff --git a/src/tooltip.cpp b/src/tooltip.cpp index 3b128a9..a30a85c 100644 --- a/src/tooltip.cpp +++ b/src/tooltip.cpp @@ -68,7 +68,7 @@ static QCString escapeId(const char *s) return res; } -void TooltipManager::addTooltip(Definition *d) +void TooltipManager::addTooltip(const Definition *d) { static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); if (!sourceTooltips) return; @@ -84,6 +84,7 @@ void TooltipManager::addTooltip(Definition *d) { id+="_"+anc; } + id = "a" + id; if (p->tooltipInfo.find(id)==0) { p->tooltipInfo.insert(id,d); @@ -113,7 +114,7 @@ void TooltipManager::writeTooltips(CodeOutputInterface &ol) QCString decl; if (d->definitionType()==Definition::TypeMember) { - MemberDef *md = (MemberDef*)d; + MemberDef *md = dynamic_cast<MemberDef*>(d); decl = md->declaration(); if (!decl.isEmpty() && decl.at(0)=='@') // hide enum values { diff --git a/src/tooltip.h b/src/tooltip.h index 34a578a..170ea3c 100644 --- a/src/tooltip.h +++ b/src/tooltip.h @@ -23,7 +23,7 @@ class TooltipManager public: static TooltipManager *instance(); void clearTooltips(); - void addTooltip(Definition *d); + void addTooltip(const Definition *d); void writeTooltips(CodeOutputInterface &ol); private: diff --git a/src/translator_br.h b/src/translator_br.h index c2d079a..01c5b9f 100644 --- a/src/translator_br.h +++ b/src/translator_br.h @@ -18,6 +18,8 @@ * Thanks to Jorge Ramos, Fernando Carijo and others for their contributions. * * History: + * 20190203: + * - Slice methods added; * 20180612: * - Updated to 1.8.15; * 20170123: @@ -47,7 +49,7 @@ #ifndef TRANSLATOR_BR_H #define TRANSLATOR_BR_H -class TranslatorBrazilian : public TranslatorAdapter_1_8_15 +class TranslatorBrazilian : public Translator { public: @@ -2088,118 +2090,253 @@ class TranslatorBrazilian : public TranslatorAdapter_1_8_15 // new since 1.8.15 ////////////////////////////////////////////////////////////////////////// - /** VHDL design unit hierarchy */ - virtual QCString trDesignUnitHierarchy() - { return "Hierarquia da Unidade de Design"; } - /** VHDL design unit list */ - virtual QCString trDesignUnitList() - { return "Lista de Unidades de Design"; } - /** VHDL design unit members */ - virtual QCString trDesignUnitMembers() - { return "Membros da Unidade de Design"; } - /** VHDL design unit list description */ - virtual QCString trDesignUnitListDescription() - { - return "Esta é uma lista de todos os membros de unidades de design " - "com ligações para as entidades às quais pertencem:"; - } - /** VHDL design unit index */ - virtual QCString trDesignUnitIndex() - { return "Índice de Unidades de Design"; } - /** VHDL design units */ - virtual QCString trDesignUnits() - { return "Unidades de Design"; } - /** VHDL functions/procedures/processes */ - virtual QCString trFunctionAndProc() - { return "Funções/Procedimentos/Processos"; } - /** VHDL type */ - virtual QCString trVhdlType(uint64 type,bool single) - { - switch(type) - { - case VhdlDocGen::LIBRARY: - if (single) return "Biblioteca"; - else return "Bibliotecas"; - case VhdlDocGen::PACKAGE: - if (single) return "Pacote"; - else return "Pacotes"; - case VhdlDocGen::SIGNAL: - if (single) return "Sinal"; - else return "Sinais"; - case VhdlDocGen::COMPONENT: - if (single) return "Componente"; - else return "Componentes"; - case VhdlDocGen::CONSTANT: - if (single) return "Constante"; - else return "Constantes"; - case VhdlDocGen::ENTITY: - if (single) return "Entidade"; - else return "Entidades"; - case VhdlDocGen::TYPE: - if (single) return "Tipo"; - else return "Tipos"; - case VhdlDocGen::SUBTYPE: - if (single) return "Subtipo"; - else return "Subtipos"; - case VhdlDocGen::FUNCTION: - if (single) return "Função"; - else return "Funções"; - case VhdlDocGen::RECORD: - if (single) return "Registro"; - else return "Registros"; - case VhdlDocGen::PROCEDURE: - if (single) return "Procedimento"; - else return "Procedimentos"; - case VhdlDocGen::ARCHITECTURE: - if (single) return "Arquitetura"; - else return "Arquiteturas"; - case VhdlDocGen::ATTRIBUTE: - if (single) return "Atributo"; - else return "Atributos"; - case VhdlDocGen::PROCESS: - if (single) return "Processo"; - else return "Processos"; - case VhdlDocGen::PORT: - if (single) return "Porta"; - else return "Portas"; - case VhdlDocGen::USE: - if (single) return "cláusula de uso"; - else return "cláusulas de uso"; - case VhdlDocGen::GENERIC: - if (single) return "Generico"; - else return "Genericos"; - case VhdlDocGen::PACKAGE_BODY: - return "Corpo do Pacote"; - case VhdlDocGen::UNITS: - return "Unidades"; - case VhdlDocGen::SHAREDVARIABLE: - if (single) return "Variável Compartilhada"; - else return "Variáveis Compartilhadas"; - case VhdlDocGen::VFILE: - if (single) return "Arquivo"; - else return "Arquivos"; - case VhdlDocGen::GROUP: - if (single) return "Grupo"; - else return "Grupos"; - case VhdlDocGen::INSTANTIATION: - if (single) return "Instância"; - else return "Instâncias"; - case VhdlDocGen::ALIAS: - if (single) return "Apelido"; - else return "Apelidos"; - case VhdlDocGen::CONFIG: - if (single) return "Configuração"; - else return "Configurações"; - case VhdlDocGen::MISCELLANEOUS: - return "Outros"; // Is this correct for VHDL? - case VhdlDocGen::UCF_CONST: - return "Restrições"; - default: - return "Classe"; - } - } - virtual QCString trCustomReference(const char *name) - { return "Referência de " + QCString(name); } + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "Hierarquia da Unidade de Design"; } + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "Lista de Unidades de Design"; } + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "Membros da Unidade de Design"; } + /** VHDL design unit list description */ + virtual QCString trDesignUnitListDescription() + { + return "Esta é uma lista de todos os membros de unidades de design " + "com ligações para as entidades às quais pertencem:"; + } + /** VHDL design unit index */ + virtual QCString trDesignUnitIndex() + { return "Índice de Unidades de Design"; } + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "Unidades de Design"; } + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "Funções/Procedimentos/Processos"; } + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch(type) + { + case VhdlDocGen::LIBRARY: + if (single) return "Biblioteca"; + else return "Bibliotecas"; + case VhdlDocGen::PACKAGE: + if (single) return "Pacote"; + else return "Pacotes"; + case VhdlDocGen::SIGNAL: + if (single) return "Sinal"; + else return "Sinais"; + case VhdlDocGen::COMPONENT: + if (single) return "Componente"; + else return "Componentes"; + case VhdlDocGen::CONSTANT: + if (single) return "Constante"; + else return "Constantes"; + case VhdlDocGen::ENTITY: + if (single) return "Entidade"; + else return "Entidades"; + case VhdlDocGen::TYPE: + if (single) return "Tipo"; + else return "Tipos"; + case VhdlDocGen::SUBTYPE: + if (single) return "Subtipo"; + else return "Subtipos"; + case VhdlDocGen::FUNCTION: + if (single) return "Função"; + else return "Funções"; + case VhdlDocGen::RECORD: + if (single) return "Registro"; + else return "Registros"; + case VhdlDocGen::PROCEDURE: + if (single) return "Procedimento"; + else return "Procedimentos"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "Arquitetura"; + else return "Arquiteturas"; + case VhdlDocGen::ATTRIBUTE: + if (single) return "Atributo"; + else return "Atributos"; + case VhdlDocGen::PROCESS: + if (single) return "Processo"; + else return "Processos"; + case VhdlDocGen::PORT: + if (single) return "Porta"; + else return "Portas"; + case VhdlDocGen::USE: + if (single) return "cláusula de uso"; + else return "cláusulas de uso"; + case VhdlDocGen::GENERIC: + if (single) return "Generico"; + else return "Genericos"; + case VhdlDocGen::PACKAGE_BODY: + return "Corpo do Pacote"; + case VhdlDocGen::UNITS: + return "Unidades"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "Variável Compartilhada"; + else return "Variáveis Compartilhadas"; + case VhdlDocGen::VFILE: + if (single) return "Arquivo"; + else return "Arquivos"; + case VhdlDocGen::GROUP: + if (single) return "Grupo"; + else return "Grupos"; + case VhdlDocGen::INSTANTIATION: + if (single) return "Instância"; + else return "Instâncias"; + case VhdlDocGen::ALIAS: + if (single) return "Apelido"; + else return "Apelidos"; + case VhdlDocGen::CONFIG: + if (single) return "Configuração"; + else return "Configurações"; + case VhdlDocGen::MISCELLANEOUS: + return "Outros"; // Is this correct for VHDL? + case VhdlDocGen::UCF_CONST: + return "Restrições"; + default: + return "Classe"; + } + } + virtual QCString trCustomReference(const char *name) + { return "Referência de " + QCString(name); } + + /* Slice */ + virtual QCString trConstants() + { + return "Constantes"; + } + virtual QCString trConstantDocumentation() + { + return "Constantes"; + } + virtual QCString trSequences() + { + return "Sequências"; + } + virtual QCString trSequenceDocumentation() + { + return "Sequências"; + } + virtual QCString trDictionaries() + { + return "Dicionários"; + } + virtual QCString trDictionaryDocumentation() + { + return "Dicionários"; + } + virtual QCString trSliceInterfaces() + { + return "Interfaces"; + } + virtual QCString trInterfaceIndex() + { + return "Índice de Interfaces"; + } + virtual QCString trInterfaceList() + { + return "Lista de Interfaces"; + } + virtual QCString trInterfaceListDescription() + { + return "Estas são as interfaces com suas respectivas descrições:"; + } + virtual QCString trInterfaceHierarchy() + { + return "Hierarquia de Interfaces"; + } + virtual QCString trInterfaceHierarchyDescription() + { + return "Esta é a lista parcialmente ordenadas de heranças:"; + } + virtual QCString trInterfaceDocumentation() + { + return "Interfaces"; + } + virtual QCString trStructs() + { + return "Estruturas"; + } + virtual QCString trStructIndex() + { + return "Índice de Estruturas"; + } + virtual QCString trStructList() + { + return "Lista de Estruturas"; + } + virtual QCString trStructListDescription() + { + return "Estas são as estruturas com suas respectivas descrições:"; + } + virtual QCString trStructDocumentation() + { + return "Estruturas"; + } + virtual QCString trExceptionIndex() + { + return "Índice the Exceções"; + } + virtual QCString trExceptionList() + { + return "Lista de Exceções"; + } + virtual QCString trExceptionListDescription() + { + return "Estas são as exceções com suas respectivas descrições:"; + } + virtual QCString trExceptionHierarchy() + { + return "Hierarquia de Exceções"; + } + virtual QCString trExceptionHierarchyDescription() + { + return "Esta é a lista parcialmente ordenadas de heranças:"; + } + virtual QCString trExceptionDocumentation() + { + return "Exceções"; + } + virtual QCString trCompoundReferenceSlice(const char *clName, ClassDef::CompoundType compType, bool isLocal) + { + QCString result=(QCString)"Referência "; + switch(compType) + { + case ClassDef::Class: result+="da Classe "; break; + case ClassDef::Struct: result+="da Estrutura "; break; + case ClassDef::Union: result+="da União "; break; + case ClassDef::Interface: result+="da Interface "; break; + case ClassDef::Protocol: result+="do Protocolo "; break; + case ClassDef::Category: result+="da Categoria "; break; + case ClassDef::Exception: result+="da Exceção "; break; + default: break; + } + if (isLocal) result+="Local "; + result+= clName; + return result; + } + virtual QCString trOperations() + { + return "Operações"; + } + virtual QCString trOperationDocumentation() + { + return "Operações"; + } + virtual QCString trDataMembers() + { + return "Dados Membros"; + } + virtual QCString trDataMemberDocumentation() + { + return "Dados Membros"; + } + +////////////////////////////////////////////////////////////////////////// + }; #endif diff --git a/src/translator_pt.h b/src/translator_pt.h index 23faf7f..970cf45 100644 --- a/src/translator_pt.h +++ b/src/translator_pt.h @@ -24,6 +24,8 @@ * VERSION HISTORY * --------------- * History: + * 20190203: + * - Slice methods added; * 20180612: * - Updated to 1.8.15; * 20131129: @@ -57,7 +59,7 @@ #define TRANSLATOR_PT_H -class TranslatorPortuguese : public TranslatorAdapter_1_8_15 +class TranslatorPortuguese : public Translator { public: @@ -2025,120 +2027,253 @@ class TranslatorPortuguese : public TranslatorAdapter_1_8_15 // new since 1.8.15 ////////////////////////////////////////////////////////////////////////// - /** VHDL design unit hierarchy */ - virtual QCString trDesignUnitHierarchy() - { return "Hierarquia da Unidade de Design"; } - /** VHDL design unit list */ - virtual QCString trDesignUnitList() - { return "Lista de Unidades de Design"; } - /** VHDL design unit members */ - virtual QCString trDesignUnitMembers() - { return "Membros da Unidade de Design"; } - /** VHDL design unit list description */ - virtual QCString trDesignUnitListDescription() - { - return "Esta é uma lista de todos os membros de unidades de design " - "com ligações para as entidades às quais pertencem:"; - } - /** VHDL design unit index */ - virtual QCString trDesignUnitIndex() - { return "Índice de Unidades de Design"; } - /** VHDL design units */ - virtual QCString trDesignUnits() - { return "Unidades de Design"; } - /** VHDL functions/procedures/processes */ - virtual QCString trFunctionAndProc() - { return "Funções/Procedimentos/Processos"; } - /** VHDL type */ - virtual QCString trVhdlType(uint64 type,bool single) - { - switch(type) - { - case VhdlDocGen::LIBRARY: - if (single) return "Biblioteca"; - else return "Bibliotecas"; - case VhdlDocGen::PACKAGE: - if (single) return "Pacote"; - else return "Pacotes"; - case VhdlDocGen::SIGNAL: - if (single) return "Sinal"; - else return "Sinais"; - case VhdlDocGen::COMPONENT: - if (single) return "Componente"; - else return "Componentes"; - case VhdlDocGen::CONSTANT: - if (single) return "Constante"; - else return "Constantes"; - case VhdlDocGen::ENTITY: - if (single) return "Entidade"; - else return "Entidades"; - case VhdlDocGen::TYPE: - if (single) return "Tipo"; - else return "Tipos"; - case VhdlDocGen::SUBTYPE: - if (single) return "Subtipo"; - else return "Subtipos"; - case VhdlDocGen::FUNCTION: - if (single) return "Função"; - else return "Funções"; - case VhdlDocGen::RECORD: - if (single) return "Registro"; - else return "Registros"; - case VhdlDocGen::PROCEDURE: - if (single) return "Procedimento"; - else return "Procedimentos"; - case VhdlDocGen::ARCHITECTURE: - if (single) return "Arquitetura"; - else return "Arquiteturas"; - case VhdlDocGen::ATTRIBUTE: - if (single) return "Atributo"; - else return "Atributos"; - case VhdlDocGen::PROCESS: - if (single) return "Processo"; - else return "Processos"; - case VhdlDocGen::PORT: - if (single) return "Porta"; - else return "Portas"; - case VhdlDocGen::USE: - if (single) return "cláusula de uso"; - else return "cláusulas de uso"; - case VhdlDocGen::GENERIC: - if (single) return "Generico"; - else return "Genericos"; - case VhdlDocGen::PACKAGE_BODY: - return "Corpo do Pacote"; - case VhdlDocGen::UNITS: - return "Unidades"; - case VhdlDocGen::SHAREDVARIABLE: - if (single) return "Variável Compartilhada"; - else return "Variáveis Compartilhadas"; - case VhdlDocGen::VFILE: - if (single) return "Ficheiro"; - else return "Ficheiros"; - case VhdlDocGen::GROUP: - if (single) return "Grupo"; - else return "Grupos"; - case VhdlDocGen::INSTANTIATION: - if (single) return "Instância"; - else return "Instâncias"; - case VhdlDocGen::ALIAS: - if (single) return "Apelido"; - else return "Apelidos"; - case VhdlDocGen::CONFIG: - if (single) return "Configuração"; - else return "Configurações"; - case VhdlDocGen::MISCELLANEOUS: - return "Outros"; // Is this correct for VHDL? - case VhdlDocGen::UCF_CONST: - return "Restrições"; - default: - return "Classe"; - } - } - virtual QCString trCustomReference(const char *name) - { return "Referência de " + QCString(name); } + /** VHDL design unit hierarchy */ + virtual QCString trDesignUnitHierarchy() + { return "Hierarquia da Unidade de Design"; } + /** VHDL design unit list */ + virtual QCString trDesignUnitList() + { return "Lista de Unidades de Design"; } + /** VHDL design unit members */ + virtual QCString trDesignUnitMembers() + { return "Membros da Unidade de Design"; } + /** VHDL design unit list description */ + virtual QCString trDesignUnitListDescription() + { + return "Esta é uma lista de todos os membros de unidades de design " + "com ligações para as entidades às quais pertencem:"; + } + /** VHDL design unit index */ + virtual QCString trDesignUnitIndex() + { return "Índice de Unidades de Design"; } + /** VHDL design units */ + virtual QCString trDesignUnits() + { return "Unidades de Design"; } + /** VHDL functions/procedures/processes */ + virtual QCString trFunctionAndProc() + { return "Funções/Procedimentos/Processos"; } + /** VHDL type */ + virtual QCString trVhdlType(uint64 type,bool single) + { + switch(type) + { + case VhdlDocGen::LIBRARY: + if (single) return "Biblioteca"; + else return "Bibliotecas"; + case VhdlDocGen::PACKAGE: + if (single) return "Pacote"; + else return "Pacotes"; + case VhdlDocGen::SIGNAL: + if (single) return "Sinal"; + else return "Sinais"; + case VhdlDocGen::COMPONENT: + if (single) return "Componente"; + else return "Componentes"; + case VhdlDocGen::CONSTANT: + if (single) return "Constante"; + else return "Constantes"; + case VhdlDocGen::ENTITY: + if (single) return "Entidade"; + else return "Entidades"; + case VhdlDocGen::TYPE: + if (single) return "Tipo"; + else return "Tipos"; + case VhdlDocGen::SUBTYPE: + if (single) return "Subtipo"; + else return "Subtipos"; + case VhdlDocGen::FUNCTION: + if (single) return "Função"; + else return "Funções"; + case VhdlDocGen::RECORD: + if (single) return "Registro"; + else return "Registros"; + case VhdlDocGen::PROCEDURE: + if (single) return "Procedimento"; + else return "Procedimentos"; + case VhdlDocGen::ARCHITECTURE: + if (single) return "Arquitetura"; + else return "Arquiteturas"; + case VhdlDocGen::ATTRIBUTE: + if (single) return "Atributo"; + else return "Atributos"; + case VhdlDocGen::PROCESS: + if (single) return "Processo"; + else return "Processos"; + case VhdlDocGen::PORT: + if (single) return "Porta"; + else return "Portas"; + case VhdlDocGen::USE: + if (single) return "cláusula de uso"; + else return "cláusulas de uso"; + case VhdlDocGen::GENERIC: + if (single) return "Generico"; + else return "Genericos"; + case VhdlDocGen::PACKAGE_BODY: + return "Corpo do Pacote"; + case VhdlDocGen::UNITS: + return "Unidades"; + case VhdlDocGen::SHAREDVARIABLE: + if (single) return "Variável Compartilhada"; + else return "Variáveis Compartilhadas"; + case VhdlDocGen::VFILE: + if (single) return "Ficheiro"; + else return "Ficheiros"; + case VhdlDocGen::GROUP: + if (single) return "Grupo"; + else return "Grupos"; + case VhdlDocGen::INSTANTIATION: + if (single) return "Instância"; + else return "Instâncias"; + case VhdlDocGen::ALIAS: + if (single) return "Apelido"; + else return "Apelidos"; + case VhdlDocGen::CONFIG: + if (single) return "Configuração"; + else return "Configurações"; + case VhdlDocGen::MISCELLANEOUS: + return "Outros"; // Is this correct for VHDL? + case VhdlDocGen::UCF_CONST: + return "Restrições"; + default: + return "Classe"; + } + } + virtual QCString trCustomReference(const char *name) + { return "Referência de " + QCString(name); } + + /* Slice */ + virtual QCString trConstants() + { + return "Constantes"; + } + virtual QCString trConstantDocumentation() + { + return "Constantes"; + } + virtual QCString trSequences() + { + return "Sequências"; + } + virtual QCString trSequenceDocumentation() + { + return "Sequências"; + } + virtual QCString trDictionaries() + { + return "Dicionários"; + } + virtual QCString trDictionaryDocumentation() + { + return "Dicionários"; + } + virtual QCString trSliceInterfaces() + { + return "Interfaces"; + } + virtual QCString trInterfaceIndex() + { + return "Índice de Interfaces"; + } + virtual QCString trInterfaceList() + { + return "Lista de Interfaces"; + } + virtual QCString trInterfaceListDescription() + { + return "Estas são as interfaces com suas respectivas descrições:"; + } + virtual QCString trInterfaceHierarchy() + { + return "Hierarquia de Interfaces"; + } + virtual QCString trInterfaceHierarchyDescription() + { + return "Esta é a lista parcialmente ordenadas de heranças:"; + } + virtual QCString trInterfaceDocumentation() + { + return "Interfaces"; + } + virtual QCString trStructs() + { + return "Estruturas"; + } + virtual QCString trStructIndex() + { + return "Índice de Estruturas"; + } + virtual QCString trStructList() + { + return "Lista de Estruturas"; + } + virtual QCString trStructListDescription() + { + return "Estas são as estruturas com suas respectivas descrições:"; + } + virtual QCString trStructDocumentation() + { + return "Estruturas"; + } + virtual QCString trExceptionIndex() + { + return "Índice the Exceções"; + } + virtual QCString trExceptionList() + { + return "Lista de Exceções"; + } + virtual QCString trExceptionListDescription() + { + return "Estas são as exceções com suas respectivas descrições:"; + } + virtual QCString trExceptionHierarchy() + { + return "Hierarquia de Exceções"; + } + virtual QCString trExceptionHierarchyDescription() + { + return "Esta é a lista parcialmente ordenadas de heranças:"; + } + virtual QCString trExceptionDocumentation() + { + return "Exceções"; + } + virtual QCString trCompoundReferenceSlice(const char *clName, ClassDef::CompoundType compType, bool isLocal) + { + QCString result=(QCString)"Referência "; + switch(compType) + { + case ClassDef::Class: result+="da Classe "; break; + case ClassDef::Struct: result+="da Estrutura "; break; + case ClassDef::Union: result+="da União "; break; + case ClassDef::Interface: result+="da Interface "; break; + case ClassDef::Protocol: result+="do Protocolo "; break; + case ClassDef::Category: result+="da Categoria "; break; + case ClassDef::Exception: result+="da Exceção "; break; + default: break; + } + if (isLocal) result+="Local "; + result+= clName; + return result; + } + virtual QCString trOperations() + { + return "Operações"; + } + virtual QCString trOperationDocumentation() + { + return "Operações"; + } + virtual QCString trDataMembers() + { + return "Dados Membros"; + } + virtual QCString trDataMemberDocumentation() + { + return "Dados Membros"; + } + +////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// }; #endif diff --git a/src/util.cpp b/src/util.cpp index 08c13fb..f5e43a4 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -184,7 +184,7 @@ QCString removeAnonymousScopes(const QCString &s) p=i+l; } result+=s.right(sl-p); - //printf("removeAnonymousScopes(`%s')=`%s'\n",s.data(),result.data()); + //printf("removeAnonymousScopes('%s')='%s'\n",s.data(),result.data()); return result; } @@ -210,7 +210,7 @@ QCString replaceAnonymousScopes(const QCString &s,const char *replacement) p=i+l; } result+=s.right(sl-p); - //printf("replaceAnonymousScopes(`%s')=`%s'\n",s.data(),result.data()); + //printf("replaceAnonymousScopes('%s')='%s'\n",s.data(),result.data()); return result; } @@ -241,7 +241,7 @@ QCString stripAnonymousNamespaceScope(const QCString &s) p=i+l; } done: - //printf("stripAnonymousNamespaceScope(`%s')=`%s'\n",s.data(),newScope.data()); + //printf("stripAnonymousNamespaceScope('%s')='%s'\n",s.data(),newScope.data()); return newScope; } @@ -346,8 +346,8 @@ int guessSection(const char *name) return 0; } -QCString resolveTypeDef(Definition *context,const QCString &qualifiedName, - Definition **typedefContext) +QCString resolveTypeDef(const Definition *context,const QCString &qualifiedName, + const Definition **typedefContext) { //printf("<<resolveTypeDef(%s,%s)\n", // context ? context->name().data() : "<none>",qualifiedName.data()); @@ -358,7 +358,7 @@ QCString resolveTypeDef(Definition *context,const QCString &qualifiedName, return result; } - Definition *mContext=context; + const Definition *mContext=context; if (typedefContext) *typedefContext=context; // see if the qualified name has a scope part @@ -378,12 +378,12 @@ QCString resolveTypeDef(Definition *context,const QCString &qualifiedName, while (mContext && md==0) { // step 1: get the right scope - Definition *resScope=mContext; + const Definition *resScope=mContext; if (scopeIndex!=-1) { // split-off scope part QCString resScopeName = qualifiedName.left(scopeIndex); - //printf("resScopeName=`%s'\n",resScopeName.data()); + //printf("resScopeName='%s'\n",resScopeName.data()); // look-up scope in context int is,ps=0; @@ -394,7 +394,7 @@ QCString resolveTypeDef(Definition *context,const QCString &qualifiedName, QCString tmp = resolveTypeDef(mContext,qualScopePart); if (!tmp.isEmpty()) qualScopePart=tmp; resScope = resScope->findInnerCompound(qualScopePart); - //printf("qualScopePart=`%s' resScope=%p\n",qualScopePart.data(),resScope); + //printf("qualScopePart='%s' resScope=%p\n",qualScopePart.data(),resScope); if (resScope==0) break; ps=is+l; } @@ -444,7 +444,7 @@ QCString resolveTypeDef(Definition *context,const QCString &qualifiedName, // step 3: get the member's type if (md) { - //printf(">>resolveTypeDef: Found typedef name `%s' in scope `%s' value=`%s' args='%s'\n", + //printf(">>resolveTypeDef: Found typedef name '%s' in scope '%s' value='%s' args='%s'\n", // qualifiedName.data(),context->name().data(),md->typeString(),md->argsString() // ); result=md->typeString(); @@ -461,7 +461,7 @@ QCString resolveTypeDef(Definition *context,const QCString &qualifiedName, } else { - //printf(">>resolveTypeDef: Typedef `%s' not found in scope `%s'!\n", + //printf(">>resolveTypeDef: Typedef '%s' not found in scope '%s'!\n", // qualifiedName.data(),context ? context->name().data() : "<global>"); } return result; @@ -518,10 +518,10 @@ static QDict<MemberDef> g_resolvedTypedefs; static QDict<Definition> g_visitedNamespaces; // forward declaration -static ClassDef *getResolvedClassRec(const Definition *scope, +static const ClassDef *getResolvedClassRec(const Definition *scope, const FileDef *fileScope, const char *n, - MemberDef **pTypeDef, + const MemberDef **pTypeDef, QCString *pTemplSpec, QCString *pResolvedType ); @@ -535,10 +535,12 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop * * Example: typedef int T; will return 0, since "int" is not a class. */ -ClassDef *newResolveTypedef(const FileDef *fileScope,MemberDef *md, - MemberDef **pMemType,QCString *pTemplSpec, - QCString *pResolvedType, - ArgumentList *actTemplParams) +const ClassDef *newResolveTypedef(const FileDef *fileScope, + const MemberDef *md, + const MemberDef **pMemType, + QCString *pTemplSpec, + QCString *pResolvedType, + ArgumentList *actTemplParams) { //printf("newResolveTypedef(md=%p,cachedVal=%p)\n",md,md->getCachedTypedefVal()); bool isCached = md->isTypedefValCached(); // value already cached @@ -559,7 +561,7 @@ ClassDef *newResolveTypedef(const FileDef *fileScope,MemberDef *md, g_resolvedTypedefs.insert(qname,md); // put on the trace list - ClassDef *typeClass = md->getClassDef(); + const ClassDef *typeClass = md->getClassDef(); QCString type = md->typeString(); // get the "value" of the typedef if (typeClass && typeClass->isTemplate() && actTemplParams && actTemplParams->count()>0) @@ -581,8 +583,8 @@ ClassDef *newResolveTypedef(const FileDef *fileScope,MemberDef *md, int sp=0; tl=type.length(); // length may have been changed while (sp<tl && type.at(sp)==' ') sp++; - MemberDef *memTypeDef = 0; - ClassDef *result = getResolvedClassRec(md->getOuterScope(), + const MemberDef *memTypeDef = 0; + const ClassDef *result = getResolvedClassRec(md->getOuterScope(), fileScope,type,&memTypeDef,0,pResolvedType); // if type is a typedef then return what it resolves to. if (memTypeDef && memTypeDef->isTypedef()) @@ -652,7 +654,7 @@ done: //printf("setting cached typedef %p in result %p\n",md,result); //printf("==> %s (%s,%d)\n",result->name().data(),result->getDefFileName().data(),result->getDefLine()); //printf("*pResolvedType=%s\n",pResolvedType?pResolvedType->data():"<none>"); - md->cacheTypedefVal(result, + const_cast<MemberDef*>(md)->cacheTypedefVal(result, pTemplSpec ? *pTemplSpec : QCString(), pResolvedType ? *pResolvedType : QCString() ); @@ -667,7 +669,7 @@ done: * value of the typedef or \a name if no typedef was found. */ static QCString substTypedef(const Definition *scope,const FileDef *fileScope,const QCString &name, - MemberDef **pTypeDef=0) + const MemberDef **pTypeDef=0) { QCString result=name; if (name.isEmpty()) return result; @@ -689,7 +691,7 @@ static QCString substTypedef(const Definition *scope,const FileDef *fileScope,co if (d->definitionType()==Definition::TypeMember) { // that are also typedefs - MemberDef *md = (MemberDef *)d; + MemberDef *md = dynamic_cast<MemberDef *>(d); if (md->isTypedef()) // d is a typedef { // test accessibility of typedef within scope. @@ -708,7 +710,7 @@ static QCString substTypedef(const Definition *scope,const FileDef *fileScope,co { Definition *d = (Definition*)di; // that are also typedefs - MemberDef *md = (MemberDef *)di; + MemberDef *md = dynamic_cast<MemberDef *>(di); if (md->isTypedef()) // d is a typedef { // test accessibility of typedef within scope. @@ -730,7 +732,7 @@ static QCString substTypedef(const Definition *scope,const FileDef *fileScope,co return result; } -static Definition *endOfPathIsUsedClass(SDict<Definition> *cl,const QCString &localName) +static const Definition *endOfPathIsUsedClass(const SDict<Definition> *cl,const QCString &localName) { if (cl) { @@ -763,12 +765,12 @@ static const Definition *followPath(const Definition *start,const FileDef *fileS while ((is=getScopeFragment(path,ps,&l))!=-1) { // try to resolve the part if it is a typedef - MemberDef *typeDef=0; + const MemberDef *typeDef=0; QCString qualScopePart = substTypedef(current,fileScope,path.mid(is,l),&typeDef); //printf(" qualScopePart=%s\n",qualScopePart.data()); if (typeDef) { - ClassDef *type = newResolveTypedef(fileScope,typeDef); + const ClassDef *type = newResolveTypedef(fileScope,typeDef); if (type) { //printf("Found type %s\n",type->name().data()); @@ -786,12 +788,12 @@ static const Definition *followPath(const Definition *start,const FileDef *fileS if (current->definitionType()==Definition::TypeNamespace) { next = endOfPathIsUsedClass( - ((NamespaceDef *)current)->getUsedClasses(),qualScopePart); + (dynamic_cast<const NamespaceDef *>(current))->getUsedClasses(),qualScopePart); } else if (current->definitionType()==Definition::TypeFile) { next = endOfPathIsUsedClass( - ((FileDef *)current)->getUsedClasses(),qualScopePart); + (dynamic_cast<const FileDef *>(current))->getUsedClasses(),qualScopePart); } current = next; if (current==0) break; @@ -852,18 +854,21 @@ bool accessibleViaUsingNamespace(const NamespaceSDict *nl, //printf("] found it\n"); return TRUE; } - QCString key=und->name(); - if (und->getUsedNamespaces() && visitedDict.find(key)==0) + if (item->getLanguage()==SrcLangExt_Cpp) { - visitedDict.insert(key,(void *)0x08); - - if (accessibleViaUsingNamespace(und->getUsedNamespaces(),fileScope,item,explicitScopePart)) + QCString key=und->name(); + if (und->getUsedNamespaces() && visitedDict.find(key)==0) { - //printf("] found it via recursion\n"); - return TRUE; - } + visitedDict.insert(key,(void *)0x08); + + if (accessibleViaUsingNamespace(und->getUsedNamespaces(),fileScope,item,explicitScopePart)) + { + //printf("] found it via recursion\n"); + return TRUE; + } - visitedDict.remove(key); + visitedDict.remove(key); + } } //printf("] Try via used namespace done\n"); } @@ -968,13 +973,13 @@ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Defi (item->definitionType()==Definition::TypeMember && // a member itemScope && itemScope->definitionType()==Definition::TypeClass && // of a class scope->definitionType()==Definition::TypeClass && // accessible - ((ClassDef*)scope)->isAccessibleMember((MemberDef *)item) // from scope + (dynamic_cast<const ClassDef*>(scope))->isAccessibleMember(dynamic_cast<const MemberDef *>(item)) // from scope ); bool nestedClassInsideBaseClass = (item->definitionType()==Definition::TypeClass && // a nested class itemScope && itemScope->definitionType()==Definition::TypeClass && // inside a base scope->definitionType()==Definition::TypeClass && // class of scope - ((ClassDef*)scope)->isBaseClass((ClassDef*)itemScope,TRUE) + (dynamic_cast<const ClassDef*>(scope))->isBaseClass(dynamic_cast<ClassDef*>(itemScope),TRUE) ); if (itemScope==scope || memberAccessibleFromScope || nestedClassInsideBaseClass) @@ -1009,15 +1014,15 @@ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Defi // check if scope is a namespace, which is using other classes and namespaces if (scope->definitionType()==Definition::TypeNamespace) { - NamespaceDef *nscope = (NamespaceDef*)scope; + const NamespaceDef *nscope = dynamic_cast<const NamespaceDef*>(scope); //printf(" %s is namespace with %d used classes\n",nscope->name().data(),nscope->getUsedClasses()); - SDict<Definition> *cl = nscope->getUsedClasses(); + const SDict<Definition> *cl = nscope->getUsedClasses(); if (accessibleViaUsingClass(cl,fileScope,item)) { //printf("> found via used class\n"); goto done; } - NamespaceSDict *nl = nscope->getUsedNamespaces(); + const NamespaceSDict *nl = nscope->getUsedNamespaces(); if (accessibleViaUsingNamespace(nl,fileScope,item)) { //printf("> found via used namespace\n"); @@ -1089,7 +1094,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop else if (itemScope && newScope && itemScope->definitionType()==Definition::TypeClass && newScope->definitionType()==Definition::TypeClass && - ((ClassDef*)newScope)->isBaseClass((ClassDef*)itemScope,TRUE,0) + (dynamic_cast<const ClassDef*>(newScope))->isBaseClass(dynamic_cast<const ClassDef*>(itemScope),TRUE,0) ) { // inheritance is also ok. Example: looking for B::I, where @@ -1114,12 +1119,12 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop // A::B::C but is explicit referenced as A::C, where B is imported // in A via a using directive. //printf("newScope is a namespace: %s!\n",newScope->name().data()); - NamespaceDef *nscope = (NamespaceDef*)newScope; - SDict<Definition> *cl = nscope->getUsedClasses(); + const NamespaceDef *nscope = dynamic_cast<const NamespaceDef*>(newScope); + const SDict<Definition> *cl = nscope->getUsedClasses(); if (cl) { SDict<Definition>::Iterator cli(*cl); - Definition *cd; + const Definition *cd; for (cli.toFirst();(cd=cli.current());++cli) { //printf("Trying for class %s\n",cd->name().data()); @@ -1130,11 +1135,11 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop } } } - NamespaceSDict *nl = nscope->getUsedNamespaces(); + const NamespaceSDict *nl = nscope->getUsedNamespaces(); if (nl) { NamespaceSDict::Iterator nli(*nl); - NamespaceDef *nd; + const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { if (g_visitedNamespaces.find(nd->name())==0) @@ -1165,8 +1170,8 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop //printf(" failed to resolve: scope=%s\n",scope->name().data()); if (scope->definitionType()==Definition::TypeNamespace) { - NamespaceDef *nscope = (NamespaceDef*)scope; - NamespaceSDict *nl = nscope->getUsedNamespaces(); + const NamespaceDef *nscope = dynamic_cast<const NamespaceDef*>(scope); + const NamespaceSDict *nl = nscope->getUsedNamespaces(); if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) { //printf("> found in used namespace\n"); @@ -1177,7 +1182,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop { if (fileScope) { - NamespaceSDict *nl = fileScope->getUsedNamespaces(); + const NamespaceSDict *nl = fileScope->getUsedNamespaces(); if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) { //printf("> found in used namespace\n"); @@ -1215,8 +1220,8 @@ static void getResolvedSymbol(const Definition *scope, const QCString &explicitScopePart, ArgumentList *actTemplParams, int &minDistance, - ClassDef *&bestMatch, - MemberDef *&bestTypedef, + const ClassDef *&bestMatch, + const MemberDef *&bestTypedef, QCString &bestTemplSpec, QCString &bestResolvedType ) @@ -1227,7 +1232,7 @@ static void getResolvedSymbol(const Definition *scope, // only look at classes and members that are enums or typedefs if (d->definitionType()==Definition::TypeClass || (d->definitionType()==Definition::TypeMember && - (((MemberDef*)d)->isTypedef() || ((MemberDef*)d)->isEnumerate()) + ((dynamic_cast<MemberDef*>(d))->isTypedef() || (dynamic_cast<MemberDef*>(d))->isEnumerate()) ) ) { @@ -1240,7 +1245,7 @@ static void getResolvedSymbol(const Definition *scope, // see if we are dealing with a class or a typedef if (d->definitionType()==Definition::TypeClass) // d is a class { - ClassDef *cd = (ClassDef *)d; + ClassDef *cd = dynamic_cast<ClassDef *>(d); //printf("cd=%s\n",cd->name().data()); if (!cd->isTemplateArgument()) // skip classes that // are only there to @@ -1285,7 +1290,7 @@ static void getResolvedSymbol(const Definition *scope, } else if (d->definitionType()==Definition::TypeMember) { - MemberDef *md = (MemberDef *)d; + MemberDef *md = dynamic_cast<MemberDef *>(d); //printf(" member isTypedef()=%d\n",md->isTypedef()); if (md->isTypedef()) // d is a typedef { @@ -1303,8 +1308,8 @@ static void getResolvedSymbol(const Definition *scope, QCString spec; QCString type; minDistance=distance; - MemberDef *enumType = 0; - ClassDef *cd = newResolveTypedef(fileScope,md,&enumType,&spec,&type,actTemplParams); + const MemberDef *enumType = 0; + const ClassDef *cd = newResolveTypedef(fileScope,md,&enumType,&spec,&type,actTemplParams); if (cd) // type resolves to a class { //printf(" bestTypeDef=%p spec=%s type=%s\n",md,spec.data(),type.data()); @@ -1374,10 +1379,10 @@ static void getResolvedSymbol(const Definition *scope, * match against the input name. Can recursively call itself when * resolving typedefs. */ -static ClassDef *getResolvedClassRec(const Definition *scope, +static const ClassDef *getResolvedClassRec(const Definition *scope, const FileDef *fileScope, const char *n, - MemberDef **pTypeDef, + const MemberDef **pTypeDef, QCString *pTemplSpec, QCString *pResolvedType ) @@ -1496,8 +1501,8 @@ static ClassDef *getResolvedClassRec(const Definition *scope, Doxygen::lookupCache->insert(key,new LookupInfo); } - ClassDef *bestMatch=0; - MemberDef *bestTypedef=0; + const ClassDef *bestMatch=0; + const MemberDef *bestTypedef=0; QCString bestTemplSpec; QCString bestResolvedType; int minDistance=10000; // init at "infinite" @@ -1563,10 +1568,10 @@ static ClassDef *getResolvedClassRec(const Definition *scope, * Loops through scope and each of its parent scopes looking for a * match against the input name. */ -ClassDef *getResolvedClass(const Definition *scope, +const ClassDef *getResolvedClass(const Definition *scope, const FileDef *fileScope, const char *n, - MemberDef **pTypeDef, + const MemberDef **pTypeDef, QCString *pTemplSpec, bool mayBeUnlinkable, bool mayBeHidden, @@ -1590,7 +1595,7 @@ ClassDef *getResolvedClass(const Definition *scope, // n, // mayBeUnlinkable // ); - ClassDef *result; + const ClassDef *result; if (optimizeOutputVhdl) { result = getClass(n); @@ -1672,6 +1677,7 @@ struct CharAroundSpace charMap['='].after=FALSE; charMap[' '].after=FALSE; + charMap['['].after=FALSE; charMap[']'].after=FALSE; charMap['\t'].after=FALSE; charMap['\n'].after=FALSE; @@ -1707,7 +1713,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) // improve the performance of this function static char *growBuf = 0; static int growBufLen = 0; - if (s.length()*3>growBufLen) // For input character we produce at most 3 output characters, + if ((int)s.length()*3>growBufLen) // For input character we produce at most 3 output characters, { growBufLen = s.length()*3; growBuf = (char *)realloc(growBuf,growBufLen+1); // add 1 for 0-terminator @@ -1847,7 +1853,8 @@ QCString removeRedundantWhiteSpace(const QCString &s) case '*': if (i>0 && pc!=' ' && pc!='\t' && pc!=':' && pc!='*' && pc!='&' && pc!='(' && pc!='/' && - pc!='.' && (osp<9 || !(pc=='>' && osp==11))) + pc!='.' && osp<9 + ) // avoid splitting &&, **, .*, operator*, operator->* { *dst++=' '; @@ -1855,7 +1862,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) *dst++=c; break; case '&': - if (i>0 && isId(pc)) + if (i>0 && isId(pc) && osp<9) { if (nc != '=') // avoid splitting operator&= @@ -1868,7 +1875,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) case '@': // '@name' -> ' @name' case '$': // '$name' -> ' $name' case '\'': // ''name' -> '' name' - if (i>0 && i<l-1 && pc!='=' && pc!=':' && !isspace(pc) && + if (i>0 && i<l-1 && pc!='=' && pc!=':' && !isspace((uchar)pc) && isId(nc) && osp<8) // ")id" -> ") id" { *dst++=' '; @@ -1895,7 +1902,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) if (g_charAroundSpace.charMap[(uchar)pc].before && g_charAroundSpace.charMap[(uchar)nc].after && !(pc==',' && nc=='.') && - (osp<8 || (osp>=8 && pc!='"' && isId(nc)) || (osp>=8 && pc!='"' && nc!='"')) + (osp<8 || (osp>=8 && isId(pc) && isId(nc))) // e.g. 'operator >>' -> 'operator>>', // 'operator "" _x' -> 'operator""_x', // but not 'operator int' -> 'operatorint' @@ -1912,14 +1919,14 @@ QCString removeRedundantWhiteSpace(const QCString &s) default: *dst++=c; if (c=='t' && csp==5 && i<l-1 && // found 't' in 'const' - !(isId(nc) || nc==')' || nc==',' || isspace(nc)) + !(isId(nc) || nc==')' || nc==',' || isspace((uchar)nc)) ) // prevent const ::A from being converted to const::A { *dst++=' '; csp=0; } else if (c=='l' && vsp==7 && i<l-1 && // found 'l' in 'virtual' - !(isId(nc) || nc==')' || nc==',' || isspace(nc)) + !(isId(nc) || nc==')' || nc==',' || isspace((uchar)nc)) ) // prevent virtual ::A from being converted to virtual::A { *dst++=' '; @@ -2011,7 +2018,7 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope, const char *text, bool autoBreak,bool external, bool keepSpaces,int indentLevel) { - //printf("linkify=`%s'\n",text); + //printf("linkify='%s'\n",text); static QRegExp regExp("[a-z_A-Z\\x80-\\xFF][~!a-z_A-Z0-9$\\\\.:\\x80-\\xFF]*"); static QRegExp regExpSplit("(?!:),"); QCString txtStr=text; @@ -2027,12 +2034,17 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope, int floatingIndex=0; if (strLen==0) return; // read a word from the text string - while ((newIndex=regExp.match(txtStr,index,&matchLen))!=-1 && - (newIndex==0 || !(txtStr.at(newIndex-1)>='0' && txtStr.at(newIndex-1)<='9')) // avoid matching part of hex numbers - ) + while ((newIndex=regExp.match(txtStr,index,&matchLen))!=-1) { - // add non-word part to the result floatingIndex+=newIndex-skipIndex+matchLen; + if (newIndex>0 && txtStr.at(newIndex-1)=='0') // ignore hex numbers (match x00 in 0x00) + { + out.writeString(txtStr.mid(skipIndex,newIndex+matchLen-skipIndex),keepSpaces); + skipIndex=index=newIndex+matchLen; + continue; + } + + // add non-word part to the result bool insideString=FALSE; int i; for (i=index;i<newIndex;i++) @@ -2076,14 +2088,14 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope, bool found=FALSE; if (!insideString) { - ClassDef *cd=0; - FileDef *fd=0; - MemberDef *md=0; - NamespaceDef *nd=0; - GroupDef *gd=0; + const MemberDef *md=0; + const ClassDef *cd=0; + const FileDef *fd=0; + const NamespaceDef *nd=0; + const GroupDef *gd=0; //printf("** Match word '%s'\n",matchWord.data()); - MemberDef *typeDef=0; + const MemberDef *typeDef=0; cd=getResolvedClass(scope,fileScope,matchWord,&typeDef); if (typeDef) // First look at typedef then class, see bug 584184. { @@ -2248,12 +2260,12 @@ void writeExample(OutputList &ol,ExampleSDict *ed) } -QCString argListToString(ArgumentList *al,bool useCanonicalType,bool showDefVals) +QCString argListToString(const ArgumentList *al,bool useCanonicalType,bool showDefVals) { QCString result; if (al==0) return result; ArgumentListIterator ali(*al); - Argument *a=ali.current(); + const Argument *a=ali.current(); result+="("; while (a) { @@ -2296,13 +2308,13 @@ QCString argListToString(ArgumentList *al,bool useCanonicalType,bool showDefVals return removeRedundantWhiteSpace(result); } -QCString tempArgListToString(ArgumentList *al,SrcLangExt lang) +QCString tempArgListToString(const ArgumentList *al,SrcLangExt lang) { QCString result; if (al==0) return result; result="<"; ArgumentListIterator ali(*al); - Argument *a=ali.current(); + const Argument *a=ali.current(); while (a) { if (!a->name.isEmpty()) // add template argument name @@ -2555,7 +2567,7 @@ QCString fileToString(const char *name,bool filter,bool isSourceCode) QFileInfo fi(name); if (!fi.exists() || !fi.isFile()) { - err("file `%s' not found\n",name); + err("file '%s' not found\n",name); return ""; } BufStr buf(fi.size()); @@ -2573,7 +2585,7 @@ QCString fileToString(const char *name,bool filter,bool isSourceCode) } if (!fileOpened) { - err("cannot open file `%s' for reading\n",name); + err("cannot open file '%s' for reading\n",name); } return ""; } @@ -2630,7 +2642,7 @@ QCString yearToString() //---------------------------------------------------------------------- // recursive function that returns the number of branches in the -// inheritance tree that the base class `bcd' is below the class `cd' +// inheritance tree that the base class 'bcd' is below the class 'cd' int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level) { @@ -2661,7 +2673,7 @@ int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level) return m; } -Protection classInheritedProtectionLevel(ClassDef *cd,ClassDef *bcd,Protection prot,int level) +Protection classInheritedProtectionLevel(const ClassDef *cd,const ClassDef *bcd,Protection prot,int level) { if (bcd->categoryOf()) // use class that is being extended in case of // an Objective-C category @@ -2680,7 +2692,7 @@ Protection classInheritedProtectionLevel(ClassDef *cd,ClassDef *bcd,Protection p else if (cd->baseClasses()) { BaseClassListIterator bcli(*cd->baseClasses()); - BaseClassDef *bcdi; + const BaseClassDef *bcdi; for (;(bcdi=bcli.current()) && prot!=Private;++bcli) { Protection baseProt = classInheritedProtectionLevel(bcdi->classDef,bcd,bcdi->prot,level+1); @@ -2701,7 +2713,7 @@ exit: // printf("("); // for (;(a=ali.current());++ali) // { -// printf("t=`%s' n=`%s' v=`%s' ",a->type.data(),!a->name.isEmpty()>0?a->name.data():"",!a->defval.isEmpty()>0?a->defval.data():""); +// printf("t='%s' n='%s' v='%s' ",a->type.data(),!a->name.isEmpty()>0?a->name.data():"",!a->defval.isEmpty()>0?a->defval.data():""); // } // printf(")"); //} @@ -2847,7 +2859,7 @@ static QCString trimScope(const QCString &name,const QCString &s) { QCString tmp; QCString scope=name.left(scopeOffset)+"::"; - //printf("Trying with scope=`%s'\n",scope.data()); + //printf("Trying with scope='%s'\n",scope.data()); int i,p=0,l; while ((i=findScopePattern(scope,result,p,&l))!=-1) // for each occurrence @@ -2867,7 +2879,7 @@ static QCString trimScope(const QCString &name,const QCString &s) void trimBaseClassScope(BaseClassList *bcl,QCString &s,int level=0) { - //printf("trimBaseClassScope level=%d `%s'\n",level,s.data()); + //printf("trimBaseClassScope level=%d '%s'\n",level,s.data()); BaseClassListIterator bcli(*bcl); BaseClassDef *bcd; for (;(bcd=bcli.current());++bcli) @@ -2881,7 +2893,7 @@ void trimBaseClassScope(BaseClassList *bcl,QCString &s,int level=0) s.length()-spos-cd->name().length()-2 ); } - //printf("base class `%s'\n",cd->name().data()); + //printf("base class '%s'\n",cd->name().data()); if (cd->baseClasses()) trimBaseClassScope(cd->baseClasses(),s,level+1); } @@ -3038,7 +3050,7 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA, NamespaceSDict *usingNamespaces, SDict<Definition> *usingClasses) { - //printf("match argument start `%s|%s' <-> `%s|%s' using nsp=%p class=%p\n", + //printf("match argument start '%s|%s' <-> '%s|%s' using nsp=%p class=%p\n", // srcA->type.data(),srcA->name.data(), // dstA->type.data(),dstA->name.data(), // usingNamespaces, @@ -3100,7 +3112,7 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA, //srcAType=stripTemplateSpecifiersFromScope(srcAType,FALSE); //dstAType=stripTemplateSpecifiersFromScope(dstAType,FALSE); - //printf("srcA=`%s|%s' dstA=`%s|%s'\n",srcAType.data(),srcAName.data(), + //printf("srcA='%s|%s' dstA='%s|%s'\n",srcAType.data(),srcAName.data(), // dstAType.data(),dstAName.data()); if (srcA->array!=dstA->array) // nomatch for char[] against char @@ -3125,7 +3137,7 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA, { srcAType=trimScope(className,srcAType); dstAType=trimScope(className,dstAType); - //printf("trimScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data()); + //printf("trimScope: '%s' <=> '%s'\n",srcAType.data(),dstAType.data()); ClassDef *cd; if (!namespaceName.isEmpty()) cd=getClass(namespaceName+"::"+className); @@ -3136,7 +3148,7 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA, trimBaseClassScope(cd->baseClasses(),srcAType); trimBaseClassScope(cd->baseClasses(),dstAType); } - //printf("trimBaseClassScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data()); + //printf("trimBaseClassScope: '%s' <=> '%s'\n",srcAType.data(),dstAType.data()); } if (!namespaceName.isEmpty()) { @@ -3229,7 +3241,7 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA, while (dstPos<dstATypeLen && isId(dstAType.at(dstPos))) dstPos++; // if nothing more follows for both types then we assume we have - // found a match. Note that now `signed int' and `signed' match, but + // found a match. Note that now 'signed int' and 'signed' match, but // seeing that int is not a name can only be done by looking at the // semantics. @@ -3447,9 +3459,9 @@ static QCString stripDeclKeywords(const QCString &s) } // forward decl for circular dependencies -static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type); +static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCString type); -QCString getCanonicalTemplateSpec(Definition *d,FileDef *fs,const QCString& spec) +QCString getCanonicalTemplateSpec(const Definition *d,const FileDef *fs,const QCString& spec) { QCString templSpec = spec.stripWhiteSpace(); @@ -3470,7 +3482,7 @@ QCString getCanonicalTemplateSpec(Definition *d,FileDef *fs,const QCString& spec static QCString getCanonicalTypeForIdentifier( - Definition *d,FileDef *fs,const QCString &word, + const Definition *d,const FileDef *fs,const QCString &word, QCString *tSpec,int count=0) { if (count>10) return word; // oops recursion @@ -3491,8 +3503,8 @@ static QCString getCanonicalTypeForIdentifier( //printf("getCanonicalTypeForIdentifier(%s,[%s->%s]) start\n", // word.data(),tSpec?tSpec->data():"<none>",templSpec.data()); - ClassDef *cd = 0; - MemberDef *mType = 0; + const ClassDef *cd = 0; + const MemberDef *mType = 0; QCString ts; QCString resolvedType; @@ -3606,7 +3618,7 @@ static QCString getCanonicalTypeForIdentifier( return result; } -static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type) +static QCString extractCanonicalType(const Definition *d,const FileDef *fs,QCString type) { type = type.stripWhiteSpace(); @@ -3676,7 +3688,7 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type) return removeRedundantWhiteSpace(canType); } -static QCString extractCanonicalArgType(Definition *d,FileDef *fs,const Argument *arg) +static QCString extractCanonicalArgType(const Definition *d,const FileDef *fs,const Argument *arg) { QCString type = arg->type.stripWhiteSpace(); QCString name = arg->name; @@ -3700,11 +3712,11 @@ static QCString extractCanonicalArgType(Definition *d,FileDef *fs,const Argument } static bool matchArgument2( - Definition *srcScope,FileDef *srcFileScope,Argument *srcA, - Definition *dstScope,FileDef *dstFileScope,Argument *dstA + const Definition *srcScope,const FileDef *srcFileScope,Argument *srcA, + const Definition *dstScope,const FileDef *dstFileScope,Argument *dstA ) { - //printf(">> match argument: %s::`%s|%s' (%s) <-> %s::`%s|%s' (%s)\n", + //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(), // dstScope ? dstScope->name().data() : "", @@ -3761,10 +3773,9 @@ static bool matchArgument2( // new algorithm for argument matching -bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *srcAl, - Definition *dstScope,FileDef *dstFileScope,ArgumentList *dstAl, - bool checkCV - ) +bool matchArguments2(const Definition *srcScope,const FileDef *srcFileScope,const ArgumentList *srcAl, + const Definition *dstScope,const FileDef *dstFileScope,const ArgumentList *dstAl, + bool checkCV) { //printf("*** matchArguments2\n"); ASSERT(srcScope!=0 && dstScope!=0); @@ -3790,7 +3801,7 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr { // special case for finding match between func() and func(void) Argument *a=new Argument; a->type = "void"; - srcAl->append(a); + const_cast<ArgumentList*>(srcAl)->append(a); MATCH return TRUE; } @@ -3799,7 +3810,7 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr { // special case for finding match between func(void) and func() Argument *a=new Argument; a->type = "void"; - dstAl->append(a); + const_cast<ArgumentList*>(dstAl)->append(a); MATCH return TRUE; } @@ -3854,7 +3865,7 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr // pre: the types of the arguments in the list should match. void mergeArguments(ArgumentList *srcAl,ArgumentList *dstAl,bool forceNameOverwrite) { - //printf("mergeArguments `%s', `%s'\n", + //printf("mergeArguments '%s', '%s'\n", // argListToString(srcAl).data(),argListToString(dstAl).data()); if (srcAl==0 || dstAl==0 || srcAl->count()!=dstAl->count()) @@ -3868,12 +3879,12 @@ void mergeArguments(ArgumentList *srcAl,ArgumentList *dstAl,bool forceNameOverwr { if (srcA->defval.isEmpty() && !dstA->defval.isEmpty()) { - //printf("Defval changing `%s'->`%s'\n",srcA->defval.data(),dstA->defval.data()); + //printf("Defval changing '%s'->'%s'\n",srcA->defval.data(),dstA->defval.data()); srcA->defval=dstA->defval.copy(); } else if (!srcA->defval.isEmpty() && dstA->defval.isEmpty()) { - //printf("Defval changing `%s'->`%s'\n",dstA->defval.data(),srcA->defval.data()); + //printf("Defval changing '%s'->'%s'\n",dstA->defval.data(),srcA->defval.data()); dstA->defval=srcA->defval.copy(); } @@ -3895,15 +3906,15 @@ void mergeArguments(ArgumentList *srcAl,ArgumentList *dstAl,bool forceNameOverwr //printf("1. merging %s:%s <-> %s:%s\n",srcA->type.data(),srcA->name.data(),dstA->type.data(),dstA->name.data()); if (srcA->name.isEmpty() && !dstA->name.isEmpty()) { - //printf("type: `%s':=`%s'\n",srcA->type.data(),dstA->type.data()); - //printf("name: `%s':=`%s'\n",srcA->name.data(),dstA->name.data()); + //printf("type: '%s':='%s'\n",srcA->type.data(),dstA->type.data()); + //printf("name: '%s':='%s'\n",srcA->name.data(),dstA->name.data()); srcA->type = dstA->type.copy(); srcA->name = dstA->name.copy(); } else if (!srcA->name.isEmpty() && dstA->name.isEmpty()) { - //printf("type: `%s':=`%s'\n",dstA->type.data(),srcA->type.data()); - //printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data()); + //printf("type: '%s':='%s'\n",dstA->type.data(),srcA->type.data()); + //printf("name: '%s':='%s'\n",dstA->name.data(),srcA->name.data()); dstA->type = srcA->type.copy(); dstA->name = dstA->name.copy(); } @@ -3957,15 +3968,15 @@ void mergeArguments(ArgumentList *srcAl,ArgumentList *dstAl,bool forceNameOverwr j2=dstA->type.length()-i2-2; if (i1!=-1 && i2==-1 && srcA->type.right(j1)==dstA->type) { - //printf("type: `%s':=`%s'\n",dstA->type.data(),srcA->type.data()); - //printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data()); + //printf("type: '%s':='%s'\n",dstA->type.data(),srcA->type.data()); + //printf("name: '%s':='%s'\n",dstA->name.data(),srcA->name.data()); dstA->type = srcA->type.left(i1+2)+dstA->type; dstA->name = dstA->name.copy(); } else if (i1==-1 && i2!=-1 && dstA->type.right(j2)==srcA->type) { - //printf("type: `%s':=`%s'\n",srcA->type.data(),dstA->type.data()); - //printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data()); + //printf("type: '%s':='%s'\n",srcA->type.data(),dstA->type.data()); + //printf("name: '%s':='%s'\n",dstA->name.data(),srcA->name.data()); srcA->type = dstA->type.left(i2+2)+srcA->type; srcA->name = dstA->name.copy(); } @@ -3977,7 +3988,7 @@ void mergeArguments(ArgumentList *srcAl,ArgumentList *dstAl,bool forceNameOverwr { dstA->docs = srcA->docs.copy(); } - //printf("Merge argument `%s|%s' `%s|%s'\n", + //printf("Merge argument '%s|%s' '%s|%s'\n", // srcA->type.data(),srcA->name.data(), // dstA->type.data(),dstA->name.data()); } @@ -3986,20 +3997,20 @@ void mergeArguments(ArgumentList *srcAl,ArgumentList *dstAl,bool forceNameOverwr static void findMembersWithSpecificName(MemberName *mn, const char *args, bool checkStatics, - FileDef *currentFile, + const FileDef *currentFile, bool checkCV, const char *forceTagFile, QList<MemberDef> &members) { - //printf(" Function with global scope name `%s' args=`%s'\n", + //printf(" Function with global scope name '%s' args='%s'\n", // mn->memberName(),args); MemberNameIterator mli(*mn); - MemberDef *md; + const MemberDef *md = 0; for (mli.toFirst();(md=mli.current());++mli) { - FileDef *fd=md->getFileDef(); - GroupDef *gd=md->getGroupDef(); - //printf(" md->name()=`%s' md->args=`%s' fd=%p gd=%p current=%p ref=%s\n", + const FileDef *fd=md->getFileDef(); + const GroupDef *gd=md->getGroupDef(); + //printf(" md->name()='%s' md->args='%s' fd=%p gd=%p current=%p ref=%s\n", // md->name().data(),args,fd,gd,currentFile,md->getReference().data()); if ( ((gd && gd->isLinkable()) || (fd && fd->isLinkable()) || md->isReference()) && @@ -4013,7 +4024,7 @@ static void findMembersWithSpecificName(MemberName *mn, if (args && !md->isDefine() && qstrcmp(args,"()")!=0) { argList=new ArgumentList; - ArgumentList *mdAl = md->argumentList(); + const ArgumentList *mdAl = md->argumentList(); stringToArgumentList(args,argList); match=matchArguments2( md->getOuterScope(),fd,mdAl, @@ -4031,11 +4042,11 @@ static void findMembersWithSpecificName(MemberName *mn, } /*! - * Searches for a member definition given its name `memberName' as a string. + * Searches for a member definition given its name 'memberName' as a string. * memberName may also include a (partial) scope to indicate the scope * in which the member is located. * - * The parameter `scName' is a string representing the name of the scope in + * The parameter 'scName' is a string representing the name of the scope in * which the link was found. * * In case of a function args contains a string representation of the @@ -4044,24 +4055,24 @@ static void findMembersWithSpecificName(MemberName *mn, * * The function returns TRUE if the member is known and documented or * FALSE if it is not. - * If TRUE is returned parameter `md' contains a pointer to the member - * definition. Furthermore exactly one of the parameter `cd', `nd', or `fd' + * If TRUE is returned parameter 'md' contains a pointer to the member + * definition. Furthermore exactly one of the parameter 'cd', 'nd', or 'fd' * will be non-zero: - * - if `cd' is non zero, the member was found in a class pointed to by cd. - * - if `nd' is non zero, the member was found in a namespace pointed to by nd. - * - if `fd' is non zero, the member was found in the global namespace of + * - if 'cd' is non zero, the member was found in a class pointed to by cd. + * - if 'nd' is non zero, the member was found in a namespace pointed to by nd. + * - if 'fd' is non zero, the member was found in the global namespace of * file fd. */ bool getDefs(const QCString &scName, const QCString &mbName, const char *args, - MemberDef *&md, - ClassDef *&cd, - FileDef *&fd, - NamespaceDef *&nd, - GroupDef *&gd, + const MemberDef *&md, + const ClassDef *&cd, + const FileDef *&fd, + const NamespaceDef *&nd, + const GroupDef *&gd, bool forceEmptyScope, - FileDef *currentFile, + const FileDef *currentFile, bool checkCV, const char *forceTagFile ) @@ -4104,7 +4115,7 @@ bool getDefs(const QCString &scName, // handle special the case where both scope name and member scope are equal if (mScope==scopeName) scopeName.resize(0); - //printf("mScope=`%s' mName=`%s'\n",mScope.data(),mName.data()); + //printf("mScope='%s' mName='%s'\n",mScope.data(),mName.data()); MemberName *mn = Doxygen::memberNameSDict->find(mName); //printf("mName=%s mn=%p\n",mName.data(),mn); @@ -4126,8 +4137,8 @@ bool getDefs(const QCString &scName, className=mScope; } - MemberDef *tmd=0; - ClassDef *fcd=getResolvedClass(Doxygen::globalScope,0,className,&tmd); + const MemberDef *tmd=0; + const ClassDef *fcd=getResolvedClass(Doxygen::globalScope,0,className,&tmd); if (fcd==0 && className.find('<')!=-1) // try without template specifiers as well { QCString nameWithoutTemplates = stripTemplateSpecifiersFromScope(className,FALSE); @@ -4224,7 +4235,7 @@ bool getDefs(const QCString &scName, if (tmd && tmd->isEnumerate() && tmd->isStrong()) // scoped enum { //printf("Found scoped enum!\n"); - MemberList *tml = tmd->enumFieldList(); + const MemberList *tml = tmd->enumFieldList(); if (tml) { MemberListIterator tmi(*tml); @@ -4305,7 +4316,7 @@ bool getDefs(const QCString &scName, // maybe an namespace, file or group member ? - //printf("Testing for global symbol scopeName=`%s' mScope=`%s' :: mName=`%s'\n", + //printf("Testing for global symbol scopeName='%s' mScope='%s' :: mName='%s'\n", // scopeName.data(),mScope.data(),mName.data()); if ((mn=Doxygen::functionNameSDict->find(mName))) // name is known { @@ -4329,16 +4340,16 @@ bool getDefs(const QCString &scName, fnd->isLinkable() ) { - //printf("Symbol inside existing namespace `%s' count=%d\n", + //printf("Symbol inside existing namespace '%s' count=%d\n", // namespaceName.data(),mn->count()); bool found=FALSE; MemberNameIterator mmli(*mn); - MemberDef *mmd; + const MemberDef *mmd; for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli) { //printf("mmd->getNamespaceDef()=%p fnd=%p\n", // mmd->getNamespaceDef(),fnd); - MemberDef *emd = mmd->getEnumScope(); + const MemberDef *emd = mmd->getEnumScope(); if (emd && emd->isStrong()) { //printf("yes match %s<->%s!\n",mScope.data(),emd->localName().data()); @@ -4357,14 +4368,14 @@ bool getDefs(const QCString &scName, return FALSE; } } - else if (mmd->getNamespaceDef()==fnd /* && mmd->isLinkable() */ ) + else if (mmd->getOuterScope()==fnd /* && mmd->isLinkable() */ ) { // namespace is found bool match=TRUE; ArgumentList *argList=0; if (args && qstrcmp(args,"()")!=0) { argList=new ArgumentList; - ArgumentList *mmdAl = mmd->argumentList(); + const ArgumentList *mmdAl = mmd->argumentList(); stringToArgumentList(args,argList); match=matchArguments2( mmd->getOuterScope(),mmd->getFileDef(),mmdAl, @@ -4397,7 +4408,7 @@ bool getDefs(const QCString &scName, } } } - if (found) + if (found) { if (!md->isLinkable()) { @@ -4407,7 +4418,7 @@ bool getDefs(const QCString &scName, } else { - gd=md->getGroupDef(); + gd=md->resolveAlias()->getGroupDef(); if (gd && gd->isLinkable()) nd=0; else gd=0; return TRUE; } @@ -4420,7 +4431,7 @@ bool getDefs(const QCString &scName, MemberDef *mmd; for (mmli.toFirst();(mmd=mmli.current());++mmli) { - MemberDef *tmd = mmd->getEnumScope(); + const MemberDef *tmd = mmd->getEnumScope(); //printf("try member %s tmd=%s\n",mmd->name().data(),tmd?tmd->name().data():"<none>"); int ni=namespaceName.findRev("::"); //printf("namespaceName=%s ni=%d\n",namespaceName.data(),ni); @@ -4470,11 +4481,11 @@ bool getDefs(const QCString &scName, MemberNameIterator mni(*mn); for (mni.toLast();(md=mni.current());--mni) { - //printf("Found member `%s'\n",md->name().data()); - //printf("member is linkable md->name()=`%s'\n",md->name().data()); + //printf("Found member '%s'\n",md->name().data()); + //printf("member is linkable md->name()='%s'\n",md->name().data()); fd=md->getFileDef(); gd=md->getGroupDef(); - MemberDef *tmd = md->getEnumScope(); + const MemberDef *tmd = md->getEnumScope(); if ( (gd && gd->isLinkable()) || (fd && fd->isLinkable()) || (tmd && tmd->isStrong()) @@ -4544,7 +4555,7 @@ static bool getScopeDefs(const char *docScope,const char *scope, cd=0;nd=0; QCString scopeName=scope; - //printf("getScopeDefs: docScope=`%s' scope=`%s'\n",docScope,scope); + //printf("getScopeDefs: docScope='%s' scope='%s'\n",docScope,scope); if (scopeName.isEmpty()) return FALSE; bool explicitGlobalScope=FALSE; @@ -4553,6 +4564,10 @@ static bool getScopeDefs(const char *docScope,const char *scope, scopeName=scopeName.right(scopeName.length()-2); explicitGlobalScope=TRUE; } + if (scopeName.isEmpty()) + { + return FALSE; + } QCString docScopeName=docScope; int scopeOffset=explicitGlobalScope ? 0 : docScopeName.length(); @@ -4601,10 +4616,10 @@ static bool isLowerCase(QCString &s) bool resolveRef(/* in */ const char *scName, /* in */ const char *name, /* in */ bool inSeeBlock, - /* out */ Definition **resContext, - /* out */ MemberDef **resMember, + /* out */ const Definition **resContext, + /* out */ const MemberDef **resMember, bool lookForSpecialization, - FileDef *currentFile, + const FileDef *currentFile, bool checkScope ) { @@ -4703,11 +4718,11 @@ bool resolveRef(/* in */ const char *scName, QCString scopeStr=scName; - MemberDef *md = 0; - ClassDef *cd = 0; - FileDef *fd = 0; - NamespaceDef *nd = 0; - GroupDef *gd = 0; + const MemberDef *md = 0; + const ClassDef *cd = 0; + const FileDef *fd = 0; + const NamespaceDef *nd = 0; + const GroupDef *gd = 0; // check if nameStr is a member or global. //printf("getDefs(scope=%s,name=%s,args=%s checkScope=%d)\n", @@ -4805,10 +4820,10 @@ QCString linkToText(SrcLangExt lang,const char *link,bool isFileName) #if 0 /* * generate a reference to a class, namespace or member. - * `scName' is the name of the scope that contains the documentation + * 'scName' is the name of the scope that contains the documentation * string that is returned. - * `name' is the name that we want to link to. - * `name' may have five formats: + * 'name' is the name that we want to link to. + * 'name' may have the following formats: * 1) "ScopeName" * 2) "memberName()" one of the (overloaded) function or define * with name memberName. @@ -4875,7 +4890,7 @@ bool generateRef(OutputDocInterface &od,const char *scName, bool resolveLink(/* in */ const char *scName, /* in */ const char *lr, /* in */ bool /*inSeeBlock*/, - /* out */ Definition **resContext, + /* out */ const Definition **resContext, /* out */ QCString &resAnchor ) { @@ -4884,12 +4899,12 @@ bool resolveLink(/* in */ const char *scName, QCString linkRef=lr; QCString linkRefWithoutTemplates = stripTemplateSpecifiersFromScope(linkRef,FALSE); //printf("ResolveLink linkRef=%s\n",lr); - FileDef *fd; - GroupDef *gd; - PageDef *pd; - ClassDef *cd; - DirDef *dir; - NamespaceDef *nd; + const FileDef *fd; + const GroupDef *gd; + const PageDef *pd; + const ClassDef *cd; + const DirDef *dir; + const NamespaceDef *nd; SectionInfo *si=0; bool ambig; if (linkRef.isEmpty()) // no reference name! @@ -4898,7 +4913,7 @@ bool resolveLink(/* in */ const char *scName, } else if ((pd=Doxygen::pageSDict->find(linkRef))) // link to a page { - GroupDef *gd = pd->getGroupDef(); + const GroupDef *gd = pd->getGroupDef(); if (gd) { if (!pd->name().isEmpty()) si=Doxygen::sectionDict->find(pd->name()); @@ -4970,7 +4985,7 @@ bool resolveLink(/* in */ const char *scName, } else // probably a member reference { - MemberDef *md; + const MemberDef *md = 0; bool res = resolveRef(scName,lr,TRUE,resContext,&md); if (md) resAnchor=md->anchor(); return res; @@ -4980,8 +4995,8 @@ bool resolveLink(/* in */ const char *scName, //---------------------------------------------------------------------- // General function that generates the HTML code for a reference to some -// file, class or member from text `lr' within the context of class `clName'. -// This link has the text 'lt' (if not 0), otherwise `lr' is used as a +// file, class or member from text 'lr' within the context of class 'clName'. +// This link has the text 'lt' (if not 0), otherwise 'lr' is used as a // basis for the link's text. // returns TRUE if a link could be generated. @@ -4989,7 +5004,7 @@ bool generateLink(OutputDocInterface &od,const char *clName, const char *lr,bool inSeeBlock,const char *lt) { //printf("generateLink(clName=%s,lr=%s,lr=%s)\n",clName,lr,lt); - Definition *compound; + const Definition *compound = 0; //PageDef *pageDef=0; QCString anchor,linkText=linkToText(SrcLangExt_Unknown,lt,FALSE); //printf("generateLink linkText=%s\n",linkText.data()); @@ -5001,7 +5016,7 @@ bool generateLink(OutputDocInterface &od,const char *clName, compound->definitionType()==Definition::TypeGroup /* is group */ ) { - linkText=((GroupDef *)compound)->groupTitle(); // use group's title as link + linkText=(dynamic_cast<const GroupDef *>(compound))->groupTitle(); // use group's title as link } else if (compound->definitionType()==Definition::TypeFile) { @@ -5126,7 +5141,7 @@ FileDef *findFileDef(const FileNameDict *fnDict,const char *n,bool &ambig) if (fn->count()==1) { FileDef *fd = fn->getFirst(); -#if defined(_WIN32) || defined(__MACOSX__) // Windows or MacOSX +#if defined(_WIN32) || defined(__MACOSX__) || defined(__CYGWIN__) // Windows or MacOSX bool isSamePath = fd->getPath().right(path.length()).lower()==path.lower(); #else // Unix bool isSamePath = fd->getPath().right(path.length())==path; @@ -5326,7 +5341,7 @@ QCString substituteKeywords(const QCString &s,const char *title, result = substitute(result,"$datetime",dateToString(TRUE)); result = substitute(result,"$date",dateToString(FALSE)); result = substitute(result,"$year",yearToString()); - result = substitute(result,"$doxygenversion",versionString); + result = substitute(result,"$doxygenversion",getVersion()); result = substitute(result,"$projectname",projName); result = substitute(result,"$projectnumber",projNum); result = substitute(result,"$projectbrief",projBrief); @@ -5373,12 +5388,12 @@ static void initBaseClassHierarchy(BaseClassList *bcl) { initBaseClassHierarchy(cd->baseClasses()); } - cd->visited=FALSE; + cd->setVisited(FALSE); } } //---------------------------------------------------------------------------- -bool classHasVisibleChildren(ClassDef *cd) +bool classHasVisibleChildren(const ClassDef *cd) { BaseClassList *bcl; @@ -5413,21 +5428,21 @@ void initClassHierarchy(ClassSDict *cl) ClassDef *cd; for ( ; (cd=cli.current()); ++cli) { - cd->visited=FALSE; + cd->setVisited(FALSE); initBaseClassHierarchy(cd->baseClasses()); } } //---------------------------------------------------------------------------- -bool hasVisibleRoot(BaseClassList *bcl) +bool hasVisibleRoot(const BaseClassList *bcl) { if (bcl) { BaseClassListIterator bcli(*bcl); for ( ; bcli.current(); ++bcli) { - ClassDef *cd=bcli.current()->classDef; + const ClassDef *cd=bcli.current()->classDef; if (cd->isVisibleInHierarchy()) return TRUE; hasVisibleRoot(cd->baseClasses()); } @@ -5444,6 +5459,7 @@ QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscor static bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES); static GrowBuf growBuf; growBuf.clear(); + if (name==0) return ""; char c; const char *p=name; while ((c=*p++)!=0) @@ -5471,10 +5487,12 @@ QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscor case '(': growBuf.addStr("_07"); break; case ')': growBuf.addStr("_08"); break; case '+': growBuf.addStr("_09"); break; - case '=': growBuf.addStr("_0A"); break; - case '$': growBuf.addStr("_0B"); break; - case '\\': growBuf.addStr("_0C"); break; - case '@': growBuf.addStr("_0D"); break; + case '=': growBuf.addStr("_0a"); break; + case '$': growBuf.addStr("_0b"); break; + case '\\': growBuf.addStr("_0c"); break; + case '@': growBuf.addStr("_0d"); break; + case ']': growBuf.addStr("_0e"); break; + case '[': growBuf.addStr("_0f"); break; default: if (c<0) { @@ -5546,6 +5564,76 @@ QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscor return growBuf.get(); } +QCString unescapeCharsInString(const char *s) +{ + static bool caseSenseNames = Config_getBool(CASE_SENSE_NAMES); + QCString result; + const char *p = s; + if (p) + { + char c; + while ((c=*p++)) + { + if (c=='_') // 2 or 3 character escape + { + switch (*p) + { + case '_': result+=c; p++; break; // __ -> '_' + case '1': result+=':'; p++; break; // _1 -> ':' + case '2': result+='/'; p++; break; // _2 -> '/' + case '3': result+='<'; p++; break; // _3 -> '<' + case '4': result+='>'; p++; break; // _4 -> '>' + case '5': result+='*'; p++; break; // _5 -> '*' + case '6': result+='&'; p++; break; // _6 -> '&' + case '7': result+='|'; p++; break; // _7 -> '|' + case '8': result+='.'; p++; break; // _8 -> '.' + case '9': result+='!'; p++; break; // _9 -> '!' + case '0': // 3 character escape + switch (*(p+1)) + { + case '0': result+=','; p+=2; break; // _00 -> ',' + case '1': result+=' '; p+=2; break; // _01 -> ' ' + case '2': result+='{'; p+=2; break; // _02 -> '{' + case '3': result+='}'; p+=2; break; // _03 -> '}' + case '4': result+='?'; p+=2; break; // _04 -> '?' + case '5': result+='^'; p+=2; break; // _05 -> '^' + case '6': result+='%'; p+=2; break; // _06 -> '%' + case '7': result+='('; p+=2; break; // _07 -> '(' + case '8': result+=')'; p+=2; break; // _08 -> ')' + case '9': result+='+'; p+=2; break; // _09 -> '+' + case 'a': result+='='; p+=2; break; // _0a -> '=' + case 'b': result+='$'; p+=2; break; // _0b -> '$' + case 'c': result+='\\'; p+=2; break;// _0c -> '\' + case 'd': result+='@'; p+=2; break; // _0d -> '@' + case 'e': result+=']'; p+=2; break; // _0e -> ']' + case 'f': result+='['; p+=2; break; // _0f -> '[' + default: // unknown escape, just pass underscore character as-is + result+=c; + break; + } + break; + default: + if (!caseSenseNames && c>='a' && c<='z') // lower to upper case escape, _a -> 'A' + { + result+=toupper(*p); + p++; + } + else // unknown escape, pass underscore character as-is + { + result+=c; + } + break; + } + } + else // normal character; pass as is + { + result+=c; + } + } + } + return result; +} + /*! This function determines the file name on disk of an item * given its name, which could be a class name with template * arguments, so special characters need to be escaped. @@ -5715,7 +5803,7 @@ done: className=namespaceName.copy(); namespaceName.resize(0); } - //printf("extractNamespace `%s' => `%s|%s'\n",scopeName.data(), + //printf("extractNamespace '%s' => '%s|%s'\n",scopeName.data(), // className.data(),namespaceName.data()); if (/*className.right(2)=="-g" ||*/ className.right(2)=="-p") { @@ -5736,7 +5824,7 @@ QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &te ((cd=getClass(scope.left(si)))==0 || cd->templateArguments()==0) ) { - //printf("Tried `%s'\n",(scope.left(si)+templ).data()); + //printf("Tried '%s'\n",(scope.left(si)+templ).data()); pi=si+2; } if (si==-1) // not nested => append template specifier @@ -5748,7 +5836,7 @@ QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &te result=scope.left(si) + templ + scope.right(scope.length()-si); } } - //printf("insertTemplateSpecifierInScope(`%s',`%s')=%s\n", + //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n", // scope.data(),templ.data(),result.data()); return result; } @@ -5914,7 +6002,7 @@ QCString convertToId(const char *s) } /*! Converts a string to an XML-encoded string */ -QCString convertToXML(const char *s) +QCString convertToXML(const char *s, bool keepEntities) { static GrowBuf growBuf; growBuf.clear(); @@ -5927,7 +6015,30 @@ QCString convertToXML(const char *s) { case '<': growBuf.addStr("<"); break; case '>': growBuf.addStr(">"); break; - case '&': growBuf.addStr("&"); break; + case '&': if (keepEntities) + { + const char *e=p; + char ce; + while ((ce=*e++)) + { + if (ce==';' || (!(isId(ce) || ce=='#'))) break; + } + if (ce==';') // found end of an entity + { + // copy entry verbatim + growBuf.addChar(c); + while (p<e) growBuf.addChar(*p++); + } + else + { + growBuf.addStr("&"); + } + } + else + { + growBuf.addStr("&"); + } + break; case '\'': growBuf.addStr("'"); break; case '"': growBuf.addStr("""); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: @@ -6129,7 +6240,7 @@ QCString getOverloadDocs() void addMembersToMemberGroup(MemberList *ml, MemberGroupSDict **ppMemberGroupSDict, - Definition *context) + const Definition *context) { ASSERT(context!=0); //printf("addMemberToMemberGroup()\n"); @@ -6141,7 +6252,7 @@ void addMembersToMemberGroup(MemberList *ml, { if (md->isEnumerate()) // insert enum value of this enum into groups { - MemberList *fmdl=md->enumFieldList(); + const MemberList *fmdl=md->enumFieldList(); if (fmdl!=0) { MemberListIterator fmli(*fmdl); @@ -6299,7 +6410,7 @@ int extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCStri QCString normalizeNonTemplateArgumentsInString( const QCString &name, - Definition *context, + const Definition *context, const ArgumentList * formalArgs) { // skip until < @@ -6319,7 +6430,7 @@ QCString normalizeNonTemplateArgumentsInString( if (formalArgs) // check that n is not a formal template argument { ArgumentListIterator formAli(*formalArgs); - Argument *formArg; + const Argument *formArg; for (formAli.toFirst(); (formArg=formAli.current()) && !found; ++formAli @@ -6331,7 +6442,7 @@ QCString normalizeNonTemplateArgumentsInString( if (!found) { // try to resolve the type - ClassDef *cd = getResolvedClass(context,0,n); + const ClassDef *cd = getResolvedClass(context,0,n); if (cd) { result+=cd->name(); @@ -6631,7 +6742,7 @@ found: PageDef *addRelatedPage(const char *name,const QCString &ptitle, const QCString &doc, - QList<SectionInfo> * /*anchors*/, + const QList<SectionInfo> * /*anchors*/, const char *fileName,int startLine, const QList<ListItemInfo> *sli, GroupDef *gd, @@ -6643,9 +6754,11 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, //printf("addRelatedPage(name=%s gd=%p)\n",name,gd); if ((pd=Doxygen::pageSDict->find(name)) && !tagInfo) { + warn(fileName,startLine,"multiple use of page label '%s', (other occurrence: %s, line: %d)", + name,pd->docFile().data(),pd->docLine()); // append documentation block to the page. pd->setDocumentation(doc,fileName,startLine); - //printf("Adding page docs `%s' pi=%p name=%s\n",doc.data(),pd,name); + //printf("Adding page docs '%s' pi=%p name=%s\n",doc.data(),pd,name); // append (x)refitems to the page. pd->setRefItems(sli); } @@ -6658,7 +6771,7 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length()); QCString title=ptitle.stripWhiteSpace(); - pd=new PageDef(fileName,startLine,baseName,doc,title); + pd=createPageDef(fileName,startLine,baseName,doc,title); pd->setRefItems(sli); pd->setLanguage(lang); @@ -6669,12 +6782,12 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, pd->setFileName(tagInfo->fileName); } - //printf("Appending page `%s'\n",baseName.data()); + //printf("Appending page '%s'\n",baseName.data()); Doxygen::pageSDict->append(baseName,pd); if (gd) gd->addPage(pd); - if (!pd->title().isEmpty()) + if (pd->hasTitle()) { //outputList->writeTitle(pi->name,pi->title); @@ -6704,7 +6817,7 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, { si=new SectionInfo( file,-1,pd->name(),pd->title(),SectionInfo::Page,0,pd->getReference()); - //printf("si->label=`%s' si->definition=%s si->fileName=`%s'\n", + //printf("si->label='%s' si->definition=%s si->fileName='%s'\n", // si->label.data(),si->definition?si->definition->name().data():"<none>", // si->fileName.data()); //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,si->fileName.data()); @@ -6757,7 +6870,7 @@ void addRefItem(const QList<ListItemInfo> *sli, } } -bool recursivelyAddGroupListToTitle(OutputList &ol,Definition *d,bool root) +bool recursivelyAddGroupListToTitle(OutputList &ol,const Definition *d,bool root) { GroupList *groups = d->partOfGroups(); if (groups) // write list of group to which this definition belongs @@ -6790,7 +6903,7 @@ bool recursivelyAddGroupListToTitle(OutputList &ol,Definition *d,bool root) return false; } -void addGroupListToTitle(OutputList &ol,Definition *d) +void addGroupListToTitle(OutputList &ol,const Definition *d) { recursivelyAddGroupListToTitle(ol,d,TRUE); } @@ -6831,6 +6944,7 @@ void filterLatexString(FTextStream &t,const char *str, case '%': t << "\\%"; break; case '#': t << "\\#"; break; case '$': t << "\\$"; break; + case '-': t << "-\\/"; break; case '^': (usedTableLevels()>0) ? t << "\\string^" : t << (char)c; break; case '~': (usedTableLevels()>0) ? t << "\\string~" : t << (char)c; break; case ' ': if (keepSpaces) t << "~"; else t << ' '; @@ -6939,6 +7053,7 @@ void filterLatexString(FTextStream &t,const char *str, QCString latexEscapeLabelName(const char *s) { + if (s==0) return ""; QGString result; QCString tmp(qstrlen(s)+1); FTextStream t(&result); @@ -6976,6 +7091,7 @@ QCString latexEscapeLabelName(const char *s) QCString latexEscapeIndexChars(const char *s) { + if (s==0) return ""; QGString result; QCString tmp(qstrlen(s)+1); FTextStream t(&result); @@ -7014,6 +7130,7 @@ QCString latexEscapeIndexChars(const char *s) QCString latexEscapePDFString(const char *s) { + if (s==0) return ""; QGString result; FTextStream t(&result); const char *p=s; @@ -7038,6 +7155,7 @@ QCString latexEscapePDFString(const char *s) QCString latexFilterURL(const char *s) { + if (s==0) return ""; QGString result; FTextStream t(&result); const char *p=s; @@ -7047,6 +7165,7 @@ QCString latexFilterURL(const char *s) switch (c) { case '#': t << "\\#"; break; + case '%': t << "\\%"; break; default: t << c; break; @@ -7170,7 +7289,7 @@ bool findAndRemoveWord(QCString &s,const QCString &word) { if (i>0 && isspace((uchar)s.at(i-1))) i--,l++; - else if (i+l<(int)s.length() && isspace(s.at(i+l))) + else if (i+l<(int)s.length() && isspace((uchar)s.at(i+l))) l++; s = s.left(i)+s.mid(i+l); // remove word + spacing return TRUE; @@ -7382,27 +7501,31 @@ void addCodeOnlyMappings() SrcLangExt getLanguageFromFileName(const QCString& fileName) { - int i = fileName.findRev('.'); - if (i!=-1) // name has an extension - { - QCString extStr=fileName.right(fileName.length()-i).lower(); - if (!extStr.isEmpty()) // non-empty extension + QFileInfo fi(fileName); + QCString extName = fi.extension().lower().data(); + if (extName.isEmpty()) extName=".no_extension"; + if (extName.at(0)!='.') extName.prepend("."); + int *pVal=g_extLookup.find(extName.data()); + if (pVal) // listed extension { - int *pVal=g_extLookup.find(extStr); - if (pVal) // listed extension - { - //printf("getLanguageFromFileName(%s)=%x\n",extStr.data(),*pVal); - return (SrcLangExt)*pVal; - } + //printf("getLanguageFromFileName(%s)=%x\n",fi.extension().data(),*pVal); + return (SrcLangExt)*pVal; } - } //printf("getLanguageFromFileName(%s) not found!\n",fileName.data()); return SrcLangExt_Cpp; // not listed => assume C-ish language. } +QCString getFileNameExtension(QCString fn) +{ + if (fn.isEmpty()) return ""; + int lastDot = fn.findRev('.'); + if (lastDot!=-1) return fn.mid(lastDot); + return ""; +} + //-------------------------------------------------------------------------- -MemberDef *getMemberFromSymbol(Definition *scope,FileDef *fileScope, +MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fileScope, const char *n) { if (scope==0 || @@ -7451,7 +7574,7 @@ MemberDef *getMemberFromSymbol(Definition *scope,FileDef *fileScope, if (distance!=-1 && distance<minDistance) { minDistance = distance; - bestMatch = (MemberDef *)d; + bestMatch = dynamic_cast<MemberDef *>(d); //printf("new best match %s distance=%d\n",bestMatch->qualifiedName().data(),distance); } } @@ -7466,7 +7589,7 @@ MemberDef *getMemberFromSymbol(Definition *scope,FileDef *fileScope, if (distance!=-1 && distance<minDistance) { minDistance = distance; - bestMatch = (MemberDef *)d; + bestMatch = dynamic_cast<MemberDef *>(d); //printf("new best match %s distance=%d\n",bestMatch->qualifiedName().data(),distance); } } @@ -7474,7 +7597,7 @@ MemberDef *getMemberFromSymbol(Definition *scope,FileDef *fileScope, } /*! Returns true iff the given name string appears to be a typedef in scope. */ -bool checkIfTypedef(Definition *scope,FileDef *fileScope,const char *n) +bool checkIfTypedef(const Definition *scope,const FileDef *fileScope,const char *n) { MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n); @@ -7901,12 +8024,12 @@ QCString expandAlias(const QCString &aliasName,const QCString &aliasValue) return result; } -void writeTypeConstraints(OutputList &ol,Definition *d,ArgumentList *al) +void writeTypeConstraints(OutputList &ol,const Definition *d,const ArgumentList *al) { if (al==0) return; ol.startConstraintList(theTranslator->trTypeConstraints()); ArgumentListIterator ali(*al); - Argument *a; + const Argument *a; for (;(a=ali.current());++ali) { ol.startConstraintParam(); @@ -8097,8 +8220,8 @@ QCString filterTitle(const QCString &title) } //---------------------------------------------------------------------------- -// returns TRUE if the name of the file represented by `fi' matches -// one of the file patterns in the `patList' list. +// returns TRUE if the name of the file represented by 'fi' matches +// one of the file patterns in the 'patList' list. bool patternMatch(const QFileInfo &fi,const QStrList *patList) { @@ -8106,7 +8229,7 @@ bool patternMatch(const QFileInfo &fi,const QStrList *patList) bool found = FALSE; // For Windows/Mac, always do the case insensitive match -#if defined(_WIN32) || defined(__MACOSX__) +#if defined(_WIN32) || defined(__MACOSX__) || defined(__CYGWIN__) caseSenseNames = FALSE; #endif @@ -8132,7 +8255,7 @@ bool patternMatch(const QFileInfo &fi,const QStrList *patList) re.match(fp)!=-1 || re.match(afp)!=-1; if (found) break; - //printf("Matching `%s' against pattern `%s' found=%d\n", + //printf("Matching '%s' against pattern '%s' found=%d\n", // fi->fileName().data(),pattern.data(),found); } } @@ -8191,10 +8314,6 @@ QCString externalRef(const QCString &relPath,const QCString &ref,bool href) result.prepend(relPath); l+=relPath.length(); } - if (!href){ - result.prepend("doxygen=\""+ref+":"); - l+=10+ref.length(); - } if (l>0 && result.at(l-1)!='/') result+='/'; if (!href) result.append("\" "); } @@ -8426,16 +8545,25 @@ QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope) return "::"; } } - +QCString replaceScopeSeparator(QCString str) +{ + // we don't know about the language so we have to go for the worse + return substitute(substitute(str,"\\","::"),".","::"); // PHP and Java, CSharp, VHDL, Python +} +/** Checks whether the given url starts with a supported protocol */ +bool isURL(const QCString &url) +{ + QCString loc_url = url.stripWhiteSpace(); + return loc_url.left(5)=="http:" || loc_url.left(6)=="https:" || + loc_url.left(4)=="ftp:" || loc_url.left(5)=="file:"; +} /** Corrects URL \a url according to the relative path \a relPath. * Returns the corrected URL. For absolute URLs no correction will be done. */ QCString correctURL(const QCString &url,const QCString &relPath) { QCString result = url; - if (!relPath.isEmpty() && - url.left(5)!="http:" && url.left(6)!="https:" && - url.left(4)!="ftp:" && url.left(5)!="file:") + if (!relPath.isEmpty() && !isURL(url)) { result.prepend(relPath); } @@ -8523,7 +8651,7 @@ QCString stripIndentation(const QCString &s) } -bool fileVisibleInIndex(FileDef *fd,bool &genSourceFile) +bool fileVisibleInIndex(const FileDef *fd,bool &genSourceFile) { static bool allExternals = Config_getBool(ALLEXTERNALS); bool isDocFile = fd->isDocumentationFile(); @@ -8642,12 +8770,12 @@ uint getUtf8CodeToUpper( const QCString& s, int idx ) //-------------------------------------------------------------------------------------- -bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses,bool filterClasses,ClassDef::CompoundType ct) +bool namespaceHasVisibleChild(const NamespaceDef *nd,bool includeClasses,bool filterClasses,ClassDef::CompoundType ct) { if (nd->getNamespaceSDict()) { NamespaceSDict::Iterator cnli(*nd->getNamespaceSDict()); - NamespaceDef *cnd; + const NamespaceDef *cnd; for (cnli.toFirst();(cnd=cnli.current());++cnli) { if (cnd->isLinkableInProject() && cnd->localName().find('@')==-1) @@ -8662,7 +8790,7 @@ bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses,bool filterCl } if (includeClasses) { - ClassSDict *d = nd->getClassSDict(); + const ClassSDict *d = nd->getClassSDict(); if (filterClasses) { if (ct == ClassDef::Interface) @@ -8682,7 +8810,7 @@ bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses,bool filterCl if (d) { ClassSDict::Iterator cli(*d); - ClassDef *cd; + const ClassDef *cd; for (;(cd=cli.current());++cli) { if (cd->isLinkableInProject() && cd->templateMaster()==0) @@ -8697,7 +8825,7 @@ bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses,bool filterCl //---------------------------------------------------------------------------- -bool classVisibleInIndex(ClassDef *cd) +bool classVisibleInIndex(const ClassDef *cd) { static bool allExternals = Config_getBool(ALLEXTERNALS); return (allExternals && cd->isLinkable()) || cd->isLinkableInProject(); @@ -8919,10 +9047,7 @@ void convertProtectionLevel( bool mainPageHasTitle() { - if (Doxygen::mainPage==0) return FALSE; - if (Doxygen::mainPage->title().isEmpty()) return FALSE; - if (Doxygen::mainPage->title().lower()=="notitle") return FALSE; - return TRUE; + return Doxygen::mainPage!=0 && Doxygen::mainPage->hasTitle(); } QCString getDotImageExtension(void) @@ -119,6 +119,7 @@ class LetterToIndexMap : public SIntDict<T> QCString langToString(SrcLangExt lang); QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope=FALSE); +QCString replaceScopeSeparator(QCString str); //-------------------------------------------------------------------- @@ -142,13 +143,13 @@ QCString dateToString(bool); bool getDefs(const QCString &scopeName, const QCString &memberName, const char *, - MemberDef *&md, - ClassDef *&cd, - FileDef *&fd, - NamespaceDef *&nd, - GroupDef *&gd, + const MemberDef *&md, + const ClassDef *&cd, + const FileDef *&fd, + const NamespaceDef *&nd, + const GroupDef *&gd, bool forceEmptyScope=FALSE, - FileDef *currentFile=0, + const FileDef *currentFile=0, bool checkCV=FALSE, const char *forceTagFile=0 ); @@ -158,17 +159,17 @@ QCString getFileFilter(const char* name,bool isSourceCode); bool resolveRef(/* in */ const char *scName, /* in */ const char *name, /* in */ bool inSeeBlock, - /* out */ Definition **resContext, - /* out */ MemberDef **resMember, + /* out */ const Definition **resContext, + /* out */ const MemberDef **resMember, /* in */ bool lookForSpecializations = TRUE, - /* in */ FileDef *currentFile = 0, + /* in */ const FileDef *currentFile = 0, /* in */ bool checkScope = FALSE ); bool resolveLink(/* in */ const char *scName, /* in */ const char *lr, /* in */ bool inSeeBlock, - /* out */ Definition **resContext, + /* out */ const Definition **resContext, /* out */ QCString &resAnchor ); @@ -183,10 +184,10 @@ void generateFileRef(OutputDocInterface &od,const char *, void writePageRef(OutputDocInterface &od,const char *cn,const char *mn); -QCString getCanonicalTemplateSpec(Definition *d,FileDef *fs,const QCString& spec); +QCString getCanonicalTemplateSpec(const Definition *d,const FileDef *fs,const QCString& spec); -bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *srcAl, - Definition *dstScope,FileDef *dstFileScope,ArgumentList *dstAl, +bool matchArguments2(const Definition *srcScope,const FileDef *srcFileScope,const ArgumentList *srcAl, + const Definition *dstScope,const FileDef *dstFileScope,const ArgumentList *dstAl, bool checkCV ); @@ -206,10 +207,10 @@ QCString resolveDefines(const char *n); ClassDef *getClass(const char *key); -ClassDef *getResolvedClass(const Definition *scope, +const ClassDef *getResolvedClass(const Definition *scope, const FileDef *fileScope, const char *key, - MemberDef **pTypeDef=0, + const MemberDef **pTypeDef=0, QCString *pTemplSpec=0, bool mayBeUnlinkable=FALSE, bool mayBeHidden=FALSE, @@ -231,9 +232,9 @@ inline bool isId(int c) QCString removeRedundantWhiteSpace(const QCString &s); -QCString argListToString(ArgumentList *al,bool useCanonicalType=FALSE,bool showDefVals=TRUE); +QCString argListToString(const ArgumentList *al,bool useCanonicalType=FALSE,bool showDefVals=TRUE); -QCString tempArgListToString(ArgumentList *al,SrcLangExt lang); +QCString tempArgListToString(const ArgumentList *al,SrcLangExt lang); QCString generateMarker(int id); @@ -260,13 +261,13 @@ QCString replaceAnonymousScopes(const QCString &s,const char *replacement=0); void initClassHierarchy(ClassSDict *cl); -bool hasVisibleRoot(BaseClassList *bcl); -bool classHasVisibleChildren(ClassDef *cd); -bool namespaceHasVisibleChild(NamespaceDef *nd,bool includeClasses,bool filterClasses,ClassDef::CompoundType ct); -bool classVisibleInIndex(ClassDef *cd); +bool hasVisibleRoot(const BaseClassList *bcl); +bool classHasVisibleChildren(const ClassDef *cd); +bool namespaceHasVisibleChild(const NamespaceDef *nd,bool includeClasses,bool filterClasses,ClassDef::CompoundType ct); +bool classVisibleInIndex(const ClassDef *cd); int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level=0); -Protection classInheritedProtectionLevel(ClassDef *cd,ClassDef *bcd,Protection prot=Public,int level=0); +Protection classInheritedProtectionLevel(const ClassDef *cd,const ClassDef *bcd,Protection prot=Public,int level=0); QCString convertNameToFile(const char *name,bool allowDots=FALSE,bool allowUnderscore=FALSE); @@ -284,7 +285,7 @@ QCString convertToHtml(const char *s,bool keepEntities=TRUE); QCString convertToLaTeX(const QCString &s,bool insideTabbing=FALSE,bool keepSpaces=FALSE); -QCString convertToXML(const char *s); +QCString convertToXML(const char *s, bool keepEntities=FALSE); QCString convertToDocBook(const char *s); @@ -292,16 +293,16 @@ QCString convertToJSString(const char *s, bool applyTextDir = true); QCString getOverloadDocs(); -void addMembersToMemberGroup(/* in */ MemberList *ml, +void addMembersToMemberGroup(/* in,out */ MemberList *ml, /* in,out */ MemberGroupSDict **ppMemberGroupSDict, - /* in */ Definition *context); + /* in */ const Definition *context); int extractClassNameFromType(const QCString &type,int &pos, QCString &name,QCString &templSpec,SrcLangExt=SrcLangExt_Unknown); QCString normalizeNonTemplateArgumentsInString( const QCString &name, - Definition *context, + const Definition *context, const ArgumentList *formalArgs); QCString substituteTemplateArgumentsInString( @@ -315,8 +316,8 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly=TRUE, QCString *lastScopeStripped=0); -QCString resolveTypeDef(Definition *d,const QCString &name, - Definition **typedefContext=0); +QCString resolveTypeDef(const Definition *d,const QCString &name, + const Definition **typedefContext=0); QCString mergeScopes(const QCString &leftScope,const QCString &rightScope); @@ -328,18 +329,21 @@ void addRefItem(const QList<ListItemInfo> *sli,const char *prefix, const char *key, const char *name,const char *title,const char *args,Definition *scope); -PageDef *addRelatedPage(const char *name,const QCString &ptitle, - const QCString &doc,QList<SectionInfo> *anchors, - const char *fileName,int startLine, - const QList<ListItemInfo> *sli, - GroupDef *gd=0, - TagInfo *tagInfo=0, - SrcLangExt lang=SrcLangExt_Unknown - ); +PageDef *addRelatedPage(const char *name, + const QCString &ptitle, + const QCString &doc, + const QList<SectionInfo> *anchors, + const char *fileName,int startLine, + const QList<ListItemInfo> *sli, + GroupDef *gd=0, + TagInfo *tagInfo=0, + SrcLangExt lang=SrcLangExt_Unknown + ); QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscore=FALSE); +QCString unescapeCharsInString(const char *s); -void addGroupListToTitle(OutputList &ol,Definition *d); +void addGroupListToTitle(OutputList &ol,const Definition *d); void filterLatexString(FTextStream &t,const char *str, bool insideTabbing=FALSE, @@ -385,23 +389,22 @@ bool findAndRemoveWord(QCString &s,const QCString &word); QCString stripLeadingAndTrailingEmptyLines(const QCString &s,int &docLine); -//void stringToSearchIndex(const QCString &docUrlBase,const QCString &title, -// const QCString &str, bool priority=FALSE, -// const QCString &anchor=""); - bool updateLanguageMapping(const QCString &extension,const QCString &parser); SrcLangExt getLanguageFromFileName(const QCString& fileName); +QCString getFileNameExtension(QCString fn); void initDefaultExtensionMapping(); void addCodeOnlyMappings(); -MemberDef *getMemberFromSymbol(Definition *scope,FileDef *fileScope, +MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fileScope, const char *n); -bool checkIfTypedef(Definition *scope,FileDef *fileScope,const char *n); +bool checkIfTypedef(const Definition *scope,const FileDef *fileScope,const char *n); -ClassDef *newResolveTypedef(const FileDef *fileScope,MemberDef *md, - MemberDef **pMemType=0,QCString *pTemplSpec=0, - QCString *pResolvedType=0, - ArgumentList *actTemplParams=0); +const ClassDef *newResolveTypedef(const FileDef *fileScope, + const MemberDef *md, + const MemberDef **pMemType=0, + QCString *pTemplSpec=0, + QCString *pResolvedType=0, + ArgumentList *actTemplParams=0); QCString parseCommentAsText(const Definition *scope,const MemberDef *member,const QCString &doc,const QCString &fileName,int lineNr); @@ -418,7 +421,7 @@ int countAliasArguments(const QCString argList); QCString resolveAliasCmd(const QCString aliasCmd); QCString expandAlias(const QCString &aliasName,const QCString &aliasValue); -void writeTypeConstraints(OutputList &ol,Definition *d,ArgumentList *al); +void writeTypeConstraints(OutputList &ol,const Definition *d,const ArgumentList *al); QCString convertCharEntitiesToUTF8(const QCString &s); @@ -453,6 +456,8 @@ bool copyFile(const QCString &src,const QCString &dest); QCString extractBlock(const QCString text,const QCString marker); int lineBlock(const QCString text,const QCString marker); +bool isURL(const QCString &url); + QCString correctURL(const QCString &url,const QCString &relPath); QCString processMarkup(const QCString &s); @@ -463,7 +468,7 @@ QCString stripIndentation(const QCString &s); QCString getDotImageExtension(void); -bool fileVisibleInIndex(FileDef *fd,bool &genSourceFile); +bool fileVisibleInIndex(const FileDef *fd,bool &genSourceFile); void addDocCrossReference(MemberDef *src,MemberDef *dst); diff --git a/src/version.h b/src/version.h deleted file mode 100644 index 16bf9df..0000000 --- a/src/version.h +++ /dev/null @@ -1,23 +0,0 @@ -/****************************************************************************** - * - * - * - * 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 - * 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 VERSION_H -#define VERSION_H - -extern char versionString[]; - -#endif diff --git a/src/vhdlcode.h b/src/vhdlcode.h index e21ddea..a7b4687 100644 --- a/src/vhdlcode.h +++ b/src/vhdlcode.h @@ -8,7 +8,7 @@ class MemberDef; void parseVhdlCode(CodeOutputInterface &,const char *,const QCString &, bool ,const char *,FileDef *fd, int startLine,int endLine,bool inlineFragment, - MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx, + const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, bool collectXRefs); void resetVhdlCodeParserState(); void codeFreeVhdlScanner(); diff --git a/src/vhdlcode.l b/src/vhdlcode.l index aa15183..5f668c6 100644 --- a/src/vhdlcode.l +++ b/src/vhdlcode.l @@ -86,7 +86,7 @@ static int g_inputPosition; //!< read offset during parsing static int g_inputLines; //!< number of line in the code fragment static int g_yyLineNr; //!< current line number static bool g_needsTermination; -static Definition *g_searchCtx; +static const Definition *g_searchCtx; static bool g_exampleBlock; static QCString g_exampleName; @@ -347,7 +347,7 @@ static void writeWord(const char *word,const char* curr_class=0,bool classLink=F }// writeWord -/*! write a code fragment `text' that may span multiple lines, inserting +/*! write a code fragment 'text' that may span multiple lines, inserting * line numbers for each line. */ static void codifyLines(const char *text,const char *cl=0,bool classlink=FALSE,bool comment=FALSE) @@ -430,13 +430,13 @@ static void writeMultiLineCodeLink(CodeOutputInterface &ol, } } -static void setParameterList(MemberDef *md) +static void setParameterList(const MemberDef *md) { g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : ""; - ArgumentList *al = md->argumentList(); + const ArgumentList *al = md->argumentList(); if (al==0) return; ArgumentListIterator ali(*al); - Argument *a; + const Argument *a; for (ali.toFirst();(a=ali.current());++ali) { g_parmName = a->name.copy(); @@ -544,7 +544,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName Definition *d = cd->getOuterScope(); if (d && d->definitionType()==Definition::TypeClass) { - cd = (ClassDef*)d; + cd = dynamic_cast<ClassDef*>(d); } else { @@ -1543,18 +1543,16 @@ void resetVhdlCodeParserState() void parseVhdlCode(CodeOutputInterface &od,const char *className,const QCString &s, bool exBlock, const char *exName,FileDef *fd, int startLine,int endLine,bool inlineFragment, - MemberDef *memberDef,bool,Definition *searchCtx, + const MemberDef *memberDef,bool,const Definition *searchCtx, bool /* collectXRefs */) { //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd); if (s.isEmpty()) return; printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL); - TooltipManager::instance()->clearTooltips(); if (memberDef) { - ClassDef *dd=memberDef->getClassDef(); + const ClassDef *dd=memberDef->getClassDef(); if (dd) g_CurrClass=dd->name(); - startLine--; } resetVhdlCodeParserState(); g_code = &od; @@ -1584,7 +1582,7 @@ void parseVhdlCode(CodeOutputInterface &od,const char *className,const QCString if (exBlock && fd==0) { // create a dummy filedef for the example - g_sourceFileDef = new FileDef("",exName); + g_sourceFileDef = createFileDef("",exName); cleanupSourceDef = TRUE; } if (g_sourceFileDef) @@ -1599,10 +1597,7 @@ void parseVhdlCode(CodeOutputInterface &od,const char *className,const QCString g_exampleFile = convertNameToFile(g_exampleName+"-example"); } g_includeCodeFragment = inlineFragment; - if (!memberDef) - { - startCodeLine(); - } + startCodeLine(); // g_type.resize(0); // g_name.resize(0); // g_args.resize(0); @@ -1623,10 +1618,6 @@ void parseVhdlCode(CodeOutputInterface &od,const char *className,const QCString { endCodeLine(); } - if (fd) - { - TooltipManager::instance()->writeTooltips(*g_code); - } if (cleanupSourceDef) { // delete the temporary file definition used for this example diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index b18bd3f..38a80ef 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -168,7 +168,7 @@ static void createSVG() QCString vlargs="-Tsvg \""+ov+"\" "+dir ; - if (portable_system("dot",vlargs)!=0) + if (portable_system(Config_getString(DOT_PATH) + "dot",vlargs)!=0) { err("could not create dot file"); } @@ -1730,8 +1730,8 @@ QCString VhdlDocGen::convertArgumentListToString(const ArgumentList* al,bool fun } -void VhdlDocGen::writeVhdlDeclarations(MemberList* ml, - OutputList& ol,GroupDef* gd,ClassDef* cd,FileDef *fd,NamespaceDef* nd) +void VhdlDocGen::writeVhdlDeclarations(const MemberList* ml, + OutputList& ol,const GroupDef* gd,const ClassDef* cd,const FileDef *fd,const NamespaceDef* nd) { VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::LIBRARY,FALSE),0,FALSE,VhdlDocGen::LIBRARY); VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::USE,FALSE),0,FALSE,VhdlDocGen::USE); @@ -1761,36 +1761,49 @@ void VhdlDocGen::writeVhdlDeclarations(MemberList* ml, } -static void setGlobalType(MemberList *ml) +void VhdlDocGen::correctMemberProperties(MemberDef *md) { - if (ml==0) return; - MemberDef *mdd=0; - MemberListIterator mmli(*ml); - for ( ; (mdd=mmli.current()); ++mmli ) + if (qstrcmp(md->argsString(),"package")==0) { - if (qstrcmp(mdd->argsString(),"package")==0) - { - mdd->setMemberSpecifiers(VhdlDocGen::INSTANTIATION); - } - else if (qstrcmp(mdd->argsString(),"configuration")==0) - { - mdd->setMemberSpecifiers(VhdlDocGen::CONFIG); - } - else if (qstrcmp(mdd->typeString(),"library")==0) - { - mdd->setMemberSpecifiers(VhdlDocGen::LIBRARY); - } - else if (qstrcmp(mdd->typeString(),"use")==0) - { - mdd->setMemberSpecifiers(VhdlDocGen::USE); - } - else if (qstricmp(mdd->typeString(),"misc")==0) + md->setMemberSpecifiers(VhdlDocGen::INSTANTIATION); + } + else if (qstrcmp(md->argsString(),"configuration")==0) + { + md->setMemberSpecifiers(VhdlDocGen::CONFIG); + } + else if (qstrcmp(md->typeString(),"library")==0) + { + md->setMemberSpecifiers(VhdlDocGen::LIBRARY); + } + else if (qstrcmp(md->typeString(),"use")==0) + { + md->setMemberSpecifiers(VhdlDocGen::USE); + } + else if (qstricmp(md->typeString(),"misc")==0) + { + md->setMemberSpecifiers(VhdlDocGen::MISCELLANEOUS); + } + else if (qstricmp(md->typeString(),"ucf_const")==0) + { + md->setMemberSpecifiers(VhdlDocGen::UCF_CONST); + } + + if (md->getMemberSpecifiers()==VhdlDocGen::UCF_CONST) + { + int mm=md->name().findRev('_'); + if (mm>0) { - mdd->setMemberSpecifiers(VhdlDocGen::MISCELLANEOUS); + md->setName(md->name().left(mm)); } - else if (qstricmp(mdd->typeString(),"ucf_const")==0) + } + else if (md->getMemberSpecifiers()==VhdlDocGen::TYPE) + { + QCString largs=md->argsString(); + bool bRec=largs.stripPrefix("record") ; + bool bUnit=largs.stripPrefix("units") ; + if (bRec || bUnit) { - mdd->setMemberSpecifiers(VhdlDocGen::UCF_CONST); + md->setType(""); } } } @@ -1798,7 +1811,7 @@ static void setGlobalType(MemberList *ml) /* writes a vhdl type documentation */ bool VhdlDocGen::writeVHDLTypeDocumentation(const MemberDef* mdef, const Definition *d, OutputList &ol) { - ClassDef *cd=(ClassDef*)d; + const ClassDef *cd=dynamic_cast<const ClassDef*>(d); bool hasParams = FALSE; if (cd==0) return hasParams; @@ -1924,11 +1937,11 @@ void VhdlDocGen::writeTagFile(MemberDef *mdef,FTextStream &tagFile) /* writes a vhdl type declaration */ -void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, +void VhdlDocGen::writeVHDLDeclaration(const MemberDef* mdef,OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, bool /*inGroup*/) { - Definition *d=0; + const Definition *d=0; ASSERT(cd!=0 || nd!=0 || fd!=0 || gd!=0 || mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY || @@ -1987,14 +2000,9 @@ void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, /*VHDL CHANGE */ bool bRec,bUnit; QCString ltype(mdef->typeString()); - // ltype=ltype.replace(reg," "); QCString largs(mdef->argsString()); - // largs=largs.replace(reg," "); - mdef->setType(ltype.data()); - mdef->setArgsString(largs.data()); - //ClassDef * plo=mdef->getClassDef(); ClassDef *kl=0; - ArgumentList *alp = mdef->argumentList(); + const ArgumentList *alp = mdef->argumentList(); QCString nn; //VhdlDocGen::adjustRecordMember(mdef); if (gd) gd=0; @@ -2153,11 +2161,6 @@ void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, } break; case VhdlDocGen::UCF_CONST: - mm=mdef->name().findRev('_'); - if (mm>0) - { - mdef->setName(mdef->name().left(mm)); - } writeUCFLink(mdef,ol); break; case VhdlDocGen::SIGNAL: @@ -2198,7 +2201,6 @@ void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, if (bRec || bUnit) { writeRecorUnit(largs,ol,mdef); - mdef->setType(""); } ol.endBold(); break; @@ -2260,8 +2262,8 @@ void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, void VhdlDocGen::writePlainVHDLDeclarations( - MemberList* mlist,OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,int specifier) + const MemberList* mlist,OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,int specifier) { SDict<QCString> pack(1009); @@ -2292,7 +2294,7 @@ void VhdlDocGen::writePlainVHDLDeclarations( pack.clear(); }//plainDeclaration -static bool membersHaveSpecificType(MemberList *ml,uint64 type) +static bool membersHaveSpecificType(const MemberList *ml,uint64 type) { if (ml==0) return FALSE; MemberDef *mdd=0; @@ -2320,11 +2322,10 @@ static bool membersHaveSpecificType(MemberList *ml,uint64 type) return FALSE; } -void VhdlDocGen::writeVHDLDeclarations(MemberList* ml,OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, +void VhdlDocGen::writeVHDLDeclarations(const MemberList* ml,OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, const char *title,const char *subtitle,bool /*showEnumValues*/,int type) { - setGlobalType(ml); if (!membersHaveSpecificType(ml,type)) return; if (title) @@ -2377,7 +2378,7 @@ void VhdlDocGen::writeVHDLDeclarations(MemberList* ml,OutputList &ol, }// writeVHDLDeclarations -bool VhdlDocGen::writeClassType( ClassDef *& cd, +bool VhdlDocGen::writeClassType( const ClassDef * cd, OutputList &ol ,QCString & cname) { int id=cd->protection(); @@ -2398,7 +2399,7 @@ void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& { if (mdef) { - ClassDef *cd=mdef->getClassDef(); + const ClassDef *cd=mdef->getClassDef(); if (cd) { QCString n=cd->name(); @@ -2418,7 +2419,7 @@ void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& -void VhdlDocGen::writeSource(MemberDef *mdef,OutputList& ol,QCString & cname) +void VhdlDocGen::writeSource(const MemberDef *mdef,OutputList& ol,const QCString & cname) { ParserInterface *pIntf = Doxygen::parserManager->getParser(".vhd"); // pIntf->resetCodeParserState(); @@ -2452,7 +2453,7 @@ void VhdlDocGen::writeSource(MemberDef *mdef,OutputList& ol,QCString & cname) SrcLangExt_VHDL, // lang FALSE, // isExample 0, // exampleName - mdef->getFileDef(), // fileDef + const_cast<FileDef*>(mdef->getFileDef()), // fileDef mdef->getStartBodyLine(), // startLine mdef->getEndBodyLine(), // endLine TRUE, // inlineFragment @@ -2984,7 +2985,7 @@ static void addInstance(ClassDef* classEntity, ClassDef* ar, ferr: QCString uu=cur->name; - MemberDef *md=new MemberDef( + MemberDef *md=createMemberDef( ar->getDefFileName(), cur->startLine,cur->startColumn, n1,uu,uu, 0, Public, Normal, cur->stat,Member, @@ -3091,7 +3092,7 @@ bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int BaseClassListIterator bcli(*cd->subClasses()); for ( ; bcli.current() && !found ; ++bcli) { - ClassDef *ccd=bcli.current()->classDef; + const ClassDef *ccd=bcli.current()->classDef; if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster(); //printf("isSubClass() subclass %s\n",ccd->name().data()); if (ccd==scd) @@ -3178,7 +3179,7 @@ void VhdlDocGen::createFlowChart(const MemberDef *mdef) int actualStart= mdef->getStartBodyLine(); int actualEnd=mdef->getEndBodyLine(); - FileDef* fd=mdef->getFileDef(); + const FileDef* fd=mdef->getFileDef(); bool b=readCodeFragment( fd->absFilePath().data(), actualStart,actualEnd,codeFragment); if (!b) return; @@ -3774,8 +3775,8 @@ void FlowChart::printUmlTree() QCString n=convertNameToFileName(); QCString tmp=htmlOutDir; - n=writePlantUMLSource(tmp,n,qcs); - generatePlantUMLOutput(n.data(),tmp.data(),PUML_SVG); + n=PlantumlManager::instance()->writePlantUMLSource(tmp,n,qcs,PlantumlManager::PUML_SVG); + PlantumlManager::instance()->generatePlantUMLOutput(n.data(),tmp.data(),PlantumlManager::PUML_SVG); } QCString FlowChart::convertNameToFileName() @@ -3844,7 +3845,7 @@ void FlowChart::createSVG() QCString vlargs="-Tsvg \""+ov+"\" "+dir ; - if (portable_system("dot",vlargs)!=0) + if (portable_system(Config_getString(DOT_PATH) + "dot",vlargs)!=0) { err("could not create dot file"); } @@ -4374,9 +4375,9 @@ void VHDLLanguageScanner::parseCode(CodeOutputInterface &codeOutIntf, int startLine, int endLine, bool inlineFragment, - MemberDef *memberDef, + const MemberDef *memberDef, bool showLineNumbers, - Definition *searchCtx, + const Definition *searchCtx, bool collectXRefs ) { diff --git a/src/vhdldocgen.h b/src/vhdldocgen.h index 9dd8417..e2c843c 100644 --- a/src/vhdldocgen.h +++ b/src/vhdldocgen.h @@ -163,20 +163,21 @@ class VhdlDocGen static bool writeVHDLTypeDocumentation(const MemberDef* mdef, const Definition* d, OutputList &ol); - static void writeVhdlDeclarations(MemberList*,OutputList&,GroupDef*,ClassDef*,FileDef*,NamespaceDef*); + static void writeVhdlDeclarations(const MemberList*,OutputList&,const GroupDef*,const ClassDef*,const FileDef*,const NamespaceDef*); - static void writeVHDLDeclaration(MemberDef* mdef,OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, + static void writeVHDLDeclaration(const MemberDef* mdef,OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, bool inGroup); - static void writePlainVHDLDeclarations(MemberList* ml,OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,int specifier); + static void writePlainVHDLDeclarations(const MemberList* ml,OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + int specifier); - static void writeVHDLDeclarations(MemberList* ml,OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, + static void writeVHDLDeclarations(const MemberList* ml,OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, const char *title,const char *subtitle,bool showEnumValues,int type); - static bool writeClassType(ClassDef *&,OutputList &ol ,QCString & cname); + static bool writeClassType(const ClassDef *,OutputList &ol ,QCString & cname); static QCString convertArgumentListToString(const ArgumentList* al,bool f); static QCString getProcessNumber(); @@ -192,8 +193,9 @@ class VhdlDocGen static ClassDef* findArchitecture(const ClassDef *cd); static ClassDef* findArchitecture(QCString identifier, QCString entity_name); + static void correctMemberProperties(MemberDef *md); - static void writeSource(MemberDef *mdef,OutputList& ol,QCString & cname); + static void writeSource(const MemberDef *mdef,OutputList& ol,const QCString & cname); static void writeAlphbeticalClass(OutputList& ol,const ClassDef* cd,const QCString &); static QCString parseForConfig(QCString & entity,QCString & arch); diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp index 81a7ca1..aeed048 100644 --- a/src/vhdljjparser.cpp +++ b/src/vhdljjparser.cpp @@ -146,7 +146,7 @@ void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,En oldEntry = 0; VhdlParser::current=new Entry(); VhdlParser::initEntry(VhdlParser::current); - groupEnterFile(fileName,yyLineNr); + Doxygen::docGroup.enterFile(fileName,yyLineNr); vhdlFileName = fileName; lineParse=new int[200]; // Dimitri: dangerous constant: should be bigger than largest token id in VhdlParserConstants.h VhdlParserIF::parseVhdlfile(fileBuf,inLine); @@ -193,7 +193,7 @@ void VhdlParser::initEntry(Entry *e) e->fileName = yyFileName; e->lang = SrcLangExt_VHDL; isVhdlDocPending(); - initGroupInfo(e); + Doxygen::docGroup.initGroupInfo(e); } void VhdlParser::newEntry() @@ -244,7 +244,6 @@ void VhdlParser::handleFlowComment(const char* doc) void VhdlParser::handleCommentBlock(const char* doc1,bool brief) { - int position=0; QCString doc; doc.append(doc1); // fprintf(stderr,"\n %s",doc.data()); @@ -258,7 +257,6 @@ void VhdlParser::handleCommentBlock(const char* doc1,bool brief) VhdlDocGen::prepareComment(doc); - bool needsEntry=FALSE; Protection protection=Public; if (oldEntry==current) @@ -290,10 +288,13 @@ void VhdlParser::handleCommentBlock(const char* doc1,bool brief) current->stat=true; } + int position=0; + bool needsEntry=FALSE; + QCString processedDoc = preprocessCommentBlock(doc,yyFileName,iDocLine); while (parseCommentBlock( g_thisParser, current, - doc, // text + processedDoc, // text yyFileName, // file iDocLine, // line of block start brief, diff --git a/src/vhdljjparser.h b/src/vhdljjparser.h index 3a2ed61..fffea47 100644 --- a/src/vhdljjparser.h +++ b/src/vhdljjparser.h @@ -59,9 +59,9 @@ class VHDLLanguageScanner : public ParserInterface int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, - MemberDef *memberDef=0, + const MemberDef *memberDef=0, bool showLineNumbers=TRUE, - Definition *searchCtx=0, + const Definition *searchCtx=0, bool collectXRefs=TRUE ); bool needsPreprocessing(const QCString &) { return TRUE; } diff --git a/src/xmlcode.h b/src/xmlcode.h index 5a9c78c..e463866 100644 --- a/src/xmlcode.h +++ b/src/xmlcode.h @@ -30,7 +30,7 @@ class Definition; extern void parseXmlCode(CodeOutputInterface &,const char *,const QCString &, bool ,const char *,FileDef *fd, int startLine,int endLine,bool inlineFragment, - MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx, + const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, bool collectXRefs); extern void resetXmlCodeParserState(); diff --git a/src/xmlcode.l b/src/xmlcode.l index d2f94ad..42218b1 100644 --- a/src/xmlcode.l +++ b/src/xmlcode.l @@ -35,6 +35,7 @@ #include "config.h" #include "filedef.h" #include "tooltip.h" +#include "message.h" #define YY_NEVER_INTERACTIVE 1 #define YY_NO_INPUT 1 @@ -49,7 +50,7 @@ static int g_inputPosition; //!< read offset during parsing static int g_inputLines; //!< number of line in the code fragment static int g_yyLineNr; //!< current line number static bool g_needsTermination; -static Definition *g_searchCtx; +static const Definition *g_searchCtx; static bool g_exampleBlock; static QCString g_exampleName; @@ -332,14 +333,13 @@ void parseXmlCode( int startLine, int endLine, bool inlineFragment, - MemberDef *, - bool,Definition *searchCtx, + const MemberDef *, + bool,const Definition *searchCtx, bool /*collectXRefs*/ ) { if (s.isEmpty()) return; - - TooltipManager::instance()->clearTooltips(); + printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL); g_code = &od; g_inputString = s; @@ -367,7 +367,7 @@ void parseXmlCode( if (exBlock && fd==0) { // create a dummy filedef for the example - g_sourceFileDef = new FileDef("",(exName?exName:"generated")); + g_sourceFileDef = createFileDef("",(exName?exName:"generated")); cleanupSourceDef = TRUE; } @@ -388,10 +388,6 @@ void parseXmlCode( { endCodeLine(); } - if (fd) - { - TooltipManager::instance()->writeTooltips(*g_code); - } if (cleanupSourceDef) { // delete the temporary file definition used for this example @@ -399,6 +395,7 @@ void parseXmlCode( g_sourceFileDef=0; } + printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL); return; } diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp index a65695c..a0afa9d 100644 --- a/src/xmldocvisitor.cpp +++ b/src/xmldocvisitor.cpp @@ -60,7 +60,7 @@ static void visitPreStart(FTextStream &t, const char *cmd, bool doCaption, } if (!name.isEmpty()) { - t << " name=\"" << name << "\""; + t << " name=\"" << convertToXML(name, TRUE) << "\""; } if (!width.isEmpty()) { @@ -70,7 +70,10 @@ static void visitPreStart(FTextStream &t, const char *cmd, bool doCaption, { t << " height=\"" << convertToXML(height) << "\""; } - if (inlineImage) t << " inline=\"yes\">"; + if (inlineImage) + { + t << " inline=\"yes\""; + } if (doCaption) { t << " caption=\""; @@ -187,9 +190,15 @@ void XmlDocVisitor::visit(DocStyleChange *s) case DocStyleChange::Strike: if (s->enable()) m_t << "<strike>"; else m_t << "</strike>"; break; + case DocStyleChange::Del: + if (s->enable()) m_t << "<del>"; else m_t << "</del>"; + break; case DocStyleChange::Underline: if (s->enable()) m_t << "<underline>"; else m_t << "</underline>"; break; + case DocStyleChange::Ins: + if (s->enable()) m_t << "<ins>"; else m_t << "</ins>"; + break; case DocStyleChange::Italic: if (s->enable()) m_t << "<emphasis>"; else m_t << "</emphasis>"; break; @@ -296,20 +305,21 @@ void XmlDocVisitor::visit(DocInclude *inc) { m_t << "<programlisting filename=\"" << inc->file() << "\">"; QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), inc->exampleFile(), - &fd, // fileDef, + fd, // fileDef, -1, // start line -1, // end line FALSE, // inline fragment 0, // memberDef TRUE // show line numbers ); + delete fd; m_t << "</programlisting>"; } break; @@ -331,6 +341,7 @@ void XmlDocVisitor::visit(DocInclude *inc) m_t << "</programlisting>"; break; case DocInclude::DontInclude: + case DocInclude::DontIncWithLines: break; case DocInclude::HtmlInclude: if (inc->isBlock()) @@ -370,7 +381,7 @@ void XmlDocVisitor::visit(DocInclude *inc) { m_t << "<programlisting filename=\"" << inc->file() << "\">"; QFileInfo cfi( inc->file() ); - FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); Doxygen::parserManager->getParser(inc->extension()) ->parseCode(m_ci, inc->context(), @@ -378,13 +389,14 @@ void XmlDocVisitor::visit(DocInclude *inc) langExt, inc->isExample(), inc->exampleFile(), - &fd, + fd, lineBlock(inc->text(),inc->blockId()), -1, // endLine FALSE, // inlineFragment 0, // memberDef TRUE // show line number ); + delete fd; m_t << "</programlisting>"; } break; @@ -398,7 +410,7 @@ void XmlDocVisitor::visit(DocInclude *inc) void XmlDocVisitor::visit(DocIncOperator *op) { - //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n", + //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n", // op->type(),op->isFirst(),op->isLast(),op->text().data()); if (op->isFirst()) { @@ -409,16 +421,33 @@ void XmlDocVisitor::visit(DocIncOperator *op) pushEnabled(); m_hide = TRUE; } - SrcLangExt langExt = getLanguageFromFileName(m_langExt); + QCString locLangExt = getFileNameExtension(op->includeFileName()); + if (locLangExt.isEmpty()) locLangExt = m_langExt; + SrcLangExt langExt = getLanguageFromFileName(locLangExt); if (op->type()!=DocIncOperator::Skip) { popEnabled(); if (!m_hide) { - Doxygen::parserManager->getParser(m_langExt) + FileDef *fd = 0; + if (!op->includeFileName().isEmpty()) + { + QFileInfo cfi( op->includeFileName() ); + fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); + } + + Doxygen::parserManager->getParser(locLangExt) ->parseCode(m_ci,op->context(), op->text(),langExt,op->isExample(), - op->exampleFile()); + op->exampleFile(), + fd, // fileDef + op->line(), // startLine + -1, // endLine + FALSE, // inline fragment + 0, // memberDef + op->showLineNo() // show line numbers + ); + if (fd) delete fd; } pushEnabled(); m_hide=TRUE; @@ -767,9 +796,7 @@ void XmlDocVisitor::visitPost(DocInternal *) void XmlDocVisitor::visitPre(DocHRef *href) { if (m_hide) return; - m_t << "<ulink url=\""; - filter(href->url()); - m_t << "\">"; + m_t << "<ulink url=\"" << convertToXML(href->url(), TRUE) << "\">"; } void XmlDocVisitor::visitPost(DocHRef *) @@ -971,9 +998,9 @@ void XmlDocVisitor::visitPre(DocParamList *pl) { QListIterator<DocNode> li(pl->paramTypes()); DocNode *type; + m_t << "<parametertype>"; for (li.toFirst();(type=li.current());++li) { - m_t << "<parametertype>"; if (type->kind()==DocNode::Kind_Word) { visit((DocWord*)type); @@ -982,8 +1009,13 @@ void XmlDocVisitor::visitPre(DocParamList *pl) { visit((DocLinkedWord*)type); } - m_t << "</parametertype>" << endl; + else if (type->kind()==DocNode::Kind_Sep) + { + m_t << "</parametertype>" << endl; + m_t << "<parametertype>"; + } } + m_t << "</parametertype>" << endl; } m_t << "<parametername"; if (pl->direction()!=DocParamSect::Unspecified) @@ -1059,18 +1091,6 @@ void XmlDocVisitor::visitPost(DocInternalRef *) m_t << " "; } -void XmlDocVisitor::visitPre(DocCopy *c) -{ - if (m_hide) return; - m_t << "<copydoc link=\"" << convertToXML(c->link()) << "\">"; -} - -void XmlDocVisitor::visitPost(DocCopy *) -{ - if (m_hide) return; - m_t << "</copydoc>" << endl; -} - void XmlDocVisitor::visitPre(DocText *) { } diff --git a/src/xmldocvisitor.h b/src/xmldocvisitor.h index c2c6537..6fa1392 100644 --- a/src/xmldocvisitor.h +++ b/src/xmldocvisitor.h @@ -130,8 +130,6 @@ class XmlDocVisitor : public DocVisitor void visitPost(DocXRefItem *); void visitPre(DocInternalRef *); void visitPost(DocInternalRef *); - void visitPre(DocCopy *); - void visitPost(DocCopy *); void visitPre(DocText *); void visitPost(DocText *); void visitPre(DocHtmlBlockQuote *); diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index bacf4d4..d05adf0 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -29,6 +29,8 @@ #include "defargs.h" #include "outputgen.h" #include "dot.h" +#include "dotclassgraph.h" +#include "dotincldepgraph.h" #include "pagedef.h" #include "filename.h" #include "version.h" @@ -152,7 +154,7 @@ static void writeXMLHeader(FTextStream &t) t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;; t << "<doxygen xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "; t << "xsi:noNamespaceSchemaLocation=\"compound.xsd\" "; - t << "version=\"" << versionString << "\">" << endl; + t << "version=\"" << getVersion() << "\">" << endl; } static void writeCombineScript() @@ -336,10 +338,10 @@ void XMLCodeGenerator::finish() if (m_insideCodeLine) endCodeLine(); } -static void writeTemplateArgumentList(ArgumentList *al, +static void writeTemplateArgumentList(const ArgumentList *al, FTextStream &t, - Definition *scope, - FileDef *fileScope, + const Definition *scope, + const FileDef *fileScope, int indent) { QCString indentStr; @@ -348,7 +350,7 @@ static void writeTemplateArgumentList(ArgumentList *al, { t << indentStr << "<templateparamlist>" << endl; ArgumentListIterator ali(*al); - Argument *a; + const Argument *a; for (ali.toFirst();(a=ali.current());++ali) { t << indentStr << " <param>" << endl; @@ -360,8 +362,8 @@ static void writeTemplateArgumentList(ArgumentList *al, } if (!a->name.isEmpty()) { - t << indentStr << " <declname>" << a->name << "</declname>" << endl; - t << indentStr << " <defname>" << a->name << "</defname>" << endl; + t << indentStr << " <declname>" << convertToXML(a->name) << "</declname>" << endl; + t << indentStr << " <defname>" << convertToXML(a->name) << "</defname>" << endl; } if (!a->defval.isEmpty()) { @@ -381,16 +383,16 @@ static void writeTemplateArgumentList(ArgumentList *al, } } -static void writeMemberTemplateLists(MemberDef *md,FTextStream &t) +static void writeMemberTemplateLists(const MemberDef *md,FTextStream &t) { - ArgumentList *templMd = md->templateArguments(); + const ArgumentList *templMd = md->templateArguments(); if (templMd) // function template prefix { writeTemplateArgumentList(templMd,t,md->getClassDef(),md->getFileDef(),8); } } -static void writeTemplateList(ClassDef *cd,FTextStream &t) +static void writeTemplateList(const ClassDef *cd,FTextStream &t) { writeTemplateArgumentList(cd->templateArguments(),t,cd,0,4); } @@ -398,8 +400,8 @@ static void writeTemplateList(ClassDef *cd,FTextStream &t) static void writeXMLDocBlock(FTextStream &t, const QCString &fileName, int lineNr, - Definition *scope, - MemberDef * md, + const Definition *scope, + const MemberDef * md, const QCString &text) { QCString stext = text.stripWhiteSpace(); @@ -442,7 +444,7 @@ void writeXMLCodeBlock(FTextStream &t,FileDef *fd) delete xmlGen; } -static void writeMemberReference(FTextStream &t,Definition *def,MemberDef *rmd,const char *tagName) +static void writeMemberReference(FTextStream &t,const Definition *def,const MemberDef *rmd,const char *tagName) { QCString scope = rmd->getScopeString(); QCString name = rmd->name(); @@ -478,7 +480,7 @@ static void stripQualifiers(QCString &typeStr) } } -static QCString classOutputFileBase(ClassDef *cd) +static QCString classOutputFileBase(const ClassDef *cd) { //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); //if (inlineGroupedClasses && cd->partOfGroups()!=0) @@ -487,7 +489,7 @@ static QCString classOutputFileBase(ClassDef *cd) // return cd->getOutputFileBase(); } -static QCString memberOutputFileBase(MemberDef *md) +static QCString memberOutputFileBase(const MemberDef *md) { //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES); //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0) @@ -498,7 +500,7 @@ static QCString memberOutputFileBase(MemberDef *md) } -static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,Definition *def) +static void generateXMLForMember(const MemberDef *md,FTextStream &ti,FTextStream &t,const Definition *def) { // + declaration/definition arg lists @@ -566,7 +568,7 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De { t << memberOutputFileBase(md); } - t << "_1" // encoded `:' character (see util.cpp:convertNameToFile) + t << "_1" // encoded ':' character (see util.cpp:convertNameToFile) << md->anchor(); t << "\" prot=\""; switch(md->protection()) @@ -582,9 +584,14 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De if (md->isStatic()) t << "yes"; else t << "no"; t << "\""; + if (md->isConstExpr()) + { + t << " constexpr=\"yes\""; + } + if (isFunc) { - ArgumentList *al = md->argumentList(); + const ArgumentList *al = md->argumentList(); t << " const=\""; if (al!=0 && al->constSpecifier) t << "yes"; else t << "no"; t << "\""; @@ -629,6 +636,11 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De t << " required=\"yes\""; } + if (md->isNoExcept()) + { + t << " noexcept=\"yes\""; + } + if (al && al->volatileSpecifier) { t << " volatile=\"yes\""; @@ -807,7 +819,7 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De t << " <bitfield>" << convertToXML(bitfield) << "</bitfield>" << endl; } - MemberDef *rmd = md->reimplements(); + const MemberDef *rmd = md->reimplements(); if (rmd) { t << " <reimplements refid=\"" @@ -828,13 +840,13 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De if (isFunc) //function { - ArgumentList *declAl = md->declArgumentList(); - ArgumentList *defAl = md->argumentList(); + const ArgumentList *declAl = md->declArgumentList(); + const ArgumentList *defAl = md->argumentList(); if (declAl && defAl && declAl->count()>0) { ArgumentListIterator declAli(*declAl); ArgumentListIterator defAli(*defAl); - Argument *a; + const Argument *a; for (declAli.toFirst();(a=declAli.current());++declAli) { Argument *defArg = defAli.current(); @@ -898,7 +910,7 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De else { ArgumentListIterator ali(*md->argumentList()); - Argument *a; + const Argument *a; for (ali.toFirst();(a=ali.current());++ali) { t << " <param><defname>" << a->type << "</defname></param>" << endl; @@ -922,11 +934,11 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De if (md->memberType()==MemberType_Enumeration) // enum { - MemberList *enumFields = md->enumFieldList(); + const MemberList *enumFields = md->enumFieldList(); if (enumFields) { MemberListIterator emli(*enumFields); - MemberDef *emd; + const MemberDef *emd; for (emli.toFirst();(emd=emli.current());++emli) { ti << " <member refid=\"" << memberOutputFileBase(md) @@ -975,7 +987,7 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De { t << " <location file=\"" << stripFromPath(md->getDefFileName()) << "\" line=\"" - << md->getDefLine() << "\"" << " column=\"" + << md->getDefLine() << "\" column=\"" << md->getDefColumn() << "\"" ; if (md->getStartBodyLine()!=-1) { @@ -987,6 +999,12 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De t << " bodystart=\"" << md->getStartBodyLine() << "\" bodyend=\"" << md->getEndBodyLine() << "\""; } + if (md->getDeclLine()!=-1) + { + t << " declfile=\"" << stripFromPath(md->getDeclFileName()) << "\" declline=\"" + << md->getDeclLine() << "\" declcolumn=\"" + << md->getDeclColumn() << "\""; + } t << "/>" << endl; } @@ -995,7 +1013,7 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De if (mdict) { MemberSDict::Iterator mdi(*mdict); - MemberDef *rmd; + const MemberDef *rmd; for (mdi.toFirst();(rmd=mdi.current());++mdi) { writeMemberReference(t,def,rmd,"references"); @@ -1005,7 +1023,7 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De if (mdict) { MemberSDict::Iterator mdi(*mdict); - MemberDef *rmd; + const MemberDef *rmd; for (mdi.toFirst();(rmd=mdi.current());++mdi) { writeMemberReference(t,def,rmd,"referencedby"); @@ -1017,24 +1035,25 @@ static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,De // namespace members are also inserted in the file scope, but // to prevent this duplication in the XML output, we optionally filter those here. -static bool memberVisible(Definition *d,MemberDef *md) +static bool memberVisible(const Definition *d,const MemberDef *md) { return Config_getBool(XML_NS_MEMB_FILE_SCOPE) || d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0; } -static void generateXMLSection(Definition *d,FTextStream &ti,FTextStream &t, +static void generateXMLSection(const Definition *d,FTextStream &ti,FTextStream &t, MemberList *ml,const char *kind,const char *header=0, const char *documentation=0) { if (ml==0) return; MemberListIterator mli(*ml); - MemberDef *md; + const MemberDef *md; int count=0; for (mli.toFirst();(md=mli.current());++mli) { - if (memberVisible(d,md)) + if (memberVisible(d,md) && (md->memberType()!=MemberType_EnumValue) && + !md->isHidden()) { count++; } @@ -1062,7 +1081,7 @@ static void generateXMLSection(Definition *d,FTextStream &ti,FTextStream &t, t << " </sectiondef>" << endl; } -static void writeListOfAllMembers(ClassDef *cd,FTextStream &t) +static void writeListOfAllMembers(const ClassDef *cd,FTextStream &t) { t << " <listofallmembers>" << endl; if (cd->memberNameInfoSDict()) @@ -1075,7 +1094,7 @@ static void writeListOfAllMembers(ClassDef *cd,FTextStream &t) MemberInfo *mi; for (mii.toFirst();(mi=mii.current());++mii) { - MemberDef *md=mi->memberDef; + const MemberDef *md=mi->memberDef; if (md->name().at(0)!='@') // skip anonymous members { Protection prot = mi->prot; @@ -1115,7 +1134,7 @@ static void writeInnerClasses(const ClassSDict *cl,FTextStream &t) if (cl) { ClassSDict::Iterator cli(*cl); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) { if (!cd->isHidden() && cd->name().find('@')==-1) // skip anonymous scopes @@ -1140,7 +1159,7 @@ static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t) if (nl) { NamespaceSDict::Iterator nli(*nl); - NamespaceDef *nd; + const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymous scopes @@ -1189,7 +1208,7 @@ static void writeInnerGroups(const GroupList *gl,FTextStream &t) if (gl) { GroupListIterator gli(*gl); - GroupDef *sgd; + const GroupDef *sgd; for (gli.toFirst();(sgd=gli.current());++gli) { t << " <innergroup refid=\"" << sgd->getOutputFileBase() @@ -1213,7 +1232,7 @@ static void writeInnerDirs(const DirList *dl,FTextStream &t) } } -static void generateXMLForClass(ClassDef *cd,FTextStream &ti) +static void generateXMLForClass(const ClassDef *cd,FTextStream &ti) { // + brief description // + detailed description @@ -1390,14 +1409,14 @@ static void generateXMLForClass(ClassDef *cd,FTextStream &ti) t << " <detaileddescription>" << endl; writeXMLDocBlock(t,cd->docFile(),cd->docLine(),cd,0,cd->documentation()); t << " </detaileddescription>" << endl; - DotClassGraph inheritanceGraph(cd,DotNode::Inheritance); + DotClassGraph inheritanceGraph(cd,Inheritance); if (!inheritanceGraph.isTrivial()) { t << " <inheritancegraph>" << endl; inheritanceGraph.writeXML(t); t << " </inheritancegraph>" << endl; } - DotClassGraph collaborationGraph(cd,DotNode::Collaboration); + DotClassGraph collaborationGraph(cd,Collaboration); if (!collaborationGraph.isTrivial()) { t << " <collaborationgraph>" << endl; @@ -1426,7 +1445,7 @@ static void generateXMLForClass(ClassDef *cd,FTextStream &ti) ti << " </compound>" << endl; } -static void generateXMLForNamespace(NamespaceDef *nd,FTextStream &ti) +static void generateXMLForNamespace(const NamespaceDef *nd,FTextStream &ti) { // + contained class definitions // + contained namespace definitions @@ -1642,7 +1661,7 @@ static void generateXMLForFile(FileDef *fd,FTextStream &ti) ti << " </compound>" << endl; } -static void generateXMLForGroup(GroupDef *gd,FTextStream &ti) +static void generateXMLForGroup(const GroupDef *gd,FTextStream &ti) { // + members // + member groups @@ -1797,11 +1816,11 @@ static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample) if (pd==Doxygen::mainPage) // main page is special { QCString title; - if (!pd->title().isEmpty() && pd->title().lower()!="notitle") + if (mainPageHasTitle()) { title = filterTitle(convertCharEntitiesToUTF8(Doxygen::mainPage->title())); } - else + else { title = Config_getString(PROJECT_NAME); } @@ -1818,10 +1837,10 @@ static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample) } } writeInnerPages(pd->getSubPages(),t); - if (pd->localToc().isXmlEnabled()) + SectionDict *sectionDict = pd->getSectionDict(); + if (pd->localToc().isXmlEnabled() && sectionDict) { t << " <tableofcontents>" << endl; - SectionDict *sectionDict = pd->getSectionDict(); SDict<SectionInfo>::Iterator li(*sectionDict); SectionInfo *si; int level=1,l; @@ -1962,11 +1981,11 @@ void generateXML() t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;; t << "<doxygenindex xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "; t << "xsi:noNamespaceSchemaLocation=\"index.xsd\" "; - t << "version=\"" << versionString << "\">" << endl; + t << "version=\"" << getVersion() << "\">" << endl; { ClassSDict::Iterator cli(*Doxygen::classSDict); - ClassDef *cd; + const ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) { generateXMLForClass(cd,t); @@ -1982,7 +2001,7 @@ void generateXML() // } //} NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); - NamespaceDef *nd; + const NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { msg("Generating XML output for namespace %s\n",nd->name().data()); @@ -2001,7 +2020,7 @@ void generateXML() } } GroupSDict::Iterator gli(*Doxygen::groupSDict); - GroupDef *gd; + const GroupDef *gd; for (;(gd=gli.current());++gli) { msg("Generating XML output for group %s\n",gd->name().data()); diff --git a/src/xmlgen.h b/src/xmlgen.h index 0555546..4458b9f 100644 --- a/src/xmlgen.h +++ b/src/xmlgen.h @@ -39,7 +39,7 @@ class XMLCodeGenerator : public CodeOutputInterface void writeCodeAnchor(const char *); void writeLineNumber(const char *extRef,const char *compId, const char *anchorId,int l); - void setCurrentDoc(Definition *,const char *,bool){} + void setCurrentDoc(const Definition *,const char *,bool){} void addWord(const char *,bool){} void finish(); diff --git a/src/xmlscanner.h b/src/xmlscanner.h index 6053b96..cb9792c 100644 --- a/src/xmlscanner.h +++ b/src/xmlscanner.h @@ -41,9 +41,9 @@ public: int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, - MemberDef *memberDef=0, + const MemberDef *memberDef=0, bool showLineNumbers=TRUE, - Definition *searchCtx=0, + const Definition *searchCtx=0, bool collectXRefs=TRUE ) { |