Classes | Macros | Functions | Variables
dot.cpp File Reference
#include <stdlib.h>
#include <qdir.h>
#include <qfile.h>
#include <qqueue.h>
#include <qthread.h>
#include <qmutex.h>
#include <qwaitcondition.h>
#include "dot.h"
#include "doxygen.h"
#include "message.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 "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"

Go to the source code of this file.

Classes

struct  EdgeProperties
 

Macros

#define MAP_CMD   "cmapx"
 
#define FONTNAME   getDotFontName()
 
#define FONTSIZE   getDotFontSize()
 

Functions

static QCString getDotFontName ()
 
static int getDotFontSize ()
 
static void writeGraphHeader (FTextStream &t, const QCString &title=QCString())
 
static void writeGraphFooter (FTextStream &t)
 
static QCString replaceRef (const QCString &buf, const QCString relPath, bool urlOnly, const QCString &context, const QCString &target=QCString())
 
static bool convertMapFile (FTextStream &t, const char *mapName, const QCString relPath, bool urlOnly=FALSE, const QCString &context=QCString())
 
int reNumberNode (int number, bool doReNumbering)
 
static void resetReNumbering ()
 
static void setDotFontPath (const char *path)
 
static void unsetDotFontPath ()
 
static bool readBoundingBox (const char *fileName, int *width, int *height, bool isEps)
 
static bool writeVecGfxFigure (FTextStream &out, const QCString &baseName, const QCString &figureName)
 
static bool readSVGSize (const QCString &fileName, int *width, int *height)
 
static void writeSVGNotSupported (FTextStream &out)
 
static bool writeSVGFigureLink (FTextStream &out, const QCString &relPath, const QCString &baseName, const QCString &absImgName)
 
static void checkDotResult (const char *imgExt, const char *imgName)
 
static bool insertMapFile (FTextStream &out, const QCString &mapFile, const QCString &relPath, const QCString &mapLabel)
 
static void removeDotGraph (const QCString &dotName)
 
static bool checkAndUpdateMd5Signature (const QCString &baseName, const QCString &md5)
 
static bool checkDeliverables (const QCString &file1, const QCString &file2=QCString())
 
static void deleteNodes (DotNode *node, SDict< DotNode > *skipNodes=0)
 
static QCString convertLabel (const QCString &l)
 
static QCString escapeTooltip (const QCString &tooltip)
 
static void writeBoxMemberList (FTextStream &t, char prot, MemberList *ml, ClassDef *scope, bool isStatic=FALSE, const QDict< void > *skipNames=0)
 
static QCString stripProtectionPrefix (const QCString &s)
 
QCString computeMd5Signature (DotNode *root, DotNode::GraphType gt, GraphOutputFormat format, bool lrRank, bool renderParents, bool backArrows, const QCString &title, QCString &graphStr)
 
static bool updateDotGraph (DotNode *root, DotNode::GraphType gt, const QCString &baseName, GraphOutputFormat format, bool lrRank, bool renderParents, bool backArrows, const QCString &title=QCString())
 
static void writeDotDirDepGraph (FTextStream &t, DirDef *dd, bool linkRelations)
 
void generateGraphLegend (const char *path)
 
void writeDotGraphFromFile (const char *inFile, const char *outDir, const char *outFile, GraphOutputFormat format)
 
void writeDotImageMapFromFile (FTextStream &t, const QCString &inFile, const QCString &outDir, const QCString &relPath, const QCString &baseName, const QCString &context, int graphId)
 

Variables

static const char svgZoomHeader []
 
static const char svgZoomFooter []
 
static const char * normalEdgeColorMap []
 
static const char * normalArrowStyleMap []
 
static const char * normalEdgeStyleMap []
 
static const char * umlEdgeColorMap []
 
static const char * umlArrowStyleMap []
 
static const char * umlEdgeStyleMap []
 
static EdgeProperties normalEdgeProps
 
static EdgeProperties umlEdgeProps
 
static QArray< int > s_newNumber
 
static int s_max_newNumber =0
 
static QCString g_dotFontPath
 

Macro Definition Documentation

#define FONTNAME   getDotFontName()

Definition at line 54 of file dot.cpp.

#define FONTSIZE   getDotFontSize()

Definition at line 55 of file dot.cpp.

#define MAP_CMD   "cmapx"

Definition at line 51 of file dot.cpp.

Function Documentation

static bool checkAndUpdateMd5Signature ( const QCString baseName,
const QCString md5 
)
static

Checks if a file "baseName".md5 exists. If so the contents are compared with md5. If equal FALSE is returned. If the .md5 file does not exist or its contents are not equal to md5, a new .md5 is generated with the md5 string as contents.

Definition at line 731 of file dot.cpp.

733 {
734  QFile f(baseName+".md5");
735  if (f.open(IO_ReadOnly))
736  {
737  // read checksum
738  QCString md5stored(33);
739  int bytesRead=f.readBlock(md5stored.rawData(),32);
740  md5stored[32]='\0';
741  // compare checksum
742  if (bytesRead==32 && md5==md5stored)
743  {
744  // bail out if equal
745  return FALSE;
746  }
747  }
748  f.close();
749  // create checksum file
750  if (f.open(IO_WriteOnly))
751  {
752  f.writeBlock(md5.data(),32);
753  f.close();
754  }
755  return TRUE;
756 }
#define IO_WriteOnly
Definition: qiodevice.h:62
const bool FALSE
Definition: qglobal.h:370
#define IO_ReadOnly
Definition: qiodevice.h:61
const char * data() const
Definition: qcstring.h:207
The QFile class is an I/O device that operates on files.
Definition: qfile.h:50
const bool TRUE
Definition: qglobal.h:371
static bool checkDeliverables ( const QCString file1,
const QCString file2 = QCString() 
)
static

Definition at line 758 of file dot.cpp.

760 {
761  bool file1Ok = TRUE;
762  bool file2Ok = TRUE;
763  if (!file1.isEmpty())
764  {
765  QFileInfo fi(file1);
766  file1Ok = (fi.exists() && fi.size()>0);
767  }
768  if (!file2.isEmpty())
769  {
770  QFileInfo fi(file2);
771  file2Ok = (fi.exists() && fi.size()>0);
772  }
773  return file1Ok && file2Ok;
774 }
bool isEmpty() const
Definition: qcstring.h:189
The QFileInfo class provides system-independent file information.
Definition: qfileinfo.h:51
const bool TRUE
Definition: qglobal.h:371
static void checkDotResult ( const char *  imgExt,
const char *  imgName 
)
static

Definition at line 662 of file dot.cpp.

663 {
664  if (qstrcmp(imgExt,"png")==0)
665  {
666  FILE *f = portable_fopen(imgName,"rb");
667  if (f)
668  {
669  char data[4];
670  if (fread(data,1,4,f)==4)
671  {
672  if (!(data[1]=='P' && data[2]=='N' && data[3]=='G'))
673  {
674  err("Image `%s' produced by dot is not a valid PNG!\n"
675  "You should either select a different format "
676  "(DOT_IMAGE_FORMAT in the config file) or install a more "
677  "recent version of graphviz (1.7+)\n",imgName
678  );
679  }
680  }
681  else
682  {
683  err("Could not read image `%s' generated by dot!\n",imgName);
684  }
685  fclose(f);
686  }
687  else
688  {
689  err("Could not open image `%s' generated by dot!\n",imgName);
690  }
691  }
692 }
void err(const char *fmt,...)
Definition: message.cpp:226
Q_EXPORT int qstrcmp(const char *str1, const char *str2)
Definition: qcstring.h:95
FILE * portable_fopen(const char *fileName, const char *mode)
Definition: portable.cpp:344
QCString computeMd5Signature ( DotNode root,
DotNode::GraphType  gt,
GraphOutputFormat  format,
bool  lrRank,
bool  renderParents,
bool  backArrows,
const QCString title,
QCString graphStr 
)

Computes a 16 byte md5 checksum for a given dot graph. The md5 checksum is returned as a 32 character ASCII string.

Definition at line 3018 of file dot.cpp.

3027 {
3028  bool reNumber=TRUE;
3029 
3030  //printf("computeMd5Signature\n");
3031  QGString buf;
3032  FTextStream md5stream(&buf);
3033  writeGraphHeader(md5stream,title);
3034  if (lrRank)
3035  {
3036  md5stream << " rankdir=\"LR\";" << endl;
3037  }
3038  root->clearWriteFlag();
3039  root->write(md5stream,
3040  gt,
3041  format,
3043  TRUE,
3044  backArrows,
3045  reNumber);
3046  if (renderParents && root->m_parents)
3047  {
3048  QListIterator<DotNode> dnli(*root->m_parents);
3049  DotNode *pn;
3050  for (dnli.toFirst();(pn=dnli.current());++dnli)
3051  {
3052  if (pn->isVisible())
3053  {
3054  root->writeArrow(md5stream, // stream
3055  gt, // graph type
3056  format, // output format
3057  pn, // child node
3058  pn->m_edgeInfo->at(pn->m_children->findRef(root)), // edge info
3059  FALSE, // topDown?
3060  backArrows, // point back?
3061  reNumber // renumber nodes
3062  );
3063  }
3064  pn->write(md5stream, // stream
3065  gt, // graph type
3066  format, // output format
3067  TRUE, // topDown?
3068  FALSE, // toChildren?
3069  backArrows, // backward pointing arrows?
3070  reNumber // renumber nodes?
3071  );
3072  }
3073  }
3074  writeGraphFooter(md5stream);
3075  uchar md5_sig[16];
3076  QCString sigStr(33);
3077  MD5Buffer((const unsigned char *)buf.data(),buf.length(),md5_sig);
3078  MD5SigToString(md5_sig,sigStr.rawData(),33);
3079  if (reNumber)
3080  {
3081  resetReNumbering();
3082  }
3083  graphStr=buf.data();
3084  //printf("md5: %s | file: %s\n",sigStr,baseName.data());
3085  return sigStr;
3086 }
QList< EdgeInfo > * m_edgeInfo
edge info for each child
Definition: dot.h:109
static void resetReNumbering()
Definition: dot.cpp:436
char * data() const
Definition: qgstring.h:42
void clearWriteFlag()
Definition: dot.cpp:2168
uint length() const
Definition: qgstring.h:40
void write(FTextStream &t, GraphType gt, GraphOutputFormat f, bool topDown, bool toChildren, bool backArrows, bool reNumber)
Definition: dot.cpp:1906
int findRef(const type *d) const
Definition: qlist.h:89
Definition: dot.h:60
static bool format(QChar::Decomposition tag, QString &str, int index, int len)
Definition: qstring.cpp:11496
const bool FALSE
Definition: qglobal.h:370
type * at(uint i) const
Definition: qlist.h:94
Simplified and optimized version of QTextStream.
Definition: ftextstream.h:11
unsigned char uchar
Definition: nybbler.cc:11
static void writeGraphHeader(FTextStream &t, const QCString &title=QCString())
Definition: dot.cpp:251
void MD5Buffer(const unsigned char *buf, unsigned int len, unsigned char sig[16])
Definition: md5.c:275
QList< DotNode > * m_children
list of child nodes (outgoing arrows)
Definition: dot.h:108
void writeArrow(FTextStream &t, GraphType gt, GraphOutputFormat f, DotNode *cn, EdgeInfo *ei, bool topDown, bool pointBack=TRUE, bool reNumber=FALSE)
Definition: dot.cpp:1854
QList< DotNode > * m_parents
list of parent nodes (incoming arrows)
Definition: dot.h:107
static void writeGraphFooter(FTextStream &t)
Definition: dot.cpp:281
void MD5SigToString(unsigned char signature[16], char *str, int len)
Definition: md5.c:285
UWORD32 buf[4]
Definition: md5.h:42
bool isVisible() const
Definition: dot.h:89
const bool TRUE
Definition: qglobal.h:371
QTextStream & endl(QTextStream &s)
static QCString convertLabel ( const QCString l)
static

Definition at line 1564 of file dot.cpp.

1565 {
1566  QCString result;
1567  QCString bBefore("\\_/<({[: =-+@%#~?$"); // break before character set
1568  QCString bAfter(">]),:;|"); // break after character set
1569  const char *p=l.data();
1570  if (p==0) return result;
1571  char c,pc=0;
1572  char cs[2];
1573  cs[1]=0;
1574  int len=l.length();
1575  int charsLeft=len;
1576  int sinceLast=0;
1577  int foldLen=17; // ideal text length
1578  while ((c=*p++))
1579  {
1580  QCString replacement;
1581  switch(c)
1582  {
1583  case '\\': replacement="\\\\"; break;
1584  case '\n': replacement="\\n"; break;
1585  case '<': replacement="\\<"; break;
1586  case '>': replacement="\\>"; break;
1587  case '|': replacement="\\|"; break;
1588  case '{': replacement="\\{"; break;
1589  case '}': replacement="\\}"; break;
1590  case '"': replacement="\\\""; break;
1591  default: cs[0]=c; replacement=cs; break;
1592  }
1593  // Some heuristics to insert newlines to prevent too long
1594  // boxes and at the same time prevent ugly breaks
1595  if (c=='\n')
1596  {
1597  result+=replacement;
1598  foldLen = (3*foldLen+sinceLast+2)/4;
1599  sinceLast=1;
1600  }
1601  else if ((pc!=':' || c!=':') && charsLeft>foldLen/3 && sinceLast>foldLen && bBefore.contains(c))
1602  {
1603  result+="\\l";
1604  result+=replacement;
1605  foldLen = (foldLen+sinceLast+1)/2;
1606  sinceLast=1;
1607  }
1608  else if (charsLeft>1+foldLen/4 && sinceLast>foldLen+foldLen/3 &&
1609  !isupper(c) && isupper(*p))
1610  {
1611  result+=replacement;
1612  result+="\\l";
1613  foldLen = (foldLen+sinceLast+1)/2;
1614  sinceLast=0;
1615  }
1616  else if (charsLeft>foldLen/3 && sinceLast>foldLen && bAfter.contains(c) && (c!=':' || *p!=':'))
1617  {
1618  result+=replacement;
1619  result+="\\l";
1620  foldLen = (foldLen+sinceLast+1)/2;
1621  sinceLast=0;
1622  }
1623  else
1624  {
1625  result+=replacement;
1626  sinceLast++;
1627  }
1628  charsLeft--;
1629  pc=c;
1630  }
1631  return result;
1632 }
static QCString result
uint length() const
Definition: qcstring.h:195
p
Definition: test.py:223
const char * data() const
Definition: qcstring.h:207
const char * cs
static bool convertMapFile ( FTextStream t,
const char *  mapName,
const QCString  relPath,
bool  urlOnly = FALSE,
const QCString context = QCString() 
)
static

converts the rectangles in a client site image map into a stream

Parameters
tthe stream to which the result is written.
mapNamethe name of the map file.
relPaththe relative path to the root of the output directory (used in case CREATE_SUBDIRS is enabled).
urlOnlyif FALSE the url field in the map contains an external references followed by a $ and then the URL.
contextthe context (file, class, or namespace) in which the map file was found
Returns
TRUE if successful.

Definition at line 370 of file dot.cpp.

373 {
374  QFile f(mapName);
375  if (!f.open(IO_ReadOnly))
376  {
377  err("problems opening map file %s for inclusion in the docs!\n"
378  "If you installed Graphviz/dot after a previous failing run, \n"
379  "try deleting the output directory and rerun doxygen.\n",mapName);
380  return FALSE;
381  }
382  const int maxLineLen=10240;
383  while (!f.atEnd()) // foreach line
384  {
385  QCString buf(maxLineLen);
386  int numBytes = f.readLine(buf.rawData(),maxLineLen);
387  if (numBytes>0)
388  {
389  buf.resize(numBytes+1);
390 
391  if (buf.left(5)=="<area")
392  {
393  t << replaceRef(buf,relPath,urlOnly,context);
394  }
395  }
396  }
397  return TRUE;
398 }
const bool FALSE
Definition: qglobal.h:370
static QCString replaceRef(const QCString &buf, const QCString relPath, bool urlOnly, const QCString &context, const QCString &target=QCString())
Definition: dot.cpp:286
#define IO_ReadOnly
Definition: qiodevice.h:61
void err(const char *fmt,...)
Definition: message.cpp:226
The QFile class is an I/O device that operates on files.
Definition: qfile.h:50
UWORD32 buf[4]
Definition: md5.h:42
const bool TRUE
Definition: qglobal.h:371
static void deleteNodes ( DotNode node,
SDict< DotNode > *  skipNodes = 0 
)
static

helper function that deletes all nodes in a connected graph, given one of the graph's nodes

Definition at line 1443 of file dot.cpp.

1444 {
1445  //printf("deleteNodes skipNodes=%p\n",skipNodes);
1446  static DotNodeList deletedNodes;
1447  deletedNodes.setAutoDelete(TRUE);
1448  node->deleteNode(deletedNodes,skipNodes); // collect nodes to be deleted.
1449  deletedNodes.clear(); // actually remove the nodes.
1450 }
void clear()
Definition: qlist.h:82
void deleteNode(DotNodeList &deletedList, SDict< DotNode > *skipNodes=0)
Definition: dot.cpp:1526
void setAutoDelete(bool enable)
Definition: qlist.h:99
const bool TRUE
Definition: qglobal.h:371
static QCString escapeTooltip ( const QCString tooltip)
static

Definition at line 1634 of file dot.cpp.

1635 {
1636  QCString result;
1637  const char *p=tooltip.data();
1638  if (p==0) return result;
1639  char c;
1640  while ((c=*p++))
1641  {
1642  switch(c)
1643  {
1644  case '"': result+="\\\""; break;
1645  default: result+=c; break;
1646  }
1647  }
1648  return result;
1649 }
static QCString result
p
Definition: test.py:223
const char * data() const
Definition: qcstring.h:207
void generateGraphLegend ( const char *  path)

Generated a graphs legend page

Definition at line 4127 of file dot.cpp.

4128 {
4129  QDir d(path);
4130  // store the original directory
4131  if (!d.exists())
4132  {
4133  err("Output dir %s does not exist!\n",path); exit(1);
4134  }
4135 
4136  QGString theGraph;
4137  FTextStream md5stream(&theGraph);
4139  md5stream << " Node9 [shape=\"box\",label=\"Inherited\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",fillcolor=\"grey75\",style=\"filled\" fontcolor=\"black\"];\n";
4140  md5stream << " Node10 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
4141  md5stream << " Node10 [shape=\"box\",label=\"PublicBase\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classPublicBase" << Doxygen::htmlFileExtension << "\"];\n";
4142  md5stream << " Node11 -> Node10 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
4143  md5stream << " Node11 [shape=\"box\",label=\"Truncated\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"red\",URL=\"$classTruncated" << Doxygen::htmlFileExtension << "\"];\n";
4144  md5stream << " Node13 -> Node9 [dir=\"back\",color=\"darkgreen\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
4145  md5stream << " Node13 [shape=\"box\",label=\"ProtectedBase\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classProtectedBase" << Doxygen::htmlFileExtension << "\"];\n";
4146  md5stream << " Node14 -> Node9 [dir=\"back\",color=\"firebrick4\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
4147  md5stream << " Node14 [shape=\"box\",label=\"PrivateBase\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classPrivateBase" << Doxygen::htmlFileExtension << "\"];\n";
4148  md5stream << " Node15 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
4149  md5stream << " Node15 [shape=\"box\",label=\"Undocumented\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"grey75\"];\n";
4150  md5stream << " Node16 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << FONTSIZE << "\",style=\"solid\",fontname=\"" << FONTNAME << "\"];\n";
4151  md5stream << " Node16 [shape=\"box\",label=\"Templ< int >\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension << "\"];\n";
4152  md5stream << " Node17 -> Node16 [dir=\"back\",color=\"orange\",fontsize=\"" << FONTSIZE << "\",style=\"dashed\",label=\"< int >\",fontname=\"" << FONTNAME << "\"];\n";
4153  md5stream << " Node17 [shape=\"box\",label=\"Templ< T >\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension << "\"];\n";
4154  md5stream << " Node18 -> Node9 [dir=\"back\",color=\"darkorchid3\",fontsize=\"" << FONTSIZE << "\",style=\"dashed\",label=\"m_usedClass\",fontname=\"" << FONTNAME << "\"];\n";
4155  md5stream << " Node18 [shape=\"box\",label=\"Used\",fontsize=\"" << FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << FONTNAME << "\",color=\"black\",URL=\"$classUsed" << Doxygen::htmlFileExtension << "\"];\n";
4156  writeGraphFooter(md5stream);
4157  uchar md5_sig[16];
4158  QCString sigStr(33);
4159  MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig);
4160  MD5SigToString(md5_sig,sigStr.rawData(),33);
4161  QCString absBaseName = (QCString)path+"/graph_legend";
4162  QCString absDotName = absBaseName+".dot";
4163  QCString imgExt = getDotImageExtension();
4164  QCString imgFmt = Config_getEnum("DOT_IMAGE_FORMAT");
4165  QCString imgName = "graph_legend."+imgExt;
4166  QCString absImgName = absBaseName+"."+imgExt;
4167  if (checkAndUpdateMd5Signature(absBaseName,sigStr) ||
4168  !checkDeliverables(absImgName))
4169  {
4170  QFile dotFile(absDotName);
4171  if (!dotFile.open(IO_WriteOnly))
4172  {
4173  err("Could not open file %s for writing\n",dotFile.name().data());
4174  return;
4175  }
4176 
4177  FTextStream dotText(&dotFile);
4178  dotText << theGraph;
4179  dotFile.close();
4180 
4181  // run dot to generate the a bitmap image from the graph
4182 
4183  DotRunner *dotRun = new DotRunner(absDotName,d.absPath().data(),TRUE,absImgName);
4184  dotRun->addJob(imgFmt,absImgName);
4185  DotManager::instance()->addRun(dotRun);
4186  }
4187  else
4188  {
4189  removeDotGraph(absDotName);
4190  }
4191  Doxygen::indexList->addImageFile(imgName);
4192 
4193  if (imgExt=="svg")
4194  {
4196  absBaseName+Config_getString("HTML_FILE_EXTENSION"),
4197  "graph_legend",
4198  absImgName,QCString());
4199  }
4200 
4201 }
Traverses directory structures and contents in a platform-independent way.
Definition: qdir.h:52
char * data() const
Definition: qgstring.h:42
static bool checkAndUpdateMd5Signature(const QCString &baseName, const QCString &md5)
Definition: dot.cpp:731
Definition: dot.h:356
uint length() const
Definition: qgstring.h:40
static bool checkDeliverables(const QCString &file1, const QCString &file2=QCString())
Definition: dot.cpp:758
#define IO_WriteOnly
Definition: qiodevice.h:62
static QCString htmlFileExtension
Definition: doxygen.h:130
virtual QCString trLegendTitle()=0
static DotManager * instance()
Definition: dot.cpp:1221
Simplified and optimized version of QTextStream.
Definition: ftextstream.h:11
unsigned char uchar
Definition: nybbler.cc:11
static void writeGraphHeader(FTextStream &t, const QCString &title=QCString())
Definition: dot.cpp:251
#define Config_getEnum(val)
Definition: config.cpp:663
static void removeDotGraph(const QCString &dotName)
Definition: dot.cpp:714
void MD5Buffer(const unsigned char *buf, unsigned int len, unsigned char sig[16])
Definition: md5.c:275
#define FONTNAME
Definition: dot.cpp:54
void addImageFile(const char *name)
Definition: index.h:147
#define Config_getString(val)
Definition: config.cpp:660
QCString getDotImageExtension(void)
Definition: util.cpp:8562
void err(const char *fmt,...)
Definition: message.cpp:226
The QFile class is an I/O device that operates on files.
Definition: qfile.h:50
int addSVGObject(const QCString &file, const QCString &baseName, const QCString &figureNAme, const QCString &relPath)
Definition: dot.cpp:1305
#define FONTSIZE
Definition: dot.cpp:55
static void writeGraphFooter(FTextStream &t)
Definition: dot.cpp:281
void addJob(const char *format, const char *output)
Definition: dot.cpp:807
void MD5SigToString(unsigned char signature[16], char *str, int len)
Definition: md5.c:285
Translator * theTranslator
Definition: language.cpp:157
void addRun(DotRunner *run)
Definition: dot.cpp:1262
const bool TRUE
Definition: qglobal.h:371
static IndexList * indexList
Definition: doxygen.h:149
static QCString getDotFontName ( )
static

Definition at line 233 of file dot.cpp.

234 {
235  static QCString dotFontName = Config_getString("DOT_FONTNAME");
236  if (dotFontName.isEmpty())
237  {
238  //dotFontName="FreeSans.ttf";
239  dotFontName="Helvetica";
240  }
241  return dotFontName;
242 }
bool isEmpty() const
Definition: qcstring.h:189
#define Config_getString(val)
Definition: config.cpp:660
static int getDotFontSize ( )
static

Definition at line 244 of file dot.cpp.

245 {
246  static int dotFontSize = Config_getInt("DOT_FONTSIZE");
247  if (dotFontSize<4) dotFontSize=4;
248  return dotFontSize;
249 }
#define Config_getInt(val)
Definition: config.cpp:661
static bool insertMapFile ( FTextStream out,
const QCString mapFile,
const QCString relPath,
const QCString mapLabel 
)
static

Definition at line 694 of file dot.cpp.

696 {
697  QFileInfo fi(mapFile);
698  if (fi.exists() && fi.size()>0) // reuse existing map file
699  {
700  QGString tmpstr;
701  FTextStream tmpout(&tmpstr);
702  convertMapFile(tmpout,mapFile,relPath);
703  if (!tmpstr.isEmpty())
704  {
705  out << "<map name=\"" << mapLabel << "\" id=\"" << mapLabel << "\">" << endl;
706  out << tmpstr;
707  out << "</map>" << endl;
708  }
709  return TRUE;
710  }
711  return FALSE; // no map file yet, need to generate it
712 }
const bool FALSE
Definition: qglobal.h:370
Simplified and optimized version of QTextStream.
Definition: ftextstream.h:11
bool isEmpty() const
Definition: qgstring.h:39
The QFileInfo class provides system-independent file information.
Definition: qfileinfo.h:51
static bool convertMapFile(FTextStream &t, const char *mapName, const QCString relPath, bool urlOnly=FALSE, const QCString &context=QCString())
Definition: dot.cpp:370
const bool TRUE
Definition: qglobal.h:371
QTextStream & endl(QTextStream &s)
static bool readBoundingBox ( const char *  fileName,
int *  width,
int *  height,
bool  isEps 
)
static

Definition at line 479 of file dot.cpp.

480 {
481  QCString bb = isEps ? QCString("%%PageBoundingBox:") : QCString("/MediaBox [");
482  QFile f(fileName);
483  if (!f.open(IO_ReadOnly|IO_Raw))
484  {
485  //printf("readBoundingBox: could not open %s\n",fileName);
486  return FALSE;
487  }
488  const int maxLineLen=1024;
489  char buf[maxLineLen];
490  while (!f.atEnd())
491  {
492  int numBytes = f.readLine(buf,maxLineLen-1); // read line
493  if (numBytes>0)
494  {
495  buf[numBytes]='\0';
496  const char *p = strstr(buf,bb);
497  if (p) // found PageBoundingBox or /MediaBox string
498  {
499  int x,y;
500  if (sscanf(p+bb.length(),"%d %d %d %d",&x,&y,width,height)!=4)
501  {
502  //printf("readBoundingBox sscanf fail\n");
503  return FALSE;
504  }
505  return TRUE;
506  }
507  }
508  else // read error!
509  {
510  //printf("Read error %d!\n",numBytes);
511  return FALSE;
512  }
513  }
514  err("Failed to extract bounding box from generated diagram file %s\n",fileName);
515  return FALSE;
516 }
uint length() const
Definition: qcstring.h:195
#define IO_Raw
Definition: qiodevice.h:56
const bool FALSE
Definition: qglobal.h:370
#define IO_ReadOnly
Definition: qiodevice.h:61
fileName
Definition: dumpTree.py:9
p
Definition: test.py:223
void err(const char *fmt,...)
Definition: message.cpp:226
The QFile class is an I/O device that operates on files.
Definition: qfile.h:50
list x
Definition: train.py:276
UWORD32 buf[4]
Definition: md5.h:42
const bool TRUE
Definition: qglobal.h:371
static bool readSVGSize ( const QCString fileName,
int *  width,
int *  height 
)
static

Definition at line 572 of file dot.cpp.

573 {
574  bool found=FALSE;
575  QFile f(fileName);
576  if (!f.open(IO_ReadOnly))
577  {
578  return FALSE;
579  }
580  const int maxLineLen=4096;
581  char buf[maxLineLen];
582  while (!f.atEnd() && !found)
583  {
584  int numBytes = f.readLine(buf,maxLineLen-1); // read line
585  if (numBytes>0)
586  {
587  buf[numBytes]='\0';
588  if (qstrncmp(buf,"<!--zoomable ",13)==0)
589  {
590  *width=-1;
591  *height=-1;
592  sscanf(buf,"<!--zoomable %d",height);
593  //printf("Found zoomable for %s!\n",fileName.data());
594  found=TRUE;
595  }
596  else if (sscanf(buf,"<svg width=\"%dpt\" height=\"%dpt\"",width,height)==2)
597  {
598  //printf("Found fixed size %dx%d for %s!\n",*width,*height,fileName.data());
599  found=TRUE;
600  }
601  }
602  else // read error!
603  {
604  //printf("Read error %d!\n",numBytes);
605  return FALSE;
606  }
607  }
608  return TRUE;
609 }
Q_EXPORT int qstrncmp(const char *str1, const char *str2, uint len)
Definition: qcstring.h:101
const bool FALSE
Definition: qglobal.h:370
#define IO_ReadOnly
Definition: qiodevice.h:61
The QFile class is an I/O device that operates on files.
Definition: qfile.h:50
UWORD32 buf[4]
Definition: md5.h:42
const bool TRUE
Definition: qglobal.h:371
static void removeDotGraph ( const QCString dotName)
static

Definition at line 714 of file dot.cpp.

715 {
716  static bool dotCleanUp = Config_getBool("DOT_CLEANUP");
717  if (dotCleanUp)
718  {
719  QDir d;
720  d.remove(dotName);
721  }
722 }
Traverses directory structures and contents in a platform-independent way.
Definition: qdir.h:52
virtual bool remove(const QString &fileName, bool acceptAbsPath=TRUE)
Definition: qdir.cpp:915
#define Config_getBool(val)
Definition: config.cpp:664
int reNumberNode ( int  number,
bool  doReNumbering 
)
inline

Definition at line 403 of file dot.cpp.

404 {
405  if (!doReNumbering)
406  {
407  return number;
408  }
409  else
410  {
411  int s = s_newNumber.size();
412  if (number>=s)
413  {
414  int ns=0;
415  ns = s * 3 / 2 + 5; // new size
416  if (number>=ns) // number still doesn't fit
417  {
418  ns = number * 3 / 2 + 5;
419  }
420  s_newNumber.resize(ns);
421  for (int i=s;i<ns;i++) // clear new part of the array
422  {
423  s_newNumber.at(i)=0;
424  }
425  }
426  int i = s_newNumber.at(number);
427  if (i == 0) // not yet mapped
428  {
429  i = ++s_max_newNumber; // start from 1
430  s_newNumber.at(number) = i;
431  }
432  return i;
433  }
434 }
static QArray< int > s_newNumber
Definition: dot.cpp:400
QAsciiDict< Entry > ns
static QCString * s
Definition: config.cpp:1042
static int s_max_newNumber
Definition: dot.cpp:401
static QCString replaceRef ( const QCString buf,
const QCString  relPath,
bool  urlOnly,
const QCString context,
const QCString target = QCString() 
)
static

Definition at line 286 of file dot.cpp.

288 {
289  // search for href="...", store ... part in link
290  QCString href = "href";
291  //bool isXLink=FALSE;
292  int len = 6;
293  int indexS = buf.find("href=\""), indexE;
294  if (indexS>5 && buf.find("xlink:href=\"")!=-1) // XLink href (for SVG)
295  {
296  indexS-=6;
297  len+=6;
298  href.prepend("xlink:");
299  //isXLink=TRUE;
300  }
301  if (indexS>=0 && (indexE=buf.find('"',indexS+len))!=-1)
302  {
303  QCString link = buf.mid(indexS+len,indexE-indexS-len);
305  if (urlOnly) // for user defined dot graphs
306  {
307  if (link.left(5)=="\\ref " || link.left(5)=="@ref ") // \ref url
308  {
309  result=href+"=\"";
310  // fake ref node to resolve the url
311  DocRef *df = new DocRef( (DocNode*) 0, link.mid(5), context );
312  result+=externalRef(relPath,df->ref(),TRUE);
313  if (!df->file().isEmpty())
314  result += df->file().data() + Doxygen::htmlFileExtension;
315  if (!df->anchor().isEmpty())
316  result += "#" + df->anchor();
317  delete df;
318  result += "\"";
319  }
320  else
321  {
322  result = href+"=\"" + link + "\"";
323  }
324  }
325  else // ref$url (external ref via tag file), or $url (local ref)
326  {
327  int marker = link.find('$');
328  if (marker!=-1)
329  {
330  QCString ref = link.left(marker);
331  QCString url = link.mid(marker+1);
332  if (!ref.isEmpty())
333  {
334  result = externalLinkTarget() + externalRef(relPath,ref,FALSE);
335  }
336  result+= href+"=\"";
337  result+=externalRef(relPath,ref,TRUE);
338  result+= url + "\"";
339  }
340  else // should not happen, but handle properly anyway
341  {
342  result = href+"=\"" + link + "\"";
343  }
344  }
345  if (!target.isEmpty())
346  {
347  result+=" target=\""+target+"\"";
348  }
349  QCString leftPart = buf.left(indexS);
350  QCString rightPart = buf.mid(indexE+1);
351  return leftPart + result + rightPart;
352  }
353  else
354  {
355  return buf;
356  }
357 }
QCString anchor() const
Definition: docparser.h:830
static QCString result
bool isEmpty() const
Definition: qcstring.h:189
static QCString htmlFileExtension
Definition: doxygen.h:130
const bool FALSE
Definition: qglobal.h:370
QCString left(uint len) const
Definition: qcstring.cpp:213
QCString file() const
Definition: docparser.h:827
int find(char c, int index=0, bool cs=TRUE) const
Definition: qcstring.cpp:41
QCString ref() const
Definition: docparser.h:829
QCString & prepend(const char *s)
Definition: qcstring.cpp:387
const char * data() const
Definition: qcstring.h:207
QCString mid(uint index, uint len=0xffffffff) const
Definition: qcstring.cpp:246
UWORD32 buf[4]
Definition: md5.h:42
QCString externalLinkTarget()
Definition: util.cpp:7850
const bool TRUE
Definition: qglobal.h:371
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition: util.cpp:7856
static void resetReNumbering ( )
static

Definition at line 436 of file dot.cpp.

437 {
438  s_max_newNumber=0;
440 }
static QArray< int > s_newNumber
Definition: dot.cpp:400
static int s_max_newNumber
Definition: dot.cpp:401
static void setDotFontPath ( const char *  path)
static

Definition at line 444 of file dot.cpp.

445 {
447  g_dotFontPath = portable_getenv("DOTFONTPATH");
448  QCString newFontPath = Config_getString("DOT_FONTPATH");
449  QCString spath = path;
450  if (!newFontPath.isEmpty() && !spath.isEmpty())
451  {
452  newFontPath.prepend(spath+portable_pathListSeparator());
453  }
454  else if (newFontPath.isEmpty() && !spath.isEmpty())
455  {
456  newFontPath=path;
457  }
458  else
459  {
460  portable_unsetenv("DOTFONTPATH");
461  return;
462  }
463  portable_setenv("DOTFONTPATH",newFontPath);
464 }
bool isEmpty() const
Definition: qcstring.h:189
const char * portable_getenv(const char *variable)
Definition: portable.cpp:317
void portable_unsetenv(const char *variable)
Definition: portable.cpp:283
QCString & prepend(const char *s)
Definition: qcstring.cpp:387
char portable_pathListSeparator()
Definition: portable.cpp:364
#define Config_getString(val)
Definition: config.cpp:660
void portable_setenv(const char *name, const char *value)
Definition: portable.cpp:202
static QCString g_dotFontPath
Definition: dot.cpp:442
#define ASSERT(x)
Definition: qglobal.h:590
static QCString stripProtectionPrefix ( const QCString s)
static

Definition at line 1710 of file dot.cpp.

1711 {
1712  if (!s.isEmpty() && (s[0]=='-' || s[0]=='+' || s[0]=='~' || s[0]=='#'))
1713  {
1714  return s.mid(1);
1715  }
1716  else
1717  {
1718  return s;
1719  }
1720 }
bool isEmpty() const
Definition: qcstring.h:189
QCString mid(uint index, uint len=0xffffffff) const
Definition: qcstring.cpp:246
static QCString * s
Definition: config.cpp:1042
static void unsetDotFontPath ( )
static

Definition at line 466 of file dot.cpp.

467 {
468  if (g_dotFontPath.isEmpty())
469  {
470  portable_unsetenv("DOTFONTPATH");
471  }
472  else
473  {
474  portable_setenv("DOTFONTPATH",g_dotFontPath);
475  }
476  g_dotFontPath="";
477 }
bool isEmpty() const
Definition: qcstring.h:189
void portable_unsetenv(const char *variable)
Definition: portable.cpp:283
void portable_setenv(const char *name, const char *value)
Definition: portable.cpp:202
static QCString g_dotFontPath
Definition: dot.cpp:442
static bool updateDotGraph ( DotNode root,
DotNode::GraphType  gt,
const QCString baseName,
GraphOutputFormat  format,
bool  lrRank,
bool  renderParents,
bool  backArrows,
const QCString title = QCString() 
)
static

Definition at line 3088 of file dot.cpp.

3097 {
3098  QCString theGraph;
3099  // TODO: write graph to theGraph, then compute md5 checksum
3101  root,gt,format,lrRank,renderParents,
3102  backArrows,title,theGraph);
3103  QFile f(baseName+".dot");
3104  if (f.open(IO_WriteOnly))
3105  {
3106  FTextStream t(&f);
3107  t << theGraph;
3108  }
3109  return checkAndUpdateMd5Signature(baseName,md5); // graph needs to be regenerated
3110 }
static bool checkAndUpdateMd5Signature(const QCString &baseName, const QCString &md5)
Definition: dot.cpp:731
#define IO_WriteOnly
Definition: qiodevice.h:62
QCString computeMd5Signature(DotNode *root, DotNode::GraphType gt, GraphOutputFormat format, bool lrRank, bool renderParents, bool backArrows, const QCString &title, QCString &graphStr)
Definition: dot.cpp:3018
static bool format(QChar::Decomposition tag, QString &str, int index, int len)
Definition: qstring.cpp:11496
Simplified and optimized version of QTextStream.
Definition: ftextstream.h:11
The QFile class is an I/O device that operates on files.
Definition: qfile.h:50
static void writeBoxMemberList ( FTextStream t,
char  prot,
MemberList ml,
ClassDef scope,
bool  isStatic = FALSE,
const QDict< void > *  skipNames = 0 
)
static

Definition at line 1651 of file dot.cpp.

1654 {
1655  (void)isStatic;
1656  if (ml)
1657  {
1658  MemberListIterator mlia(*ml);
1659  MemberDef *mma;
1660  int totalCount=0;
1661  for (mlia.toFirst();(mma = mlia.current());++mlia)
1662  {
1663  if (mma->getClassDef()==scope &&
1664  (skipNames==0 || skipNames->find(mma->name())==0))
1665  {
1666  totalCount++;
1667  }
1668  }
1669 
1670  int count=0;
1671  for (mlia.toFirst();(mma = mlia.current());++mlia)
1672  {
1673  if (mma->getClassDef() == scope &&
1674  (skipNames==0 || skipNames->find(mma->name())==0))
1675  {
1676  static int limit = Config_getInt("UML_LIMIT_NUM_FIELDS");
1677  if (limit>0 && (totalCount>limit*3/2 && count>=limit))
1678  {
1679  t << theTranslator->trAndMore(QCString().sprintf("%d",totalCount-count)) << "\\l";
1680  break;
1681  }
1682  else
1683  {
1684  t << prot << " ";
1685  t << convertLabel(mma->name());
1686  if (!mma->isObjCMethod() &&
1687  (mma->isFunction() || mma->isSlot() || mma->isSignal())) t << "()";
1688  t << "\\l";
1689  count++;
1690  }
1691  }
1692  }
1693  // write member groups within the memberlist
1694  MemberGroupList *mgl = ml->getMemberGroupList();
1695  if (mgl)
1696  {
1697  MemberGroupListIterator mgli(*mgl);
1698  MemberGroup *mg;
1699  for (mgli.toFirst();(mg=mgli.current());++mgli)
1700  {
1701  if (mg->members())
1702  {
1703  writeBoxMemberList(t,prot,mg->members(),scope,isStatic,skipNames);
1704  }
1705  }
1706  }
1707  }
1708 }
MemberGroupList * getMemberGroupList() const
Definition: memberlist.h:78
static QCString scope
Definition: declinfo.cpp:668
static void writeBoxMemberList(FTextStream &t, char prot, MemberList *ml, ClassDef *scope, bool isStatic=FALSE, const QDict< void > *skipNames=0)
Definition: dot.cpp:1651
MemberList * members() const
Definition: membergroup.h:88
static QCString convertLabel(const QCString &l)
Definition: dot.cpp:1564
bool isSignal() const
Definition: memberdef.cpp:4130
bool isSlot() const
Definition: memberdef.cpp:4135
static constexpr double mg
Definition: Units.h:145
virtual QCString trAndMore(const QCString &number)=0
#define Config_getInt(val)
Definition: config.cpp:661
const QCString & name() const
Definition: definition.h:114
ClassDef * getClassDef() const
Definition: memberdef.cpp:4070
bool isObjCMethod() const
Definition: memberdef.cpp:3956
Translator * theTranslator
Definition: language.cpp:157
bool isFunction() const
Definition: memberdef.cpp:4160
void writeDotDirDepGraph ( FTextStream t,
DirDef dd,
bool  linkRelations 
)
static

Definition at line 4769 of file dot.cpp.

4770 {
4771  t << "digraph \"" << dd->displayName() << "\" {\n";
4772  if (Config_getBool("DOT_TRANSPARENT"))
4773  {
4774  t << " bgcolor=transparent;\n";
4775  }
4776  t << " compound=true\n";
4777  t << " node [ fontsize=\"" << FONTSIZE << "\", fontname=\"" << FONTNAME << "\"];\n";
4778  t << " edge [ labelfontsize=\"" << FONTSIZE << "\", labelfontname=\"" << FONTNAME << "\"];\n";
4779 
4780  QDict<DirDef> dirsInGraph(257);
4781 
4782  dirsInGraph.insert(dd->getOutputFileBase(),dd);
4783  if (dd->parent())
4784  {
4785  t << " subgraph cluster" << dd->parent()->getOutputFileBase() << " {\n";
4786  t << " graph [ bgcolor=\"#ddddee\", pencolor=\"black\", label=\""
4787  << dd->parent()->shortName()
4788  << "\" fontname=\"" << FONTNAME << "\", fontsize=\"" << FONTSIZE << "\", URL=\"";
4790  t << "\"]\n";
4791  }
4792  if (dd->isCluster())
4793  {
4794  t << " subgraph cluster" << dd->getOutputFileBase() << " {\n";
4795  t << " graph [ bgcolor=\"#eeeeff\", pencolor=\"black\", label=\"\""
4796  << " URL=\"" << dd->getOutputFileBase() << Doxygen::htmlFileExtension
4797  << "\"];\n";
4798  t << " " << dd->getOutputFileBase() << " [shape=plaintext label=\""
4799  << dd->shortName() << "\"];\n";
4800 
4801  // add nodes for sub directories
4802  QListIterator<DirDef> sdi(dd->subDirs());
4803  DirDef *sdir;
4804  for (sdi.toFirst();(sdir=sdi.current());++sdi)
4805  {
4806  t << " " << sdir->getOutputFileBase() << " [shape=box label=\""
4807  << sdir->shortName() << "\"";
4808  if (sdir->isCluster())
4809  {
4810  t << " color=\"red\"";
4811  }
4812  else
4813  {
4814  t << " color=\"black\"";
4815  }
4816  t << " fillcolor=\"white\" style=\"filled\"";
4817  t << " URL=\"" << sdir->getOutputFileBase()
4818  << Doxygen::htmlFileExtension << "\"";
4819  t << "];\n";
4820  dirsInGraph.insert(sdir->getOutputFileBase(),sdir);
4821  }
4822  t << " }\n";
4823  }
4824  else
4825  {
4826  t << " " << dd->getOutputFileBase() << " [shape=box, label=\""
4827  << dd->shortName() << "\", style=\"filled\", fillcolor=\"#eeeeff\","
4828  << " pencolor=\"black\", URL=\"" << dd->getOutputFileBase()
4829  << Doxygen::htmlFileExtension << "\"];\n";
4830  }
4831  if (dd->parent())
4832  {
4833  t << " }\n";
4834  }
4835 
4836  // add nodes for other used directories
4837  QDictIterator<UsedDir> udi(*dd->usedDirs());
4838  UsedDir *udir;
4839  //printf("*** For dir %s\n",shortName().data());
4840  for (udi.toFirst();(udir=udi.current());++udi)
4841  // for each used dir (=directly used or a parent of a directly used dir)
4842  {
4843  const DirDef *usedDir=udir->dir();
4844  DirDef *dir=dd;
4845  while (dir)
4846  {
4847  //printf("*** check relation %s->%s same_parent=%d !%s->isParentOf(%s)=%d\n",
4848  // dir->shortName().data(),usedDir->shortName().data(),
4849  // dir->parent()==usedDir->parent(),
4850  // usedDir->shortName().data(),
4851  // shortName().data(),
4852  // !usedDir->isParentOf(this)
4853  // );
4854  if (dir!=usedDir && dir->parent()==usedDir->parent() &&
4855  !usedDir->isParentOf(dd))
4856  // include if both have the same parent (or no parent)
4857  {
4858  t << " " << usedDir->getOutputFileBase() << " [shape=box label=\""
4859  << usedDir->shortName() << "\"";
4860  if (usedDir->isCluster())
4861  {
4862  if (!Config_getBool("DOT_TRANSPARENT"))
4863  {
4864  t << " fillcolor=\"white\" style=\"filled\"";
4865  }
4866  t << " color=\"red\"";
4867  }
4868  t << " URL=\"" << usedDir->getOutputFileBase()
4869  << Doxygen::htmlFileExtension << "\"];\n";
4870  dirsInGraph.insert(usedDir->getOutputFileBase(),usedDir);
4871  break;
4872  }
4873  dir=dir->parent();
4874  }
4875  }
4876 
4877  // add relations between all selected directories
4878  DirDef *dir;
4879  QDictIterator<DirDef> di(dirsInGraph);
4880  for (di.toFirst();(dir=di.current());++di) // foreach dir in the graph
4881  {
4882  QDictIterator<UsedDir> udi(*dir->usedDirs());
4883  UsedDir *udir;
4884  for (udi.toFirst();(udir=udi.current());++udi) // foreach used dir
4885  {
4886  const DirDef *usedDir=udir->dir();
4887  if ((dir!=dd || !udir->inherited()) && // only show direct dependendies for this dir
4888  (usedDir!=dd || !udir->inherited()) && // only show direct dependendies for this dir
4889  !usedDir->isParentOf(dir) && // don't point to own parent
4890  dirsInGraph.find(usedDir->getOutputFileBase())) // only point to nodes that are in the graph
4891  {
4892  QCString relationName;
4893  relationName.sprintf("dir_%06d_%06d",dir->dirCount(),usedDir->dirCount());
4894  if (Doxygen::dirRelations.find(relationName)==0)
4895  {
4896  // new relation
4897  Doxygen::dirRelations.append(relationName,
4898  new DirRelation(relationName,dir,udir));
4899  }
4900  int nrefs = udir->filePairs().count();
4901  t << " " << dir->getOutputFileBase() << "->"
4902  << usedDir->getOutputFileBase();
4903  t << " [headlabel=\"" << nrefs << "\", labeldistance=1.5";
4904  if (linkRelations)
4905  {
4906  t << " headhref=\"" << relationName << Doxygen::htmlFileExtension << "\"";
4907  }
4908  t << "];\n";
4909  }
4910  }
4911  }
4912 
4913  t << "}\n";
4914 }
bool isParentOf(DirDef *dir) const
Definition: dirdef.cpp:603
static SDict< DirRelation > dirRelations
Definition: doxygen.h:140
const QCString & shortName() const
Definition: dirdef.h:57
static QCString htmlFileExtension
Definition: doxygen.h:130
bool isCluster() const
Definition: dirdef.h:62
string dir
void append(const char *key, const T *d)
Definition: sortdict.h:135
QCString displayName(bool=TRUE) const
Definition: dirdef.h:56
int dirCount() const
Definition: dirdef.h:65
const DirList & subDirs() const
Definition: dirdef.h:61
const QDict< UsedDir > * usedDirs() const
Definition: dirdef.h:66
#define FONTNAME
Definition: dot.cpp:54
Definition: dirdef.h:44
type * current() const
Definition: qlist.h:146
#define Config_getBool(val)
Definition: config.cpp:664
QCString & insert(uint index, const char *s)
Definition: qcstring.cpp:355
QCString & sprintf(const char *format,...)
Definition: qcstring.cpp:27
#define FONTSIZE
Definition: dot.cpp:55
QCString getOutputFileBase() const
Definition: dirdef.cpp:113
DirDef * parent() const
Definition: dirdef.h:64
void writeDotGraphFromFile ( const char *  inFile,
const char *  outDir,
const char *  outFile,
GraphOutputFormat  format 
)

Definition at line 4203 of file dot.cpp.

4205 {
4206  QDir d(outDir);
4207  if (!d.exists())
4208  {
4209  err("Output dir %s does not exist!\n",outDir); exit(1);
4210  }
4211 
4212  QCString imgExt = getDotImageExtension();
4213  QCString imgFmt = Config_getEnum("DOT_IMAGE_FORMAT");
4214  QCString imgName = (QCString)outFile+"."+imgExt;
4215  QCString absImgName = d.absPath().utf8()+"/"+imgName;
4216  QCString absOutFile = d.absPath().utf8()+"/"+outFile;
4217 
4218  DotRunner dotRun(inFile,d.absPath().data(),FALSE,absImgName);
4219  if (format==GOF_BITMAP)
4220  dotRun.addJob(imgFmt,absImgName);
4221  else // format==GOF_EPS
4222  {
4223  if (Config_getBool("USE_PDFLATEX"))
4224  {
4225  dotRun.addJob("pdf",absOutFile+".pdf");
4226  }
4227  else
4228  {
4229  dotRun.addJob("ps",absOutFile+".eps");
4230  }
4231  }
4232 
4233  dotRun.preventCleanUp();
4234  if (!dotRun.run())
4235  {
4236  return;
4237  }
4238 
4240 
4241  Doxygen::indexList->addImageFile(imgName);
4242 
4243 }
Traverses directory structures and contents in a platform-independent way.
Definition: qdir.h:52
Definition: dot.h:356
static bool format(QChar::Decomposition tag, QString &str, int index, int len)
Definition: qstring.cpp:11496
const bool FALSE
Definition: qglobal.h:370
TFile * outFile
Definition: makeDST.cxx:36
#define Config_getEnum(val)
Definition: config.cpp:663
void addImageFile(const char *name)
Definition: index.h:147
#define Config_getBool(val)
Definition: config.cpp:664
QCString getDotImageExtension(void)
Definition: util.cpp:8562
static void checkDotResult(const char *imgExt, const char *imgName)
Definition: dot.cpp:662
void err(const char *fmt,...)
Definition: message.cpp:226
TFile * inFile
Definition: makeDST.cxx:36
void addJob(const char *format, const char *output)
Definition: dot.cpp:807
Definition: dot.h:42
static IndexList * indexList
Definition: doxygen.h:149
void writeDotImageMapFromFile ( FTextStream t,
const QCString inFile,
const QCString outDir,
const QCString relPath,
const QCString baseName,
const QCString context,
int  graphId 
)

Writes user defined image map to the output.

Parameters
ttext stream to write to
inFilejust the basename part of the filename
outDiroutput directory
relPathrelative path the to root of the output dir
baseNamethe base name of the output files
contextthe scope in which this graph is found (for resolving links)
graphIda unique id for this graph, use for dynamic sections

Definition at line 4255 of file dot.cpp.

4259 {
4260 
4261  QDir d(outDir);
4262  if (!d.exists())
4263  {
4264  err("Output dir %s does not exist!\n",outDir.data()); exit(1);
4265  }
4266 
4267  QCString mapName = baseName+".map";
4268  QCString imgExt = getDotImageExtension();
4269  QCString imgFmt = Config_getEnum("DOT_IMAGE_FORMAT");
4270  QCString imgName = baseName+"."+imgExt;
4271  QCString absOutFile = d.absPath().utf8()+"/"+mapName;
4272 
4273  DotRunner dotRun(inFile,d.absPath().data(),FALSE);
4274  dotRun.addJob(MAP_CMD,absOutFile);
4275  dotRun.preventCleanUp();
4276  if (!dotRun.run())
4277  {
4278  return;
4279  }
4280 
4281  if (imgExt=="svg") // vector graphics
4282  {
4283  //writeSVGFigureLink(t,relPath,inFile,inFile+".svg");
4284  //DotFilePatcher patcher(inFile+".svg");
4285  QCString svgName=outDir+"/"+baseName+".svg";
4286  writeSVGFigureLink(t,relPath,baseName,svgName);
4287  DotFilePatcher patcher(svgName);
4288  patcher.addSVGConversion(relPath,TRUE,context,TRUE,graphId);
4289  patcher.run();
4290  }
4291  else // bitmap graphics
4292  {
4293  t << "<img src=\"" << relPath << imgName << "\" alt=\""
4294  << imgName << "\" border=\"0\" usemap=\"#" << mapName << "\"/>" << endl
4295  << "<map name=\"" << mapName << "\" id=\"" << mapName << "\">";
4296 
4297  convertMapFile(t, absOutFile, relPath ,TRUE, context);
4298 
4299  t << "</map>" << endl;
4300  }
4301  d.remove(absOutFile);
4302 }
Traverses directory structures and contents in a platform-independent way.
Definition: qdir.h:52
Definition: dot.h:356
const bool FALSE
Definition: qglobal.h:370
#define Config_getEnum(val)
Definition: config.cpp:663
const char * data() const
Definition: qcstring.h:207
QCString getDotImageExtension(void)
Definition: util.cpp:8562
#define MAP_CMD
Definition: dot.cpp:51
void err(const char *fmt,...)
Definition: message.cpp:226
void addJob(const char *format, const char *output)
Definition: dot.cpp:807
static bool writeSVGFigureLink(FTextStream &out, const QCString &relPath, const QCString &baseName, const QCString &absImgName)
Definition: dot.cpp:618
static bool convertMapFile(FTextStream &t, const char *mapName, const QCString relPath, bool urlOnly=FALSE, const QCString &context=QCString())
Definition: dot.cpp:370
const bool TRUE
Definition: qglobal.h:371
QTextStream & endl(QTextStream &s)
static void writeGraphFooter ( FTextStream t)
static

Definition at line 281 of file dot.cpp.

282 {
283  t << "}" << endl;
284 }
QTextStream & endl(QTextStream &s)
static void writeGraphHeader ( FTextStream t,
const QCString title = QCString() 
)
static

Definition at line 251 of file dot.cpp.

252 {
253  static bool interactiveSVG = Config_getBool("INTERACTIVE_SVG");
254  t << "digraph ";
255  if (title.isEmpty())
256  {
257  t << "\"Dot Graph\"";
258  }
259  else
260  {
261  t << "\"" << convertToXML(title) << "\"";
262  }
263  t << endl << "{" << endl;
264  if (interactiveSVG) // insert a comment to force regeneration when this
265  // option is toggled
266  {
267  t << " // INTERACTIVE_SVG=YES\n";
268  }
269  if (Config_getBool("DOT_TRANSPARENT"))
270  {
271  t << " bgcolor=\"transparent\";" << endl;
272  }
273  t << " edge [fontname=\"" << FONTNAME << "\","
274  "fontsize=\"" << FONTSIZE << "\","
275  "labelfontname=\"" << FONTNAME << "\","
276  "labelfontsize=\"" << FONTSIZE << "\"];\n";
277  t << " node [fontname=\"" << FONTNAME << "\","
278  "fontsize=\"" << FONTSIZE << "\",shape=record];\n";
279 }
QCString convertToXML(const char *s)
Definition: util.cpp:5717
bool isEmpty() const
Definition: qcstring.h:189
#define FONTNAME
Definition: dot.cpp:54
#define Config_getBool(val)
Definition: config.cpp:664
#define FONTSIZE
Definition: dot.cpp:55
QTextStream & endl(QTextStream &s)
static bool writeSVGFigureLink ( FTextStream out,
const QCString relPath,
const QCString baseName,
const QCString absImgName 
)
static

Definition at line 618 of file dot.cpp.

620 {
621  int width=600,height=600;
622  if (!readSVGSize(absImgName,&width,&height))
623  {
624  return FALSE;
625  }
626  if (width==-1)
627  {
628  if (height<=60)
629  height=300;
630  else
631  height+=300; // add some extra space for zooming
632  if (height>600) height=600; // clip to maximum height of 600 pixels
633  out << "<div class=\"zoom\">";
634  //out << "<object type=\"image/svg+xml\" data=\""
635  //out << "<embed type=\"image/svg+xml\" src=\""
636  out << "<iframe scrolling=\"no\" frameborder=\"0\" src=\""
637  << relPath << baseName << ".svg\" width=\"100%\" height=\"" << height << "\">";
638  }
639  else
640  {
641  //out << "<object type=\"image/svg+xml\" data=\""
642  //out << "<embed type=\"image/svg+xml\" src=\""
643  out << "<iframe scrolling=\"no\" frameborder=\"0\" src=\""
644  << relPath << baseName << ".svg\" width=\""
645  << ((width*96+48)/72) << "\" height=\""
646  << ((height*96+48)/72) << "\">";
647  }
649  //out << "</object>";
650  //out << "</embed>";
651  out << "</iframe>";
652  if (width==-1)
653  {
654  out << "</div>";
655  }
656 
657  return TRUE;
658 }
static void writeSVGNotSupported(FTextStream &out)
Definition: dot.cpp:611
const bool FALSE
Definition: qglobal.h:370
static bool readSVGSize(const QCString &fileName, int *width, int *height)
Definition: dot.cpp:572
const bool TRUE
Definition: qglobal.h:371
static void writeSVGNotSupported ( FTextStream out)
static

Definition at line 611 of file dot.cpp.

612 {
613  out << "<p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p>";
614 }
static bool writeVecGfxFigure ( FTextStream out,
const QCString baseName,
const QCString figureName 
)
static

Definition at line 518 of file dot.cpp.

520 {
521  int width=400,height=550;
522  static bool usePdfLatex = Config_getBool("USE_PDFLATEX");
523  if (usePdfLatex)
524  {
525  if (!readBoundingBox(figureName+".pdf",&width,&height,FALSE))
526  {
527  //printf("writeVecGfxFigure()=0\n");
528  return FALSE;
529  }
530  }
531  else
532  {
533  if (!readBoundingBox(figureName+".eps",&width,&height,TRUE))
534  {
535  //printf("writeVecGfxFigure()=0\n");
536  return FALSE;
537  }
538  }
539  //printf("Got PDF/EPS size %d,%d\n",width,height);
540  int maxWidth = 350; /* approx. page width in points, excl. margins */
541  int maxHeight = 550; /* approx. page height in points, excl. margins */
542  out << "\\nopagebreak\n"
543  "\\begin{figure}[H]\n"
544  "\\begin{center}\n"
545  "\\leavevmode\n";
546  if (width>maxWidth || height>maxHeight) // figure too big for page
547  {
548  // c*width/maxWidth > c*height/maxHeight, where c=maxWidth*maxHeight>0
549  if (width*maxHeight>height*maxWidth)
550  {
551  out << "\\includegraphics[width=" << maxWidth << "pt]";
552  }
553  else
554  {
555  out << "\\includegraphics[height=" << maxHeight << "pt]";
556  }
557  }
558  else
559  {
560  out << "\\includegraphics[width=" << width << "pt]";
561  }
562 
563  out << "{" << baseName << "}\n"
564  "\\end{center}\n"
565  "\\end{figure}\n";
566 
567  //printf("writeVecGfxFigure()=1\n");
568  return TRUE;
569 }
const bool FALSE
Definition: qglobal.h:370
#define Config_getBool(val)
Definition: config.cpp:664
static bool readBoundingBox(const char *fileName, int *width, int *height, bool isEps)
Definition: dot.cpp:479
const bool TRUE
Definition: qglobal.h:371

Variable Documentation

QCString g_dotFontPath
static

Definition at line 442 of file dot.cpp.

const char* normalArrowStyleMap[]
static
Initial value:
=
{
"empty",
"empty",
"empty",
"open",
0,
0
}

Definition at line 171 of file dot.cpp.

const char* normalEdgeColorMap[]
static
Initial value:
=
{
"midnightblue",
"darkgreen",
"firebrick4",
"darkorchid3",
"grey75",
"orange",
"orange"
}

mapping from protection levels to color names

Definition at line 160 of file dot.cpp.

EdgeProperties normalEdgeProps
static
Initial value:
=
{
}
static const char * normalEdgeStyleMap[]
Definition: dot.cpp:181
static const char * normalEdgeColorMap[]
Definition: dot.cpp:160
static const char * normalArrowStyleMap[]
Definition: dot.cpp:171

Definition at line 222 of file dot.cpp.

const char* normalEdgeStyleMap[]
static
Initial value:
=
{
"solid",
"dashed"
}

Definition at line 181 of file dot.cpp.

int s_max_newNumber =0
static

Definition at line 401 of file dot.cpp.

QArray<int> s_newNumber
static

Definition at line 400 of file dot.cpp.

const char svgZoomFooter[]
static

Definition at line 103 of file dot.cpp.

const char svgZoomHeader[]
static

Definition at line 59 of file dot.cpp.

const char* umlArrowStyleMap[]
static
Initial value:
=
{
"onormal",
"onormal",
"onormal",
"odiamond",
0,
0
}

Definition at line 198 of file dot.cpp.

const char* umlEdgeColorMap[]
static
Initial value:
=
{
"midnightblue",
"darkgreen",
"firebrick4",
"grey25",
"grey75",
"orange",
"orange"
}

Definition at line 187 of file dot.cpp.

EdgeProperties umlEdgeProps
static
Initial value:
=
{
}
static const char * umlArrowStyleMap[]
Definition: dot.cpp:198
static const char * umlEdgeStyleMap[]
Definition: dot.cpp:208
static const char * umlEdgeColorMap[]
Definition: dot.cpp:187

Definition at line 227 of file dot.cpp.

const char* umlEdgeStyleMap[]
static
Initial value:
=
{
"solid",
"solid"
}

Definition at line 208 of file dot.cpp.