diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/classdef.cpp | 60 | ||||
-rw-r--r-- | src/classdef.h | 1 | ||||
-rw-r--r-- | src/code.l | 10 | ||||
-rw-r--r-- | src/config.h | 1 | ||||
-rw-r--r-- | src/config.l | 16 | ||||
-rw-r--r-- | src/dot.cpp | 231 | ||||
-rw-r--r-- | src/dot.h | 23 | ||||
-rw-r--r-- | src/doxygen.cpp | 114 | ||||
-rw-r--r-- | src/groupdef.cpp | 146 | ||||
-rw-r--r-- | src/groupdef.h | 19 | ||||
-rw-r--r-- | src/htmlgen.cpp | 4 | ||||
-rw-r--r-- | src/htmlgen.h | 4 | ||||
-rw-r--r-- | src/index.cpp | 1 | ||||
-rw-r--r-- | src/latexgen.cpp | 37 | ||||
-rw-r--r-- | src/latexgen.h | 4 | ||||
-rw-r--r-- | src/mangen.h | 4 | ||||
-rw-r--r-- | src/memberdef.cpp | 11 | ||||
-rw-r--r-- | src/memberlist.cpp | 62 | ||||
-rw-r--r-- | src/outputgen.h | 6 | ||||
-rw-r--r-- | src/outputlist.cpp | 2 | ||||
-rw-r--r-- | src/outputlist.h | 12 | ||||
-rw-r--r-- | src/rtfgen.cpp | 4 | ||||
-rw-r--r-- | src/rtfgen.h | 4 | ||||
-rw-r--r-- | src/scanner.l | 10 | ||||
-rw-r--r-- | src/util.cpp | 15 | ||||
-rw-r--r-- | src/util.h | 4 |
26 files changed, 528 insertions, 277 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp index eeeee96..3d5b4ce 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -243,7 +243,7 @@ void ClassDef::insertMember(MemberDef *md,int groupId) break; } } - else if (md->isTypedef() || md->isEnumerate()) + else if (md->isTypedef() || md->isEnumerate() || md->isEnumValue()) { switch (md->protection()) { @@ -675,8 +675,25 @@ void ClassDef::writeDocumentation(OutputList &ol) if ( icd->isVisibleInHierarchy()) count++; ibcd=inherits->next(); } - if (Config::classDiagramFlag && count>0) - // write class diagram + + + if (Config::haveDotFlag && Config::classGraphFlag) + // write class diagram using dot + { + DotClassGraph inheritanceGraph(this,DotClassGraph::Inheritance); + if (!inheritanceGraph.isTrivial()) + { + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::Man); + ol.startDotGraph(); + parseText(ol,theTranslator->trClassDiagram(name())); + ol.endDotGraph(inheritanceGraph); + ol.popGeneratorState(); + } + } + else if (Config::classDiagramFlag && count>0) + // write class diagram using build-in generator { ClassDiagram diagram(this); // create a diagram of this class. ol.startClassDiagram(); @@ -688,20 +705,16 @@ void ClassDef::writeDocumentation(OutputList &ol) if (Config::haveDotFlag && Config::collGraphFlag) { - DotGfxUsageGraph usageImplGraph(this,TRUE); + DotClassGraph usageImplGraph(this,DotClassGraph::Implementation); if (!usageImplGraph.isTrivial()) { + ol.pushGeneratorState(); ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::Man); - ol.startCollaborationDiagram(); + ol.startDotGraph(); parseText(ol,theTranslator->trCollaborationDiagram(name())); - //usageImplGraph.writeGraph(Config::htmlOutputDir); - //ol.writeString((QCString)"<p>Interface collaboration diagram for " - // "<a href=\"usage_intf_graph_"+name()+".html\">here</a>"); - //ol.writeString((QCString)"<p>Implementation collaboration diagram for " - // "<a href=\"usage_impl_graph_"+name()+".html\">here</a>"); - ol.endCollaborationDiagram(usageImplGraph); - ol.enableAll(); + ol.endDotGraph(usageImplGraph); + ol.popGeneratorState(); } } @@ -1616,6 +1629,7 @@ void ClassDef::determineImplUsageRelation() if (md->isVariable()) // for each member variable in this class { QCString type=md->typeString(); + int typeLen=type.length(); static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*"); //printf("in class %s found var type=`%s' name=`%s'\n", // name().data(),type.data(),md->name().data()); @@ -1623,17 +1637,35 @@ void ClassDef::determineImplUsageRelation() bool found=FALSE; while ((i=re.match(type,p,&l))!=-1 && !found) // for each class name in the type { + int ts=p+l; + int te=ts; + while (type.at(ts)==' ' && ts<typeLen) ts++; // skip any whitespace + if (type.at(ts)=='<') // assume template instance + { + // locate end of template + te=ts+1; + int brCount=1; + while (te<typeLen && brCount!=0) + { + if (type.at(te)=='<') brCount++; + if (type.at(te)=='>') brCount--; + te++; + } + } + QCString templSpec; + if (te>ts) templSpec = type.mid(ts,te-ts); ClassDef *cd=getResolvedClass(name()+"::"+type.mid(i,l)); if (cd==0) cd=getResolvedClass(type.mid(i,l)); // TODO: also try inbetween scopes! - if (cd /*&& cd->isLinkable()*/) // class exists and is linkable + if (cd) // class exists { found=TRUE; if (usesImplClassDict==0) usesImplClassDict = new UsesClassDict(257); UsesClassDef *ucd=usesImplClassDict->find(cd->name()); - if (ucd==0) + if (ucd==0 || ucd->templSpecifiers!=templSpec) { ucd = new UsesClassDef(cd); usesImplClassDict->insert(cd->name(),ucd); + ucd->templSpecifiers = templSpec; //printf("Adding used class %s to class %s\n", // cd->name().data(),name().data()); } diff --git a/src/classdef.h b/src/classdef.h index 817d50c..deeaddc 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -198,6 +198,7 @@ struct UsesClassDef } ClassDef *classDef; QDict<void> *accessors; + QCString templSpecifiers; }; class UsesClassDict : public QDict<UsesClassDef> @@ -965,7 +965,15 @@ TYPEKW ("bool"|"char"|"const"|"double"|"float"|"int"|"long"|"short"|"signed"|"u { startCodeLine(*g_code); } - BEGIN(g_lastSpecialCContext); + if (g_lastSpecialCContext==SkipCxxComment) + { // force end of C++ comment here + endFontClass(); + BEGIN( g_lastCContext ) ; + } + else + { + BEGIN(g_lastSpecialCContext); + } } <RemoveSpecialCComment>"*/" { BEGIN(g_lastSpecialCContext); diff --git a/src/config.h b/src/config.h index a4ed72d..71ac028 100644 --- a/src/config.h +++ b/src/config.h @@ -106,6 +106,7 @@ struct Config static bool allExtFlag; // include all external classes flag static QCString perlPath; // the absolute path to perl static bool haveDotFlag; // indicates wether or not dot is present + static bool classGraphFlag; // class graph static bool collGraphFlag; // collaboration graph static bool includeGraphFlag; // include graph static bool gfxHierarchyFlag; // flag to enable graphical hierarchy diff --git a/src/config.l b/src/config.l index 05ae799..1f75428 100644 --- a/src/config.l +++ b/src/config.l @@ -138,6 +138,7 @@ QCString Config::genTagFile; bool Config::allExtFlag = FALSE; QCString Config::perlPath = "/usr/bin/perl"; bool Config::haveDotFlag = FALSE; +bool Config::classGraphFlag = TRUE; bool Config::collGraphFlag = TRUE; bool Config::includeGraphFlag = TRUE; bool Config::gfxHierarchyFlag = TRUE; @@ -275,6 +276,7 @@ static int yyread(char *buf,int max_size) <Start>"ALLEXTERNALS"[ \t]*"=" { BEGIN(GetBool); b=&Config::allExtFlag; } <Start>"PERL_PATH"[ \t]*"=" { BEGIN(GetString); s=&Config::perlPath; s->resize(0); } <Start>"HAVE_DOT"[ \t]*"=" { BEGIN(GetBool); b=&Config::haveDotFlag; } +<Start>"CLASS_GRAPH"[ \t]*"=" { BEGIN(GetBool); b=&Config::classGraphFlag; } <Start>"COLLABORATION_GRAPH"[ \t]*"=" { BEGIN(GetBool); b=&Config::collGraphFlag; } <Start>"INCLUDE_GRAPH"[ \t]*"=" { BEGIN(GetBool); b=&Config::includeGraphFlag; } <Start>"GRAPHICAL_HIERARCHY"[ \t]*"=" { BEGIN(GetBool); b=&Config::gfxHierarchyFlag; } @@ -557,6 +559,7 @@ void dumpConfig() printf("perlPath=`%s'\n",Config::perlPath.data()); printf("# Configuration options related to the dot tool \n"); printf("haveDotFlag=`%d'\n",Config::haveDotFlag); + printf("classGraphFlag=`%d'\n",Config::classGraphFlag); printf("collGraphFlag=`%d'\n",Config::collGraphFlag); printf("includeGraphFlag=`%d'\n",Config::includeGraphFlag); printf("gfxHierarchyFlag=`%d'\n",Config::gfxHierarchyFlag); @@ -654,6 +657,7 @@ void Config::init() Config::allExtFlag = FALSE; Config::perlPath = "/usr/bin/perl"; Config::haveDotFlag = FALSE; + Config::classGraphFlag = TRUE; Config::collGraphFlag = TRUE; Config::includeGraphFlag = TRUE; Config::gfxHierarchyFlag = TRUE; @@ -1634,6 +1638,18 @@ void writeTemplateConfig(QFile *f,bool sl) if (!sl) { t << "\n"; + t << "# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \n"; + t << "# will generate a graph for each documented class showing the direct and \n"; + t << "# indirect inheritance relations. Setting this tag to YES will force the \n"; + t << "# the CLASS_DIAGRAMS tag to NO.\n"; + t << "\n"; + } + t << "CLASS_GRAPH = "; + writeBoolValue(t,Config::classGraphFlag); + t << "\n"; + if (!sl) + { + t << "\n"; t << "# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \n"; t << "# will generate a graph for each documented class showing the direct and \n"; t << "# indirect implementation dependencies (inheritance, containment, and \n"; diff --git a/src/dot.cpp b/src/dot.cpp index 211ffa3..8587866 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -312,14 +312,15 @@ void DotNode::writeBox(QTextStream &t,bool hasNonReachableChildren) t << "];" << endl; } -void DotNode::writeArrow(QTextStream &t,DotNode *cn,EdgeInfo *ei,bool topDown) +void DotNode::writeArrow(QTextStream &t,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 << " ["; - t << "dir=back,"; + if (pointBack) t << "dir=back,"; t << "color=\"" << edgeColorMap[ei->m_color] << "\",fontsize=10,style=\"" << edgeStyleMap[ei->m_style] << "\""; if (!ei->m_label.isEmpty()) @@ -330,15 +331,16 @@ void DotNode::writeArrow(QTextStream &t,DotNode *cn,EdgeInfo *ei,bool topDown) t << "];" << endl; } -void DotNode::write(QTextStream &t,bool topDown,int distance) +void DotNode::write(QTextStream &t,bool topDown,bool toChildren,int distance) { //printf("DotNode::write(%d) name=%s\n",distance,m_label.data()); if (m_written) return; // node already written to the output if (m_distance>distance) return; + QList<DotNode> *nl = toChildren ? m_children : m_parents; bool hasNonReachableChildren=FALSE; - if (m_distance==distance && m_children) + if (m_distance==distance && nl) { - QListIterator<DotNode> dnli(*m_children); + QListIterator<DotNode> dnli(*nl); DotNode *cn; for (dnli.toFirst();(cn=dnli.current());++dnli) { @@ -347,15 +349,38 @@ void DotNode::write(QTextStream &t,bool topDown,int distance) } writeBox(t,hasNonReachableChildren); m_written=TRUE; - if (m_children) + if (nl) { - QListIterator<DotNode> dnli1(*m_children); - QListIterator<EdgeInfo> dnli2(*m_edgeInfo); - DotNode *cn; - for (dnli1.toFirst();(cn=dnli1.current());++dnli1,++dnli2) + if (toChildren) { - if (cn->m_distance<=distance) writeArrow(t,cn,dnli2.current(),topDown); - cn->write(t,topDown,distance); + QListIterator<DotNode> dnli1(*nl); + QListIterator<EdgeInfo> dnli2(*m_edgeInfo); + DotNode *cn; + for (dnli1.toFirst();(cn=dnli1.current());++dnli1,++dnli2) + { + if (cn->m_distance<=distance) + { + writeArrow(t,cn,dnli2.current(),topDown); + } + cn->write(t,topDown,toChildren,distance); + } + } + else // render parents + { + QListIterator<DotNode> dnli(*nl); + DotNode *pn; + for (dnli.toFirst();(pn=dnli.current());++dnli) + { + if (pn->m_distance<=distance) + { + writeArrow(t, + pn, + pn->m_edgeInfo->at(pn->m_children->findRef(this)), + FALSE + ); + } + pn->write(t,TRUE,FALSE,distance); + } } } } @@ -510,7 +535,7 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path) DotNode *node; for (;(node=dnli2.current());++dnli2) { - if (node->m_subgraphId==n->m_subgraphId) node->write(t,FALSE); + if (node->m_subgraphId==n->m_subgraphId) node->write(t,FALSE,TRUE); } t << "}" << endl; f.close(); @@ -712,82 +737,106 @@ DotGfxHierarchyTable::~DotGfxHierarchyTable() //-------------------------------------------------------------------- -int DotGfxUsageGraph::m_curNodeNumber; +int DotClassGraph::m_curNodeNumber; -void DotGfxUsageGraph::addClass(ClassDef *cd,DotNode *n,int prot, - const char *label,int distance) +void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot, + const char *label,int distance,const char *templSpec,bool base) { //printf(":: DoxGfxUsageGraph::addClass(class=%s,parent=%s,prot=%d,label=%s,dist=%d)\n", // cd->name().data(),n->m_label.data(),prot,label,distance); int edgeStyle = label ? EdgeInfo::Dashed : EdgeInfo::Solid; - DotNode *bn = m_usedNodes->find(cd->name()); + QCString className; + if (templSpec) + className=insertTemplateSpecifierInScope(cd->name(),templSpec); + else + className=cd->name().copy(); + DotNode *bn = m_usedNodes->find(className); if (bn) // class already inserted { - n->addChild(bn,prot,edgeStyle,label); - bn->addParent(n); + 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 { bn = new DotNode(m_curNodeNumber++, - cd->name(), + className, cd->isLinkable() ? (cd->getReference()+"$"+cd->getOutputFileBase()).data() : 0, distance ); if (distance>m_maxDistance) m_maxDistance=distance; - n->addChild(bn,prot,edgeStyle,label); - bn->addParent(n); - m_usedNodes->insert(cd->name(),bn); + if (base) + { + n->addChild(bn,prot,edgeStyle,label); + bn->addParent(n); + } + else + { + bn->addChild(n,prot,edgeStyle,label); + n->addParent(bn); + } + m_usedNodes->insert(className,bn); //printf(" add used node %s of %s\n",cd->name().data(),n->m_label.data()); - if (distance<m_recDepth) buildGraph(cd,bn,distance+1); + if (distance<m_recDepth) buildGraph(cd,bn,distance+1,base); } } -void DotGfxUsageGraph::buildGraph(ClassDef *cd,DotNode *n,int distance) +void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base) { - // add base classes - BaseClassListIterator bcli(*cd->baseClasses()); + BaseClassListIterator bcli(base ? *cd->baseClasses() : *cd->superClasses()); BaseClassDef *bcd; for ( ; (bcd=bcli.current()) ; ++bcli ) { - addClass(bcd->classDef,n,bcd->prot,0,distance); + addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->templSpecifiers,base); } - UsesClassDict *dict = m_impl ? cd->usedImplementationClasses() : - cd->usedInterfaceClasses(); - if (dict) + if (m_graphType != Inheritance) { - UsesClassDictIterator ucdi(*dict); - UsesClassDef *ucd; - for (;(ucd=ucdi.current());++ucdi) + UsesClassDict *dict = + m_graphType==Implementation ? cd->usedImplementationClasses() : + cd->usedInterfaceClasses(); + if (dict) { - QCString label; - QDictIterator<void> dvi(*ucd->accessors); - const char *s; - bool first=TRUE; - for (;(s=dvi.currentKey());++dvi) + UsesClassDictIterator ucdi(*dict); + UsesClassDef *ucd; + for (;(ucd=ucdi.current());++ucdi) { - if (first) - { - label=s; - first=FALSE; - } - else + QCString label; + QDictIterator<void> dvi(*ucd->accessors); + const char *s; + bool first=TRUE; + for (;(s=dvi.currentKey());++dvi) { - label+=QCString("\\n")+s; + if (first) + { + label=s; + first=FALSE; + } + else + { + label+=QCString("\\n")+s; + } } + //printf("Found label=`%s'\n",label.data()); + addClass(ucd->classDef,n,EdgeInfo::Black,label,distance,ucd->templSpecifiers,base); } - //printf("Found label=`%s'\n",label.data()); - addClass(ucd->classDef,n,EdgeInfo::Black,label,distance); } } } -DotGfxUsageGraph::DotGfxUsageGraph(ClassDef *cd,bool impl,int maxRecursionDepth) +DotClassGraph::DotClassGraph(ClassDef *cd,GraphType t,int maxRecursionDepth) { //printf("DotGfxUsage::DotGfxUsage %s\n",cd->name().data()); - m_impl = impl; + m_graphType = t; m_maxDistance = 0; m_recDepth = maxRecursionDepth; m_startNode = new DotNode(m_curNodeNumber++, @@ -800,25 +849,33 @@ DotGfxUsageGraph::DotGfxUsageGraph(ClassDef *cd,bool impl,int maxRecursionDepth) m_usedNodes = new QDict<DotNode>(1009); m_usedNodes->insert(cd->name(),m_startNode); //printf("Root node %s\n",cd->name().data()); - if (m_recDepth>0) buildGraph(cd,m_startNode,1); + if (m_recDepth>0) + { + buildGraph(cd,m_startNode,1,TRUE); + if (t==Inheritance) buildGraph(cd,m_startNode,1,FALSE); + } m_diskName = cd->getOutputFileBase().copy(); } -bool DotGfxUsageGraph::isTrivial() const +bool DotClassGraph::isTrivial() const { - return m_startNode->m_children==0; + if (m_graphType==Inheritance) + return m_startNode->m_children==0 && m_startNode->m_parents==0; + else + return m_startNode->m_children==0; } -DotGfxUsageGraph::~DotGfxUsageGraph() +DotClassGraph::~DotClassGraph() { deleteNodes(m_startNode); delete m_usedNodes; } -static void writeDotGraph(DotNode *root,const QCString &baseName, - bool lrRank,int distance) +void writeDotGraph(DotNode *root,const QCString &baseName, + bool lrRank,bool renderParents,int distance) { // generate the graph description for dot + //printf("writeDotGraph(%s,%d)\n",baseName.data(),renderParents); QFile f; f.setName(baseName+".dot"); if (f.open(IO_WriteOnly)) @@ -831,7 +888,25 @@ static void writeDotGraph(DotNode *root,const QCString &baseName, t << " rankdir=LR;" << endl; } root->clearWriteFlag(); - root->write(t,TRUE,distance); + root->write(t,TRUE,TRUE,distance); + if (renderParents && root->m_parents) + { + //printf("rendering parents!\n"); + QListIterator<DotNode> dnli(*root->m_parents); + DotNode *pn; + for (dnli.toFirst();(pn=dnli.current());++dnli) + { + if (pn->m_distance<=distance) + { + root->writeArrow(t, + pn, + pn->m_edgeInfo->at(pn->m_children->findRef(root)), + FALSE + ); + } + pn->write(t,TRUE,FALSE,distance); + } + } t << "}" << endl; f.close(); } @@ -840,7 +915,8 @@ static void writeDotGraph(DotNode *root,const QCString &baseName, static void findMaximalDotGraph(DotNode *root,int maxDist, const QCString &baseName, QDir &thisDir, - bool lrRank=FALSE + bool lrRank=FALSE, + bool renderParents=FALSE ) { bool lastFit; @@ -854,7 +930,7 @@ static void findMaximalDotGraph(DotNode *root,int maxDist, // sized image (dimensions: maxImageWidth, maxImageHeight) do { - writeDotGraph(root,baseName,lrRank,curDistance); + writeDotGraph(root,baseName,lrRank,renderParents,curDistance); QCString dotCmd; // create annotated dot file @@ -891,19 +967,21 @@ static void findMaximalDotGraph(DotNode *root,int maxDist, if (!lastFit) { //printf("Using last fit %d\n",minDistance); - writeDotGraph(root,baseName, + writeDotGraph(root, + baseName, lrRank || (curDistance==1 && width>maxImageWidth), + renderParents, minDistance ); } } -QCString DotGfxUsageGraph::diskName() const +QCString DotClassGraph::diskName() const { return m_diskName + "_coll_graph"; } -void DotGfxUsageGraph::writeGraph(QTextStream &out, +void DotClassGraph::writeGraph(QTextStream &out, const char *path, bool isTBRank) { @@ -919,14 +997,27 @@ void DotGfxUsageGraph::writeGraph(QTextStream &out, QDir thisDir; QCString baseName; - if (m_impl) - baseName.sprintf("%s_coll_graph",m_diskName.data()); - else - baseName.sprintf("%s_intf_graph",m_diskName.data()); + QCString mapName; + switch (m_graphType) + { + case Implementation: + baseName.sprintf("%s_coll_graph",m_diskName.data()); + mapName="coll_map"; + break; + case Interface: + baseName.sprintf("%s_intf_graph",m_diskName.data()); + mapName="intf_map"; + break; + case Inheritance: + baseName.sprintf("%s_inherit_graph",m_diskName.data()); + mapName="inherit_map"; + break; + } // TODO: make sure curDistance>0 - findMaximalDotGraph(m_startNode,m_maxDistance,baseName,thisDir,!isTBRank); + findMaximalDotGraph(m_startNode,m_maxDistance,baseName, + thisDir,!isTBRank,m_graphType==Inheritance); // run dot to create a .gif image QCString dotCmd; @@ -948,12 +1039,12 @@ void DotGfxUsageGraph::writeGraph(QTextStream &out, //printf("dot -Timap %s.dot -o %s.map\n",baseName.data(),baseName.data()); out << "<p><center><img src=\"" << baseName << ".gif\" border=\"0\" usemap=\"#" - << m_startNode->m_label << "_impl_map\"></center>" << endl; - out << "<map name=\"" << m_startNode->m_label << "_impl_map\">" << endl; + << m_startNode->m_label << "_" << mapName << "\"></center>" << endl; + out << "<map name=\"" << m_startNode->m_label << "_" << mapName << "\">" << endl; convertMapFile(out,baseName+".map"); out << "</map><p>" << endl; - thisDir.remove(baseName+".dot"); + //thisDir.remove(baseName+".dot"); thisDir.remove(baseName+".map"); QDir::setCurrent(oldDir); @@ -41,9 +41,11 @@ struct EdgeInfo class DotNode { friend class DotGfxHierarchyTable; - friend class DotGfxUsageGraph; + friend class DotClassGraph; friend class DotInclDepGraph; friend class DotNodeList; + friend void writeDotGraph(DotNode *root,const QCString &baseName, + bool lrRank,bool renderParents,int distance); public: DotNode(int n,const char *lab,const char *url,int distance = 0,bool rootNode=FALSE); ~DotNode(); @@ -60,14 +62,15 @@ class DotNode void removeChild(DotNode *n); void removeParent(DotNode *n); int number() const { return m_number; } - void write(QTextStream &t,bool topDown,int maxDistance=1000); + void write(QTextStream &t,bool topDown,bool toChildren,int maxDistance=1000); int m_subgraphId; void clearWriteFlag(); private: void colorConnectedNodes(int curColor); void writeBox(QTextStream &t,bool hasNonReachableChildren); - void writeArrow(QTextStream &t,DotNode *cn,EdgeInfo *ei,bool topDown); + void writeArrow(QTextStream &t,DotNode *cn,EdgeInfo *ei,bool topDown, + bool pointBack=TRUE); const DotNode *findDocNode() const; // only works for acyclic graphs! int m_number; QCString m_label; //!< label text @@ -98,22 +101,24 @@ class DotGfxHierarchyTable DotNodeList *m_rootSubgraphs; }; -class DotGfxUsageGraph +class DotClassGraph { public: - DotGfxUsageGraph(ClassDef *cd,bool impl,int maxRecusionDepth=1000); - ~DotGfxUsageGraph(); + enum GraphType { Interface, Implementation, Inheritance }; + DotClassGraph(ClassDef *cd,GraphType t,int maxRecusionDepth=1000); + ~DotClassGraph(); bool isTrivial() const; void writeGraph(QTextStream &t,const char *path,bool TBRank=TRUE); QCString diskName() const; private: - void buildGraph(ClassDef *cd,DotNode *n,int level); - void addClass(ClassDef *cd,DotNode *n,int prot,const char *label,int level); + void buildGraph(ClassDef *cd,DotNode *n,int level,bool base); + void addClass(ClassDef *cd,DotNode *n,int prot,const char *label, + int level,const char *templSpec,bool base); DotNode *m_startNode; QDict<DotNode> *m_usedNodes; static int m_curNodeNumber; - bool m_impl; + GraphType m_graphType; int m_recDepth; QCString m_diskName; int m_maxDistance; diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 7ce7f67..c40a4da 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -154,7 +154,7 @@ int documentedIncludeFiles; QTextStream tagFile; void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl, - bool over_load); + bool over_load,NamespaceList *nl=0); const char idMask[] = "[A-Za-z_][A-Za-z_0-9]*"; QCString spaces; @@ -195,6 +195,7 @@ void buildGroupList(Entry *root) gd->addSectionsToDefinition(root->anchors); groupList.append(gd); groupDict.insert(root->name,gd); + addGroupToGroups(root,gd); } } EntryListIterator eli(*root->sublist); @@ -407,48 +408,6 @@ static bool addNamespace(Entry *root,ClassDef *cd) return FALSE; } -static void addClassToGroups(Entry *root,ClassDef *cd) -{ - QListIterator<QCString> sli(*root->groups); - QCString *s; - for (;(s=sli.current());++sli) - { - GroupDef *gd=0; - if (!s->isEmpty() && (gd=groupDict[*s])) - { - gd->addClass(cd); - //printf("Compound %s: in group %s\n",cd->name().data(),s->data()); - } - } -} - -static void addMemberToGroups(Entry *root,MemberDef *md) -{ - QListIterator<QCString> sli(*root->groups); - QCString *s; - for (;(s=sli.current());++sli) - { - GroupDef *gd=0; - if (!s->isEmpty() && (gd=groupDict[*s])) - { - GroupDef *mgd = md->groupDef(); - if (mgd==0) - { - gd->insertMember(md,root->mGrpId); - md->setGroupDef(gd); - } - else if (mgd!=gd) - { - warn("Warning: Member %s found in multiple groups.!\n" - "The member will be put in group %s, and not in group %s", - md->name().data(),mgd->name().data(),gd->name().data() - ); - } - //printf("Member %s: in group %s\n",md->name().data(),s->data()); - } - } -} - //---------------------------------------------------------------------- // build a list of all classes mentioned in the documentation // and all classes that have a documentation block before their definition. @@ -689,14 +648,8 @@ void buildNamespaceList(Entry *root) nd->setBriefDescription(root->brief); nd->addSectionsToDefinition(root->anchors); - QListIterator<QCString> sli(*root->groups); - QCString *s; - for (;(s=sli.current());++sli) - { - GroupDef *gd=0; - if (!s->isEmpty() && (gd=groupDict[*s])) - gd->addNamespace(nd); - } + //printf("Adding namespace to group\n"); + addNamespaceToGroups(root,nd); bool ambig; // file definition containing the namespace nd @@ -710,6 +663,7 @@ void buildNamespaceList(Entry *root) // add class to the list namespaceList.inSort(nd); namespaceDict.insert(fullName,nd); + } } } @@ -783,6 +737,39 @@ void findUsingDirectives(Entry *root) fd->addUsingDirective(usingNd); } } + else // unknown namespace, but add it anyway. + { + NamespaceDef *nd=new NamespaceDef(root->name); + nd->setDocumentation(root->doc); // copy docs to definition + nd->setBriefDescription(root->brief); + nd->addSectionsToDefinition(root->anchors); + + QListIterator<QCString> sli(*root->groups); + QCString *s; + for (;(s=sli.current());++sli) + { + GroupDef *gd=0; + if (!s->isEmpty() && (gd=groupDict[*s])) + gd->addNamespace(nd); + } + + bool ambig; + // file definition containing the namespace nd + FileDef *fd=findFileDef(&inputNameDict,root->fileName,ambig); + // insert the namespace in the file definition + if (fd) + { + fd->insertNamespace(nd); + fd->addUsingDirective(nd); + } + + // the empty string test is needed for extract all case + nd->setBriefDescription(root->brief); + nd->insertUsedFile(root->fileName); + // add class to the list + namespaceList.inSort(nd); + namespaceDict.insert(root->name,nd); + } } } EntryListIterator eli(*root->sublist); @@ -1961,7 +1948,7 @@ void computeMemberReferences() // over_load is set the standard overload text is added. void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl, - bool over_load) + bool over_load,NamespaceList *nl) { //printf("addMemberDocs: `%s'::`%s' `%s' funcDecl=`%s'\n", // root->parent->name.data(),md->name().data(),md->argsString(),funcDecl); @@ -1973,7 +1960,9 @@ void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl, NamespaceDef *nd=md->getNamespace(); if (matchArguments(md->argumentList(),root->argList, cd ? cd->name().data() : 0, - nd ? nd->name().data() : 0 + nd ? nd->name().data() : 0, + TRUE, + nl ) ) { @@ -2715,10 +2704,16 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded, ); // TODO: match loop for all possible scopes + + bool ambig; + FileDef *fd=findFileDef(&inputNameDict,root->fileName,ambig); + // list of namespaces using in the file that this member definition is part of + NamespaceList *nl = fd ? fd->getUsedNamespaces() : 0; + bool matching= md->isVariable() || md->isTypedef() || // needed for function pointers (md->argumentList()==0 && root->argList->count()==0) || - matchArguments(argList, root->argList,className,namespaceName); + matchArguments(argList, root->argList,className,namespaceName,TRUE,nl); Debug::print(Debug::FindMembers,0, "6. match results = %d\n",matching); @@ -2742,7 +2737,7 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded, { //printf("addMemberDocs root->inLine=%d md->isInline()=%d\n", // root->inLine,md->isInline()); - addMemberDocs(root,md,funcDecl,overloaded); + addMemberDocs(root,md,funcDecl,overloaded,nl); count++; } } @@ -4533,7 +4528,8 @@ int readDir(QFileInfo *fi, err("Error: source %s is not a readable file or directory... skipping.\n",cfi->absFilePath().data()); } else if (cfi->isFile() && - patternMatch(cfi,patList) && !patternMatch(cfi,exclPatList)) + (patList==0 || patternMatch(cfi,patList)) && + !patternMatch(cfi,exclPatList)) { totalSize+=cfi->size()+cfi->absFilePath().length()+4; QCString name=convertToQCString(cfi->fileName()); @@ -4991,13 +4987,13 @@ int main(int argc,char **argv) msg("Freeing input...\n"); input.resize(0); + msg("Building group list...\n"); + buildGroupList(root); + msg("Building namespace list...\n"); buildNamespaceList(root); findUsingDirectives(root); - msg("Building group list...\n"); - buildGroupList(root); - //msg("Computing group relations...\n"); //computeGroupRelations(root); diff --git a/src/groupdef.cpp b/src/groupdef.cpp index a13ddd8..255c200 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -36,7 +36,8 @@ GroupDef::GroupDef(const char *na,const char *t) : { fileList = new FileList; classList = new ClassList; -// groupList = new GroupList; + groupList = new GroupList; + namespaceList = new NamespaceList; allMemberList = new MemberList; allMemberDict = new QDict<MemberDef>; @@ -57,6 +58,10 @@ GroupDef::~GroupDef() { delete fileList; delete classList; + delete groupList; + delete namespaceList; + delete allMemberList; + delete allMemberDict; delete memberGroupList; delete memberGroupDict; } @@ -120,14 +125,18 @@ void GroupDef::insertMember(MemberDef *md,int groupId) } } -//void GroupDef::addGroup(const GroupDef *def) -//{ -// groupList->append(def); -//} +void GroupDef::addGroup(const GroupDef *def) +{ + groupList->append(def); +} int GroupDef::countMembers() const { - return fileList->count()+classList->count()+allMemberList->count(); + return fileList->count()+ + classList->count()+ + namespaceList->count()+ + groupList->count()+ + allMemberList->count(); } /*! Compute the HTML anchor names for all members in the class */ @@ -188,6 +197,55 @@ void GroupDef::writeDocumentation(OutputList &ol) } ol.endMemberList(); } + if (namespaceList->count()>0) + { + ol.startMemberHeader(); + parseText(ol,theTranslator->trNamespaces()); + ol.endMemberHeader(); + ol.startMemberList(); + NamespaceDef *nd=namespaceList->first(); + while (nd) + { + ol.startMemberItem(0); + ol.docify("namespace"); + ol.insertMemberAlign(); + ol.writeObjectLink(nd->getReference(),nd->getOutputFileBase(),0,nd->name()); + ol.endMemberItem(FALSE); + if (!nd->briefDescription().isEmpty() && Config::briefMemDescFlag) + { + ol.startMemberDescription(); + parseDoc(ol,0,0,nd->briefDescription()); + ol.endMemberDescription(); + ol.newParagraph(); + } + nd=namespaceList->next(); + } + ol.endMemberList(); + } + if (groupList->count()>0) + { + ol.startMemberHeader(); + parseText(ol,theTranslator->trModules()); + ol.endMemberHeader(); + ol.startMemberList(); + GroupDef *gd=groupList->first(); + while (gd) + { + ol.startMemberItem(0); + //ol.insertMemberAlign(); + ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),0,gd->groupTitle()); + ol.endMemberItem(FALSE); + if (!gd->briefDescription().isEmpty() && Config::briefMemDescFlag) + { + ol.startMemberDescription(); + parseDoc(ol,0,0,gd->briefDescription()); + ol.endMemberDescription(); + ol.newParagraph(); + } + gd=groupList->next(); + } + ol.endMemberList(); + } classList->writeDeclaration(ol); @@ -303,3 +361,79 @@ void GroupDef::writeDocumentation(OutputList &ol) endFile(ol); ol.popGeneratorState(); } + +//---- helper functions ------------------------------------------------------ + +void addClassToGroups(Entry *root,ClassDef *cd) +{ + QListIterator<QCString> sli(*root->groups); + QCString *s; + for (;(s=sli.current());++sli) + { + GroupDef *gd=0; + if (!s->isEmpty() && (gd=groupDict[*s])) + { + gd->addClass(cd); + //printf("Compound %s: in group %s\n",cd->name().data(),s->data()); + } + } +} + +void addNamespaceToGroups(Entry *root,NamespaceDef *nd) +{ + //printf("root->groups->count()=%d\n",root->groups->count()); + QListIterator<QCString> sli(*root->groups); + QCString *s; + for (;(s=sli.current());++sli) + { + GroupDef *gd=0; + //printf("group `%s'\n",s->data()); + if (!s->isEmpty() && (gd=groupDict[*s])) + { + gd->addNamespace(nd); + //printf("Namespace %s: in group %s\n",nd->name().data(),s->data()); + } + } +} + +void addGroupToGroups(Entry *root,GroupDef *subGroup) +{ + QListIterator<QCString> sli(*root->groups); + QCString *s; + for (;(s=sli.current());++sli) + { + GroupDef *gd=0; + if (!s->isEmpty() && (gd=groupDict[*s])) + { + gd->addGroup(subGroup); + } + } +} + +void addMemberToGroups(Entry *root,MemberDef *md) +{ + QListIterator<QCString> sli(*root->groups); + QCString *s; + for (;(s=sli.current());++sli) + { + GroupDef *gd=0; + if (!s->isEmpty() && (gd=groupDict[*s])) + { + GroupDef *mgd = md->groupDef(); + if (mgd==0) + { + gd->insertMember(md,root->mGrpId); + md->setGroupDef(gd); + } + else if (mgd!=gd) + { + warn("Warning: Member %s found in multiple groups.!\n" + "The member will be put in group %s, and not in group %s", + md->name().data(),mgd->name().data(),gd->name().data() + ); + } + //printf("Member %s: in group %s\n",md->name().data(),s->data()); + } + } +} + diff --git a/src/groupdef.h b/src/groupdef.h index f35536a..03adc17 100644 --- a/src/groupdef.h +++ b/src/groupdef.h @@ -41,12 +41,12 @@ class GroupDef : public Definition public: GroupDef(const char *name,const char *title); ~GroupDef(); - //const char *groupFile() const { return fileName; } QCString getOutputFileBase() const { return fileName; } const char *groupTitle() const { return title; } void addFile(const FileDef *def); void addClass(const ClassDef *def); void addNamespace(const NamespaceDef *def); + void addGroup(const GroupDef *def); void insertMember(MemberDef *def,int groupId); void addMemberToGroup(MemberDef *def,int groupId); void writeDocumentation(OutputList &ol); @@ -64,13 +64,15 @@ class GroupDef : public Definition private: QCString title; // title of the group QCString fileName; // base name of the generated file - FileList *fileList; // list of all files in the group - ClassList *classList; // list of all classes in the group - NamespaceList *namespaceList; // list of all namespace in the group + FileList *fileList; // list of files in the group + ClassList *classList; // list of classes in the group + NamespaceList *namespaceList; // list of namespaces in the group + GroupList *groupList; // list of sub groups. MemberList *allMemberList; // list of all members in the group QDict<MemberDef> *allMemberDict; - // members sorted to type + + // members sorted by type MemberList defineMembers; MemberList protoMembers; MemberList typedefMembers; @@ -80,7 +82,7 @@ class GroupDef : public Definition MemberList varMembers; /* user defined member groups */ - MemberGroupList *memberGroupList; + MemberGroupList *memberGroupList; // list of member groups in this group MemberGroupDict *memberGroupDict; }; @@ -95,4 +97,9 @@ class GroupListIterator : public QListIterator<GroupDef> GroupListIterator(const GroupList &l) : QListIterator<GroupDef>(l) {} }; +void addClassToGroups(Entry *root,ClassDef *cd); +void addNamespaceToGroups(Entry *root,NamespaceDef *nd); +void addGroupToGroups(Entry *root,GroupDef *subGroup); +void addMemberToGroups(Entry *root,MemberDef *md); + #endif diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 3d4b9c3..b71f7a0 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -784,11 +784,11 @@ void HtmlGenerator::endMemberDoc() t << "</table>" << endl; } -void HtmlGenerator::startCollaborationDiagram() +void HtmlGenerator::startDotGraph() { } -void HtmlGenerator::endCollaborationDiagram(DotGfxUsageGraph &g) +void HtmlGenerator::endDotGraph(DotClassGraph &g) { g.writeGraph(t,Config::htmlOutputDir); } diff --git a/src/htmlgen.h b/src/htmlgen.h index b111a25..3fdc67c 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -214,8 +214,8 @@ class HtmlGenerator : public OutputGenerator { t << "</td></tr>" << endl; } //static void docifyStatic(QTextStream &t,const char *str); - void startCollaborationDiagram(); - void endCollaborationDiagram(DotGfxUsageGraph &g); + void startDotGraph(); + void endDotGraph(DotClassGraph &g); void startInclDepGraph(); void endInclDepGraph(DotInclDepGraph &g); void writeGraphicalHierarchy(DotGfxHierarchyTable &g); diff --git a/src/index.cpp b/src/index.cpp index 1fdbea4..86d35c0 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -1449,6 +1449,7 @@ void writeGroupList(OutputList &ol) GroupDef *gd; for (;(gd=gli.current());++gli) { + //printf("gd->name()=%s #members=%d\n",gd->name().data(),gd->countMembers()); if (gd->countMembers()>0) { ol.startDescItem(); diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 7c32d86..ee822da 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -47,22 +47,21 @@ static QCString filterTitle(const char *s) return result; } -//static QCString escapeLabelName(const QCString &s) -//{ -// QCString result; -// uint i; -// for (i=0;i<s.length();i++) -// { -// char c=s.at(i); -// switch (c) -// { -// case '~': result+=".1"; break; -// case '%': result+=".2"; break; -// default: result+=c; -// } -// } -// return result; -//} +static QCString escapeLabelName(const QCString &s) +{ + QCString result; + uint i; + for (i=0;i<s.length();i++) + { + char c=s.at(i); + switch (c) + { + case '%': result+="\\%"; break; + default: result+=c; + } + } + return result; +} LatexGenerator::LatexGenerator() : OutputGenerator() @@ -861,11 +860,11 @@ void LatexGenerator::startMemberDoc(const char *clname, docify(clname); t << "}!"; } - t << memname << "@{"; + t << escapeLabelName(memname) << "@{"; docify(memname); t << "}}" << endl; - t << "\\index{" << memname << "@{"; + t << "\\index{" << escapeLabelName(memname) << "@{"; docify(memname); t << "}"; if (clname) @@ -921,7 +920,7 @@ void LatexGenerator::addToIndex(const char *s1,const char *s2) { if (s1) { - t << "\\index{" << s1 << "@{"; + t << "\\index{" << escapeLabelName(s1) << "@{"; docify(s1); t << "}"; if (s2) diff --git a/src/latexgen.h b/src/latexgen.h index d66f7bc..8945723 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -211,8 +211,8 @@ class LatexGenerator : public OutputGenerator //static void docifyStatic(QTextStream &t,const char *str); - void startCollaborationDiagram() {} - void endCollaborationDiagram(DotGfxUsageGraph &) {} + void startDotGraph() {} + void endDotGraph(DotClassGraph &) {} void startInclDepGraph() {} void endInclDepGraph(DotInclDepGraph &) {} void writeGraphicalHierarchy(DotGfxHierarchyTable &) {} diff --git a/src/mangen.h b/src/mangen.h index 00375c2..c68ec5c 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -197,8 +197,8 @@ class ManGenerator : public OutputGenerator void startDescTableData() { } void endDescTableData() {} - void startCollaborationDiagram() {} - void endCollaborationDiagram(DotGfxUsageGraph &) {} + void startDotGraph() {} + void endDotGraph(DotClassGraph &) {} void startInclDepGraph() {} void endInclDepGraph(DotInclDepGraph &) {} void writeGraphicalHierarchy(DotGfxHierarchyTable &) {} diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 7fc4b37..1980587 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -104,7 +104,8 @@ static void writeDefArgumentList(OutputList &ol,ClassDef *cd, bool first=TRUE; while (a) { - ol.startParameter(first); first=FALSE; + if (!md->isDefine()) ol.startParameter(first); else ol.docify(" "); + first=FALSE; QRegExp re(")("); int vp; if (!a->attrib.isEmpty()) // argument has an IDL attribute @@ -154,7 +155,7 @@ static void writeDefArgumentList(OutputList &ol,ClassDef *cd, if (a) { ol.docify(", "); // there are more arguments - ol.endParameter(FALSE); + if (!md->isDefine()) ol.endParameter(FALSE); } } ol.pushGeneratorState(); @@ -1004,7 +1005,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ol.docify("]"); ol.endTypewriter(); } - ol.endParameter(TRUE); + if (!isDefine()) ol.endParameter(TRUE); ol.endMemberDoc(); ol.endDoxyAnchor(); ol.startIndent(); @@ -1300,11 +1301,11 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, void MemberDef::warnIfUndocumented() { - //if (memberGroup) return; + if (memberGroup) return; ClassDef *cd = memberClass(); NamespaceDef *nd = getNamespace(); FileDef *fd = getFileDef(); - GroupDef *gd = groupDef(); + GroupDef *gd = groupDef(); Definition *d=0; const char *t=0; if (cd) diff --git a/src/memberlist.cpp b/src/memberlist.cpp index 80cb26d..430fb2d 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -119,67 +119,7 @@ void MemberList::countDocMembers() (Config::extractAllFlag || md->detailsAreVisible()) ) { - static QRegExp r("@[0-9]+"); - int dummy; - switch(md->memberType()) - { - case MemberDef::Enumeration: - if (r.match(md->name(),0,&dummy)==-1) - { - m_count++; - } - break; - case MemberDef::EnumValue: - { - MemberDef *scope; - scope=md->getEnumScope(); - if (scope && r.match(scope->name(),0,&dummy)!=-1) - m_count++; - } - break; - default: - m_count++; - break; - } - -// QRegExp r("@[0-9]+"); -// int dummy; -// switch(md->memberType()) -// { -// case MemberDef::Variable: -// varCnt++; -// break; -// case MemberDef::Function: -// case MemberDef::Signal: -// case MemberDef::Slot: -// funcCnt++; -// break; -// case MemberDef::Enumeration: -// if (r.match(md->name(),0,&dummy)==-1) -// { -// enumCnt++; -// } -// break; -// case MemberDef::EnumValue: -// { -// MemberDef *scope; -// scope=md->getEnumScope(); -// if (scope && r.match(scope->name(),0,&dummy)!=-1) -// enumValCnt++; -// } -// break; -// case MemberDef::Typedef: -// typeCnt++; -// break; -// case MemberDef::Prototype: -// protoCnt++; -// break; -// case MemberDef::Define: -// defCnt++; -// break; -// case MemberDef::Friend: -// friendCnt++; -// } + if (md->memberType()!=MemberDef::EnumValue) m_count++; } md=next(); } diff --git a/src/outputgen.h b/src/outputgen.h index ee0fb1e..add49b5 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -26,7 +26,7 @@ #include "index.h" class ClassDiagram; -class DotGfxUsageGraph; +class DotClassGraph; class DotInclDepGraph; class DotGfxHierarchyTable; @@ -200,8 +200,8 @@ class OutputGenerator virtual void startDescTableData() = 0; virtual void endDescTableData() = 0; - virtual void startCollaborationDiagram() = 0; - virtual void endCollaborationDiagram(DotGfxUsageGraph &g) = 0; + virtual void startDotGraph() = 0; + virtual void endDotGraph(DotClassGraph &g) = 0; virtual void startInclDepGraph() = 0; virtual void endInclDepGraph(DotInclDepGraph &g) = 0; virtual void writeGraphicalHierarchy(DotGfxHierarchyTable &g) = 0; diff --git a/src/outputlist.cpp b/src/outputlist.cpp index 5071ffa..03a5e1e 100644 --- a/src/outputlist.cpp +++ b/src/outputlist.cpp @@ -257,7 +257,7 @@ void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4),a1,a2,a3,a4) FORALL1(const char *a1,a1) FORALL1(char a1,a1) FORALL1(int a1,a1) -FORALL1(DotGfxUsageGraph &a1,a1) +FORALL1(DotClassGraph &a1,a1) FORALL1(DotInclDepGraph &a1,a1) FORALL1(DotGfxHierarchyTable &a1,a1) #if defined(HAS_BOOL_TYPE) diff --git a/src/outputlist.h b/src/outputlist.h index 4826334..7ae0827 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -33,7 +33,7 @@ void forall(void (OutputGenerator::*func)(arg1,arg2,arg3,arg4),arg1,arg2,arg3,arg4) class ClassDiagram; -class DotGfxUsageGraph; +class DotClassGraph; class DotInclDepGraph; class DotGfxHierarchyTable; @@ -347,10 +347,10 @@ class OutputList { forall(&OutputGenerator::startDescTableData); } void endDescTableData() { forall(&OutputGenerator::endDescTableData); } - void startCollaborationDiagram() - { forall(&OutputGenerator::startCollaborationDiagram); } - void endCollaborationDiagram(DotGfxUsageGraph &g) - { forall(&OutputGenerator::endCollaborationDiagram,g); } + void startDotGraph() + { forall(&OutputGenerator::startDotGraph); } + void endDotGraph(DotClassGraph &g) + { forall(&OutputGenerator::endDotGraph,g); } void startInclDepGraph() { forall(&OutputGenerator::startInclDepGraph); } void endInclDepGraph(DotInclDepGraph &g) @@ -383,7 +383,7 @@ class OutputList FORALLPROTO1(char); FORALLPROTO1(IndexSections); FORALLPROTO1(int); - FORALLPROTO1(DotGfxUsageGraph &); + FORALLPROTO1(DotClassGraph &); FORALLPROTO1(DotInclDepGraph &); FORALLPROTO1(DotGfxHierarchyTable &); #if defined(HAS_BOOL_TYPE) diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index 352049c..d8a17c7 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -1927,11 +1927,11 @@ static bool PreProcessFile(QDir &d,QCString &infName, QTextStream &t, bool bIncl return TRUE; } -void RTFGenerator::startCollaborationDiagram() +void RTFGenerator::startDotGraph() { } -void RTFGenerator::endCollaborationDiagram(DotGfxUsageGraph &g) +void RTFGenerator::endDotGraph(DotClassGraph &g) { newParagraph(); t <<"{\\comment This would be an image map..." << endl; diff --git a/src/rtfgen.h b/src/rtfgen.h index de4f5b4..f40c71e 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -191,8 +191,8 @@ class RTFGenerator : public OutputGenerator void startDescTableData(); void endDescTableData(); - void startCollaborationDiagram(); - void endCollaborationDiagram(DotGfxUsageGraph &); + void startDotGraph(); + void endDotGraph(DotClassGraph &); void startInclDepGraph(); void endInclDepGraph(DotInclDepGraph &); void writeGraphicalHierarchy(DotGfxHierarchyTable &) {} diff --git a/src/scanner.l b/src/scanner.l index dea0bee..24047ea 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -830,7 +830,7 @@ static QCString findAndCopyImage(const char *fileName,ImageTypes type) if (result.left(5)!="http:") { warn("Warning: image file %s is not found in IMAGE_PATH: " - "assuming external image. ",fileName); + "assuming external image.\n",fileName); } } return result; @@ -877,7 +877,7 @@ ID [a-z_A-Z][a-z_A-Z0-9]* SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) SCOPENAME (({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) SCOPEMASK {ID}?(("::"|"#")?(~)?{ID})+ -URLMASK [a-z_A-Z0-9\~\:\@\#\.\-\+\/]+ +URLMASK [a-z_A-Z0-9\~\:\?\@\#\.\-\+\/]+ NONTERM [\{\}\[\]\`\~\@\|\-\+\#\$\/\\\!\%\^\&\*()a-z_A-Z<>0-9] WORD ({NONTERM}+([^\n\t ]*{NONTERM}+)?)|("\""[^\n\"]"\"") ATTR ({B}+[^>\n]*)? @@ -1125,6 +1125,9 @@ DOCPARAM ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"") <DocScan>^{B}*(("//"{B}*)?)"*"*{B}*"-"{B}+ { /* found list item marker */ addListItemMarker(yytext); } +<DocScan>\n{B}*"-" { + addListItemMarker(yytext+1); + } <DocScan>"<!--" { BEGIN(DocSkipHtmlComment); } <DocSkipHtmlComment>"--"[!]?">" { BEGIN(DocScan); } <DocSkipHtmlComment>. @@ -3970,6 +3973,9 @@ DOCPARAM ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"") current->brief+=' '; lineCount(); } +<JavaDoc>".\\"/[ \t\r\n] { + current->brief+="."; + } <JavaDoc>"."[ \t\r\n] { lineCount(); current->brief+="."; diff --git a/src/util.cpp b/src/util.cpp index f49b761..0af45f5 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -946,7 +946,8 @@ static void trimNamespaceScope(QCString &t1,QCString &t2) // stored in the list should be equal. bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl, - const char *cl,const char *ns,bool checkCV) + const char *cl,const char *ns,bool checkCV, + NamespaceList *usingList) { QCString className=cl; QCString namespaceName=ns; @@ -1048,9 +1049,18 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl, srcAType=trimScope(namespaceName,srcAType); dstAType=trimScope(namespaceName,dstAType); } + if (usingList && usingList->count()>0) + { + NamespaceListIterator nli(*usingList); + NamespaceDef *nd; + for (;(nd=nli.current());++nli) + { + srcAType=trimScope(nd->name(),srcAType); + dstAType=trimScope(nd->name(),dstAType); + } + } //printf("srcAType=%s dstAType=%s\n",srcAType.data(),dstAType.data()); - //printf("`%s' <=> `%s'\n",srcAType.data(),dstAType.data()); uint srcPos=0,dstPos=0; bool equal=TRUE; while (srcPos<srcAType.length() && dstPos<dstAType.length() && equal) @@ -1201,6 +1211,7 @@ void mergeArguments(ArgumentList *srcAl,ArgumentList *dstAl) // argListToString(srcAl).data(),argListToString(dstAl).data()); //printArgList(srcAl);printf(" <=> "); //printArgList(dstAl);printf("\n"); + if (srcAl==0 || dstAl==0 || srcAl->count()!=dstAl->count()) { return; // invalid argument lists -> do not merge @@ -35,6 +35,7 @@ class ExampleList; class ClassList; class BaseClassList; class GroupDef; +class NamespaceList; extern void setAnchors(char id,MemberList *ml,int groupId=-1); extern QCString fileToString(const char *name); @@ -53,7 +54,8 @@ extern bool generateLink(OutputList &ol,const char *, extern void generateFileRef(OutputList &ol,const char *, const char *linkTxt=0); extern bool matchArguments(ArgumentList *,ArgumentList *, - const char *cl=0,const char *ns=0,bool checkCV=TRUE); + const char *cl=0,const char *ns=0,bool checkCV=TRUE, + NamespaceList *usingList=0); extern void mergeArguments(ArgumentList *,ArgumentList *); extern QCString substituteClassNames(const QCString &s); extern QCString convertSlashes(const QCString &s,bool dots=FALSE); |