summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt118
-rw-r--r--src/cite.cpp2
-rw-r--r--src/code.l3
-rw-r--r--src/commentcnv.l3
-rw-r--r--src/commentscan.l20
-rw-r--r--src/configimpl.l30
-rw-r--r--src/constexp.l2
-rw-r--r--src/declinfo.l2
-rw-r--r--src/defargs.l2
-rw-r--r--src/doctokenizer.l13
-rw-r--r--src/dot.cpp273
-rw-r--r--src/dot.h41
-rw-r--r--src/dotdirdeps.cpp8
-rw-r--r--src/dotfilepatcher.cpp152
-rw-r--r--src/dotfilepatcher.h21
-rw-r--r--src/dotgraph.cpp101
-rw-r--r--src/dotgraph.h9
-rw-r--r--src/dotgroupcollaboration.cpp11
-rw-r--r--src/dotlegendgraph.cpp72
-rw-r--r--src/dotlegendgraph.h35
-rw-r--r--src/dotnode.cpp4
-rw-r--r--src/dotrunner.cpp18
-rw-r--r--src/dotrunner.h8
-rw-r--r--src/doxygen.cpp1
-rw-r--r--src/formula.cpp18
-rw-r--r--src/fortrancode.l3
-rw-r--r--src/fortranscanner.l45
-rw-r--r--src/index.cpp7
-rw-r--r--src/markdown.cpp2
-rw-r--r--src/pre.l3
-rw-r--r--src/pycode.l2
-rw-r--r--src/pyscanner.l2
-rw-r--r--src/scan_states.py49
-rw-r--r--src/scanner.l2
-rw-r--r--src/sqlcode.l2
-rw-r--r--src/sqlite3gen.cpp4
-rw-r--r--src/tclscanner.l3
-rw-r--r--src/util.cpp6
-rw-r--r--src/vhdlcode.l4
-rw-r--r--src/xmlcode.l3
40 files changed, 611 insertions, 493 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7233052..7e54b2b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -100,25 +100,39 @@ add_custom_command(
)
set_source_files_properties(${GENERATED_SRC}/layout_default.xml.h PROPERTIES GENERATED 1)
-# Targets for flex/bison generated files
-FLEX_TARGET(scanner scanner.l ${GENERATED_SRC}/scanner.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(code code.l ${GENERATED_SRC}/code.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(pyscanner pyscanner.l ${GENERATED_SRC}/pyscanner.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(pycode pycode.l ${GENERATED_SRC}/pycode.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(fortranscanner fortranscanner.l ${GENERATED_SRC}/fortranscanner.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(fortrancode fortrancode.l ${GENERATED_SRC}/fortrancode.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(vhdlcode vhdlcode.l ${GENERATED_SRC}/vhdlcode.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(tclscanner tclscanner.l ${GENERATED_SRC}/tclscanner.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(pre pre.l ${GENERATED_SRC}/pre.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(declinfo declinfo.l ${GENERATED_SRC}/declinfo.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(defargs defargs.l ${GENERATED_SRC}/defargs.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(doctokenizer doctokenizer.l ${GENERATED_SRC}/doctokenizer.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(commentcnv commentcnv.l ${GENERATED_SRC}/commentcnv.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(commentscan commentscan.l ${GENERATED_SRC}/commentscan.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(constexp constexp.l ${GENERATED_SRC}/constexp.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(xmlcode xmlcode.l ${GENERATED_SRC}/xmlcode.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(sqlcode sqlcode.l ${GENERATED_SRC}/sqlcode.cpp COMPILE_FLAGS "${LEX_FLAGS}")
-FLEX_TARGET(configimpl configimpl.l ${GENERATED_SRC}/configimpl.cpp COMPILE_FLAGS "${LEX_FLAGS}")
+set(LEX_FILES scanner
+ code
+ pyscanner
+ pycode
+ fortranscanner
+ fortrancode
+ vhdlcode
+ tclscanner
+ pre
+ declinfo
+ defargs
+ doctokenizer
+ commentcnv
+ commentscan
+ constexp
+ xmlcode
+ sqlcode
+ configimpl)
+
+# unfortunately ${LEX_FILES_H} and ${LEX_FILES_CPP} don't work in older versions of CMake (like 3.6.2) for add_library
+foreach(lex_file ${LEX_FILES})
+ set(LEX_FILES_H ${LEX_FILES_H} " " ${GENERATED_SRC}/${lex_file}.l.h CACHE INTERNAL "Stores generated files")
+ set(LEX_FILES_CPP ${LEX_FILES_CPP} " " ${GENERATED_SRC}/${lex_file}.cpp CACHE INTERNAL "Stores generated files")
+ add_custom_command(
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/src/scan_states.py ${CMAKE_SOURCE_DIR}/src/${lex_file}.l > ${GENERATED_SRC}/${lex_file}.l.h
+ DEPENDS ${CMAKE_SOURCE_DIR}/src/scan_states.py ${CMAKE_SOURCE_DIR}/src/${lex_file}.l
+ OUTPUT ${GENERATED_SRC}/${lex_file}.l.h
+ )
+ set_source_files_properties(${GENERATED_SRC}/${lex_file}.l.h PROPERTIES GENERATED 1)
+
+ FLEX_TARGET(${lex_file} ${lex_file}.l ${GENERATED_SRC}/${lex_file}.cpp COMPILE_FLAGS "${LEX_FLAGS}")
+endforeach()
+
BISON_TARGET(constexp constexp.y ${GENERATED_SRC}/ce_parse.cpp COMPILE_FLAGS "${YACC_FLAGS}")
@@ -140,24 +154,45 @@ add_library(_doxygen STATIC
${GENERATED_SRC}/ce_parse.h
${GENERATED_SRC}/configvalues.h
${GENERATED_SRC}/resources.cpp
- # generated by flex/bison
- ${GENERATED_SRC}/scanner.cpp
+ # generated for/by flex/bison
+ #${LEX_FILES_H} #unfortunately doesn't work in older versions of CMake (like 3.6.2)
+ #${LEX_FILES_CPP} #unfortunately doesn't work in older versions of CMake (like 3.6.2)
+ ${GENERATED_SRC}/code.l.h
+ ${GENERATED_SRC}/commentcnv.l.h
+ ${GENERATED_SRC}/commentscan.l.h
+ ${GENERATED_SRC}/configimpl.l.h
+ ${GENERATED_SRC}/constexp.l.h
+ ${GENERATED_SRC}/declinfo.l.h
+ ${GENERATED_SRC}/defargs.l.h
+ ${GENERATED_SRC}/doctokenizer.l.h
+ ${GENERATED_SRC}/fortrancode.l.h
+ ${GENERATED_SRC}/fortranscanner.l.h
+ ${GENERATED_SRC}/pre.l.h
+ ${GENERATED_SRC}/pycode.l.h
+ ${GENERATED_SRC}/pyscanner.l.h
+ ${GENERATED_SRC}/scanner.l.h
+ ${GENERATED_SRC}/sqlcode.l.h
+ ${GENERATED_SRC}/tclscanner.l.h
+ ${GENERATED_SRC}/vhdlcode.l.h
+ ${GENERATED_SRC}/xmlcode.l.h
${GENERATED_SRC}/code.cpp
- ${GENERATED_SRC}/pyscanner.cpp
- ${GENERATED_SRC}/pycode.cpp
- ${GENERATED_SRC}/fortranscanner.cpp
- ${GENERATED_SRC}/fortrancode.cpp
- ${GENERATED_SRC}/vhdlcode.cpp
- ${GENERATED_SRC}/tclscanner.cpp
- ${GENERATED_SRC}/pre.cpp
- ${GENERATED_SRC}/declinfo.cpp
- ${GENERATED_SRC}/defargs.cpp
- ${GENERATED_SRC}/doctokenizer.cpp
${GENERATED_SRC}/commentcnv.cpp
${GENERATED_SRC}/commentscan.cpp
+ ${GENERATED_SRC}/configimpl.cpp
${GENERATED_SRC}/constexp.cpp
- ${GENERATED_SRC}/xmlcode.cpp
+ ${GENERATED_SRC}/declinfo.cpp
+ ${GENERATED_SRC}/defargs.cpp
+ ${GENERATED_SRC}/doctokenizer.cpp
+ ${GENERATED_SRC}/fortrancode.cpp
+ ${GENERATED_SRC}/fortranscanner.cpp
+ ${GENERATED_SRC}/pre.cpp
+ ${GENERATED_SRC}/pycode.cpp
+ ${GENERATED_SRC}/pyscanner.cpp
+ ${GENERATED_SRC}/scanner.cpp
${GENERATED_SRC}/sqlcode.cpp
+ ${GENERATED_SRC}/tclscanner.cpp
+ ${GENERATED_SRC}/vhdlcode.cpp
+ ${GENERATED_SRC}/xmlcode.cpp
#
${GENERATED_SRC}/ce_parse.cpp
#
@@ -181,16 +216,17 @@ add_library(_doxygen STATIC
docparser.cpp
docsets.cpp
dot.cpp
- dotcallgraph.cpp
- dotclassgraph.cpp
- dotdirdeps.cpp
- dotfilepatcher.cpp
+ dotcallgraph.cpp
+ dotlegendgraph.cpp
+ dotclassgraph.cpp
+ dotdirdeps.cpp
+ dotfilepatcher.cpp
dotgfxhierarchytable.cpp
dotgraph.cpp
- dotgroupcollaboration.cpp
- dotincldepgraph.cpp
+ dotgroupcollaboration.cpp
+ dotincldepgraph.cpp
dotnode.cpp
- dotrunner.cpp
+ dotrunner.cpp
doxygen.cpp
eclipsehelp.cpp
emoji.cpp
@@ -251,6 +287,10 @@ add_library(_doxygen STATIC
docgroup.cpp
)
+##foreach(lex_file ${LEX_FILES})
+##add_library(_doxygen STATIC ${GENERATED_SRC}/${lex_file}.l.h)
+##endforeach()
+
add_executable(doxygen main.cpp)
if (use_libclang)
diff --git a/src/cite.cpp b/src/cite.cpp
index fd7b0e4..a36f62c 100644
--- a/src/cite.cpp
+++ b/src/cite.cpp
@@ -151,7 +151,7 @@ void CiteDict::generatePage() const
p=s+1;
int i;
- if ((i = line.find("crossref")) != -1) /* assumption crosreference is on one line and the only item */
+ if ((i = line.find("crossref")) != -1) /* assumption crossreference is on one line and the only item */
{
int j=line.find("{",i);
int k=line.find("}",i);
diff --git a/src/code.l b/src/code.l
index d66ccc8..5ed8866 100644
--- a/src/code.l
+++ b/src/code.l
@@ -165,6 +165,8 @@ static int g_braceCount=0;
static void saveObjCContext();
static void restoreObjCContext();
+static const char *stateToString(int state);
+
static QCString g_forceTagReference;
@@ -3875,3 +3877,4 @@ extern "C" { // some bogus code to keep the compiler happy
#error "You seem to be using a version of flex newer than 2.5.4. These are currently incompatible with 2.5.4, and do NOT work with doxygen! Please use version 2.5.4 or expect things to be parsed wrongly! A bug report has been submitted (#732132)."
#endif
+#include "code.l.h"
diff --git a/src/commentcnv.l b/src/commentcnv.l
index 2550227..f144aec 100644
--- a/src/commentcnv.l
+++ b/src/commentcnv.l
@@ -94,6 +94,8 @@ static bool g_vhdl; // for VHDL old style --! comment
static SrcLangExt g_lang;
static bool isFixedForm; // For Fortran
+static const char *stateToString(int state);
+
static void replaceCommentMarker(const char *s,int len)
{
const char *p=s;
@@ -1145,3 +1147,4 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
+#include "commentcnv.l.h"
diff --git a/src/commentscan.l b/src/commentscan.l
index a495c5e..abf218c 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -78,6 +78,7 @@ static bool handleFile(const QCString &, const QCStringList &);
static bool handleDir(const QCString &, const QCStringList &);
static bool handleExample(const QCString &, const QCStringList &);
static bool handleDetails(const QCString &, const QCStringList &);
+static bool handleNoop(const QCString &, const QCStringList &);
static bool handleName(const QCString &, const QCStringList &);
static bool handleTodo(const QCString &, const QCStringList &);
static bool handleTest(const QCString &, const QCStringList &);
@@ -132,6 +133,8 @@ static bool handleEndParBlock(const QCString &, const QCStringList &);
static bool handleParam(const QCString &, const QCStringList &);
static bool handleRetval(const QCString &, const QCStringList &);
+static const char *stateToString(int state);
+
typedef bool (*DocCmdFunc)(const QCString &name, const QCStringList &optList);
struct DocCmdMap
@@ -279,6 +282,7 @@ static DocCmdMap docCmdMap[] =
{ "warning", 0, TRUE },
{ "snippet", 0, TRUE },
{ "snippetlineno", 0, TRUE },
+ { "noop", &handleNoop, TRUE },
{ 0, 0, FALSE }
};
@@ -998,6 +1002,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
%x CopyDoc
%x GuardExpr
%x CdataSection
+%x Noop
%%
@@ -2129,6 +2134,14 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
current->name+=*yytext;
}
+ /* ----- handle argument of noop command ------- */
+<Noop>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<Noop>. { // ignore other stuff
+ }
/* ----- handle argument of ingroup command ------- */
<InGroupParam>{LABELID} { // group id
@@ -2540,6 +2553,12 @@ static bool handleDetails(const QCString &, const QCStringList &)
return FALSE;
}
+static bool handleNoop(const QCString &, const QCStringList &)
+{
+ BEGIN( Noop );
+ return FALSE;
+}
+
static bool handleName(const QCString &, const QCStringList &)
{
bool stop=makeStructuralIndicator(Entry::MEMBERGRP_SEC);
@@ -3278,3 +3297,4 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
+#include "commentscan.l.h"
diff --git a/src/configimpl.l b/src/configimpl.l
index 2d91e12..7d22859 100644
--- a/src/configimpl.l
+++ b/src/configimpl.l
@@ -30,6 +30,7 @@
#include <qregexp.h>
#include <qstack.h>
#include <qglobal.h>
+#include <qthread.h>
#include "configimpl.h"
#include "version.h"
@@ -43,6 +44,8 @@
#define YY_NO_INPUT 1
#define YY_NO_UNISTD_H 1
+static const char *stateToString(int state);
+
static const char *warning_str = "warning: ";
static const char *error_str = "error: ";
@@ -1531,6 +1534,7 @@ void Config::checkAndCorrect()
// dotImageFormat = "png";
//}
+ // correct DOT_FONTNAME if needed
QCString &dotFontName=Config_getString(DOT_FONTNAME);
if (dotFontName=="FreeSans" || dotFontName=="FreeSans.ttf")
{
@@ -1538,7 +1542,32 @@ void Config::checkAndCorrect()
"You may want to clear or change DOT_FONTNAME.\n"
"Otherwise you run the risk that the wrong font is being used for dot generated graphs.\n");
}
+ else if (dotFontName.isEmpty())
+ {
+ dotFontName = "Helvetica";
+ }
+
+ // clip dotFontSize against the maximum bounds
+ int &dotFontSize = Config_getInt(DOT_FONTSIZE);
+ if (dotFontSize<4)
+ {
+ dotFontSize=4;
+ }
+ else if (dotFontSize>24)
+ {
+ dotFontSize=24;
+ }
+ // clip number of threads
+ int &dotNumThreads = Config_getInt(DOT_NUM_THREADS);
+ if (dotNumThreads>32)
+ {
+ dotNumThreads=32;
+ }
+ else if (dotNumThreads<=0)
+ {
+ dotNumThreads=QMAX(2,QThread::idealThreadCount()+1);
+ }
// check dot path
QCString &dotPath = Config_getString(DOT_PATH);
@@ -1882,3 +1911,4 @@ void Config::deinit()
ConfigImpl::instance()->deleteInstance();
}
+#include "configimpl.l.h"
diff --git a/src/constexp.l b/src/constexp.l
index c9b984a..b6b3c5c 100644
--- a/src/constexp.l
+++ b/src/constexp.l
@@ -32,6 +32,7 @@
#define YY_NO_UNISTD_H 1
+static const char *stateToString(int state);
static int yyread(char *buf,int max_size,yyscan_t yyscanner);
#undef YY_INPUT
@@ -139,3 +140,4 @@ bool parseconstexp(const char *fileName,int lineNr,const QCString &s)
extern "C" {
int constexpYYwrap(yyscan_t yyscanner) { return 1; }
}
+#include "constexp.l.h"
diff --git a/src/declinfo.l b/src/declinfo.l
index 36ef94a..0ac1516 100644
--- a/src/declinfo.l
+++ b/src/declinfo.l
@@ -63,6 +63,7 @@ struct declinfoYY_state
bool insidePHP;
};
+static const char *stateToString(int state);
static void addType(yyscan_t yyscanner);
static void addTypeName(yyscan_t yyscanner);
static int yyread(char *buf,int max_size, yyscan_t yyscanner);
@@ -391,3 +392,4 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
+#include "declinfo.l.h"
diff --git a/src/defargs.l b/src/defargs.l
index 37d904f..070103a 100644
--- a/src/defargs.l
+++ b/src/defargs.l
@@ -87,6 +87,7 @@ static int g_lastDocChar;
static int g_lastExtendsContext;
static QCString g_delimiter;
+static const char *stateToString(int state);
/* -----------------------------------------------------------------
*/
#undef YY_INPUT
@@ -637,3 +638,4 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
+#include "defargs.l.h"
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 6c02bcf..9786720 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -76,6 +76,7 @@ struct DocLexerContext
static QStack<DocLexerContext> g_lexerStack;
+static const char *stateToString(int state);
//--------------------------------------------------------------------------
void doctokenizerYYpushContext()
@@ -353,8 +354,9 @@ ATTRNAME [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF\-]*
ATTRIB {ATTRNAME}{WS}*("="{WS}*(("\""[^\"]*"\"")|("'"[^\']*"'")|[^ \t\r\n'"><]+))?
URLCHAR [a-z_A-Z0-9\!\~\,\:\;\'\$\?\@\&\%\#\.\-\+\/\=]
URLMASK ({URLCHAR}+([({]{URLCHAR}*[)}])?)+
-FILESCHAR [a-z_A-Z0-9\\:\\\/\-\+@&#]
-FILEECHAR [a-z_A-Z0-9\-\+@&#]
+URLPROTOCOL ("http:"|"https:"|"ftp:"|"file:"|"news:"|"irc")
+FILESCHAR [a-z_A-Z0-9\\:\\\/\-\+&#]
+FILEECHAR [a-z_A-Z0-9\-\+&#]
HFILEMASK ("."{FILESCHAR}*{FILEECHAR}+)+
FILEMASK ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|{HFILEMASK}
LINKMASK [^ \t\n\r\\@<&${}]+("("[^\n)]*")")?({BLANK}*("const"|"volatile"){BLANK}+)?
@@ -624,17 +626,17 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
}
return TK_COMMAND_SEL();
}
-<St_Para>("http:"|"https:"|"ftp:"|"file:"|"news:"){URLMASK}/\. { // URL.
+<St_Para>{URLPROTOCOL}{URLMASK}/\. { // URL.
g_token->name=yytext;
g_token->isEMailAddr=FALSE;
return TK_URL;
}
-<St_Para>("http:"|"https:"|"ftp:"|"file:"|"news:"){URLMASK} { // URL
+<St_Para>{URLPROTOCOL}{URLMASK} { // URL
g_token->name=yytext;
g_token->isEMailAddr=FALSE;
return TK_URL;
}
-<St_Para>"<"("http:"|"https:"|"ftp:"|"file:"|"news:"){URLMASK}">" { // URL
+<St_Para>"<"{URLPROTOCOL}{URLMASK}">" { // URL
g_token->name=yytext;
g_token->name = g_token->name.mid(1,g_token->name.length()-2);
g_token->isEMailAddr=FALSE;
@@ -1615,3 +1617,4 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
+#include "doctokenizer.l.h"
diff --git a/src/dot.cpp b/src/dot.cpp
index 5cdf92c..5ad3916 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,34 +31,8 @@
#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)
@@ -102,95 +70,6 @@ static void unsetDotFontPath()
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;
@@ -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,63 +266,6 @@ 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)
{
@@ -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 << "\">";
diff --git a/src/dot.h b/src/dot.h
index 124a32b..60f7f26 100644
--- a/src/dot.h
+++ b/src/dot.h
@@ -18,66 +18,43 @@
#include <qlist.h>
#include <qdict.h>
-#include <qwaitcondition.h>
-#include <qmutex.h>
-#include <qqueue.h>
-#include <qthread.h>
+#include <qcstring.h>
+
#include "sortdict.h"
-#include "qgstring.h"
-#include "qdir.h"
-#include "qcstring.h"
-#include "dotgraph.h"
+
+#include "dotgraph.h" // only for GraphOutputFormat
#include "dotfilepatcher.h"
#include "dotrunner.h"
class FTextStream;
class DotRunner;
class DotRunnerQueue;
-class DotWorkerThread;
-/** Singleton that manages dot relation actions */
+/** Singleton that manages parallel dot invocations and patching files for embedding image maps */
class DotManager
{
public:
static DotManager *instance();
- DotRunner* createRunner(const QCString& absDotName, const QCString& md5Hash);
- int addMap(const QCString &file,const QCString &mapFile,
- const QCString &relPath,bool urlOnly,
- const QCString &context,const QCString &label);
- int addFigure(const QCString &file,const QCString &baseName,
- const QCString &figureName,bool heightCheck);
- int addSVGConversion(const QCString &file,const QCString &relPath,
- bool urlOnly,const QCString &context,bool zoomable,int graphId);
- int addSVGObject(const QCString &file,const QCString &baseName,
- const QCString &figureNAme,const QCString &relPath);
- bool run();
+ DotRunner* createRunner(const QCString& absDotName, const QCString& md5Hash);
+ DotFilePatcher *createFilePatcher(const QCString &fileName);
+ bool run() const;
private:
DotManager();
virtual ~DotManager();
QDict<DotRunner> m_runners;
- SDict<DotFilePatcher> m_dotMaps;
+ SDict<DotFilePatcher> m_filePatchers;
static DotManager *m_theInstance;
DotRunnerQueue *m_queue;
QList<DotWorkerThread> m_workers;
};
-void initDot();
-
-/** Generated a graphs legend page */
-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=-1);
-bool writeSVGFigureLink(FTextStream &out,const QCString &relPath,
- const QCString &baseName,const QCString &absImgName);
-bool convertMapFile(FTextStream &t,const char *mapName,
- const QCString relPath, bool urlOnly=FALSE,
- const QCString &context=QCString());
#endif
diff --git a/src/dotdirdeps.cpp b/src/dotdirdeps.cpp
index 85906d1..98c7ca7 100644
--- a/src/dotdirdeps.cpp
+++ b/src/dotdirdeps.cpp
@@ -22,14 +22,16 @@
void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations)
{
+ int fontSize = Config_getInt(DOT_FONTSIZE);
+ QCString fontName = Config_getString(DOT_FONTNAME);
t << "digraph \"" << dd->displayName() << "\" {\n";
if (Config_getBool(DOT_TRANSPARENT))
{
t << " bgcolor=transparent;\n";
}
t << " compound=true\n";
- t << " node [ fontsize=\"" << DotGraph::DOT_FONTSIZE << "\", fontname=\"" << DotGraph::DOT_FONTNAME << "\"];\n";
- t << " edge [ labelfontsize=\"" << DotGraph::DOT_FONTSIZE << "\", labelfontname=\"" << DotGraph::DOT_FONTNAME << "\"];\n";
+ t << " node [ fontsize=\"" << fontSize << "\", fontname=\"" << fontName << "\"];\n";
+ t << " edge [ labelfontsize=\"" << fontSize << "\", labelfontname=\"" << fontName << "\"];\n";
QDict<DirDef> dirsInGraph(257);
@@ -39,7 +41,7 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations)
t << " subgraph cluster" << dd->parent()->getOutputFileBase() << " {\n";
t << " graph [ bgcolor=\"#ddddee\", pencolor=\"black\", label=\""
<< dd->parent()->shortName()
- << "\" fontname=\"" << DotGraph::DOT_FONTNAME << "\", fontsize=\"" << DotGraph::DOT_FONTSIZE << "\", URL=\"";
+ << "\" fontname=\"" << fontName << "\", fontsize=\"" << fontSize << "\", URL=\"";
t << dd->parent()->getOutputFileBase() << Doxygen::htmlFileExtension;
t << "\"]\n";
}
diff --git a/src/dotfilepatcher.cpp b/src/dotfilepatcher.cpp
index 91b7c78..92a5618 100644
--- a/src/dotfilepatcher.cpp
+++ b/src/dotfilepatcher.cpp
@@ -14,6 +14,7 @@
*/
#include "dotfilepatcher.h"
+#include "dotrunner.h"
#include "qstring.h"
#include "config.h"
@@ -209,7 +210,7 @@ static QCString replaceRef(const QCString &buf,const QCString relPath,
* map file was found
* \returns TRUE if successful.
*/
-bool convertMapFile(FTextStream &t,const char *mapName,
+bool DotFilePatcher::convertMapFile(FTextStream &t,const char *mapName,
const QCString relPath, bool urlOnly,
const QCString &context)
{
@@ -255,9 +256,9 @@ DotFilePatcher::DotFilePatcher(const char *patchFile)
m_maps.setAutoDelete(TRUE);
}
-QCString DotFilePatcher::file() const
+bool DotFilePatcher::isSVGFile() const
{
- return m_patchFile;
+ return m_patchFile.right(4)==".svg";
}
int DotFilePatcher::addMap(const QCString &mapFile,const QCString &relPath,
@@ -320,7 +321,7 @@ int DotFilePatcher::addSVGObject(const QCString &baseName,
return id;
}
-bool DotFilePatcher::run()
+bool DotFilePatcher::run() const
{
//printf("DotFilePatcher::run(): %s\n",m_patchFile.data());
bool interactiveSVG_local = Config_getBool(INTERACTIVE_SVG);
@@ -479,7 +480,7 @@ bool DotFilePatcher::run()
Map *map = m_maps.at(mapId);
//printf("patching FIG %d in file %s with contents of %s\n",
// mapId,m_patchFile.data(),map->mapFile.data());
- if (!DotGraph::writeVecGfxFigure(t,map->label,map->mapFile))
+ if (!writeVecGfxFigure(t,map->label,map->mapFile))
{
err("problem writing FIG %d figure!\n",mapId);
return FALSE;
@@ -537,3 +538,144 @@ bool DotFilePatcher::run()
QDir::current().remove(tmpName);
return TRUE;
}
+
+//---------------------------------------------------------------------------------------------
+
+
+// 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 do so if possible.
+/// Returns FALSE if not possible (for instance because the SVG file is not yet generated).
+bool DotFilePatcher::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;
+}
+
+bool DotFilePatcher::writeVecGfxFigure(FTextStream &out,const QCString &baseName,
+ const QCString &figureName)
+{
+ int width=400,height=550;
+ if (Config_getBool(USE_PDFLATEX))
+ {
+ if (!DotRunner::readBoundingBox(figureName+".pdf",&width,&height,FALSE))
+ {
+ //printf("writeVecGfxFigure()=0\n");
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!DotRunner::readBoundingBox(figureName+".eps",&width,&height,TRUE))
+ {
+ //printf("writeVecGfxFigure()=0\n");
+ return FALSE;
+ }
+ }
+ //printf("Got PDF/EPS size %d,%d\n",width,height);
+ int maxWidth = 350; /* approx. page width in points, excl. margins */
+ int maxHeight = 550; /* approx. page height in points, excl. margins */
+ out << "\\nopagebreak\n"
+ "\\begin{figure}[H]\n"
+ "\\begin{center}\n"
+ "\\leavevmode\n";
+ if (width>maxWidth || height>maxHeight) // figure too big for page
+ {
+ // c*width/maxWidth > c*height/maxHeight, where c=maxWidth*maxHeight>0
+ if (width*maxHeight>height*maxWidth)
+ {
+ out << "\\includegraphics[width=" << maxWidth << "pt]";
+ }
+ else
+ {
+ out << "\\includegraphics[height=" << maxHeight << "pt]";
+ }
+ }
+ else
+ {
+ out << "\\includegraphics[width=" << width << "pt]";
+ }
+
+ out << "{" << baseName << "}\n"
+ "\\end{center}\n"
+ "\\end{figure}\n";
+
+ //printf("writeVecGfxFigure()=1\n");
+ return TRUE;
+}
diff --git a/src/dotfilepatcher.h b/src/dotfilepatcher.h
index dd5c511..b68208d 100644
--- a/src/dotfilepatcher.h
+++ b/src/dotfilepatcher.h
@@ -19,21 +19,37 @@
#include "qcstring.h"
#include "qlist.h"
+class FTextStream;
+
/** Helper class to insert a set of map file into an output file */
class DotFilePatcher
{
public:
DotFilePatcher(const char *patchFile);
+
int addMap(const QCString &mapFile,const QCString &relPath,
bool urlOnly,const QCString &context,const QCString &label);
+
int addFigure(const QCString &baseName,
const QCString &figureName,bool heightCheck);
+
int addSVGConversion(const QCString &relPath,bool urlOnly,
const QCString &context,bool zoomable,int graphId);
+
int addSVGObject(const QCString &baseName, const QCString &figureName,
const QCString &relPath);
- bool run();
- QCString file() const;
+ bool run() const;
+ bool isSVGFile() const;
+
+ static bool convertMapFile(FTextStream &t,const char *mapName,
+ const QCString relPath, bool urlOnly=FALSE,
+ const QCString &context=QCString());
+
+ static bool writeSVGFigureLink(FTextStream &out,const QCString &relPath,
+ const QCString &baseName,const QCString &absImgName);
+
+ static bool writeVecGfxFigure(FTextStream& out, const QCString& baseName,
+ const QCString& figureName);
private:
struct Map
@@ -50,4 +66,5 @@ class DotFilePatcher
QCString m_patchFile;
};
+
#endif
diff --git a/src/dotgraph.cpp b/src/dotgraph.cpp
index ca6bcca..df64d66 100644
--- a/src/dotgraph.cpp
+++ b/src/dotgraph.cpp
@@ -24,11 +24,12 @@
#include "dotrunner.h"
#include "dotgraph.h"
#include "dotnode.h"
+#include "dotfilepatcher.h"
#define MAP_CMD "cmapx"
-QCString DotGraph::DOT_FONTNAME; // will be initialized in initDot
-int DotGraph::DOT_FONTSIZE; // will be initialized in initDot
+//QCString DotGraph::DOT_FONTNAME; // will be initialized in initDot
+//int DotGraph::DOT_FONTSIZE; // will be initialized in initDot
/*! Checks if a file "baseName".md5 exists. If so the contents
* are compared with \a md5. If equal FALSE is returned.
@@ -90,7 +91,7 @@ static bool insertMapFile(FTextStream &out,const QCString &mapFile,
{
QGString tmpstr;
FTextStream tmpout(&tmpstr);
- convertMapFile(tmpout,mapFile,relPath,FALSE);
+ DotFilePatcher::convertMapFile(tmpout,mapFile,relPath,FALSE);
if (!tmpstr.isEmpty())
{
out << "<map name=\"" << mapLabel << "\" id=\"" << mapLabel << "\">" << endl;
@@ -104,12 +105,10 @@ static bool insertMapFile(FTextStream &out,const QCString &mapFile,
//--------------------------------------------------------------------
-QCString DotGraph::IMG_EXT;
-
QCString DotGraph::imgName() const
{
return m_baseName + ((m_graphFormat == GOF_BITMAP) ?
- ("." + IMG_EXT) : (Config_getBool(USE_PDFLATEX) ? ".pdf" : ".eps"));
+ ("." + getDotImageExtension()) : (Config_getBool(USE_PDFLATEX) ? ".pdf" : ".eps"));
}
QCString DotGraph::writeGraph(
@@ -209,6 +208,7 @@ bool DotGraph::prepareDotFile()
void DotGraph::generateCode(FTextStream &t)
{
+ QCString imgExt = getDotImageExtension();
if (m_graphFormat==GOF_BITMAP && m_textFormat==EOF_DocBook)
{
t << "<para>" << endl;
@@ -216,7 +216,7 @@ void DotGraph::generateCode(FTextStream &t)
t << " <mediaobject>" << endl;
t << " <imageobject>" << endl;
t << " <imagedata";
- t << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << m_relPath << m_baseName << "." << IMG_EXT << "\">";
+ t << " width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"0\" fileref=\"" << m_relPath << m_baseName << "." << imgExt << "\">";
t << "</imagedata>" << endl;
t << " </imageobject>" << endl;
t << " </mediaobject>" << endl;
@@ -225,16 +225,20 @@ void DotGraph::generateCode(FTextStream &t)
}
else if (m_graphFormat==GOF_BITMAP && m_generateImageMap) // produce HTML to include the image
{
- if (IMG_EXT=="svg") // add link to SVG file without map file
+ if (imgExt=="svg") // add link to SVG file without map file
{
if (!m_noDivTag) t << "<div class=\"center\">";
- if (m_regenerate || !writeSVGFigureLink(t,m_relPath,m_baseName,absImgName())) // need to patch the links in the generated SVG file
+ if (m_regenerate || !DotFilePatcher::writeSVGFigureLink(t,m_relPath,m_baseName,absImgName())) // need to patch the links in the generated SVG file
{
if (m_regenerate)
{
- DotManager::instance()->addSVGConversion(absImgName(),m_relPath,FALSE,QCString(),m_zoomable,m_graphId);
+ DotManager::instance()->
+ createFilePatcher(absImgName())->
+ addSVGConversion(m_relPath,FALSE,QCString(),m_zoomable,m_graphId);
}
- int mapId = DotManager::instance()->addSVGObject(m_fileName,m_baseName,absImgName(),m_relPath);
+ int mapId = DotManager::instance()->
+ createFilePatcher(m_fileName)->
+ addSVGObject(m_baseName,absImgName(),m_relPath);
t << "<!-- SVG " << mapId << " -->" << endl;
}
if (!m_noDivTag) t << "</div>" << endl;
@@ -247,16 +251,20 @@ void DotGraph::generateCode(FTextStream &t)
t << endl;
if (m_regenerate || !insertMapFile(t, absMapName(), m_relPath, getMapLabel()))
{
- int mapId = DotManager::instance()->addMap(m_fileName, absMapName(), m_relPath, m_urlOnly, QCString(), getMapLabel());
+ int mapId = DotManager::instance()->
+ createFilePatcher(m_fileName)->
+ addMap(absMapName(), m_relPath, m_urlOnly, QCString(), getMapLabel());
t << "<!-- MAP " << mapId << " -->" << endl;
}
}
}
else if (m_graphFormat==GOF_EPS) // produce tex to include the .eps image
{
- if (m_regenerate || !writeVecGfxFigure(t,m_baseName,absBaseName()))
+ if (m_regenerate || !DotFilePatcher::writeVecGfxFigure(t,m_baseName,absBaseName()))
{
- int figId = DotManager::instance()->addFigure(m_fileName,m_baseName,absBaseName(),FALSE /*TRUE*/);
+ int figId = DotManager::instance()->
+ createFilePatcher(m_fileName)->
+ addFigure(m_baseName,absBaseName(),FALSE /*TRUE*/);
t << endl << "% FIG " << figId << endl;
}
}
@@ -264,6 +272,8 @@ void DotGraph::generateCode(FTextStream &t)
void DotGraph::writeGraphHeader(FTextStream &t,const QCString &title)
{
+ int fontSize = Config_getInt(DOT_FONTSIZE);
+ QCString fontName = Config_getString(DOT_FONTNAME);
t << "digraph ";
if (title.isEmpty())
{
@@ -284,12 +294,12 @@ void DotGraph::writeGraphHeader(FTextStream &t,const QCString &title)
{
t << " bgcolor=\"transparent\";" << endl;
}
- t << " edge [fontname=\"" << DOT_FONTNAME << "\","
- "fontsize=\"" << DOT_FONTSIZE << "\","
- "labelfontname=\"" << DOT_FONTNAME << "\","
- "labelfontsize=\"" << DOT_FONTSIZE << "\"];\n";
- t << " node [fontname=\"" << DOT_FONTNAME << "\","
- "fontsize=\"" << DOT_FONTSIZE << "\",shape=record];\n";
+ t << " edge [fontname=\"" << fontName << "\","
+ "fontsize=\"" << fontSize << "\","
+ "labelfontname=\"" << fontName << "\","
+ "labelfontsize=\"" << fontSize << "\"];\n";
+ t << " node [fontname=\"" << fontName << "\","
+ "fontsize=\"" << fontSize << "\",shape=record];\n";
}
void DotGraph::writeGraphFooter(FTextStream &t)
@@ -347,54 +357,3 @@ void DotGraph::computeGraph(DotNode *root,
graphStr=buf.data();
}
-bool DotGraph::writeVecGfxFigure(FTextStream &out,const QCString &baseName,
- const QCString &figureName)
-{
- int width=400,height=550;
- if (Config_getBool(USE_PDFLATEX))
- {
- if (!DotRunner::readBoundingBox(figureName+".pdf",&width,&height,FALSE))
- {
- //printf("writeVecGfxFigure()=0\n");
- return FALSE;
- }
- }
- else
- {
- if (!DotRunner::readBoundingBox(figureName+".eps",&width,&height,TRUE))
- {
- //printf("writeVecGfxFigure()=0\n");
- return FALSE;
- }
- }
- //printf("Got PDF/EPS size %d,%d\n",width,height);
- int maxWidth = 350; /* approx. page width in points, excl. margins */
- int maxHeight = 550; /* approx. page height in points, excl. margins */
- out << "\\nopagebreak\n"
- "\\begin{figure}[H]\n"
- "\\begin{center}\n"
- "\\leavevmode\n";
- if (width>maxWidth || height>maxHeight) // figure too big for page
- {
- // c*width/maxWidth > c*height/maxHeight, where c=maxWidth*maxHeight>0
- if (width*maxHeight>height*maxWidth)
- {
- out << "\\includegraphics[width=" << maxWidth << "pt]";
- }
- else
- {
- out << "\\includegraphics[height=" << maxHeight << "pt]";
- }
- }
- else
- {
- out << "\\includegraphics[width=" << width << "pt]";
- }
-
- out << "{" << baseName << "}\n"
- "\\end{center}\n"
- "\\end{figure}\n";
-
- //printf("writeVecGfxFigure()=1\n");
- return TRUE;
-}
diff --git a/src/dotgraph.h b/src/dotgraph.h
index 27d6938..0eda3a8 100644
--- a/src/dotgraph.h
+++ b/src/dotgraph.h
@@ -34,11 +34,6 @@ class DotGraph
DotGraph() : m_curNodeNumber(0), m_doNotAddImageToIndex(FALSE), m_noDivTag(FALSE), m_zoomable(TRUE), m_urlOnly(FALSE) {}
virtual ~DotGraph() {}
- static QCString DOT_FONTNAME; // will be initialized in initDot
- static int DOT_FONTSIZE; // will be initialized in initDot
-
- static bool writeVecGfxFigure(FTextStream& out, const QCString& baseName, const QCString& figureName);
-
protected:
/** returns node numbers. The Counter is reset by the constructor */
int getNextNodeNumber() { return ++m_curNodeNumber; }
@@ -72,10 +67,6 @@ class DotGraph
virtual void computeTheGraph() = 0;
- static QCString IMG_EXT;
-
- friend void initDot();
-
QCString absBaseName() const { return m_absPath + m_baseName; }
QCString absDotName() const { return m_absPath + m_baseName + ".dot"; }
QCString imgName() const;
diff --git a/src/dotgroupcollaboration.cpp b/src/dotgroupcollaboration.cpp
index be55ac0..f9a11e7 100644
--- a/src/dotgroupcollaboration.cpp
+++ b/src/dotgroupcollaboration.cpp
@@ -356,9 +356,10 @@ bool DotGroupCollaboration::isTrivial() const
return m_usedNodes->count() <= 1;
}
-void DotGroupCollaboration::writeGraphHeader(FTextStream &t,
- const QCString &title) const
+void DotGroupCollaboration::writeGraphHeader(FTextStream &t,const QCString &title) const
{
+ int fontSize = Config_getInt(DOT_FONTSIZE);
+ QCString fontName = Config_getString(DOT_FONTNAME);
t << "digraph ";
if (title.isEmpty())
{
@@ -374,8 +375,8 @@ void DotGroupCollaboration::writeGraphHeader(FTextStream &t,
{
t << " bgcolor=\"transparent\";" << endl;
}
- t << " edge [fontname=\"" << DOT_FONTNAME << "\",fontsize=\"" << DOT_FONTSIZE << "\","
- "labelfontname=\"" << DOT_FONTNAME << "\",labelfontsize=\"" << DOT_FONTSIZE << "\"];\n";
- t << " node [fontname=\"" << DOT_FONTNAME << "\",fontsize=\"" << DOT_FONTSIZE << "\",shape=box];\n";
+ t << " edge [fontname=\"" << fontName << "\",fontsize=\"" << fontSize << "\","
+ "labelfontname=\"" << fontName << "\",labelfontsize=\"" << fontSize << "\"];\n";
+ t << " node [fontname=\"" << fontName << "\",fontsize=\"" << fontSize << "\",shape=box];\n";
t << " rankdir=LR;\n";
}
diff --git a/src/dotlegendgraph.cpp b/src/dotlegendgraph.cpp
new file mode 100644
index 0000000..98e1f88
--- /dev/null
+++ b/src/dotlegendgraph.cpp
@@ -0,0 +1,72 @@
+/******************************************************************************
+*
+* Copyright (C) 1997-2019 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 "dotlegendgraph.h"
+#include "util.h"
+#include "config.h"
+#include "doxygen.h"
+#include "dot.h"
+#include "language.h"
+#include "dotfilepatcher.h"
+
+void DotLegendGraph::writeGraph(const char *path)
+{
+ FTextStream ts;
+ DotGraph::writeGraph(ts, GOF_BITMAP, EOF_Html, path, "", "", FALSE, 0);
+
+ if (getDotImageExtension()=="svg")
+ {
+ DotManager::instance()->
+ createFilePatcher(absBaseName()+Config_getString(HTML_FILE_EXTENSION))->
+ addSVGObject("graph_legend", absImgName(),QCString());
+ }
+}
+
+QCString DotLegendGraph::getBaseName() const
+{
+ return "graph_legend";
+}
+
+void DotLegendGraph::computeTheGraph()
+{
+ int fontSize = Config_getInt(DOT_FONTSIZE);
+ QCString fontName = Config_getString(DOT_FONTNAME);
+ FTextStream md5stream(&m_theGraph);
+ writeGraphHeader(md5stream,theTranslator->trLegendTitle());
+ md5stream << " Node9 [shape=\"box\",label=\"Inherited\",fontsize=\"" << fontSize << "\",height=0.2,width=0.4,fontname=\"" << fontName << "\",fillcolor=\"grey75\",style=\"filled\" fontcolor=\"black\"];\n";
+ md5stream << " Node10 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << fontSize << "\",style=\"solid\",fontname=\"" << fontName << "\"];\n";
+ md5stream << " Node10 [shape=\"box\",label=\"PublicBase\",fontsize=\"" << fontSize << "\",height=0.2,width=0.4,fontname=\"" << fontName << "\",color=\"black\"];\n";
+ md5stream << " Node11 -> Node10 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << fontSize << "\",style=\"solid\",fontname=\"" << fontName << "\"];\n";
+ md5stream << " Node11 [shape=\"box\",label=\"Truncated\",fontsize=\"" << fontSize << "\",height=0.2,width=0.4,fontname=\"" << fontName << "\",color=\"red\"];\n";
+ md5stream << " Node13 -> Node9 [dir=\"back\",color=\"darkgreen\",fontsize=\"" << fontSize << "\",style=\"solid\",fontname=\"" << fontName << "\"];\n";
+ md5stream << " Node13 [shape=\"box\",label=\"ProtectedBase\",fontsize=\"" << fontSize << "\",height=0.2,width=0.4,fontname=\"" << fontName << "\",color=\"black\"];\n";
+ md5stream << " Node14 -> Node9 [dir=\"back\",color=\"firebrick4\",fontsize=\"" << fontSize << "\",style=\"solid\",fontname=\"" << fontName << "\"];\n";
+ md5stream << " Node14 [shape=\"box\",label=\"PrivateBase\",fontsize=\"" << fontSize << "\",height=0.2,width=0.4,fontname=\"" << fontName << "\",color=\"black\"];\n";
+ md5stream << " Node15 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << fontSize << "\",style=\"solid\",fontname=\"" << fontName << "\"];\n";
+ md5stream << " Node15 [shape=\"box\",label=\"Undocumented\",fontsize=\"" << fontSize << "\",height=0.2,width=0.4,fontname=\"" << fontName << "\",color=\"grey75\"];\n";
+ md5stream << " Node16 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" << fontSize << "\",style=\"solid\",fontname=\"" << fontName << "\"];\n";
+ md5stream << " Node16 [shape=\"box\",label=\"Templ< int >\",fontsize=\"" << fontSize << "\",height=0.2,width=0.4,fontname=\"" << fontName << "\",color=\"black\"];\n";
+ md5stream << " Node17 -> Node16 [dir=\"back\",color=\"orange\",fontsize=\"" << fontSize << "\",style=\"dashed\",label=\"< int >\",fontname=\"" << fontName << "\"];\n";
+ md5stream << " Node17 [shape=\"box\",label=\"Templ< T >\",fontsize=\"" << fontSize << "\",height=0.2,width=0.4,fontname=\"" << fontName << "\",color=\"black\"];\n";
+ md5stream << " Node18 -> Node9 [dir=\"back\",color=\"darkorchid3\",fontsize=\"" << fontSize << "\",style=\"dashed\",label=\"m_usedClass\",fontname=\"" << fontName << "\"];\n";
+ md5stream << " Node18 [shape=\"box\",label=\"Used\",fontsize=\"" << fontSize << "\",height=0.2,width=0.4,fontname=\"" << fontName << "\",color=\"black\"];\n";
+ writeGraphFooter(md5stream);
+}
+
+QCString DotLegendGraph::getMapLabel() const
+{
+ return "";
+}
+
diff --git a/src/dotlegendgraph.h b/src/dotlegendgraph.h
new file mode 100644
index 0000000..2d8eeec
--- /dev/null
+++ b/src/dotlegendgraph.h
@@ -0,0 +1,35 @@
+/******************************************************************************
+*
+* Copyright (C) 1997-2019 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.
+*
+*/
+
+#ifndef DOTLEGENDGRAPH_H
+#define DOTLEGENDGRAPH_H
+
+#include "dotgraph.h"
+
+/** Representation of a legend explaining the meaning of boxes, arrows, and colors */
+class DotLegendGraph : public DotGraph
+{
+ public:
+ void writeGraph(const char *path);
+
+ private:
+ virtual QCString getBaseName() const;
+ virtual void computeTheGraph();
+ virtual QCString getMapLabel() const;
+
+};
+
+#endif
+
diff --git a/src/dotnode.cpp b/src/dotnode.cpp
index ae06fb2..491bcb5 100644
--- a/src/dotnode.cpp
+++ b/src/dotnode.cpp
@@ -540,7 +540,7 @@ void DotNode::writeArrow(FTextStream &t,
if (pointBack && !umlUseArrow) t << "dir=\"back\",";
t << "color=\"" << eProps->edgeColorMap[ei->color()]
- << "\",fontsize=\"" << DotGraph::DOT_FONTSIZE << "\",";
+ << "\",fontsize=\"" << Config_getInt(DOT_FONTSIZE) << "\",";
t << "style=\"" << eProps->edgeStyleMap[ei->style()] << "\"";
if (!ei->label().isEmpty())
{
@@ -559,7 +559,7 @@ void DotNode::writeArrow(FTextStream &t,
t << ",arrowhead=\"" << eProps->arrowStyleMap[ei->color()] << "\"";
}
- if (format==GOF_BITMAP) t << ",fontname=\"" << DotGraph::DOT_FONTNAME << "\"";
+ if (format==GOF_BITMAP) t << ",fontname=\"" << Config_getString(DOT_FONTNAME) << "\"";
t << "];" << endl;
}
diff --git a/src/dotrunner.cpp b/src/dotrunner.cpp
index 3a621c7..c01a4e5 100644
--- a/src/dotrunner.cpp
+++ b/src/dotrunner.cpp
@@ -28,6 +28,7 @@
#define MAX_LATEX_GRAPH_INCH 150
#define MAX_LATEX_GRAPH_SIZE (MAX_LATEX_GRAPH_INCH * 72)
+//-----------------------------------------------------------------------------------------
// since dot silently reproduces the input file when it does not
// support the PNG format, we need to check the result.
@@ -142,12 +143,11 @@ bool DotRunner::readBoundingBox(const char *fileName,int *width,int *height,bool
return FALSE;
}
-bool DotRunner::DOT_CLEANUP;
-bool DotRunner::DOT_MULTI_TARGETS;
-DotConstString DotRunner::DOT_EXE;
+//---------------------------------------------------------------------------------
DotRunner::DotRunner(const QCString& absDotName, const QCString& md5Hash)
- : m_file(absDotName), m_md5Hash(md5Hash), m_cleanUp(DOT_CLEANUP)
+ : m_file(absDotName), m_md5Hash(md5Hash), m_cleanUp(Config_getBool(DOT_CLEANUP)),
+ m_dotExe(Config_getString(DOT_PATH)+"dot")
{
m_jobs.setAutoDelete(TRUE);
}
@@ -183,7 +183,7 @@ bool DotRunner::run()
DotJob *s;
// create output
- if (DOT_MULTI_TARGETS)
+ if (Config_getBool(DOT_MULTI_TARGETS))
{
dotArgs=QCString("\"")+m_file.data()+"\"";
for (li.toFirst();(s=li.current());++li)
@@ -191,14 +191,14 @@ bool DotRunner::run()
dotArgs+=' ';
dotArgs+=s->args.data();
}
- if ((exitCode=portable_system(DOT_EXE.data(),dotArgs,FALSE))!=0) goto error;
+ if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error;
}
else
{
for (li.toFirst();(s=li.current());++li)
{
dotArgs=QCString("\"")+m_file.data()+"\" "+s->args.data();
- if ((exitCode=portable_system(DOT_EXE.data(),dotArgs,FALSE))!=0) goto error;
+ if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error;
}
}
@@ -214,7 +214,7 @@ bool DotRunner::run()
{
if (!resetPDFSize(width,height,getBaseNameOfOutput(s->output.data()))) goto error;
dotArgs=QCString("\"")+m_file.data()+"\" "+s->args.data();
- if ((exitCode=portable_system(DOT_EXE.data(),dotArgs,FALSE))!=0) goto error;
+ if ((exitCode=portable_system(m_dotExe.data(),dotArgs,FALSE))!=0) goto error;
}
}
@@ -245,7 +245,7 @@ bool DotRunner::run()
return TRUE;
error:
err("Problems running dot: exit code=%d, command='%s', arguments='%s'\n",
- exitCode,DOT_EXE.data(),dotArgs.data());
+ exitCode,m_dotExe.data(),dotArgs.data());
return FALSE;
}
diff --git a/src/dotrunner.h b/src/dotrunner.h
index 4128fe8..1b68c18 100644
--- a/src/dotrunner.h
+++ b/src/dotrunner.h
@@ -34,7 +34,6 @@ class DotConstString
DotConstString(const DotConstString &s) : m_str(0) { set(s.data()); }
const char *data() const { return m_str; }
bool isEmpty() const { return m_str==0 || m_str[0]=='\0'; }
- void init(const char *s) { set(s); }
private:
void set(char const* s)
@@ -101,14 +100,9 @@ class DotRunner
private:
DotConstString m_file;
DotConstString m_md5Hash;
+ DotConstString m_dotExe;
bool m_cleanUp;
QList<DotJob> m_jobs;
-
- static bool DOT_CLEANUP;
- static bool DOT_MULTI_TARGETS;
- static DotConstString DOT_EXE;
- friend void initDot();
-
};
/** Queue of dot jobs to run. */
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index a6455fc..f8e54de 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -11680,7 +11680,6 @@ void generateOutput()
}
initSearchIndexer();
- initDot();
bool generateHtml = Config_getBool(GENERATE_HTML);
bool generateLatex = Config_getBool(GENERATE_LATEX);
diff --git a/src/formula.cpp b/src/formula.cpp
index 1c5042e..534f56a 100644
--- a/src/formula.cpp
+++ b/src/formula.cpp
@@ -118,11 +118,12 @@ void FormulaList::generateBitmaps(const char *path)
int pageNum=*pagePtr;
msg("Generating image form_%d.png for formula\n",pageNum);
char dviArgs[4096];
+ char psArgs[4096];
QCString formBase;
formBase.sprintf("_form%d",pageNum);
// run dvips to convert the page with number pageIndex to an
- // encapsulated postscript.
- sprintf(dviArgs,"-q -D 600 -E -n 1 -p %d -o %s.eps _formulas.dvi",
+ // postscript file.
+ sprintf(dviArgs,"-q -D 600 -n 1 -p %d -o %s_tmp.ps _formulas.dvi",
pageIndex,formBase.data());
portable_sysTimerStart();
if (portable_system("dvips",dviArgs)!=0)
@@ -133,6 +134,18 @@ void FormulaList::generateBitmaps(const char *path)
return;
}
portable_sysTimerStop();
+ // run ps2epsi to convert to an encapsulated postscript file with
+ // boundingbox (dvips with -E has some problems here).
+ sprintf(psArgs,"%s_tmp.ps %s.eps",formBase.data(),formBase.data());
+ portable_sysTimerStart();
+ if (portable_system("ps2epsi",psArgs)!=0)
+ {
+ err("Problems running ps2epsi. Check your installation!\n");
+ portable_sysTimerStop();
+ QDir::setCurrent(oldDir);
+ return;
+ }
+ portable_sysTimerStop();
// now we read the generated postscript file to extract the bounding box
QFileInfo fi(formBase+".eps");
if (fi.exists())
@@ -282,6 +295,7 @@ void FormulaList::generateBitmaps(const char *path)
f.close();
}
// remove intermediate image files
+ thisDir.remove(formBase+"_tmp.ps");
thisDir.remove(formBase+".eps");
thisDir.remove(formBase+".pnm");
thisDir.remove(formBase+".ps");
diff --git a/src/fortrancode.l b/src/fortrancode.l
index 38188ef..eee4d47 100644
--- a/src/fortrancode.l
+++ b/src/fortrancode.l
@@ -166,6 +166,8 @@ static int inTypeDecl = 0;
static bool g_endComment;
+static const char *stateToString(int state);
+
static void endFontClass()
{
if (g_currentFontClass)
@@ -1405,3 +1407,4 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
+#include "fortrancode.l.h"
diff --git a/src/fortranscanner.l b/src/fortranscanner.l
index 09c4490..38abb89 100644
--- a/src/fortranscanner.l
+++ b/src/fortranscanner.l
@@ -2882,47 +2882,4 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
-#define scanStateToString(x) case x: resultString = #x; break;
-static const char *stateToString(int state)
-{
- const char *resultString;
- switch(state)
- {
- scanStateToString(INITIAL)
- scanStateToString(Subprog)
- scanStateToString(SubprogPrefix)
- scanStateToString(Parameterlist)
- scanStateToString(SubprogBody)
- scanStateToString(SubprogBodyContains)
- scanStateToString(Start)
- scanStateToString(Comment)
- scanStateToString(Module)
- scanStateToString(Program)
- scanStateToString(ModuleBody)
- scanStateToString(ModuleBodyContains)
- scanStateToString(AttributeList)
- scanStateToString(Variable)
- scanStateToString(Initialization)
- scanStateToString(ArrayInitializer)
- scanStateToString(Enum)
- scanStateToString(Typedef)
- scanStateToString(TypedefBody)
- scanStateToString(TypedefBodyContains)
- scanStateToString(InterfaceBody)
- scanStateToString(StrIgnore)
- scanStateToString(String)
- scanStateToString(Use)
- scanStateToString(UseOnly)
- scanStateToString(ModuleProcedure)
- scanStateToString(Prepass)
- scanStateToString(DocBlock)
- scanStateToString(DocBackLine)
- scanStateToString(EndDoc)
- scanStateToString(BlockData)
- scanStateToString(Prototype)
- scanStateToString(PrototypeSubprog)
- scanStateToString(PrototypeArgs)
- default: resultString = "Unknown"; break;
- }
- return resultString;
-}
+#include "fortranscanner.l.h"
diff --git a/src/index.cpp b/src/index.cpp
index 0631ee4..f5faea4 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -41,6 +41,7 @@
#include "ftvhelp.h"
#include "dot.h"
#include "dotgfxhierarchytable.h"
+#include "dotlegendgraph.h"
#include "pagedef.h"
#include "dirdef.h"
#include "vhdldocgen.h"
@@ -3919,7 +3920,9 @@ void writeGraphInfo(OutputList &ol)
if (!Config_getBool(HAVE_DOT) || !Config_getBool(GENERATE_HTML)) return;
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
- generateGraphLegend(Config_getString(HTML_OUTPUT));
+
+ DotLegendGraph gd;
+ gd.writeGraph(Config_getString(HTML_OUTPUT));
bool &stripCommentsStateRef = Config_getBool(STRIP_CODE_COMMENTS);
bool oldStripCommentsState = stripCommentsStateRef;
@@ -3944,7 +3947,7 @@ void writeGraphInfo(OutputList &ol)
legendDocs = legendDocs.left(s+8) + "[!-- SVG 0 --]\n" + legendDocs.mid(e);
//printf("legendDocs=%s\n",legendDocs.data());
}
- FileDef *fd = createFileDef("","graph_legend");
+ FileDef *fd = createFileDef("","graph_legend.dox");
ol.generateDoc("graph_legend",1,fd,0,legendDocs,FALSE,FALSE);
delete fd;
diff --git a/src/markdown.cpp b/src/markdown.cpp
index 3ee1b71..48f3dbc 100644
--- a/src/markdown.cpp
+++ b/src/markdown.cpp
@@ -2069,7 +2069,7 @@ static int writeCodeBlock(GrowBuf &out,const char *data,int size,int refIndent)
emptyLines++;
i=end;
}
- else if (indent>=refIndent+codeBlockIndent) // enough indent to contine the code block
+ else if (indent>=refIndent+codeBlockIndent) // enough indent to continue the code block
{
while (emptyLines>0) // write skipped empty lines
{
diff --git a/src/pre.l b/src/pre.l
index 596108f..c413a11 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -62,6 +62,8 @@
//#define DBG_CTX(x) fprintf x
#define DBG_CTX(x) do { } while(0)
+static const char *stateToString(int state);
+
struct CondCtx
{
CondCtx(int line,QCString id,bool b)
@@ -3337,3 +3339,4 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
+#include "pre.l.h"
diff --git a/src/pycode.l b/src/pycode.l
index 0f04baa..a76129d 100644
--- a/src/pycode.l
+++ b/src/pycode.l
@@ -97,6 +97,7 @@ static bool g_endComment;
static void endFontClass();
static void adjustScopesAndSuites(unsigned indentLength);
+static const char *stateToString(int state);
/*! Represents a stack of variable to class mappings as found in the
@@ -1646,3 +1647,4 @@ extern "C" { // some bogus code to keep the compiler happy
#error "You seem to be using a version of flex newer than 2.5.4. These are currently incompatible with 2.5.4, and do NOT work with doxygen! Please use version 2.5.4 or expect things to be parsed wrongly! A bug report has been submitted (#732132)."
#endif
+#include "pycode.l.h"
diff --git a/src/pyscanner.l b/src/pyscanner.l
index 3fe66f2..2320bca 100644
--- a/src/pyscanner.l
+++ b/src/pyscanner.l
@@ -123,6 +123,7 @@ static int g_search_count = 0;
static QCString g_argType = "";
static bool g_funcParamsEnd;
//-----------------------------------------------------------------------------
+static const char *stateToString(int state);
static void initParser()
@@ -1994,3 +1995,4 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
+#include "pyscanner.l.h"
diff --git a/src/scan_states.py b/src/scan_states.py
new file mode 100644
index 0000000..e156b97
--- /dev/null
+++ b/src/scan_states.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+# python script to generate an overview of the staes based on the input lex file.
+#
+# Copyright (C) 1997-2019 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.
+#
+import sys
+import os
+import re
+
+
+def main():
+ if len(sys.argv)!=2:
+ sys.exit('Usage: %s <lex_file>' % sys.argv[0])
+
+ lex_file = sys.argv[1]
+ if (os.path.exists(lex_file)):
+ #write preamble
+ print("static const char *stateToString(int state)")
+ print("{")
+ print(" switch(state)")
+ print(" {")
+ print(" case INITIAL: return \"INITIAL\";")
+
+ with open(lex_file) as f:
+ for line in f:
+ if re.search(r'^%x', line) or re.search(r'^%s', line):
+ state = line.split()[1]
+ print(" case %s: return \"%s\";" % (state,state))
+ elif re.search(r'^%%', line):
+ break
+ else:
+ pass
+ f.close()
+ #write post
+ print(" }")
+ print(" return \"Unknown\";")
+ print("}")
+
+if __name__ == '__main__':
+ main()
diff --git a/src/scanner.l b/src/scanner.l
index 75786ef..f6ffdff 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -193,6 +193,7 @@ static int g_column;
static int g_fencedSize=0;
static bool g_nestedComment=0;
+static const char *stateToString(int state);
//-----------------------------------------------------------------------------
// forward declarations
@@ -7490,3 +7491,4 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
+#include "scanner.l.h"
diff --git a/src/sqlcode.l b/src/sqlcode.l
index eec9732..2685c46 100644
--- a/src/sqlcode.l
+++ b/src/sqlcode.l
@@ -63,6 +63,7 @@ struct sqlcodeYY_state
};
static void codify(const char* text);
+static const char *stateToString(int state);
static void setCurrentDoc(const QCString &anchor,yyscan_t yyscanner);
static void startCodeLine(yyscan_t yyscanner);
static void endFontClass(yyscan_t yyscanner);
@@ -461,3 +462,4 @@ extern "C" { // some bogus code to keep the compiler happy
#error "You seem to be using a version of flex newer than 2.5.4. These are currently incompatible with 2.5.4, and do NOT work with doxygen! Please use version 2.5.4 or expect things to be parsed wrongly! A bug report has been submitted (#732132)."
#endif
+#include "sqlcode.l.h"
diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp
index 012a0c0..49818b2 100644
--- a/src/sqlite3gen.cpp
+++ b/src/sqlite3gen.cpp
@@ -127,7 +127,7 @@ const char * table_schema[][2] = {
* I rolled this back when I had trouble getting a FileDef for all types
* (PageDef in particular).
*
- * Note: all colums referencing path would need an update.
+ * Note: all columns referencing path would need an update.
*/
{ "path",
"CREATE TABLE IF NOT EXISTS path (\n"
@@ -233,7 +233,7 @@ const char * table_schema[][2] = {
},
{ "reimplements",
"CREATE TABLE IF NOT EXISTS reimplements (\n"
- "\t-- Inherited member reimplmentation relations.\n"
+ "\t-- Inherited member reimplementation relations.\n"
"\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
"\tmemberdef_rowid INTEGER NOT NULL REFERENCES memberdef, -- reimplementing memberdef id.\n"
"\treimplemented_rowid INTEGER NOT NULL REFERENCES memberdef, -- reimplemented memberdef id.\n"
diff --git a/src/tclscanner.l b/src/tclscanner.l
index 88bd474..a680cf9 100644
--- a/src/tclscanner.l
+++ b/src/tclscanner.l
@@ -59,6 +59,8 @@
#define MAX_INCLUDE_DEPTH 10
+static const char *stateToString(int state);
+
//! Application error.
#define tcl_err \
printf("Error %d %s() at line %d! ",__LINE__,tcl.file_name.data(),yylineno); \
@@ -3121,3 +3123,4 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
+#include "tclscanner.l.h"
diff --git a/src/util.cpp b/src/util.cpp
index 8816de1..4dc7c71 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -9051,9 +9051,9 @@ bool mainPageHasTitle()
QCString getDotImageExtension(void)
{
- QCString imgExt = Config_getEnum(DOT_IMAGE_FORMAT);
- imgExt = imgExt.replace( QRegExp(":.*"), "" );
- return imgExt;
+ QCString imgExt = Config_getEnum(DOT_IMAGE_FORMAT);
+ int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
+ return i==-1 ? imgExt : imgExt.left(i);
}
bool openOutputFile(const char *outFile,QFile &f)
diff --git a/src/vhdlcode.l b/src/vhdlcode.l
index 5f668c6..03bf883 100644
--- a/src/vhdlcode.l
+++ b/src/vhdlcode.l
@@ -112,6 +112,7 @@ static bool writeColoredWord(QCString& word );
static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool typeOnly=FALSE, const char *curr_class=0);
static void endFontClass();
static void startFontClass(const char *s);
+static const char *stateToString(int state);
//-------------------------------------------------------------------
@@ -1646,6 +1647,5 @@ extern "C" { // some bogus code to keep the compiler happy
#error "You seem to be using a version of flex newer than 2.5.4 but older than 2.5.33. These versions do NOT work with doxygen! Please use version <=2.5.4 or >=2.5.33 or expect things to be parsed wrongly!"
#endif
-
-
+#include "vhdlcode.l.h"
diff --git a/src/xmlcode.l b/src/xmlcode.l
index 42218b1..bd6e8a8 100644
--- a/src/xmlcode.l
+++ b/src/xmlcode.l
@@ -69,6 +69,8 @@ static MemberDef * g_currentMemberDef;
static bool g_includeCodeFragment;
static const char * g_currentFontClass;
+static const char *stateToString(int state);
+
static void codify(const char* text)
{
g_code->codify(text);
@@ -413,3 +415,4 @@ extern "C" { // some bogus code to keep the compiler happy
#error "You seem to be using a version of flex newer than 2.5.4. These are currently incompatible with 2.5.4, and do NOT work with doxygen! Please use version 2.5.4 or expect things to be parsed wrongly! A bug report has been submitted (#732132)."
#endif
+#include "xmlcode.l.h"