summaryrefslogtreecommitdiffstats
path: root/src/dot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dot.cpp')
-rw-r--r--src/dot.cpp295
1 files changed, 38 insertions, 257 deletions
diff --git a/src/dot.cpp b/src/dot.cpp
index 5cdf92c..f26bee4 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -16,12 +16,6 @@
#include <stdlib.h>
#include <qdir.h>
-#include <qfile.h>
-#include <qqueue.h>
-#include <qthread.h>
-#include <qmutex.h>
-#include <qwaitcondition.h>
-#include <qregexp.h>
#include "config.h"
#include "dot.h"
@@ -37,45 +31,19 @@
#define MAP_CMD "cmapx"
-static int DOT_NUM_THREADS; // will be initialized in initDot
-
//--------------------------------------------------------------------
-void initDot()
-{
- DotGraph::DOT_FONTNAME = Config_getString(DOT_FONTNAME);
- if (DotGraph::DOT_FONTNAME.isEmpty())
- {
- DotGraph::DOT_FONTNAME="Helvetica";
- }
-
- DotGraph::DOT_FONTSIZE = Config_getInt(DOT_FONTSIZE);
- if (DotGraph::DOT_FONTSIZE<4) DotGraph::DOT_FONTSIZE=4;
-
- DOT_NUM_THREADS = Config_getInt(DOT_NUM_THREADS);
- if (DOT_NUM_THREADS > 32) DOT_NUM_THREADS = 32;
- if (DOT_NUM_THREADS <= 0) DOT_NUM_THREADS = QMAX(2,QThread::idealThreadCount()+1);
-
- // these are copied to be sure to be thread save
- DotRunner::DOT_CLEANUP = Config_getBool(DOT_CLEANUP);
- DotRunner::DOT_MULTI_TARGETS = Config_getBool(DOT_MULTI_TARGETS);
- DotRunner::DOT_EXE.init(Config_getString(DOT_PATH) + "dot");
-
- DotGraph::IMG_EXT = getDotImageExtension();
-}
-
-
static QCString g_dotFontPath;
static void setDotFontPath(const char *path)
{
ASSERT(g_dotFontPath.isEmpty());
- g_dotFontPath = portable_getenv("DOTFONTPATH");
+ g_dotFontPath = Portable::getenv("DOTFONTPATH");
QCString newFontPath = Config_getString(DOT_FONTPATH);
QCString spath = path;
if (!newFontPath.isEmpty() && !spath.isEmpty())
{
- newFontPath.prepend(spath+portable_pathListSeparator());
+ newFontPath.prepend(spath+Portable::pathListSeparator());
}
else if (newFontPath.isEmpty() && !spath.isEmpty())
{
@@ -83,114 +51,25 @@ static void setDotFontPath(const char *path)
}
else
{
- portable_unsetenv("DOTFONTPATH");
+ Portable::unsetenv("DOTFONTPATH");
return;
}
- portable_setenv("DOTFONTPATH",newFontPath);
+ Portable::setenv("DOTFONTPATH",newFontPath);
}
static void unsetDotFontPath()
{
if (g_dotFontPath.isEmpty())
{
- portable_unsetenv("DOTFONTPATH");
+ Portable::unsetenv("DOTFONTPATH");
}
else
{
- portable_setenv("DOTFONTPATH",g_dotFontPath);
+ Portable::setenv("DOTFONTPATH",g_dotFontPath);
}
g_dotFontPath="";
}
-// extract size from a dot generated SVG file
-static bool readSVGSize(const QCString &fileName,int *width,int *height)
-{
- bool found=FALSE;
- QFile f(fileName);
- if (!f.open(IO_ReadOnly))
- {
- return FALSE;
- }
- const int maxLineLen=4096;
- char buf[maxLineLen];
- while (!f.atEnd() && !found)
- {
- int numBytes = f.readLine(buf,maxLineLen-1); // read line
- if (numBytes>0)
- {
- buf[numBytes]='\0';
- if (qstrncmp(buf,"<!--zoomable ",13)==0)
- {
- *width=-1;
- *height=-1;
- sscanf(buf,"<!--zoomable %d",height);
- //printf("Found zoomable for %s!\n",fileName.data());
- found=TRUE;
- }
- else if (sscanf(buf,"<svg width=\"%dpt\" height=\"%dpt\"",width,height)==2)
- {
- //printf("Found fixed size %dx%d for %s!\n",*width,*height,fileName.data());
- found=TRUE;
- }
- }
- else // read error!
- {
- //printf("Read error %d!\n",numBytes);
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static void writeSVGNotSupported(FTextStream &out)
-{
- out << "<p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p>";
-}
-
-// check if a reference to a SVG figure can be written and does so if possible.
-// return FALSE if not possible (for instance because the SVG file is not yet generated).
-bool writeSVGFigureLink(FTextStream &out,const QCString &relPath,
- const QCString &baseName,const QCString &absImgName)
-{
- int width=600,height=600;
- if (!readSVGSize(absImgName,&width,&height))
- {
- return FALSE;
- }
- if (width==-1)
- {
- if (height<=60)
- height=300;
- else
- height+=300; // add some extra space for zooming
- if (height>600) height=600; // clip to maximum height of 600 pixels
- out << "<div class=\"zoom\">";
- //out << "<object type=\"image/svg+xml\" data=\""
- //out << "<embed type=\"image/svg+xml\" src=\""
- out << "<iframe scrolling=\"no\" frameborder=\"0\" src=\""
- << relPath << baseName << ".svg\" width=\"100%\" height=\"" << height << "\">";
- }
- else
- {
- //out << "<object type=\"image/svg+xml\" data=\""
- //out << "<embed type=\"image/svg+xml\" src=\""
- out << "<iframe scrolling=\"no\" frameborder=\"0\" src=\""
- << relPath << baseName << ".svg\" width=\""
- << ((width*96+48)/72) << "\" height=\""
- << ((height*96+48)/72) << "\">";
- }
- writeSVGNotSupported(out);
- //out << "</object>";
- //out << "</embed>";
- out << "</iframe>";
- if (width==-1)
- {
- out << "</div>";
- }
-
- return TRUE;
-}
-
//--------------------------------------------------------------------
DotManager *DotManager::m_theInstance = 0;
@@ -204,15 +83,16 @@ DotManager *DotManager::instance()
return m_theInstance;
}
-DotManager::DotManager() : m_dotMaps(1009)
+DotManager::DotManager() : m_runners(1009), m_filePatchers(1009)
{
m_runners.setAutoDelete(TRUE);
- m_dotMaps.setAutoDelete(TRUE);
+ m_filePatchers.setAutoDelete(TRUE);
m_queue = new DotRunnerQueue;
int i;
- if (DOT_NUM_THREADS!=1)
+ int dotNumThreads = Config_getInt(DOT_NUM_THREADS);
+ if (dotNumThreads!=1)
{
- for (i=0;i<DOT_NUM_THREADS;i++)
+ for (i=0;i<dotNumThreads;i++)
{
DotWorkerThread *thread = new DotWorkerThread(m_queue);
thread->start();
@@ -253,62 +133,22 @@ DotRunner* DotManager::createRunner(const QCString& absDotName, const QCString&
return run;
}
-
-int DotManager::addMap(const QCString &file,const QCString &mapFile,
- const QCString &relPath,bool urlOnly,const QCString &context,
- const QCString &label)
-{
- DotFilePatcher *map = m_dotMaps.find(file);
- if (map==0)
- {
- map = new DotFilePatcher(file);
- m_dotMaps.append(file,map);
- }
- return map->addMap(mapFile,relPath,urlOnly,context,label);
-}
-
-int DotManager::addFigure(const QCString &file,const QCString &baseName,
- const QCString &figureName,bool heightCheck)
-{
- DotFilePatcher *map = m_dotMaps.find(file);
- if (map==0)
- {
- map = new DotFilePatcher(file);
- m_dotMaps.append(file,map);
- }
- return map->addFigure(baseName,figureName,heightCheck);
-}
-
-int DotManager::addSVGConversion(const QCString &file,const QCString &relPath,
- bool urlOnly,const QCString &context,bool zoomable,
- int graphId)
+DotFilePatcher *DotManager::createFilePatcher(const QCString &fileName)
{
- DotFilePatcher *map = m_dotMaps.find(file);
- if (map==0)
+ DotFilePatcher *patcher = m_filePatchers.find(fileName);
+ if (patcher==0)
{
- map = new DotFilePatcher(file);
- m_dotMaps.append(file,map);
+ patcher = new DotFilePatcher(fileName);
+ m_filePatchers.append(fileName,patcher);
}
- return map->addSVGConversion(relPath,urlOnly,context,zoomable,graphId);
+ return patcher;
}
-int DotManager::addSVGObject(const QCString &file,const QCString &baseName,
- const QCString &absImgName,const QCString &relPath)
-{
- DotFilePatcher *map = m_dotMaps.find(file);
- if (map==0)
- {
- map = new DotFilePatcher(file);
- m_dotMaps.append(file,map);
- }
- return map->addSVGObject(baseName,absImgName,relPath);
-}
-
-bool DotManager::run()
+bool DotManager::run() const
{
uint numDotRuns = m_runners.count();
- uint numDotMaps = m_dotMaps.count();
- if (numDotRuns+numDotMaps>1)
+ uint numFilePatchers = m_filePatchers.count();
+ if (numDotRuns+numFilePatchers>1)
{
if (m_workers.count()==0)
{
@@ -316,7 +156,7 @@ bool DotManager::run()
}
else
{
- msg("Generating dot graphs using %d parallel threads...\n",QMIN(numDotRuns+numDotMaps,m_workers.count()));
+ msg("Generating dot graphs using %d parallel threads...\n",QMIN(numDotRuns+numFilePatchers,m_workers.count()));
}
}
int i=1;
@@ -343,7 +183,7 @@ bool DotManager::run()
setDotFontPath(Config_getString(DOCBOOK_OUTPUT));
setPath=TRUE;
}
- portable_sysTimerStart();
+ Portable::sysTimerStart();
// fill work queue with dot operations
DotRunner *dr;
int prev=1;
@@ -371,7 +211,7 @@ bool DotManager::run()
msg("Running dot for graph %d/%d\n",prev,numDotRuns);
prev++;
}
- portable_sleep(100);
+ Portable::sleep(100);
}
while ((int)numDotRuns>=prev)
{
@@ -389,7 +229,7 @@ bool DotManager::run()
m_workers.at(i)->wait();
}
}
- portable_sysTimerStop();
+ Portable::sysTimerStop();
if (setPath)
{
unsetDotFontPath();
@@ -397,27 +237,27 @@ bool DotManager::run()
// patch the output file and insert the maps and figures
i=1;
- SDict<DotFilePatcher>::Iterator di(m_dotMaps);
- DotFilePatcher *map;
+ SDict<DotFilePatcher>::Iterator di(m_filePatchers);
+ const DotFilePatcher *fp;
// since patching the svg files may involve patching the header of the SVG
// (for zoomable SVGs), and patching the .html files requires reading that
// header after the SVG is patched, we first process the .svg files and
// then the other files.
- for (di.toFirst();(map=di.current());++di)
+ for (di.toFirst();(fp=di.current());++di)
{
- if (map->file().right(4)==".svg")
+ if (fp->isSVGFile())
{
- msg("Patching output file %d/%d\n",i,numDotMaps);
- if (!map->run()) return FALSE;
+ msg("Patching output file %d/%d\n",i,numFilePatchers);
+ if (!fp->run()) return FALSE;
i++;
}
}
- for (di.toFirst();(map=di.current());++di)
+ for (di.toFirst();(fp=di.current());++di)
{
- if (map->file().right(4)!=".svg")
+ if (!fp->isSVGFile())
{
- msg("Patching output file %d/%d\n",i,numDotMaps);
- if (!map->run()) return FALSE;
+ msg("Patching output file %d/%d\n",i,numFilePatchers);
+ if (!fp->run()) return FALSE;
i++;
}
}
@@ -426,70 +266,13 @@ bool DotManager::run()
//--------------------------------------------------------------------
-class GraphLegendDotGraph : public DotGraph
-{
- private:
- virtual QCString getBaseName() const
- {
- return "graph_legend";
- }
-
- virtual void computeTheGraph()
- {
- FTextStream md5stream(&m_theGraph);
- writeGraphHeader(md5stream,theTranslator->trLegendTitle());
- md5stream << " Node9 [shape=\"box\",label=\"Inherited\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",fillcolor=\"grey75\",style=\"filled\" fontcolor=\"black\"];\n";
- md5stream << " Node10 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n";
- md5stream << " Node10 [shape=\"box\",label=\"PublicBase\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classPublicBase" << Doxygen::htmlFileExtension << "\"];\n";
- md5stream << " Node11 -> Node10 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n";
- md5stream << " Node11 [shape=\"box\",label=\"Truncated\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"red\",URL=\"$classTruncated" << Doxygen::htmlFileExtension << "\"];\n";
- md5stream << " Node13 -> Node9 [dir=\"back\",color=\"darkgreen\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n";
- md5stream << " Node13 [shape=\"box\",label=\"ProtectedBase\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classProtectedBase" << Doxygen::htmlFileExtension << "\"];\n";
- md5stream << " Node14 -> Node9 [dir=\"back\",color=\"firebrick4\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n";
- md5stream << " Node14 [shape=\"box\",label=\"PrivateBase\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classPrivateBase" << Doxygen::htmlFileExtension << "\"];\n";
- md5stream << " Node15 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n";
- md5stream << " Node15 [shape=\"box\",label=\"Undocumented\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"grey75\"];\n";
- md5stream << " Node16 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"solid\",fontname=\"" << DOT_FONTNAME << "\"];\n";
- md5stream << " Node16 [shape=\"box\",label=\"Templ< int >\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension << "\"];\n";
- md5stream << " Node17 -> Node16 [dir=\"back\",color=\"orange\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"dashed\",label=\"< int >\",fontname=\"" << DOT_FONTNAME << "\"];\n";
- md5stream << " Node17 [shape=\"box\",label=\"Templ< T >\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension << "\"];\n";
- md5stream << " Node18 -> Node9 [dir=\"back\",color=\"darkorchid3\",fontsize=\"" << DOT_FONTSIZE << "\",style=\"dashed\",label=\"m_usedClass\",fontname=\"" << DOT_FONTNAME << "\"];\n";
- md5stream << " Node18 [shape=\"box\",label=\"Used\",fontsize=\"" << DOT_FONTSIZE << "\",height=0.2,width=0.4,fontname=\"" << DOT_FONTNAME << "\",color=\"black\",URL=\"$classUsed" << Doxygen::htmlFileExtension << "\"];\n";
- writeGraphFooter(md5stream);
- }
-
- virtual QCString getMapLabel() const
- {
- return "";
- }
-
- friend void generateGraphLegend(const char* path);
-};
-
-void generateGraphLegend(const char *path)
-{
- QDir d(path);
- GraphLegendDotGraph dg;
- FTextStream ts;
- dg.writeGraph(ts, GOF_BITMAP, EOF_Html, path, "", "", FALSE, 0);
-
- if (getDotImageExtension()=="svg")
- {
- DotManager::instance()->addSVGObject(
- dg.absBaseName()+Config_getString(HTML_FILE_EXTENSION),
- "graph_legend",
- dg.absImgName(),QCString());
- }
-
-}
-
void writeDotGraphFromFile(const char *inFile,const char *outDir,
const char *outFile,GraphOutputFormat format)
{
QDir d(outDir);
if (!d.exists())
{
- err("Output dir %s does not exist!\n",outDir); exit(1);
+ term("Output dir %s does not exist!\n",outDir);
}
QCString imgExt = getDotImageExtension();
@@ -542,7 +325,7 @@ void writeDotImageMapFromFile(FTextStream &t,
QDir d(outDir);
if (!d.exists())
{
- err("Output dir %s does not exist!\n",outDir.data()); exit(1);
+ term("Output dir %s does not exist!\n",outDir.data());
}
QCString mapName = baseName+".map";
@@ -560,10 +343,8 @@ void writeDotImageMapFromFile(FTextStream &t,
if (imgExt=="svg") // vector graphics
{
- //writeSVGFigureLink(t,relPath,inFile,inFile+".svg");
- //DotFilePatcher patcher(inFile+".svg");
QCString svgName=outDir+"/"+baseName+".svg";
- writeSVGFigureLink(t,relPath,baseName,svgName);
+ DotFilePatcher::writeSVGFigureLink(t,relPath,baseName,svgName);
DotFilePatcher patcher(svgName);
patcher.addSVGConversion("",TRUE,context,TRUE,graphId);
patcher.run();
@@ -575,7 +356,7 @@ void writeDotImageMapFromFile(FTextStream &t,
t << "<img src=\"" << relPath << imgName << "\" alt=\""
<< imgName << "\" border=\"0\" usemap=\"#" << mapName << "\"/>" << endl;
- convertMapFile(tt, absOutFile, relPath ,TRUE, context);
+ DotFilePatcher::convertMapFile(tt, absOutFile, relPath ,TRUE, context);
if (!result.isEmpty())
{
t << "<map name=\"" << mapName << "\" id=\"" << mapName << "\">";