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

📄 dot.cpp

📁 doxygen(一个自动从源代码生成文档的工具)的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
  //{  //  printf("Node %s color=%d (c=%d,p=%d)\n",  //      n->m_label.data(),n->m_subgraphId,  //      n->m_children?n->m_children->count():0,  //      n->m_parents?n->m_parents->count():0);  //}}DotGfxHierarchyTable::~DotGfxHierarchyTable(){  DotNode *n = m_rootNodes->first();  while (n)  {    DotNode *oldNode=n;    n=m_rootNodes->next();    deleteNodes(oldNode);   }  delete m_rootNodes;  delete m_usedNodes;  delete m_rootSubgraphs;}//--------------------------------------------------------------------int DotClassGraph::m_curNodeNumber;void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,    const char *label,int distance,const char *usedName,const char *templSpec,bool base){  if (Config_getBool("HIDE_UNDOC_CLASSES") && !cd->isLinkable()) return;  int edgeStyle = (label || prot==EdgeInfo::Orange) ? EdgeInfo::Dashed : EdgeInfo::Solid;  QCString className;  if (usedName) // name is a typedef  {    className=usedName;  }  else if (templSpec) // name has a template part  {    className=insertTemplateSpecifierInScope(cd->name(),templSpec);  }  else // just a normal name  {    className=cd->displayName();  }  //printf("DotClassGraph::addClass(class=`%s',parent=%s,prot=%d,label=%s,dist=%d,usedName=%s,templSpec=%s,base=%d)\n",  //                                 className.data(),n->m_label.data(),prot,label,distance,usedName,templSpec,base);  DotNode *bn = m_usedNodes->find(className);  if (bn) // class already inserted  {    if (base)    {      n->addChild(bn,prot,edgeStyle,label);      bn->addParent(n);    }    else    {      bn->addChild(n,prot,edgeStyle,label);      n->addParent(bn);    }    bn->setDistance(distance);    //printf(" add exiting node %s of %s\n",bn->m_label.data(),n->m_label.data());  }  else // new class  {    QCString displayName=className;    if (Config_getBool("HIDE_SCOPE_NAMES")) displayName=stripScope(displayName);    QCString tmp_url;    if (cd->isLinkable())     {      tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();    }    bn = new DotNode(m_curNodeNumber++,        displayName,        tmp_url.data(),        distance       );    if (distance>m_maxDistance) m_maxDistance=distance;    if (base)    {      n->addChild(bn,prot,edgeStyle,label);      bn->addParent(n);    }    else    {      bn->addChild(n,prot,edgeStyle,label);      n->addParent(bn);    }    m_usedNodes->insert(className,bn);    //printf(" add new child node `%s' to %s\n",className.data(),n->m_label.data());    if (distance<m_recDepth) buildGraph(cd,bn,distance+1,base);  }}void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base){  // ---- Add inheritance relations  BaseClassListIterator bcli(base ? *cd->baseClasses() : *cd->subClasses());  BaseClassDef *bcd;  for ( ; (bcd=bcli.current()) ; ++bcli )  {    //printf("-------- inheritance relation %s->%s templ=`%s'\n",    //            cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data());    addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->usedName,               bcd->templSpecifiers,base);   }  if (m_graphType != Inheritance)  {    // ---- Add usage relations        UsesClassDict *dict =       m_graphType==Implementation ? cd->usedImplementationClasses() :                                    cd->usedInterfaceClasses();    if (dict)    {      UsesClassDictIterator ucdi(*dict);      UsesClassDef *ucd;      for (;(ucd=ucdi.current());++ucdi)      {        QCString label;        QDictIterator<void> dvi(*ucd->accessors);        const char *s;        bool first=TRUE;        for (;(s=dvi.currentKey());++dvi)        {          if (first)           {            label=s;            first=FALSE;          }          else          {            label+=QCString("\\n")+s;          }        }        addClass(ucd->classDef,n,EdgeInfo::Purple,label,distance,0,                 ucd->templSpecifiers,base);      }    }  }  // ---- Add template instantiation relations  if (Config_getBool("TEMPLATE_RELATIONS"))  {    if (base) // template relations for base classes    {      ClassDef *templMaster=cd->templateMaster();      if (templMaster)      {        QDictIterator<ClassDef> cli(*templMaster->getTemplateInstances());        ClassDef *templInstance;        for (;(templInstance=cli.current());++cli)        {          if (templInstance==cd)          {            addClass(templMaster,n,EdgeInfo::Orange,cli.currentKey(),distance,0,                0,TRUE);          }        }      }    }    else // template relations for super classes    {      QDict<ClassDef> *templInstances = cd->getTemplateInstances();      if (templInstances)      {        QDictIterator<ClassDef> cli(*templInstances);        ClassDef *templInstance;        for (;(templInstance=cli.current());++cli)        {          addClass(templInstance,n,EdgeInfo::Orange,cli.currentKey(),distance,0,              0,FALSE);        }      }    }  }}DotClassGraph::DotClassGraph(ClassDef *cd,GraphType t,int maxRecursionDepth){  //printf("--------------- DotClassGraph::DotClassGraph `%s'\n",cd->displayName().data());  m_graphType = t;  m_maxDistance = 0;  m_recDepth = maxRecursionDepth;  QCString tmp_url="";  if (cd->isLinkable()) tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();  QCString className = cd->displayName();  //if (cd->templateArguments())  //{  //  className+=tempArgListToString(cd->templateArguments());  //}  m_startNode = new DotNode(m_curNodeNumber++,                            className,                            tmp_url.data(),                            0,                         // distance                            TRUE                       // is a root node                           );  m_usedNodes = new QDict<DotNode>(1009);  m_usedNodes->insert(className,m_startNode);  //ClassSDict::Iterator cli(Doxygen::classSDict);  //ClassDef *icd;  //for (cli.toFirst();(icd=cli.current());++cli) icd->initTemplateMapping();  //printf("Root node %s\n",cd->name().data());  if (m_recDepth>0)   {    buildGraph(cd,m_startNode,1,TRUE);    if (t==Inheritance) buildGraph(cd,m_startNode,1,FALSE);  }  m_diskName = cd->getFileBase().copy();}bool DotClassGraph::isTrivial() const{  if (m_graphType==Inheritance)    return m_startNode->m_children==0 && m_startNode->m_parents==0;  else    return m_startNode->m_children==0;}DotClassGraph::~DotClassGraph(){  deleteNodes(m_startNode);  delete m_usedNodes;}void writeDotGraph(DotNode *root,                   GraphOutputFormat format,                   const QCString &baseName,                   bool lrRank,                   bool renderParents,                   int distance,                   bool backArrows                  ){  // generate the graph description for dot  //printf("writeDotGraph(%s,%d)\n",baseName.data(),backArrows);  QFile f;  f.setName(baseName+".dot");  if (f.open(IO_WriteOnly))  {    QTextStream t(&f);    t << "digraph inheritance" << endl;    t << "{" << endl;    if (lrRank)    {      t << "  rankdir=LR;" << endl;    }    root->clearWriteFlag();    root->write(t,format,TRUE,TRUE,distance,backArrows);    if (renderParents && root->m_parents)     {      //printf("rendering parents!\n");      QListIterator<DotNode>  dnli(*root->m_parents);      DotNode *pn;      for (dnli.toFirst();(pn=dnli.current());++dnli)      {        if (pn->m_distance<=distance)         {          root->writeArrow(t,                           format,                           pn,                           pn->m_edgeInfo->at(pn->m_children->findRef(root)),                           FALSE,                           backArrows                          );        }        pn->write(t,format,TRUE,FALSE,distance,backArrows);      }    }    t << "}" << endl;    f.close();  }}static void findMaximalDotGraph(DotNode *root,                                int maxDist,                                const QCString &baseName,                                QDir &thisDir,                                GraphOutputFormat format,                                bool lrRank=FALSE,                                bool renderParents=FALSE,                                bool backArrows=TRUE                               ){  bool lastFit;  int minDistance=1;  int maxDistance=maxDist;  int curDistance=maxDistance;  int width=0;  int height=0;  // binary search for the maximal inheritance depth that fits in a reasonable  // sized image (dimensions: Config_getInt("MAX_DOT_GRAPH_WIDTH"), Config_getInt("MAX_DOT_GRAPH_HEIGHT"))  do  {    writeDotGraph(root,format,baseName,lrRank,renderParents,                  curDistance,backArrows);    QCString dotArgs(4096);    // create annotated dot file    dotArgs.sprintf("-Tdot \"%s.dot\" -o \"%s_tmp.dot\"",baseName.data(),baseName.data());    if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0)    {      err("Problems running dot. Check your installation!\n");      return;    }    // extract bounding box from the result    readBoundingBoxDot(baseName+"_tmp.dot",&width,&height);    width  = width *96/72; // 96 pixels/inch, 72 points/inch    height = height*96/72; // 96 pixels/inch, 72 points/inch    //printf("Found bounding box (%d,%d) max (%d,%d)\n",width,height,    //    Config_getInt("MAX_DOT_GRAPH_WIDTH"),Config_getInt("MAX_DOT_GRAPH_HEIGHT"));        lastFit=(width<Config_getInt("MAX_DOT_GRAPH_WIDTH") && height<Config_getInt("MAX_DOT_GRAPH_HEIGHT"));    if (lastFit) // image is small enough    {      minDistance=curDistance;      //printf("Image fits [%d-%d]\n",minDistance,maxDistance);    }    else    {      maxDistance=curDistance;      //printf("Image does not fit [%d-%d]\n",minDistance,maxDistance);    }    curDistance=minDistance+(maxDistance-minDistance)/2;    //printf("curDistance=%d\n",curDistance);        // remove temporary dot file    thisDir.remove(baseName+"_tmp.dot");      } while ((maxDistance-minDistance)>1);  if (!lastFit)  {    writeDotGraph(root,                  format,                  baseName,                  lrRank || (curDistance==1 && width>Config_getInt("MAX_DOT_GRAPH_WIDTH")),                  renderParents,                  minDistance,                  backArrows                 );  }}QCString DotClassGraph::diskName() const{  QCString result=m_diskName.copy();  switch (m_graphType)  {    case Implementation:      result+="_coll_graph";      break;    case Interface:      result+="_intf_graph";      break;    case Inheritance:      result+="_inherit_graph";      break;  }  return result;}QCString DotClassGraph::writeGraph(QTextStream &out,                               GraphOutputFormat format,                               const char *path,                               bool isTBRank,                               bool generateImageMap){  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 html output directory (i.e. path)  QDir::setCurrent(d.absPath());  QDir thisDir;  QCString baseName;  QCString mapName;  switch (m_graphType)  {    case Implementation:      mapName="coll_map";      break;    case Interface:      mapName="intf_map";      break;    case Inheritance:      mapName="inherit_map";      break;  }  baseName = convertNameToFile(diskName());  findMaximalDotGraph(m_startNode,m_maxDistance,baseName,                      thisDir,format,!isTBRank,m_graphType==Inheritance);

⌨️ 快捷键说明

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