Orb/Doxygen/src/dot.cpp
changeset 4 468f4c8d3d5b
parent 0 42188c7ea2d9
equal deleted inserted replaced
3:d8fccb2cd802 4:468f4c8d3d5b
     1 /*****************************************************************************
     1 /*****************************************************************************
     2  *
     2  *
     3  * 
     3  * 
     4  *
     4  *
     5  *
     5  *
     6  * Copyright (C) 1997-2008 by Dimitri van Heesch.
     6  * Copyright (C) 1997-2010 by Dimitri van Heesch.
     7  *
     7  *
     8  * Permission to use, copy, modify, and distribute this software and its
     8  * Permission to use, copy, modify, and distribute this software and its
     9  * documentation under the terms of the GNU General Public License is hereby 
     9  * documentation under the terms of the GNU General Public License is hereby 
    10  * granted. No representations are made about the suitability of this software 
    10  * granted. No representations are made about the suitability of this software 
    11  * for any purpose. It is provided "as is" without express or implied warranty.
    11  * for any purpose. It is provided "as is" without express or implied warranty.
    33 #include "docparser.h"
    33 #include "docparser.h"
    34 #include "debug.h"
    34 #include "debug.h"
    35 #include "pagedef.h"
    35 #include "pagedef.h"
    36 #include "portable.h"
    36 #include "portable.h"
    37 #include "dirdef.h"
    37 #include "dirdef.h"
    38 
    38 #include "vhdldocgen.h"
    39 #include <qdir.h>
    39 #include <qdir.h>
    40 #include <qfile.h>
    40 #include <qfile.h>
    41 #include <qtextstream.h>
    41 #include <qtextstream.h>
    42 #include <md5.h>
    42 #include <md5.h>
    43 
    43 
   266 static void setDotFontPath(const char *path)
   266 static void setDotFontPath(const char *path)
   267 {
   267 {
   268   ASSERT(g_dotFontPath.isEmpty());
   268   ASSERT(g_dotFontPath.isEmpty());
   269   g_dotFontPath = portable_getenv("DOTFONTPATH");
   269   g_dotFontPath = portable_getenv("DOTFONTPATH");
   270   QCString newFontPath = Config_getString("DOT_FONTPATH");
   270   QCString newFontPath = Config_getString("DOT_FONTPATH");
   271   if (!newFontPath.isEmpty() && path)
   271   QCString spath = path;
   272   {
   272   if (!newFontPath.isEmpty() && !spath.isEmpty())
   273     newFontPath.prepend(path+portable_pathListSeparator());
   273   {
   274   }
   274     newFontPath.prepend(spath+portable_pathListSeparator());
   275   else if (newFontPath.isEmpty() && path)
   275   }
       
   276   else if (newFontPath.isEmpty() && !spath.isEmpty())
   276   {
   277   {
   277     newFontPath=path;
   278     newFontPath=path;
   278   }
   279   }
   279   else
   280   else
   280   {
   281   {
   284   portable_setenv("DOTFONTPATH",newFontPath);
   285   portable_setenv("DOTFONTPATH",newFontPath);
   285 }
   286 }
   286 
   287 
   287 static void unsetDotFontPath()
   288 static void unsetDotFontPath()
   288 {
   289 {
   289   portable_setenv("DOTFONTPATH",g_dotFontPath);
   290   if (g_dotFontPath.isEmpty())
       
   291   {
       
   292     portable_unsetenv("DOTFONTPATH");
       
   293   }
       
   294   else
       
   295   {
       
   296     portable_setenv("DOTFONTPATH",g_dotFontPath);
       
   297   }
   290   g_dotFontPath="";
   298   g_dotFontPath="";
   291 }
   299 }
   292 
   300 
   293 static bool readBoundingBoxEPS(const char *fileName,int *width,int *height)
   301 static bool readBoundingBoxEPS(const char *fileName,int *width,int *height)
   294 {
   302 {
   716   {
   724   {
   717     t << ",color=\"black\", fillcolor=\"grey75\", style=\"filled\" fontcolor=\"black\"";
   725     t << ",color=\"black\", fillcolor=\"grey75\", style=\"filled\" fontcolor=\"black\"";
   718   }
   726   }
   719   else 
   727   else 
   720   {
   728   {
   721     if (!Config_getBool("DOT_TRANSPARENT"))
   729     static bool dotTransparent = Config_getBool("DOT_TRANSPARENT");
   722     {
   730     static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
   723       t << ",color=\"" << labCol << "\", fillcolor=\"white\", style=\"filled\"";
   731     if (!dotTransparent)
       
   732     {
       
   733       ClassDef* ccd=this->m_classDef;
       
   734 
       
   735       t << ",color=\"" << labCol << "\", fillcolor=\"";
       
   736       if (ccd && vhdlOpt && (VhdlDocGen::VhdlClasses)ccd->protection()==VhdlDocGen::ARCHITECTURECLASS)
       
   737         t << "khaki";	
       
   738       else
       
   739         t << "white";
       
   740       t << "\", style=\"filled\"";
   724     }
   741     }
   725     else
   742     else
   726     {
   743     {
   727       t << ",color=\"" << labCol << "\"";
   744       t << ",color=\"" << labCol << "\"";
   728     }
   745     }
   914     } 
   931     } 
   915   }
   932   }
   916   t << "      </node>" << endl;
   933   t << "      </node>" << endl;
   917 }
   934 }
   918 
   935 
   919 void DotNode::writeXML(XmlStream &xt, bool isClassGraph)
       
   920 {
       
   921 	QString idNumber;
       
   922 	idNumber.setNum(m_number);
       
   923 	XmlElement nodeElem(xt, "node", "id", idNumber);
       
   924 	{
       
   925 		XmlElement nodeLabel(xt, "label");
       
   926 		xt << m_label;
       
   927 	}
       
   928 	if (!m_url.isEmpty()) {
       
   929 		QCString url(m_url);
       
   930 		char *refPtr = url.data();
       
   931 		char *urlPtr = strchr(url.data(),'$');
       
   932 		if (urlPtr) {
       
   933 			*urlPtr++='\0';
       
   934 			AttributeMap linkAttrs;
       
   935 			linkAttrs["refid"] = convertToXML(urlPtr);
       
   936 			if (*refPtr!='\0') {
       
   937 				linkAttrs["external"] = convertToXML(refPtr);
       
   938 			}
       
   939 			XmlElement(xt, "link", linkAttrs);
       
   940 		}
       
   941 	}
       
   942 	if (m_children) {
       
   943 		QListIterator<DotNode> nli(*m_children);
       
   944 		QListIterator<EdgeInfo> eli(*m_edgeInfo);
       
   945 		DotNode *childNode;
       
   946 		EdgeInfo *edgeInfo;
       
   947 		for (;(childNode=nli.current());++nli,++eli) {
       
   948 			edgeInfo=eli.current();
       
   949 			AttributeMap childAttrs;
       
   950 			QString childIdNumber;
       
   951 			childIdNumber.setNum(childNode->m_number);
       
   952 			childAttrs["refid"] = childIdNumber; 
       
   953 			if (isClassGraph) {
       
   954 				switch(edgeInfo->m_color) {
       
   955 					case EdgeInfo::Blue:    childAttrs["relation"] = "public-inheritance"; break;
       
   956 					case EdgeInfo::Green:   childAttrs["relation"] = "protected-inheritance"; break;
       
   957 					case EdgeInfo::Red:     childAttrs["relation"] = "private-inheritance"; break;
       
   958 					case EdgeInfo::Purple:  childAttrs["relation"] = "usage"; break;
       
   959 					case EdgeInfo::Orange:  childAttrs["relation"] = "template-instance"; break;
       
   960 					case EdgeInfo::Grey:    ASSERT(0); break;
       
   961 				}
       
   962 			} else {
       
   963 				// include graph
       
   964 				childAttrs["relation"] = "include"; 
       
   965 			}
       
   966 			XmlElement childnodeElem(xt, "childnode", childAttrs);
       
   967 			if (!edgeInfo->m_label.isEmpty()) {
       
   968 				int p=0;
       
   969 				int ni;
       
   970 				while ((ni=edgeInfo->m_label.find('\n',p))!=-1) {
       
   971 					XmlElement edgelabelElem(xt, "edgelabel");
       
   972 					xt << edgeInfo->m_label.mid(p,ni-p);
       
   973 					p=ni+1;
       
   974 				}
       
   975 				XmlElement edgelabelElem(xt, "edgelabel");
       
   976 				xt << edgeInfo->m_label.right(edgeInfo->m_label.length()-p);
       
   977 			}
       
   978 		} 
       
   979 	}
       
   980 }
       
   981 
       
   982 void DotNode::writeXMLDITA(XmlStream &xt, bool isClassGraph)
       
   983 {
       
   984 	QString idNumber;
       
   985 	idNumber.setNum(m_number);
       
   986 	XmlElement nodeElem(xt, "node", "id", idNumber);
       
   987 	{
       
   988 		XmlElement nodeLabel(xt, "label");
       
   989 		xt << m_label;
       
   990 	}
       
   991 	if (!m_url.isEmpty()) {
       
   992 		QCString url(m_url);
       
   993 		char *refPtr = url.data();
       
   994 		char *urlPtr = strchr(url.data(),'$');
       
   995 		if (urlPtr) {
       
   996 			*urlPtr++='\0';
       
   997 			AttributeMap linkAttrs;
       
   998 			linkAttrs["refid"] = convertToXML(urlPtr);
       
   999 			if (*refPtr!='\0') {
       
  1000 				linkAttrs["external"] = convertToXML(refPtr);
       
  1001 			}
       
  1002 			XmlElement(xt, "link", linkAttrs);
       
  1003 		}
       
  1004 	}
       
  1005 	if (m_children) {
       
  1006 		QListIterator<DotNode> nli(*m_children);
       
  1007 		QListIterator<EdgeInfo> eli(*m_edgeInfo);
       
  1008 		DotNode *childNode;
       
  1009 		EdgeInfo *edgeInfo;
       
  1010 		for (;(childNode=nli.current());++nli,++eli) {
       
  1011 			edgeInfo=eli.current();
       
  1012 			AttributeMap childAttrs;
       
  1013 			QString childIdNumber;
       
  1014 			childIdNumber.setNum(childNode->m_number);
       
  1015 			childAttrs["refid"] = childIdNumber; 
       
  1016 			if (isClassGraph) {
       
  1017 				switch(edgeInfo->m_color) {
       
  1018 					case EdgeInfo::Blue:    childAttrs["relation"] = "public-inheritance"; break;
       
  1019 					case EdgeInfo::Green:   childAttrs["relation"] = "protected-inheritance"; break;
       
  1020 					case EdgeInfo::Red:     childAttrs["relation"] = "private-inheritance"; break;
       
  1021 					case EdgeInfo::Purple:  childAttrs["relation"] = "usage"; break;
       
  1022 					case EdgeInfo::Orange:  childAttrs["relation"] = "template-instance"; break;
       
  1023 					case EdgeInfo::Grey:    ASSERT(0); break;
       
  1024 				}
       
  1025 			} else {
       
  1026 				// include graph
       
  1027 				childAttrs["relation"] = "include"; 
       
  1028 			}
       
  1029 			XmlElement childnodeElem(xt, "childnode", childAttrs);
       
  1030 			if (!edgeInfo->m_label.isEmpty()) {
       
  1031 				int p=0;
       
  1032 				int ni;
       
  1033 				while ((ni=edgeInfo->m_label.find('\n',p))!=-1) {
       
  1034 					XmlElement edgelabelElem(xt, "edgelabel");
       
  1035 					xt << edgeInfo->m_label.mid(p,ni-p);
       
  1036 					p=ni+1;
       
  1037 				}
       
  1038 				XmlElement edgelabelElem(xt, "edgelabel");
       
  1039 				xt << edgeInfo->m_label.right(edgeInfo->m_label.length()-p);
       
  1040 			}
       
  1041 		} 
       
  1042 	}
       
  1043 }
       
  1044 
   936 
  1045 void DotNode::writeDEF(QTextStream &t)
   937 void DotNode::writeDEF(QTextStream &t)
  1046 {
   938 {
  1047   const char* nodePrefix = "        node-";
   939   const char* nodePrefix = "        node-";
  1048 
   940 
  2155   {
  2047   {
  2156     node->writeXML(t,TRUE);
  2048     node->writeXML(t,TRUE);
  2157   }
  2049   }
  2158 }
  2050 }
  2159 
  2051 
  2160 void DotClassGraph::writeXML(XmlStream &t)
       
  2161 {
       
  2162   QDictIterator<DotNode> dni(*m_usedNodes);
       
  2163   DotNode *node;
       
  2164   for (;(node=dni.current());++dni)
       
  2165   {
       
  2166     node->writeXML(t,TRUE);
       
  2167   }
       
  2168 }
       
  2169 
       
  2170 void DotClassGraph::writeXMLDITA(XmlStream &t)
       
  2171 {
       
  2172   QDictIterator<DotNode> dni(*m_usedNodes);
       
  2173   DotNode *node;
       
  2174   for (;(node=dni.current());++dni)
       
  2175   {
       
  2176     node->writeXMLDITA(t,TRUE);
       
  2177   }
       
  2178 }
       
  2179 
       
  2180 void DotClassGraph::writeDEF(QTextStream &t)
  2052 void DotClassGraph::writeDEF(QTextStream &t)
  2181 {
  2053 {
  2182   QDictIterator<DotNode> dni(*m_usedNodes);
  2054   QDictIterator<DotNode> dni(*m_usedNodes);
  2183   DotNode *node;
  2055   DotNode *node;
  2184   for (;(node=dni.current());++dni)
  2056   for (;(node=dni.current());++dni)
  2487   {
  2359   {
  2488     node->writeXML(t,FALSE);
  2360     node->writeXML(t,FALSE);
  2489   }
  2361   }
  2490 }
  2362 }
  2491 
  2363 
  2492 void DotInclDepGraph::writeXML(XmlStream &xt)
       
  2493 {
       
  2494   QDictIterator<DotNode> dni(*m_usedNodes);
       
  2495   DotNode *node;
       
  2496   for (;(node=dni.current());++dni)
       
  2497   {
       
  2498     node->writeXML(xt,FALSE);
       
  2499   }
       
  2500 }
       
  2501 
       
  2502 //-------------------------------------------------------------
  2364 //-------------------------------------------------------------
  2503 
  2365 
  2504 int DotCallGraph::m_curNodeNumber = 0;
  2366 int DotCallGraph::m_curNodeNumber = 0;
  2505 
  2367 
  2506 void DotCallGraph::buildGraph(DotNode *n,MemberDef *md,int distance)
  2368 void DotCallGraph::buildGraph(DotNode *n,MemberDef *md,int distance)
  2974   QDir d(outDir);
  2836   QDir d(outDir);
  2975   if (!d.exists())
  2837   if (!d.exists())
  2976   {
  2838   {
  2977     err("Error: Output dir %s does not exist!\n",outDir); exit(1);
  2839     err("Error: Output dir %s does not exist!\n",outDir); exit(1);
  2978   }
  2840   }
  2979   setDotFontPath(0);
  2841   setDotFontPath("");
  2980 
  2842 
  2981   QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
  2843   QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
  2982   QCString imgName = (QCString)outFile+"."+imgExt;
  2844   QCString imgName = (QCString)outFile+"."+imgExt;
  2983   QCString absImgName = QCString(d.absPath())+"/"+imgName;
  2845   QCString absImgName = QCString(d.absPath())+"/"+imgName;
  2984   QCString absOutFile = QCString(d.absPath())+"/"+outFile;
  2846   QCString absOutFile = QCString(d.absPath())+"/"+outFile;
  3028   {
  2890   {
  3029     err("Error: Output dir %s does not exist!\n",outDir.data()); exit(1);
  2891     err("Error: Output dir %s does not exist!\n",outDir.data()); exit(1);
  3030   }
  2892   }
  3031   setDotFontPath(d.absPath());
  2893   setDotFontPath(d.absPath());
  3032 
  2894 
       
  2895   QCString absInFile  = QCString(d.absPath())+"/"+inFile.data();
  3033   QCString absOutFile = QCString(d.absPath())+"/"+outFile.data();
  2896   QCString absOutFile = QCString(d.absPath())+"/"+outFile.data();
  3034 
  2897 
  3035   DotRunner dotRun(inFile);
  2898   DotRunner dotRun(absInFile);
  3036   dotRun.addJob(MAP_CMD,absOutFile);
  2899   dotRun.addJob(MAP_CMD,absOutFile);
  3037   if (!dotRun.run())
  2900   if (!dotRun.run())
  3038   {
  2901   {
  3039     unsetDotFontPath();
  2902     unsetDotFontPath();
  3040     return "";
  2903     return "";