⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dot.cpp

📁 doxygen(一个自动从源代码生成文档的工具)的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * * $Id: dot.cpp,v 1.20 2001/03/19 19:27:40 root Exp $ * * * Copyright (C) 1997-2001 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby  * granted. No representations are made about the suitability of this software  * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * */#include <stdlib.h>#include "dot.h"#include "doxygen.h"#include "message.h"#include "util.h"#include "config.h"#include "language.h"#include "scanner.h"#include "defargs.h"#include <qdir.h>#include <qfile.h>#include <qtextstream.h>//--------------------------------------------------------------------/*! mapping from protection levels to color names */static const char *edgeColorMap[] ={  "midnightblue",  // Public  "darkgreen",     // Protected  "firebrick4",    // Private  "darkorchid3",   // "use" relation  "grey75",        // Undocumented  "orange"         // template relation};static const char *edgeStyleMap[] ={  "solid",         // inheritance  "dashed"         // usage};/*! converts the rectangles in a server site image map into a client  *  site image map. *  \param t the stream to which the result is written. *  \param mapName the name of the map file. *  \returns TRUE if succesful. */static bool convertMapFile(QTextStream &t,const char *mapName){  QFile f(mapName);  if (!f.open(IO_ReadOnly))   {    err("Error opening map file %s for inclusion in the docs!\n",mapName);    return FALSE;  }  const int maxLineLen=1024;  char buf[maxLineLen];  char url[maxLineLen];  int x1,y1,x2,y2;  while (!f.atEnd())  {    int numBytes = f.readLine(buf,maxLineLen);    buf[numBytes-1]='\0';    //printf("ReadLine `%s'\n",buf);    if (strncmp(buf,"rect",4)==0)    {      sscanf(buf,"rect %s %d,%d %d,%d",url,&x1,&y2,&x2,&y1);      char *refPtr = url;      char *urlPtr = strchr(url,'$');      //printf("url=`%s'\n",url);      if (urlPtr)      {        QCString *dest;        *urlPtr++='\0';        //printf("refPtr=`%s' urlPtr=`%s'\n",refPtr,urlPtr);        //printf("Found url=%s coords=%d,%d,%d,%d\n",url,x1,y1,x2,y2);        t << "<area ";        if (*refPtr!='\0')        {          t << "doxygen=\"" << refPtr << ":";          if ((dest=Doxygen::tagDestinationDict[refPtr])) t << *dest << "/";          t << "\" ";        }        t << "href=\"";         if (*refPtr!='\0')        {          if ((dest=Doxygen::tagDestinationDict[refPtr])) t << *dest << "/";        }        t << urlPtr << "\" shape=\"rect\" coords=\""           << x1 << "," << y1 << "," << x2 << "," << y2 << "\""          << " alt=\"\">" << endl;      }    }  }    return TRUE;}static bool readBoundingBoxDot(const char *fileName,int *width,int *height){  QFile f(fileName);  if (!f.open(IO_ReadOnly)) return FALSE;  const int maxLineLen=1024;  char buf[maxLineLen];  while (!f.atEnd())  {    int numBytes = f.readLine(buf,maxLineLen);    buf[numBytes-1]='\0';    if (strncmp(buf,"\tgraph [bb",10)==0)    {      int x,y;      if (sscanf(buf,"\tgraph [bb= \"%d,%d,%d,%d\"];",&x,&y,width,height)!=4)      {        return FALSE;      }      return TRUE;    }  }  return FALSE;}static bool readBoundingBoxEPS(const char *fileName,int *width,int *height){  QFile f(fileName);  if (!f.open(IO_ReadOnly)) return FALSE;  const int maxLineLen=1024;  char buf[maxLineLen];  while (!f.atEnd())  {    int numBytes = f.readLine(buf,maxLineLen);    buf[numBytes-1]='\0';    if (strncmp(buf,"%%BoundingBox: ",15)==0)    {      int x,y;      if (sscanf(buf,"%%%%BoundingBox: %d %d %d %d",&x,&y,width,height)!=4)      {        return FALSE;      }      return TRUE;    }  }  return FALSE;}/*! returns TRUE if class cd is a leaf (i.e. has no visible children) */static bool isLeaf(ClassDef *cd){  BaseClassList *bcl = cd->subClasses();  if (bcl->count()>0) // class has children, check their visibility  {    BaseClassListIterator bcli(*bcl);    BaseClassDef *bcd;    for ( ; (bcd=bcli.current()); ++bcli )    {      ClassDef *bClass = bcd->classDef;      //if (bClass->isLinkable() || !isLeaf(bClass)) return FALSE;            // if class is not a leaf      if (!isLeaf(bClass)) return FALSE;      // or class is not documented in this project      if (!Config_getBool("ALLEXTERNALS") && !bClass->isLinkableInProject()) return FALSE;      // or class is not documented and all ALLEXTERNALS = YES      if (Config_getBool("ALLEXTERNALS") && !bClass->isLinkable()) return FALSE;        }  }  return TRUE;}//--------------------------------------------------------------------class DotNodeList : public QList<DotNode>{  public:    DotNodeList() : QList<DotNode>() {}   ~DotNodeList() {}   int compareItems(GCI item1,GCI item2)   {     return stricmp(((DotNode *)item1)->m_label,((DotNode *)item2)->m_label);   }};//--------------------------------------------------------------------/*! helper function that deletes all nodes in a connected graph, given *  one of the graph's nodes */static void deleteNodes(DotNode *node){  static DotNodeList deletedNodes;  deletedNodes.setAutoDelete(TRUE);  node->deleteNode(deletedNodes); // collect nodes to be deleted.  deletedNodes.clear(); // actually remove the nodes.}DotNode::DotNode(int n,const char *lab,const char *url,int distance,bool isRoot)  : m_number(n), m_label(lab), m_url(url), m_isRoot(isRoot){  m_children = 0;   m_edgeInfo = 0;  m_parents = 0;  m_subgraphId=-1;  m_deleted=FALSE;  m_written=FALSE;  m_hasDoc=FALSE;  m_distance = distance;}DotNode::~DotNode(){  delete m_children;  delete m_parents;  delete m_edgeInfo;}void DotNode::setDistance(int distance){  if (distance<m_distance) m_distance=distance;}void DotNode::addChild(DotNode *n,                       int edgeColor,                       int edgeStyle,                       const char *edgeLab,                       const char *edgeURL,                       int edgeLabCol                      ){  if (m_children==0)  {    m_children = new QList<DotNode>;    m_edgeInfo = new QList<EdgeInfo>;    m_edgeInfo->setAutoDelete(TRUE);  }  m_children->append(n);  EdgeInfo *ei = new EdgeInfo;  ei->m_color = edgeColor;  ei->m_style = edgeStyle;   ei->m_label = edgeLab;  ei->m_url   = edgeURL;  if (edgeLabCol==-1)    ei->m_labColor=edgeColor;  else    ei->m_labColor=edgeLabCol;  m_edgeInfo->append(ei);}void DotNode::addParent(DotNode *n){  if (m_parents==0)  {    m_parents = new QList<DotNode>;  }  m_parents->append(n);}void DotNode::removeChild(DotNode *n){  if (m_children) m_children->remove(n);}void DotNode::removeParent(DotNode *n){  if (m_parents) m_parents->remove(n);}void DotNode::deleteNode(DotNodeList &deletedList){  if (m_deleted) return; // avoid recursive loops in case the graph has cycles  m_deleted=TRUE;  if (m_parents!=0) // delete all parent nodes of this node  {    QListIterator<DotNode> dnlip(*m_parents);    DotNode *pn;    for (dnlip.toFirst();(pn=dnlip.current());++dnlip)    {      //pn->removeChild(this);      pn->deleteNode(deletedList);    }  }  if (m_children!=0) // delete all child nodes of this node  {    QListIterator<DotNode> dnlic(*m_children);    DotNode *cn;    for (dnlic.toFirst();(cn=dnlic.current());++dnlic)    {      //cn->removeParent(this);      cn->deleteNode(deletedList);    }  }  // add this node to the list of deleted nodes.  deletedList.append(this);}static QCString convertLabel(const QCString &l){  QCString result;  const char *p=l.data();  char c;  while ((c=*p++))  {    if (c=='\\') result+="\\\\";    else result+=c;  }  return result;}void DotNode::writeBox(QTextStream &t,                       GraphOutputFormat format,                       bool hasNonReachableChildren){  const char *labCol =           m_url.isEmpty() ? "grey75" :  // non link           (            (hasNonReachableChildren) ? "red" : "black"           );  t << "  Node" << m_number << " [shape=\"box\",label=\""    << convertLabel(m_label)        << "\",fontsize=10,height=0.2,width=0.4";  if (format==GIF) t << ",fontname=\"doxfont\"";  t << ",color=\"" << labCol << "\"";  if (m_isRoot)  {    t << ",style=\"filled\" fontcolor=\"white\"";  }  else if (!m_url.isEmpty())  {    t << ",URL=\"" << m_url << ".html\"";  }  t << "];" << endl; }void DotNode::writeArrow(QTextStream &t,                         GraphOutputFormat format,                         DotNode *cn,                         EdgeInfo *ei,                         bool topDown,                          bool pointBack                        ){  t << "  Node";  if (topDown) t << cn->number(); else t << m_number;  t << " -> Node";  if (topDown) t << m_number; else t << cn->number();  t << " [";  if (pointBack) t << "dir=back,";  t << "color=\"" << edgeColorMap[ei->m_color]     << "\",fontsize=10,style=\"" << edgeStyleMap[ei->m_style] << "\"";  if (!ei->m_label.isEmpty())  {    t << ",label=\"" << ei->m_label << "\"";  }  if (format==GIF) t << ",fontname=\"doxfont\"";  t << "];" << endl; }void DotNode::write(QTextStream &t,                    GraphOutputFormat format,                    bool topDown,                    bool toChildren,                    int distance,                    bool backArrows                   ){  //printf("DotNode::write(%d) name=%s\n",distance,m_label.data());  if (m_written) return; // node already written to the output  if (m_distance>distance) return;  QList<DotNode> *nl = toChildren ? m_children : m_parents;   bool hasNonReachableChildren=FALSE;  if (m_distance==distance && nl)  {    QListIterator<DotNode> dnli(*nl);    DotNode *cn;    for (dnli.toFirst();(cn=dnli.current());++dnli)    {      if (cn->m_distance>distance) hasNonReachableChildren=TRUE;    }  }  writeBox(t,format,hasNonReachableChildren);  m_written=TRUE;  if (nl)  {    if (toChildren)    {      QListIterator<DotNode>  dnli1(*nl);      QListIterator<EdgeInfo> dnli2(*m_edgeInfo);      DotNode *cn;      for (dnli1.toFirst();(cn=dnli1.current());++dnli1,++dnli2)      {        if (cn->m_distance<=distance)         {          writeArrow(t,format,cn,dnli2.current(),topDown,backArrows);        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -