From d048df9811a8686d93dc28f275a1c5c575833669 Mon Sep 17 00:00:00 2001 From: dimitri Date: Mon, 13 Dec 2004 18:59:17 +0000 Subject: Release-1.3.9.1-20041213 --- INSTALL | 4 +- README | 4 +- VERSION | 2 +- configure | 2 +- packages/rpm/doxygen.spec | 2 +- qtools/qstring.cpp | 12 +- qtools/scstring.cpp | 2 +- qtools/scstring.h | 1 + src/classdef.cpp | 2 +- src/code.l | 1 + src/config.l | 7 + src/definition.h | 2 + src/dirdef.cpp | 4 +- src/dirdef.h | 4 +- src/dot.cpp | 409 ++++++++++++++++++++++++++++++++++++++++++++++ src/dot.h | 69 ++++++++ src/doxygen.cpp | 1 + src/groupdef.cpp | 18 ++ src/groupdef.h | 1 + src/htmlgen.cpp | 11 ++ src/htmlgen.h | 2 + src/htmlhelp.cpp | 2 +- src/latexgen.cpp | 9 + src/latexgen.h | 2 + src/mangen.h | 2 + src/outputgen.h | 4 + src/outputlist.cpp | 1 + src/outputlist.h | 6 + src/rtfgen.cpp | 8 + src/rtfgen.h | 2 + src/scanner.l | 11 +- src/xmlgen.cpp | 246 +++++++++++++--------------- wintools/qtools.dsp | 2 +- 33 files changed, 698 insertions(+), 157 deletions(-) diff --git a/INSTALL b/INSTALL index 08d49d6..ba714f6 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,7 @@ -DOXYGEN Version 1.3.9.1-20041206 +DOXYGEN Version 1.3.9.1-20041213 Please read the installation section of the manual (http://www.doxygen.org/install.html) for instructions. -------- -Dimitri van Heesch (06 December 2004) +Dimitri van Heesch (13 December 2004) diff --git a/README b/README index baf3659..31508a9 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOXYGEN Version 1.3.9.1_20041206 +DOXYGEN Version 1.3.9.1_20041213 Please read INSTALL for compilation instructions. @@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives. Enjoy, -Dimitri van Heesch (dimitri@stack.nl) (06 December 2004) +Dimitri van Heesch (dimitri@stack.nl) (13 December 2004) diff --git a/VERSION b/VERSION index 5d60811..94992c2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.9.1-20041206 +1.3.9.1-20041213 diff --git a/configure b/configure index 127053d..576e87d 100755 --- a/configure +++ b/configure @@ -1,4 +1,4 @@ -#! /bin/sh +#! /bin/bash # # $Id$ # diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec index 107a382..8904473 100644 --- a/packages/rpm/doxygen.spec +++ b/packages/rpm/doxygen.spec @@ -1,6 +1,6 @@ Summary: A documentation system for C/C++. Name: doxygen -Version: 1.3.9.1_20041206 +Version: 1.3.9.1_20041213 Release: 1 Epoch: 1 Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz diff --git a/qtools/qstring.cpp b/qtools/qstring.cpp index 4707fed..e073168 100644 --- a/qtools/qstring.cpp +++ b/qtools/qstring.cpp @@ -15156,16 +15156,18 @@ QCString qt_winQString2MB( const QString& s, int uclen ) if ( uclen == 0 ) return QCString(); BOOL used_def; - QCString mb(4096); + int bufSize=4096; + QCString mb(bufSize); int len; while ( !(len=WideCharToMultiByte(CP_ACP, 0, (const WCHAR*)s.unicode(), uclen, - mb.data(), mb.size()-1, 0, &used_def)) ) + mb.data(), bufSize-1, 0, &used_def)) ) { int r = GetLastError(); if ( r == ERROR_INSUFFICIENT_BUFFER ) { - mb.resize(1+WideCharToMultiByte( CP_ACP, 0, - (const WCHAR*)s.unicode(), uclen, - 0, 0, 0, &used_def)); + bufSize=1+WideCharToMultiByte( CP_ACP, 0, + (const WCHAR*)s.unicode(), uclen, + 0, 0, 0, &used_def); + mb.resize(bufSize); // and try again... } else { // Fail. diff --git a/qtools/scstring.cpp b/qtools/scstring.cpp index ebf54a9..a265afe 100644 --- a/qtools/scstring.cpp +++ b/qtools/scstring.cpp @@ -34,7 +34,7 @@ SCString::SCString(int size) m_data = (char *)malloc(size); if (m_data) { - m_data[0]='\0'; + if (size>1) memset(m_data,' ',size-1); m_data[size-1]='\0'; } } diff --git a/qtools/scstring.h b/qtools/scstring.h index 0c388b8..41dcfac 100644 --- a/qtools/scstring.h +++ b/qtools/scstring.h @@ -144,6 +144,7 @@ inline void SCString::duplicate( const char *str) } inline SCString &SCString::duplicate( const char *str, int) { + if (m_data) free(m_data); duplicate(str); return *this; } diff --git a/src/classdef.cpp b/src/classdef.cpp index 2a22456..ce8431c 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -2497,8 +2497,8 @@ QCString ClassDef::compoundTypeString() const case Protocol: return "protocol"; case Category: return "category"; case Exception: return "exception"; + default: return "unknown"; } - return "unknown"; } QCString ClassDef::getOutputFileBase() const diff --git a/src/code.l b/src/code.l index 75facca..bd1a4a6 100644 --- a/src/code.l +++ b/src/code.l @@ -716,6 +716,7 @@ static MemberDef *setCallContextForVar(const QCString &name) static void addDocCrossReference(MemberDef *src,MemberDef *dst) { + if (dst->isTypedef() || dst->isEnumerate()) return; // don't add types //printf("addDocCrossReference src=%s,dst=%s\n",src->name().data(),dst->name().data()); if (Config_getBool("REFERENCED_BY_RELATION") && (src->isFunction() || src->isSlot()) diff --git a/src/config.l b/src/config.l index 60060e5..06bf179 100644 --- a/src/config.l +++ b/src/config.l @@ -2656,6 +2656,13 @@ void Config::create() ); cb->addDependency("HAVE_DOT"); cb = addBool( + "GROUP_GRAPHS", + "If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen \n" + "will generate a graph for groups, showing the direct groups dependencies\n", + TRUE + ); + cb->addDependency("HAVE_DOT"); + cb = addBool( "UML_LOOK", "If the UML_LOOK tag is set to YES doxygen will generate inheritance and \n" "collaboration diagrams in a style similar to the OMG's Unified Modeling \n" diff --git a/src/definition.h b/src/definition.h index 30328e6..0000cc2 100644 --- a/src/definition.h +++ b/src/definition.h @@ -197,6 +197,8 @@ class Definition void writeNavigationPath(OutputList &ol) const; protected: + void setLocalName(const QCString name) { m_localName=name; } + int m_startBodyLine; // line number of the start of the definition int m_endBodyLine; // line number of the end of the definition FileDef *m_bodyDef; // file definition containing the function body diff --git a/src/dirdef.cpp b/src/dirdef.cpp index 12ec111..aef5e3f 100644 --- a/src/dirdef.cpp +++ b/src/dirdef.cpp @@ -27,9 +27,9 @@ DirDef::DirDef(const char *path) : Definition(path,1,path) { // remove everything till the last / m_shortName = m_shortName.mid(pi+1); } + setLocalName(m_shortName); m_fileList = new FileList; - m_classSDict = new ClassSDict(17); m_usedDirs = new QDict(257); m_usedDirs->setAutoDelete(TRUE); m_dirCount = g_dirCount++; @@ -39,6 +39,8 @@ DirDef::DirDef(const char *path) : Definition(path,1,path) DirDef::~DirDef() { + delete m_fileList; + delete m_usedDirs; } bool DirDef::isLinkableInProject() const diff --git a/src/dirdef.h b/src/dirdef.h index 9d00b60..2bc725d 100644 --- a/src/dirdef.h +++ b/src/dirdef.h @@ -57,9 +57,8 @@ class DirDef : public Definition QCString shortName() const { return m_shortName; } void addSubDir(DirDef *subdir); FileList * getFiles() const { return m_fileList; } - ClassSDict * getClasses() const { return m_classSDict; } void addFile(FileDef *fd); - const QList &subDirs() const { return m_subdirs; } + 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; } @@ -90,7 +89,6 @@ class DirDef : public Definition QCString m_dispName; QCString m_shortName; FileList *m_fileList; // list of files in the group - ClassSDict *m_classSDict; // list of classes in the group int m_dirCount; int m_level; DirDef *m_parent; diff --git a/src/dot.cpp b/src/dot.cpp index 41d6901..bb2eb92 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -28,6 +28,7 @@ #include "defargs.h" #include "docparser.h" #include "debug.h" +#include "pagedef.h" #include #include @@ -2646,4 +2647,412 @@ QString getDotImageMapFromFile(const QString& inFile, const QString& outDir, } // end MDG mods +//------------------------------------------------------------- + +DotGroupCollaboration::DotGroupCollaboration(GroupDef* gd) +{ + m_curNodeId = 0; + QCString tmp_url = gd->getReference()+"$"+gd->getOutputFileBase(); + m_usedNodes = new QDict(1009); + m_rootNode = new DotNode(m_curNodeId++, gd->groupTitle(), tmp_url, 0, TRUE ); + m_usedNodes->insert(gd->name(), m_rootNode ); + m_edges.setAutoDelete(TRUE); + + m_diskName = gd->getOutputFileBase(); + + buildGraph( gd, 0 ); +} + +DotGroupCollaboration::~DotGroupCollaboration() +{ + delete m_usedNodes; +} + +void DotGroupCollaboration::buildGraph(GroupDef* gd,int) +{ + QCString tmp_url; + //=========================== + // hierarchy. + + // Write parents + if ( gd->partOfGroups() ) + { + GroupListIterator gli(*gd->partOfGroups()); + 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(); + nnode = new DotNode(m_curNodeId++, d->groupTitle(), tmp_url ); + 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 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(); + nnode = new DotNode(m_curNodeId++, def->groupTitle(), tmp_url ); + m_usedNodes->insert(def->name(), nnode ); + } + tmp_url = ""; + addEdge( m_rootNode, nnode, DotGroupCollaboration::thierarchy, tmp_url, tmp_url ); + } + } + //======================= + // Write collaboration + + // Add members + addMemberList( gd->getMembers() ); + + // 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; + 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 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 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 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(); + nnode = new DotNode(m_curNodeId++, d->groupTitle(), tmp_str ); + m_usedNodes->insert(d->name(), nnode ); + } + tmp_str = def->qualifiedName(); + addEdge( m_rootNode, nnode, eType, tmp_str, url ); + } + } +} + + +QCString DotGroupCollaboration::writeGraph( QTextStream &t, GraphOutputFormat format, + const char *path, const char *, + bool writeImageMap) +{ + QDir d(path); + // store the original directory + if (!d.exists()) + { + err("Error: Output dir %s does not exist!\n",path); + exit(1); + } + QCString oldDir = convertToQCString(QDir::currentDirPath()); + // go to the output directory (i.e. path) + QDir::setCurrent(d.absPath()); + QDir thisDir; + QCString baseName = m_diskName; + + QFile dotfile(baseName+".dot"); + if (dotfile.open(IO_WriteOnly)) + { + QTextStream tdot(&dotfile); + writeGraphHeader(tdot); + + // clean write flags + QDictIterator 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(tdot,DotNode::Inheritance,format,TRUE,FALSE,1,FALSE,FALSE); + } + + // write edges + QListIterator eli(m_edges); + Edge* edge; + for (eli.toFirst();(edge=eli.current());++eli) + { + edge->write( tdot, m_curNodeId ); + } + + writeGraphFooter(tdot); + dotfile.close(); + } + + QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT"); + if (format==BITMAP) // run dot to create a bitmap image + { + QCString dotArgs(maxCmdLine); + QCString imgName = baseName+"."+imgExt; + dotArgs.sprintf("\"%s.dot\" -T%s -o \"%s\"", + baseName.data(), imgExt.data(), imgName.data()); + QCString mapName=baseName+".map"; + + if (writeImageMap) + { + // run dot also to create an image map + dotArgs+=" -Timap -o \""+mapName+"\""; + } + + if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) + { + err("Error: Problems running dot. Check your installation!\n"); + QDir::setCurrent(oldDir); + return baseName; + } + + if (writeImageMap) + { + QCString mapLabel = convertNameToFile(baseName); + t << "
\"\"" << endl; + t << "" << endl; + convertMapFile(t,mapName,""); + t << "
" << endl; + thisDir.remove(mapName); + } + } + else if (format==EPS) + { + QCString dotArgs(maxCmdLine); + dotArgs.sprintf("-Tps \"%s.dot\" -o \"%s.eps\"", + baseName.data(),baseName.data()); + if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) + { + err("Error: Problems running dot. Check your installation!\n"); + QDir::setCurrent(oldDir); + return baseName; + } + if (Config_getBool("USE_PDFLATEX")) + { + QCString epstopdfArgs(maxCmdLine); + epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"", + baseName.data(),baseName.data()); + if (iSystem("epstopdf",epstopdfArgs,TRUE)!=0) + { + err("Error: Problems running epstopdf. Check your TeX installation!\n"); + QDir::setCurrent(oldDir); + return baseName; + } + } + int width,height; + if (!readBoundingBoxEPS(baseName+".eps",&width,&height)) + { + err("Error: Could not extract bounding box from .eps!\n"); + QDir::setCurrent(oldDir); + return baseName; + } + int maxWidth = 420; /* approx. page width in points */ + t << "\\begin{figure}[H]\n" + "\\begin{center}\n" + "\\leavevmode\n" + "\\includegraphics[width=" << QMIN(width/2,maxWidth) + << "pt]{" << baseName << "}\n" + "\\end{center}\n" + "\\end{figure}\n"; + } + if (Config_getBool("DOT_CLEANUP")) + { + thisDir.remove(baseName+".dot"); + } + + QDir::setCurrent(oldDir); + + return baseName; +} + +void DotGroupCollaboration::Edge::write( QTextStream &t, int& ) +{ + 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=<"; + //QListIterator lli(links); + //Link *link; + //for( lli.toFirst(); (link=lli.current()); ++lli) + //{ + // t << "url.isEmpty() ) + // t << " HREF=\"" << link->url << "\""; + // t << ">" << link->label << ""; + //} + //t << "
>"; + + t << "label=\""; + QListIterator lli(links); + Link *link; + bool first=TRUE; + for( lli.toFirst(); (link=lli.current()); ++lli) + { + if (first) first=FALSE; else t << "\\n"; + t << link->label; + } + t << "\""; + + } + switch( eType ) + { + case thierarchy : + arrowStyle = "dir=\"back\", style=\"solid\""; + default : + t << ", color=\"" << linkTypeColor[(int)eType] << "\""; + break; + } + t << ", " << arrowStyle; + t << "];" << endl; +} + +bool DotGroupCollaboration::isTrivial() const +{ + return m_usedNodes->count() <= 1; +} + +void DotGroupCollaboration::writeGraphHeader(QTextStream &t) +{ + t << "digraph structs" << endl; + t << "{" << endl; +#if defined(DOT_TRANSPARENT) + t << " bgcolor=\"transparent\"" << endl; +#endif + t << " edge [fontname=\"Helvetica\",fontsize=8," + "labelfontname=\"Helvetica\",labelfontsize=8];\n"; + t << " node [fontname=\"Helvetica\",fontsize=10,shape=record];\n"; + t << "rankdir=LR;\n"; +} diff --git a/src/dot.h b/src/dot.h index 477eba4..3e5d790 100644 --- a/src/dot.h +++ b/src/dot.h @@ -32,6 +32,8 @@ class ClassSDict; class MemberDef; class Definition; class DirDef; +class GroupDef; +class DotGroupCollaboration; enum GraphOutputFormat { BITMAP , EPS }; @@ -66,6 +68,7 @@ class DotNode void deleteNode(DotNodeList &deletedList,SDict *skipNodes=0); void removeChild(DotNode *n); void removeParent(DotNode *n); + int findParent( DotNode *n ); void write(QTextStream &t,GraphType gt,GraphOutputFormat f, bool topDown,bool toChildren,int maxDistance,bool backArrows,bool reNumber); int m_subgraphId; @@ -100,6 +103,8 @@ class DotNode friend class DotInclDepGraph; friend class DotNodeList; friend class DotCallGraph; + friend class DotGroupCollaboration; + friend void writeDotGraph( DotNode *root, GraphType gt, GraphOutputFormat f, const QCString &baseName, @@ -113,6 +118,13 @@ class DotNode int distance, bool backArrows ); }; +inline +int DotNode::findParent( DotNode *n ) +{ + if( !m_parents ) + return -1; + return m_parents->find(n); +} class DotGfxHierarchyTable { @@ -217,6 +229,63 @@ class DotDirDeps DirDef *m_dir; }; +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 links; + void write( QTextStream &t, int& curNodeId ); + }; + + DotGroupCollaboration(GroupDef* gd); + ~DotGroupCollaboration(); + QCString writeGraph(QTextStream &t, GraphOutputFormat format, + const char *path,const char *relPath, + bool writeImageMap=TRUE); + void buildGraph(GroupDef* gd,int distance); + bool isTrivial() const; + private : + void addCollaborationMember( Definition* def, QCString& url, EdgeType eType ); + void addMemberList( class MemberList* ml ); + void writeGraphHeader(QTextStream &t); + Edge* addEdge( DotNode* _pNStart, DotNode* _pNEnd, EdgeType _eType, + const QCString& _label, const QCString& _url ); + + DotNode *m_rootNode; + int m_curNodeId; + QDict *m_usedNodes; + QCString m_diskName; + QList m_edges; +}; + void generateGraphLegend(const char *path); void writeDotGraphFromFile(const char *inFile,const char *outDir, const char *outFile,GraphOutputFormat format); diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 60e1c09..213689c 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -8470,6 +8470,7 @@ void parseInput() if (fi.size()==0) { err("No input read, no output generated!\n"); + QDir().remove(tmpName); delete root; cleanUpDoxygen(); exit(1); diff --git a/src/groupdef.cpp b/src/groupdef.cpp index 439548c..260348c 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -33,6 +33,7 @@ #include "pagedef.h" #include "docparser.h" #include "searchindex.h" +#include "dot.h" GroupDef::GroupDef(const char *df,int dl,const char *na,const char *t, const char *refFileName) : Definition(df,dl,na) @@ -483,6 +484,23 @@ void GroupDef::writeDocumentation(OutputList &ol) } } + if (Config_getBool("HAVE_DOT") && Config_getBool("GROUP_GRAPHS") ) + { + DotGroupCollaboration graph(this); + if (!graph.isTrivial()) + { + msg("Generating dependency graph for group %s\n",qualifiedName().data()); + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Man); + ol.newParagraph(); + ol.startGroupCollaboration(); + ol.parseText(theTranslator->trCollaborationDiagram(title)); + ol.endGroupCollaboration(graph); + ol.popGeneratorState(); + } + } + + if (Config_getBool("DETAILS_AT_TOP")) { writeDetailedDocumentation(ol); diff --git a/src/groupdef.h b/src/groupdef.h index d9926d7..a6c1c1e 100644 --- a/src/groupdef.h +++ b/src/groupdef.h @@ -112,6 +112,7 @@ class GroupDef : public Definition GroupList * getSubGroups() const { return groupList; } PageSDict * getPages() const { return pageDict; } DirList * getDirs() const { return dirList; } + MemberList* getMembers() const { return allMemberList; } protected: void addMemberListToGroup(MemberList *,bool (MemberDef::*)() const); diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 5cf23ee..4886bf4 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -1260,6 +1260,17 @@ void HtmlGenerator::endInclDepGraph(DotInclDepGraph &g) g.writeGraph(t,BITMAP,dir,relPath); } + +void HtmlGenerator::startGroupCollaboration() +{ +} + +void HtmlGenerator::endGroupCollaboration(DotGroupCollaboration &g) +{ + g.writeGraph(t,BITMAP,dir,relPath); +} + + void HtmlGenerator::startCallGraph() { } diff --git a/src/htmlgen.h b/src/htmlgen.h index ebaf4fa..cf5c036 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -190,6 +190,8 @@ class HtmlGenerator : public OutputGenerator void endDotGraph(DotClassGraph &g); void startInclDepGraph(); void endInclDepGraph(DotInclDepGraph &g); + void startGroupCollaboration(); + void endGroupCollaboration(DotGroupCollaboration &g); void startCallGraph(); void endCallGraph(DotCallGraph &g); void startDirDepGraph(); diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp index 0d5b9c8..8ccb57b 100644 --- a/src/htmlhelp.cpp +++ b/src/htmlhelp.cpp @@ -174,7 +174,7 @@ void HtmlHelpIndex::writeFields(QTextStream &t) { // finish old list at level 2 if (level2Started) t << " " << endl; level2Started=FALSE; - + // // Added this code so that an item with only one subitem is written // without any subitem. diff --git a/src/latexgen.cpp b/src/latexgen.cpp index b8998d9..db10e42 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -1448,6 +1448,15 @@ void LatexGenerator::endInclDepGraph(DotInclDepGraph &g) g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),relPath); } +void LatexGenerator::startGroupCollaboration() +{ +} + +void LatexGenerator::endGroupCollaboration(DotGroupCollaboration &g) +{ + g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),relPath); +} + void LatexGenerator::startCallGraph() { } diff --git a/src/latexgen.h b/src/latexgen.h index 237e4f0..992ba9d 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -184,6 +184,8 @@ class LatexGenerator : public OutputGenerator void startInclDepGraph(); void endInclDepGraph(DotInclDepGraph &); void startCallGraph(); + void startGroupCollaboration(); + void endGroupCollaboration(DotGroupCollaboration &g); void endCallGraph(DotCallGraph &); void startDirDepGraph(); void endDirDepGraph(DotDirDeps &g); diff --git a/src/mangen.h b/src/mangen.h index e4a145b..b807e28 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -229,6 +229,8 @@ class ManGenerator : public OutputGenerator void endDotGraph(DotClassGraph &) {} void startInclDepGraph() {} void endInclDepGraph(DotInclDepGraph &) {} + void startGroupCollaboration() {} + void endGroupCollaboration(DotGroupCollaboration &) {} void startCallGraph() {} void endCallGraph(DotCallGraph &) {} void startDirDepGraph() {} diff --git a/src/outputgen.h b/src/outputgen.h index 16e56a8..5cf4f4e 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -32,8 +32,10 @@ class DotInclDepGraph; class DotCallGraph; class DotDirDeps; class DotGfxHierarchyTable; +class DotGroupCollaboration; class DocNode; class MemberDef; +class GroupDef; /*! \brief Output interface for code parser. */ @@ -338,6 +340,8 @@ class OutputGenerator : public BaseOutputDocInterface virtual void endDotGraph(DotClassGraph &g) = 0; virtual void startInclDepGraph() = 0; virtual void endInclDepGraph(DotInclDepGraph &g) = 0; + virtual void startGroupCollaboration() = 0; + virtual void endGroupCollaboration(DotGroupCollaboration &g) = 0; virtual void startCallGraph() = 0; virtual void endCallGraph(DotCallGraph &g) = 0; virtual void startDirDepGraph() = 0; diff --git a/src/outputlist.cpp b/src/outputlist.cpp index 917e5f6..6f07a0e 100644 --- a/src/outputlist.cpp +++ b/src/outputlist.cpp @@ -268,6 +268,7 @@ 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) diff --git a/src/outputlist.h b/src/outputlist.h index 78fc8cd..5ca4751 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -38,6 +38,7 @@ class DotDirDeps; class DotInclDepGraph; class DotGfxHierarchyTable; class SectionDict; +class DotGroupCollaboration; class OutputList : public OutputDocInterface { @@ -327,6 +328,10 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startDirDepGraph); } void endDirDepGraph(DotDirDeps &g) { forall(&OutputGenerator::endDirDepGraph,g); } + void startGroupCollaboration() + { forall(&OutputGenerator::startGroupCollaboration); } + void endGroupCollaboration(DotGroupCollaboration &g) + { forall(&OutputGenerator::endGroupCollaboration,g); } void writeGraphicalHierarchy(DotGfxHierarchyTable &g) { forall(&OutputGenerator::writeGraphicalHierarchy,g); } void startTextBlock(bool dense=FALSE) @@ -392,6 +397,7 @@ class OutputList : public OutputDocInterface FORALLPROTO1(DotClassGraph &); FORALLPROTO1(DotInclDepGraph &); FORALLPROTO1(DotCallGraph &); + FORALLPROTO1(DotGroupCollaboration &); FORALLPROTO1(DotDirDeps &); FORALLPROTO1(DotGfxHierarchyTable &); FORALLPROTO1(SectionTypes); diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index ad240f3..f1f6f34 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -2236,6 +2236,14 @@ void RTFGenerator::endInclDepGraph(DotInclDepGraph &g) DBG_RTF(t << "{\\comment (endInclDepGraph)}" << endl) } +void RTFGenerator::startGroupCollaboration() +{ +} + +void RTFGenerator::endGroupCollaboration(DotGroupCollaboration &) +{ +} + void RTFGenerator::startCallGraph() { DBG_RTF(t << "{\\comment (startCallGraph)}" << endl) diff --git a/src/rtfgen.h b/src/rtfgen.h index 1c92bee..2d5cb5a 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -225,6 +225,8 @@ class RTFGenerator : public OutputGenerator void endDotGraph(DotClassGraph &); void startInclDepGraph(); void endInclDepGraph(DotInclDepGraph &); + void startGroupCollaboration(); + void endGroupCollaboration(DotGroupCollaboration &g); void startCallGraph(); void endCallGraph(DotCallGraph &); void startDirDepGraph(); diff --git a/src/scanner.l b/src/scanner.l index e9b01b3..ac2f2a4 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -376,7 +376,7 @@ static void addXRefItem(const char *listName,const char *itemTitle,const char *l SectionInfo *si=new SectionInfo(listName,anchorLabel, sectionTitle,SectionInfo::Anchor); Doxygen::sectionDict.insert(anchorLabel,si); - current->anchors->append(new SectionInfo(*si)); + current->anchors->append(si); } current->brief = slString.copy(); // restore orginial brief desc. } @@ -2303,6 +2303,10 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] current->startLine = yyLineNr; current_root->addSubEntry( current ) ; } + else + { + delete current; + } if ( *yytext == ',') { current = new Entry(*current); @@ -3665,6 +3669,10 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] } else { + if (current->section == Entry::ENUM_SEC) + { // found "enum a b" -> variable + current->section = Entry::VARIABLE_SEC ; + } current->type += ' ' ; current->type += current->name ; current->name = yytext ; @@ -5983,6 +5991,7 @@ static void parseCompounds(Entry *rt) insideObjC = ce->objc; //printf("---> Inner block starts at line %d\n",yyLineNr); //current->reset(); + if (current) delete current; current = new Entry; gstat = FALSE; int ni=ce->name.findRev("::"); if (ni==-1) ni=0; else ni+=2; diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index dbd2979..7b531ff 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -888,6 +888,102 @@ static void writeListOfAllMembers(ClassDef *cd,QTextStream &t) t << " " << endl; } +static void writeInnerClasses(const ClassSDict *cl,QTextStream &t) +{ + if (cl) + { + ClassSDict::Iterator cli(*cl); + ClassDef *cd; + for (cli.toFirst();(cd=cli.current());++cli) + { + if (cd->name().find('@')!=-1) // skip anonymous scopes + { + t << " getOutputFileBase() + << "\">" << convertToXML(cd->name()) << "" << endl; + } + } + } +} + +static void writeInnerNamespaces(const NamespaceSDict *nl,QTextStream &t) +{ + if (nl) + { + NamespaceSDict::Iterator nli(*nl); + NamespaceDef *nd; + for (nli.toFirst();(nd=nli.current());++nli) + { + if (nd->name().find('@')!=-1) // skip anonymouse scopes + { + t << " getOutputFileBase() + << "\">" << convertToXML(nd->name()) << "" << endl; + } + } + } +} + +static void writeInnerFiles(const FileList *fl,QTextStream &t) +{ + if (fl) + { + QListIterator fli(*fl); + FileDef *fd; + for (fli.toFirst();(fd=fli.current());++fli) + { + t << " getOutputFileBase() + << "\">" << convertToXML(fd->name()) << "" << endl; + } + } +} + +static void writeInnerPages(const PageSDict *pl,QTextStream &t) +{ + if (pl) + { + PageSDict::Iterator pli(*pl); + PageDef *pd; + for (pli.toFirst();(pd=pli.current());++pli) + { + t << " getOutputFileBase(); + if (pd->getGroupDef()) + { + t << "_" << pd->name(); + } + t << "\">" << convertToXML(pd->title()) << "" << endl; + } + } +} + +static void writeInnerGroups(const GroupList *gl,QTextStream &t) +{ + if (gl) + { + GroupListIterator gli(*gl); + GroupDef *sgd; + for (gli.toFirst();(sgd=gli.current());++gli) + { + t << " getOutputFileBase() + << "\">" << convertToXML(sgd->groupTitle()) + << "" << endl; + } + } +} + +static void writeInnerDirs(const DirList *dl,QTextStream &t) +{ + if (dl) + { + QListIterator subdirs(*dl); + DirDef *subdir; + for (subdirs.toFirst();(subdir=subdirs.current());++subdirs) + { + t << " getOutputFileBase() + << "\">" << convertToXML(subdir->displayName()) << "" << endl; + } + } +} + + static void generateXMLForClass(ClassDef *cd,QTextStream &ti) { // + brief description @@ -1027,18 +1123,7 @@ static void generateXMLForClass(ClassDef *cd,QTextStream &ti) } } - ClassSDict *cl = cd->getInnerClasses(); - if (cl) - { - ClassSDict::Iterator cli(*cl); - ClassDef *cd; - for (cli.toFirst();(cd=cli.current());++cli) - { - t << " getOutputFileBase() - << "\">" << convertToXML(cd->name()) << "" << endl; - } - } - + writeInnerClasses(cd->getInnerClasses(),t); writeTemplateList(cd,t); MemberGroupSDict::Iterator mgli(*cd->memberGroupSDict); @@ -1152,28 +1237,9 @@ static void generateXMLForNamespace(NamespaceDef *nd,QTextStream &ti) writeXMLString(t,nd->name()); t << "" << endl; - ClassSDict *cl = nd->classSDict; - if (cl) - { - ClassSDict::Iterator cli(*cl); - ClassDef *cd; - for (cli.toFirst();(cd=cli.current());++cli) - { - t << " getOutputFileBase() - << "\">" << convertToXML(cd->name()) << "" << endl; - } - } - NamespaceSDict *nl = nd->namespaceSDict; - if (nl) - { - NamespaceSDict::Iterator nli(*nl); - NamespaceDef *nd; - for (nli.toFirst();(nd=nli.current());++nli) - { - t << " getOutputFileBase() - << "\">" << convertToXML(nd->name()) << "" << endl; - } - } + writeInnerClasses(nd->classSDict,t); + writeInnerNamespaces(nd->namespaceSDict,t); + MemberGroupSDict::Iterator mgli(*nd->memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) @@ -1287,28 +1353,8 @@ static void generateXMLForFile(FileDef *fd,QTextStream &ti) t << " " << endl; } - ClassSDict *cl = fd->classSDict; - if (cl) - { - ClassSDict::Iterator cli(*cl); - ClassDef *cd; - for (cli.toFirst();(cd=cli.current());++cli) - { - t << " getOutputFileBase() - << "\">" << convertToXML(cd->name()) << "" << endl; - } - } - NamespaceSDict *nl = fd->namespaceSDict; - if (nl) - { - NamespaceSDict::Iterator nli(*nl); - NamespaceDef *nd; - for (nli.toFirst();(nd=nli.current());++nli) - { - t << " getOutputFileBase() - << "\">" << convertToXML(nd->name()) << "" << endl; - } - } + writeInnerClasses(fd->classSDict,t); + writeInnerNamespaces(fd->namespaceSDict,t); MemberGroupSDict::Iterator mgli(*fd->memberGroupSDict); MemberGroup *mg; @@ -1380,67 +1426,11 @@ static void generateXMLForGroup(GroupDef *gd,QTextStream &ti) t << " " << convertToXML(gd->name()) << "" << endl; t << " " << convertToXML(gd->groupTitle()) << "" << endl; - FileList *fl = gd->getFiles(); - if (fl) - { - QListIterator fli(*fl); - FileDef *fd = fl->first(); - for (fli.toFirst();(fd=fli.current());++fli) - { - t << " getOutputFileBase() - << "\">" << convertToXML(fd->name()) << "" << endl; - } - } - ClassSDict *cl = gd->getClasses(); - if (cl) - { - ClassSDict::Iterator cli(*cl); - ClassDef *cd; - for (cli.toFirst();(cd=cli.current());++cli) - { - t << " getOutputFileBase() - << "\">" << convertToXML(cd->name()) << "" << endl; - } - } - NamespaceSDict *nl = gd->getNamespaces(); - if (nl) - { - NamespaceSDict::Iterator nli(*nl); - NamespaceDef *nd; - for (nli.toFirst();(nd=nli.current());++nli) - { - t << " getOutputFileBase() - << "\">" << convertToXML(nd->name()) << "" << endl; - } - } - PageSDict *pl = gd->getPages(); - if (pl) - { - PageSDict::Iterator pli(*pl); - PageDef *pd; - for (pli.toFirst();(pd=pli.current());++pli) - { - t << " getOutputFileBase(); - if (pd->getGroupDef()) - { - t << "_" << pd->name(); - } - t << "\">" << convertToXML(pd->title()) << "" << endl; - } - } - - GroupList *gl = gd->getSubGroups(); - if (gl) - { - GroupListIterator gli(*gl); - GroupDef *sgd; - for (gli.toFirst();(sgd=gli.current());++gli) - { - t << " getOutputFileBase() - << "\">" << convertToXML(sgd->groupTitle()) - << "" << endl; - } - } + writeInnerFiles(gd->getFiles(),t); + writeInnerClasses(gd->getClasses(),t); + writeInnerNamespaces(gd->getNamespaces(),t); + writeInnerPages(gd->getPages(),t); + writeInnerGroups(gd->getSubGroups(),t); MemberGroupSDict::Iterator mgli(*gd->memberGroupSDict); MemberGroup *mg; @@ -1492,25 +1482,9 @@ static void generateXMLForDir(DirDef *dd,QTextStream &ti) << dd->getOutputFileBase() << "\" kind=\"dir\">" << endl; t << " " << convertToXML(dd->displayName()) << "" << endl; - QListIterator subdirs(dd->subDirs()); - DirDef *subdir; - for (subdirs.toFirst();(subdir=subdirs.current());++subdirs) - { - t << " getOutputFileBase() - << "\">" << convertToXML(subdir->displayName()) << "" << endl; - } - - FileList *fl = dd->getFiles(); - if (fl) - { - QListIterator fli(*fl); - FileDef *fd = fl->first(); - for (fli.toFirst();(fd=fli.current());++fli) - { - t << " getOutputFileBase() - << "\">" << convertToXML(fd->name()) << "" << endl; - } - } + writeInnerDirs(&dd->subDirs(),t); + writeInnerFiles(dd->getFiles(),t); + t << " " << endl; writeXMLDocBlock(t,dd->briefFile(),dd->briefLine(),dd,0,dd->briefDescription()); t << " " << endl; diff --git a/wintools/qtools.dsp b/wintools/qtools.dsp index 315f33d..83b6cb8 100644 --- a/wintools/qtools.dsp +++ b/wintools/qtools.dsp @@ -92,7 +92,7 @@ SOURCE=..\qtools\qcollection.cpp # End Source File # Begin Source File -SOURCE=..\qtools\qcstring.cpp +SOURCE=..\qtools\scstring.cpp # End Source File # Begin Source File -- cgit v0.12