summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/classdef.cpp124
-rw-r--r--src/classdef.h4
-rw-r--r--src/code.l2
-rw-r--r--src/config.h6
-rw-r--r--src/config.l78
-rw-r--r--src/definition.cpp4
-rw-r--r--src/definition.h2
-rw-r--r--src/diagram.cpp19
-rw-r--r--src/dot.cpp32
-rw-r--r--src/doxygen.cpp194
-rw-r--r--src/doxygen.dtd115
-rw-r--r--src/doxygen.pro.in7
-rw-r--r--src/doxygen.t2
-rw-r--r--src/entry.cpp4
-rw-r--r--src/entry.h2
-rw-r--r--src/filedef.cpp81
-rw-r--r--src/filedef.h4
-rw-r--r--src/filename.cpp11
-rw-r--r--src/formula.cpp46
-rw-r--r--src/index.cpp8
-rw-r--r--src/latexgen.cpp50
-rw-r--r--src/memberdef.cpp217
-rw-r--r--src/memberdef.h3
-rw-r--r--src/outputgen.h6
-rw-r--r--src/reflist.cpp86
-rw-r--r--src/reflist.h55
-rw-r--r--src/rtfgen.cpp10
-rw-r--r--src/scanner.l272
-rw-r--r--src/translator.h16
-rw-r--r--src/translator_de.h128
-rw-r--r--src/translator_nl.h16
-rw-r--r--src/util.cpp81
-rw-r--r--src/util.h68
-rw-r--r--src/xml.cpp139
-rw-r--r--src/xml.h25
-rw-r--r--src/xml_dtd.h115
36 files changed, 1800 insertions, 232 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 8fd8d92..928860a 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -33,6 +33,7 @@
#include "example.h"
#include "outputlist.h"
#include "dot.h"
+#include "xml.h"
static QCString stripExtension(const char *fName)
{
@@ -1763,3 +1764,126 @@ void ClassDef::determineIntfUsageRelation()
}
}
#endif
+
+void ClassDef::generateXMLSection(QTextStream &t,MemberList *ml,const char *type)
+{
+ if (ml->count()>0)
+ {
+ t << " <sectiondef type=\"" << type << "\">" << endl;
+ t << " <memberlist>" << endl;
+ MemberListIterator mli(*ml);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ md->generateXML(t,this);
+ }
+ t << " </memberlist>" << endl;
+ t << " </sectiondef>" << endl;
+ }
+}
+
+void ClassDef::generateXML(QTextStream &t)
+{
+ t << " <compounddef id=\""
+ << getOutputFileBase() << "\" type=\"";
+ switch(compType)
+ {
+ case Class: t << "class"; break;
+ case Struct: t << "struct"; break;
+ case Union: t << "union"; break;
+ default: t << "interface"; break;
+ }
+ t << "\">" << endl;
+ t << " <compoundname>";
+ writeXMLString(t,name());
+ t << "</compoundname>" << endl;
+ if (inherits->count()>0)
+ {
+ t << " <basecompoundlist>" << endl;
+ BaseClassListIterator bcli(*inherits);
+ BaseClassDef *bcd;
+ for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ {
+ t << " <basecompoundref idref=\""
+ << bcd->classDef->getOutputFileBase()
+ << "\" prot=\"";
+ switch (bcd->prot)
+ {
+ case Public: t << "public"; break;
+ case Protected: t << "protected"; break;
+ case Private: t << "private"; break;
+ }
+ t << "\" virt=\"";
+ switch(bcd->virt)
+ {
+ case Normal: t << "non-virtual"; break;
+ case Virtual: t << "virtual"; break;
+ case Pure: t <<"pure-virtual"; break;
+ }
+ t << "\"/>" << endl;
+ }
+ t << " </basecompoundlist>" << endl;
+ }
+ if (inheritedBy->count()>0)
+ {
+ t << " <derivedcompoundlist>" << endl;
+ BaseClassListIterator bcli(*inheritedBy);
+ BaseClassDef *bcd;
+ for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ {
+ t << " <derivedcompoundref idref=\""
+ << bcd->classDef->getOutputFileBase()
+ << "\" prot=\"";
+ switch (bcd->prot)
+ {
+ case Public: t << "public"; break;
+ case Protected: t << "protected"; break;
+ case Private: t << "private"; break;
+ }
+ t << "\" virt=\"";
+ switch(bcd->virt)
+ {
+ case Normal: t << "non-virtual"; break;
+ case Virtual: t << "virtual"; break;
+ case Pure: t << "pure-virtual"; break;
+ }
+ t << "\"/>" << endl;
+ }
+ t << " </derivedcompoundlist>" << endl;
+ }
+ int numMembers =
+ pubTypes.count()+pubMembers.count()+pubAttribs.count()+
+ pubSlots.count()+signals.count()+pubStaticMembers.count()+
+ pubStaticAttribs.count()+proTypes.count()+proMembers.count()+
+ proAttribs.count()+proSlots.count()+proStaticMembers.count()+
+ proStaticAttribs.count()+priTypes.count()+priMembers.count()+
+ priAttribs.count()+priSlots.count()+priStaticMembers.count()+
+ priStaticAttribs.count()+friends.count()+related.count();
+ if (numMembers>0)
+ {
+ t << " <sectionlist>" << endl;
+ generateXMLSection(t,&pubTypes,"public-type");
+ generateXMLSection(t,&pubMembers,"public-func");
+ generateXMLSection(t,&pubAttribs,"public-attrib");
+ generateXMLSection(t,&pubSlots,"public-slot");
+ generateXMLSection(t,&signals,"signal");
+ generateXMLSection(t,&pubStaticMembers,"public-static-func");
+ generateXMLSection(t,&pubStaticAttribs,"public-static-attrib");
+ generateXMLSection(t,&proTypes,"protected-type");
+ generateXMLSection(t,&proMembers,"protected-func");
+ generateXMLSection(t,&proAttribs,"protected-attrib");
+ generateXMLSection(t,&proSlots,"protected-slot");
+ generateXMLSection(t,&proStaticMembers,"protected-static-func");
+ generateXMLSection(t,&proStaticAttribs,"protected-static-attrib");
+ generateXMLSection(t,&priTypes,"private-type");
+ generateXMLSection(t,&priMembers,"private-func");
+ generateXMLSection(t,&priAttribs,"private-attrib");
+ generateXMLSection(t,&priSlots,"private-slot");
+ generateXMLSection(t,&priStaticMembers,"private-static-func");
+ generateXMLSection(t,&priStaticAttribs,"private-static-attrib");
+ generateXMLSection(t,&friends,"signal");
+ generateXMLSection(t,&related,"related");
+ t << " </sectionlist>" << endl;
+ }
+ t << " </compounddef>" << endl;
+}
diff --git a/src/classdef.h b/src/classdef.h
index a52173d..a0a494d 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -42,6 +42,7 @@ class MemberNameInfoDict;
class UsesClassDict;
class MemberGroupList;
class MemberGroupDict;
+class QTextStream;
struct IncludeInfo;
class ClassDef : public Definition
@@ -126,6 +127,9 @@ class ClassDef : public Definition
void addMembersToMemberGroup();
void distributeMemberGroupDocumentation();
+
+ void generateXML(QTextStream &t);
+ void generateXMLSection(QTextStream &t,MemberList *ml,const char *type);
protected:
void addUsedInterfaceClasses(MemberDef *md,const char *typeStr);
diff --git a/src/code.l b/src/code.l
index db0f554..ae0beeb 100644
--- a/src/code.l
+++ b/src/code.l
@@ -1506,7 +1506,7 @@ void parseCode(OutputList &ol,const char *className,const QCString &s,
g_searchingForBody = FALSE;
g_insideBody = FALSE;
g_bracketCount = 0;
- g_exampleFile = convertSlashes(g_exampleName,TRUE)+"-example";
+ g_exampleFile = convertFileName(g_exampleName)+"-example";
g_includeCodeFragment = inlineFragment;
startCodeLine(*g_code);
g_type.resize(0);
diff --git a/src/config.h b/src/config.h
index a7c220d..7bd72a7 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,4 +1,4 @@
-/* This file was generated by configgen on Fri Jul 14 20:01:34 2000
+/* This file was generated by configgen on Fri Jul 28 19:43:36 2000
* from config_templ.h
*
* DO NOT EDIT!
@@ -67,6 +67,8 @@ struct Config
static bool sortMembersFlag; // sort members alphabetically?
static int tabSize; // number of spaces in a tab
static QStrList sectionFilterList; // list of section filters that are enabled
+ static bool generateTodoList; // do we want a todo list?
+ static bool generateTestList; // do we want a test list?
static bool quietFlag; // generate progress messages flag
static bool warningFlag; // generate warnings flag
static bool warningUndocFlag; // generate undocumented warnings
@@ -97,6 +99,7 @@ struct Config
static QStrList extraPackageList; // list of extra LaTeX packages.
static QCString latexHeaderFile; // the name of the personal LaTeX header
static bool pdfHyperFlag; // generate latex prepared creating hyperlinked pdfs.
+ static bool usePDFLatexFlag; // use pdflatex instead of plain latex
static bool latexBatchModeFlag; // continue after latex errors?
static bool generateRTF; // generate RTF flag
static QCString rtfOutputDir; // the directory to put the RTF files
@@ -106,6 +109,7 @@ struct Config
static bool generateMan; // generate Man pages
static QCString manOutputDir; // the directory to put the man pages
static QCString manExtension; // extension the man page files
+ static bool generateXML; // generate XML output
static bool preprocessingFlag; // enable preprocessing
static bool macroExpansionFlag; // expand macros in the source.
static bool onlyPredefinedFlag; // expand only predefined macros
diff --git a/src/config.l b/src/config.l
index 8c864ff..06521d3 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1,4 +1,4 @@
-/* This file was generated by configgen on Fri Jul 14 20:01:34 2000
+/* This file was generated by configgen on Fri Jul 28 19:43:36 2000
* from config_templ.l
*
* DO NOT EDIT!
@@ -102,6 +102,8 @@ bool Config::inlineInfoFlag = TRUE;
bool Config::sortMembersFlag = TRUE;
int Config::tabSize = 8;
QStrList Config::sectionFilterList;
+bool Config::generateTodoList = TRUE;
+bool Config::generateTestList = TRUE;
bool Config::quietFlag = FALSE;
bool Config::warningFlag = TRUE;
bool Config::warningUndocFlag = TRUE;
@@ -132,6 +134,7 @@ QCString Config::paperType = "a4wide";
QStrList Config::extraPackageList;
QCString Config::latexHeaderFile;
bool Config::pdfHyperFlag = FALSE;
+bool Config::usePDFLatexFlag = FALSE;
bool Config::latexBatchModeFlag = FALSE;
bool Config::generateRTF = TRUE;
QCString Config::rtfOutputDir = "rtf";
@@ -141,6 +144,7 @@ QCString Config::rtfStylesheetFile;
bool Config::generateMan = TRUE;
QCString Config::manOutputDir = "man";
QCString Config::manExtension = ".3";
+bool Config::generateXML = FALSE;
bool Config::preprocessingFlag = TRUE;
bool Config::macroExpansionFlag = FALSE;
bool Config::onlyPredefinedFlag = FALSE;
@@ -251,6 +255,8 @@ static int yyread(char *buf,int max_size)
<Start>"SORT_MEMBER_DOCS"[ \t]*"=" { BEGIN(GetBool); b=&Config::sortMembersFlag; }
<Start>"TAB_SIZE"[ \t]*"=" { BEGIN(GetString); s=&tabSizeString; s->resize(0); }
<Start>"ENABLED_SECTIONS"[ \t]*"=" { BEGIN(GetStrList); l=&Config::sectionFilterList; l->clear(); elemStr=""; }
+<Start>"GENERATE_TODOLIST"[ \t]*"=" { BEGIN(GetBool); b=&Config::generateTodoList; }
+<Start>"GENERATE_TESTLIST"[ \t]*"=" { BEGIN(GetBool); b=&Config::generateTestList; }
<Start>"QUIET"[ \t]*"=" { BEGIN(GetBool); b=&Config::quietFlag; }
<Start>"WARNINGS"[ \t]*"=" { BEGIN(GetBool); b=&Config::warningFlag; }
<Start>"WARN_IF_UNDOCUMENTED"[ \t]*"=" { BEGIN(GetBool); b=&Config::warningUndocFlag; }
@@ -281,6 +287,7 @@ static int yyread(char *buf,int max_size)
<Start>"EXTRA_PACKAGES"[ \t]*"=" { BEGIN(GetStrList); l=&Config::extraPackageList; l->clear(); elemStr=""; }
<Start>"LATEX_HEADER"[ \t]*"=" { BEGIN(GetString); s=&Config::latexHeaderFile; s->resize(0); }
<Start>"PDF_HYPERLINKS"[ \t]*"=" { BEGIN(GetBool); b=&Config::pdfHyperFlag; }
+<Start>"USE_PDFLATEX"[ \t]*"=" { BEGIN(GetBool); b=&Config::usePDFLatexFlag; }
<Start>"LATEX_BATCHMODE"[ \t]*"=" { BEGIN(GetBool); b=&Config::latexBatchModeFlag; }
<Start>"GENERATE_RTF"[ \t]*"=" { BEGIN(GetBool); b=&Config::generateRTF; }
<Start>"RTF_OUTPUT"[ \t]*"=" { BEGIN(GetString); s=&Config::rtfOutputDir; s->resize(0); }
@@ -290,6 +297,7 @@ static int yyread(char *buf,int max_size)
<Start>"GENERATE_MAN"[ \t]*"=" { BEGIN(GetBool); b=&Config::generateMan; }
<Start>"MAN_OUTPUT"[ \t]*"=" { BEGIN(GetString); s=&Config::manOutputDir; s->resize(0); }
<Start>"MAN_EXTENSION"[ \t]*"=" { BEGIN(GetString); s=&Config::manExtension; s->resize(0); }
+<Start>"GENERATE_XML"[ \t]*"=" { BEGIN(GetBool); b=&Config::generateXML; }
<Start>"ENABLE_PREPROCESSING"[ \t]*"=" { BEGIN(GetBool); b=&Config::preprocessingFlag; }
<Start>"MACRO_EXPANSION"[ \t]*"=" { BEGIN(GetBool); b=&Config::macroExpansionFlag; }
<Start>"EXPAND_ONLY_PREDEF"[ \t]*"=" { BEGIN(GetBool); b=&Config::onlyPredefinedFlag; }
@@ -452,6 +460,8 @@ void dumpConfig()
is=Config::sectionFilterList.next();
}
}
+ printf("generateTodoList=`%d'\n",Config::generateTodoList);
+ printf("generateTestList=`%d'\n",Config::generateTestList);
printf("# configuration options related to warning and progress messages\n");
printf("quietFlag=`%d'\n",Config::quietFlag);
printf("warningFlag=`%d'\n",Config::warningFlag);
@@ -550,6 +560,7 @@ void dumpConfig()
}
printf("latexHeaderFile=`%s'\n",Config::latexHeaderFile.data());
printf("pdfHyperFlag=`%d'\n",Config::pdfHyperFlag);
+ printf("usePDFLatexFlag=`%d'\n",Config::usePDFLatexFlag);
printf("latexBatchModeFlag=`%d'\n",Config::latexBatchModeFlag);
printf("# configuration options related to the RTF output\n");
printf("generateRTF=`%d'\n",Config::generateRTF);
@@ -561,6 +572,8 @@ void dumpConfig()
printf("generateMan=`%d'\n",Config::generateMan);
printf("manOutputDir=`%s'\n",Config::manOutputDir.data());
printf("manExtension=`%s'\n",Config::manExtension.data());
+ printf("# configuration options related to the XML output\n");
+ printf("generateXML=`%d'\n",Config::generateXML);
printf("# Configuration options related to the preprocessor \n");
printf("preprocessingFlag=`%d'\n",Config::preprocessingFlag);
printf("macroExpansionFlag=`%d'\n",Config::macroExpansionFlag);
@@ -669,6 +682,8 @@ void Config::init()
Config::sortMembersFlag = TRUE;
Config::tabSize = 8;
Config::sectionFilterList.clear();
+ Config::generateTodoList = TRUE;
+ Config::generateTestList = TRUE;
Config::quietFlag = FALSE;
Config::warningFlag = TRUE;
Config::warningUndocFlag = TRUE;
@@ -699,6 +714,7 @@ void Config::init()
Config::extraPackageList.clear();
Config::latexHeaderFile.resize(0);
Config::pdfHyperFlag = FALSE;
+ Config::usePDFLatexFlag = FALSE;
Config::latexBatchModeFlag = FALSE;
Config::generateRTF = TRUE;
Config::rtfOutputDir = "rtf";
@@ -708,6 +724,7 @@ void Config::init()
Config::generateMan = TRUE;
Config::manOutputDir = "man";
Config::manExtension = ".3";
+ Config::generateXML = FALSE;
Config::preprocessingFlag = TRUE;
Config::macroExpansionFlag = FALSE;
Config::onlyPredefinedFlag = FALSE;
@@ -846,7 +863,7 @@ void writeTemplateConfig(QFile *f,bool sl)
t << "# information to generate all constant output in the proper language. \n";
t << "# The default language is English, other supported languages are: \n";
t << "# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese, \n";
- t << "# Spanish, Russian, Croatian and Polish.\n";
+ t << "# Spanish, Russian, Croatian, Polish, and Portuguese.\n";
t << "\n";
}
t << "OUTPUT_LANGUAGE = ";
@@ -1146,6 +1163,28 @@ void writeTemplateConfig(QFile *f,bool sl)
if (!sl)
{
t << "\n";
+ t << "# The GENERATE_TODOLIST tag can be used to enable (YES) or \n";
+ t << "# disable (NO) the todo list. This list is created by putting \\todo \n";
+ t << "# commands in the documentation.\n";
+ t << "\n";
+ }
+ t << "GENERATE_TODOLIST = ";
+ writeBoolValue(t,Config::generateTodoList);
+ t << "\n";
+ if (!sl)
+ {
+ t << "\n";
+ t << "# The GENERATE_TESTLIST tag can be used to enable (YES) or \n";
+ t << "# disable (NO) the test list. This list is created by putting \\test \n";
+ t << "# commands in the documentation.\n";
+ t << "\n";
+ }
+ t << "GENERATE_TESTLIST = ";
+ writeBoolValue(t,Config::generateTestList);
+ t << "\n";
+ if (!sl)
+ {
+ t << "\n";
}
t << "#---------------------------------------------------------------------------\n";
t << "# configuration options related to warning and progress messages\n";
@@ -1519,6 +1558,17 @@ void writeTemplateConfig(QFile *f,bool sl)
if (!sl)
{
t << "\n";
+ t << "# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of \n";
+ t << "# plain latex in the generated Makefile. Set this option to YES to get a \n";
+ t << "# higher quality PDF documentation. \n";
+ t << "\n";
+ }
+ t << "USE_PDFLATEX = ";
+ writeBoolValue(t,Config::usePDFLatexFlag);
+ t << "\n";
+ if (!sl)
+ {
+ t << "\n";
t << "# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\\\batchmode. \n";
t << "# command to the generated LaTeX files. This will instruct LaTeX to keep \n";
t << "# running if errors occur, instead of asking the user for help. \n";
@@ -1539,9 +1589,8 @@ void writeTemplateConfig(QFile *f,bool sl)
{
t << "\n";
t << "# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output \n";
- t << "# For now this is experimental and is disabled by default. The RTF output \n";
- t << "# is optimised for Word 97 and may not look too pretty with other readers \n";
- t << "# or editors.\n";
+ t << "# The RTF output is optimised for Word 97 and may not look very pretty with \n";
+ t << "# other RTF readers or editors.\n";
t << "\n";
}
t << "GENERATE_RTF = ";
@@ -1637,6 +1686,25 @@ void writeTemplateConfig(QFile *f,bool sl)
t << "\n";
}
t << "#---------------------------------------------------------------------------\n";
+ t << "# configuration options related to the XML output\n";
+ t << "#---------------------------------------------------------------------------\n";
+ if (!sl)
+ {
+ t << "\n";
+ t << "# If the GENERATE_XML tag is set to YES Doxygen will \n";
+ t << "# generate an XML file that captures the structure of \n";
+ t << "# the code including all documentation. Warning: This feature \n";
+ t << "# is still experimental and very incomplete.\n";
+ t << "\n";
+ }
+ t << "GENERATE_XML = ";
+ writeBoolValue(t,Config::generateXML);
+ t << "\n";
+ if (!sl)
+ {
+ t << "\n";
+ }
+ t << "#---------------------------------------------------------------------------\n";
t << "# Configuration options related to the preprocessor \n";
t << "#---------------------------------------------------------------------------\n";
if (!sl)
diff --git a/src/definition.cpp b/src/definition.cpp
index 3ce5893..a28228f 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -48,9 +48,9 @@ Definition::~Definition()
delete sourceRefDict;
}
-QCString Definition::nameToFile(const char *name)
+QCString Definition::nameToFile(const char *name,bool allowDots)
{
- return convertNameToFile(name);
+ return convertNameToFile(name,allowDots);
#if 0
QCString result;
char c;
diff --git a/src/definition.h b/src/definition.h
index 701fd03..232e632 100644
--- a/src/definition.h
+++ b/src/definition.h
@@ -79,7 +79,7 @@ class Definition
* The function getOutputFileBase() also uses this function in most cases.
* \sa setName(),Definition()
*/
- QCString nameToFile(const char *name);
+ QCString nameToFile(const char *name,bool allowDot=FALSE);
/*! Add the list of anchors that mark the sections that are found in the
* documentation.
diff --git a/src/diagram.cpp b/src/diagram.cpp
index 80e6d10..3f6dd61 100644
--- a/src/diagram.cpp
+++ b/src/diagram.cpp
@@ -985,8 +985,6 @@ void ClassDiagram::writeFigure(QTextStream &output,const char *path,
output << ":\\begin{figure}[H]\n"
"\\begin{center}\n"
"\\leavevmode\n";
- //output << "\\setlength{\\epsfysize}{" << realHeight << "cm}\n";
- //output << "\\epsfbox{" << fileName << ".eps}\n"
output << "\\includegraphics[height=" << realHeight << "cm]{"
<< fileName << "}" << endl;
output << "\\end{center}\n"
@@ -994,7 +992,9 @@ void ClassDiagram::writeFigure(QTextStream &output,const char *path,
//printf("writeFigure rows=%d cols=%d\n",rows,cols);
- QFile f1((QCString)path+"/"+fileName+".eps");
+ QCString epsBaseName=(QCString)path+"/"+fileName;
+ QCString epsName=epsBaseName+".eps";
+ QFile f1(epsName.data());
if (!f1.open(IO_WriteOnly))
{
err("Could not open file %s for writing\n",convertToQCString(f1.name()).data());
@@ -1227,6 +1227,19 @@ void ClassDiagram::writeFigure(QTextStream &output,const char *path,
t << "\n% ----- relations -----\n\n";
base->drawConnectors(t,0,TRUE,FALSE,baseRows,superRows,0,0);
super->drawConnectors(t,0,FALSE,FALSE,baseRows,superRows,0,0);
+
+ f1.close();
+ if (Config::usePDFLatexFlag)
+ {
+ QCString epstopdfCmd(4096);
+ epstopdfCmd.sprintf("epstopdf \"%s.eps\" -outfile=\"%s.pdf\"",
+ epsBaseName.data(),epsBaseName.data());
+ if (iSystem(epstopdfCmd)!=0)
+ {
+ err("Error: Problems running epstopdf. Check your TeX installation!\n");
+ return;
+ }
+ }
}
diff --git a/src/dot.cpp b/src/dot.cpp
index 02a0b07..ccf991f 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -39,7 +39,7 @@ static const char *edgeColorMap[] =
"darkgreen", // Protected
"firebrick4", // Private
"darkorchid3", // "use" relation
- "grey50" // Undocumented
+ "grey75" // Undocumented
};
static const char *edgeStyleMap[] =
@@ -319,7 +319,7 @@ void DotNode::writeBox(QTextStream &t,
bool hasNonReachableChildren)
{
const char *labCol =
- m_url.isEmpty() ? "grey50" : // non link
+ m_url.isEmpty() ? "grey75" : // non link
(
(hasNonReachableChildren) ? "red" : "black"
);
@@ -1141,13 +1141,23 @@ void DotClassGraph::writeGraph(QTextStream &out,
QDir::setCurrent(oldDir);
return;
}
+ if (Config::usePDFLatexFlag)
+ {
+ QCString epstopdfCmd(4096);
+ epstopdfCmd.sprintf("epstopdf \"%s.eps\" -outfile=\"%s.pdf\"",
+ baseName.data(),baseName.data());
+ if (iSystem(epstopdfCmd)!=0)
+ {
+ err("Error: Problems running epstopdf. Check your TeX installation!\n");
+ QDir::setCurrent(oldDir);
+ return;
+ }
+ }
int maxWidth = 420; /* approx. page width in points */
out << "\\begin{figure}[H]\n"
"\\begin{center}\n"
"\\leavevmode\n"
- //"\\setlength{\\epsfxsize}{" << QMIN(width/2,maxWidth) << "pt}\n"
- //"\\epsfbox{" << baseName << ".eps}\n"
"\\includegraphics[width=" << QMIN(width/2,maxWidth)
<< "pt]{" << baseName << "}\n"
"\\end{center}\n"
@@ -1321,6 +1331,18 @@ void DotInclDepGraph::writeGraph(QTextStream &out,
QDir::setCurrent(oldDir);
return;
}
+ if (Config::usePDFLatexFlag)
+ {
+ QCString epstopdfCmd(4096);
+ epstopdfCmd.sprintf("epstopdf \"%s.eps\" -outfile=\"%s.pdf\"",
+ baseName.data(),baseName.data());
+ if (iSystem(epstopdfCmd)!=0)
+ {
+ err("Error: Problems running epstopdf. Check your TeX installation!\n");
+ QDir::setCurrent(oldDir);
+ return;
+ }
+ }
int maxWidth = 420; /* approx. page width in points */
out << "\\begin{figure}[H]\n"
@@ -1368,7 +1390,7 @@ void generateGraphLegend(const char *path)
dotText << " Node12 -> Node7 [dir=back,color=\"firebrick4\",fontsize=10,style=\"solid\",fontname=\"doxfont\"];\n";
dotText << " Node12 [shape=\"box\",label=\"PrivateBase\",fontsize=10,height=0.2,width=0.4,fontname=\"doxfont\",color=\"black\",URL=\"$class_privatebase.html\"];\n";
dotText << " Node13 -> Node7 [dir=back,color=\"midnightblue\",fontsize=10,style=\"solid\",fontname=\"doxfont\"];\n";
- dotText << " Node13 [shape=\"box\",label=\"Undocumented\",fontsize=10,height=0.2,width=0.4,fontname=\"doxfont\",color=\"grey50\"];\n";
+ dotText << " Node13 [shape=\"box\",label=\"Undocumented\",fontsize=10,height=0.2,width=0.4,fontname=\"doxfont\",color=\"grey75\"];\n";
dotText << " Node14 -> Node7 [dir=back,color=\"darkorchid3\",fontsize=10,style=\"dashed\",label=\"m_usedClass\",fontname=\"doxfont\"];\n";
dotText << " Node14 [shape=\"box\",label=\"Used\",fontsize=10,height=0.2,width=0.4,fontname=\"doxfont\",color=\"black\",URL=\"$class_used.html\"];\n";
dotText << "}\n";
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index c756ba8..9c6f35c 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -52,6 +52,8 @@
#include "htmlhelp.h"
#include "defargs.h"
#include "rtfgen.h"
+#include "xml.h"
+#include "reflist.h"
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define popen _popen
@@ -170,6 +172,78 @@ const char *getOverloadDocs()
//----------------------------------------------------------------------------
+static void addTodoItem(Entry *root,const char *prefix,
+ const char *name,const char *title=0)
+{
+ //printf("addTodoItem(%s) todoId=%d\n",name,root->todoId);
+ if (root->todoId==0 || !Config::generateTodoList) return;
+ RefItem *item = todoList.getRefItem(root->todoId);
+ ASSERT(item!=0);
+ if (item->written) return;
+
+ Entry *page = new Entry;
+ page->section = Entry::PAGEDOC_SEC;
+ page->fileName = "generated";
+ page->startLine = 1;
+ page->name = "todo";
+ page->args = theTranslator->trTodoList();
+ page->doc += "<dl><dt>\\anchor ";
+ page->doc += item->listAnchor;
+ page->doc += "\n";
+ page->doc += prefix;
+ page->doc += " \\ref ";
+ page->doc += name;
+ page->doc += " \"";
+ if (title && title[0]!='\0')
+ page->doc += title;
+ else
+ page->doc += name;
+ page->doc += "\":</dt>\n<dd>";
+ page->doc += item->text;
+ page->doc += "</dd></dl>\n";
+ root->addSubEntry(page);
+
+ item->written=TRUE;
+}
+
+//----------------------------------------------------------------------------
+
+static void addTestItem(Entry *root,const char *prefix,
+ const char *name,const char *title=0)
+{
+ //printf("addTestItem(%s) testId=%d\n",name,root->testId);
+ if (root->testId==0 || !Config::generateTestList) return;
+ RefItem *item = testList.getRefItem(root->testId);
+ ASSERT(item!=0);
+ if (item->written) return;
+
+ Entry *page = new Entry;
+ page->section = Entry::PAGEDOC_SEC;
+ page->fileName = "generated";
+ page->startLine = 1;
+ page->name = "test";
+ page->args = theTranslator->trTestList();
+ page->doc += "<dl><dt>\\anchor ";
+ page->doc += item->listAnchor;
+ page->doc += "\n";
+ page->doc += prefix;
+ page->doc += " \\ref ";
+ page->doc += name;
+ page->doc += " \"";
+ if (title && title[0]!='\0')
+ page->doc += title;
+ else
+ page->doc += name;
+ page->doc += "\":</dt>\n<dd>";
+ page->doc += item->text;
+ page->doc += "</dd></dl>\n";
+ root->addSubEntry(page);
+
+ item->written=TRUE;
+}
+
+//----------------------------------------------------------------------------
+
static void buildGroupList(Entry *root)
{
@@ -195,6 +269,8 @@ static void buildGroupList(Entry *root)
groupList.append(gd);
groupDict.insert(root->name,gd);
addGroupToGroups(root,gd);
+ addTodoItem(root,"group",gd->name());
+ addTestItem(root,"group",gd->name());
}
}
EntryListIterator eli(*root->sublist);
@@ -278,6 +354,8 @@ static void buildFileList(Entry *root)
//printf("File %s: in group %s\n",fd->name().data(),s->data());
}
}
+ addTodoItem(root,"file",fd->name());
+ addTestItem(root,"file",fd->name());
}
}
else
@@ -507,6 +585,8 @@ static void buildClassList(Entry *root)
fd->insertClass(cd);
}
addClassToGroups(root,cd);
+ addTodoItem(root,"class",cd->name());
+ addTestItem(root,"class",cd->name());
if (!root->subGrouping) cd->setSubGrouping(FALSE);
}
else // new class
@@ -547,6 +627,8 @@ static void buildClassList(Entry *root)
if (!root->subGrouping) cd->setSubGrouping(FALSE);
addClassToGroups(root,cd);
+ addTodoItem(root,"class",cd->name());
+ addTestItem(root,"class",cd->name());
// see if the class is found inside a namespace
bool found=addNamespace(root,cd);
@@ -584,6 +666,8 @@ static void buildClassList(Entry *root)
// the empty string test is needed for extract all case
cd->setBriefDescription(root->brief);
cd->insertUsedFile(root->fileName);
+
+
// add class to the list
classList.inSort(cd);
//printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data());
@@ -656,6 +740,8 @@ static void buildNamespaceList(Entry *root)
// insert the namespace in the file definition
if (fd) fd->insertNamespace(nd);
addNamespaceToGroups(root,nd);
+ addTodoItem(root,"namespace",nd->name());
+ addTestItem(root,"namespace",nd->name());
}
else /* if (!root->doc.isEmpty() ||
!root->brief.isEmpty() ||
@@ -670,6 +756,8 @@ static void buildNamespaceList(Entry *root)
//printf("Adding namespace to group\n");
addNamespaceToGroups(root,nd);
+ addTodoItem(root,"namespace",nd->name());
+ addTestItem(root,"namespace",nd->name());
bool ambig;
// file definition containing the namespace nd
@@ -792,6 +880,8 @@ static void findUsingDirectives(Entry *root)
// add class to the list
namespaceList.inSort(nd);
namespaceDict.insert(root->name,nd);
+ addTodoItem(root,"namespace",nd->name());
+ addTestItem(root,"namespace",nd->name());
}
}
}
@@ -805,7 +895,7 @@ static void findUsingDirectives(Entry *root)
//----------------------------------------------------------------------
-void findUsingDeclarations(Entry *root)
+static void findUsingDeclarations(Entry *root)
{
if (root->section==Entry::USINGDECL_SEC)
{
@@ -1004,6 +1094,8 @@ static MemberDef *addVariableToClass(
// add the member to the class
}
cd->insertMember(md);
+ addTodoItem(root,"member",cd->name()+"::"+md->name());
+ addTestItem(root,"member",cd->name()+"::"+md->name());
//TODO: insert FileDef instead of filename strings.
cd->insertUsedFile(root->fileName);
@@ -1089,6 +1181,16 @@ static MemberDef *addVariableToFile(
// variable already in the scope
{
addMemberDocs(root,md,def,0,FALSE);
+ if (nscope.isEmpty())
+ {
+ addTodoItem(root,"member",md->name());
+ addTestItem(root,"member",md->name());
+ }
+ else
+ {
+ addTodoItem(root,"member",nscope+"::"+md->name());
+ addTestItem(root,"member",nscope+"::"+md->name());
+ }
return md;
}
md=mn->next();
@@ -1125,6 +1227,8 @@ static MemberDef *addVariableToFile(
{
nd->insertMember(md);
md->setNamespace(nd);
+ addTodoItem(root,"member",nd->name()+"::"+md->name());
+ addTestItem(root,"member",nd->name()+"::"+md->name());
}
else
{
@@ -1133,6 +1237,8 @@ static MemberDef *addVariableToFile(
{
fd->insertMember(md);
md->setFileDef(fd);
+ addTodoItem(root,"member",md->name());
+ addTestItem(root,"member",md->name());
}
}
@@ -1526,6 +1632,8 @@ static void buildMemberList(Entry *root)
cd->insertMember(md);
// add file to list of used files
cd->insertUsedFile(root->fileName);
+ addTodoItem(root,"member",cd->name()+"::"+md->name());
+ addTestItem(root,"member",cd->name()+"::"+md->name());
addMemberToGroups(root,md);
}
@@ -1682,6 +1790,8 @@ static void buildMemberList(Entry *root)
{
nd->insertMember(md);
md->setNamespace(nd);
+ addTodoItem(root,"member",nd->name()+"::"+md->name());
+ addTestItem(root,"member",nd->name()+"::"+md->name());
}
else
{
@@ -1696,6 +1806,8 @@ static void buildMemberList(Entry *root)
// add member to the file
fd->insertMember(md);
md->setFileDef(fd);
+ addTodoItem(root,"member",md->name());
+ addTestItem(root,"member",md->name());
}
}
@@ -1921,11 +2033,12 @@ static bool findBaseClassRelation(Entry *root,ClassDef *cd,
baseClassName.prepend(scopeName.left(scopeOffset)+"::");
}
ClassDef *baseClass=getResolvedClass(baseClassName);
+ //printf("baseClassName=`%s' baseClass=%p\n",baseClassName.data(),baseClass);
if (baseClassName!=root->name) // check for base class with the same name,
// look in the outer scope for a match
{
Debug::print(
- Debug::Classes,0,"baseClass %s of %s found (%s and %s)\n",
+ Debug::Classes,0," baseClass %s of %s found (%s and %s)\n",
baseClassName.data(),
root->name.data(),
(bi->prot==Private)?"private":((bi->prot==Protected)?"protected":"public"),
@@ -2183,6 +2296,11 @@ static void addMemberDocs(Entry *root,
md->setDefinition(fDecl);
ClassDef *cd=md->getClassDef();
NamespaceDef *nd=md->getNamespaceDef();
+ QCString fullName;
+ if (cd) fullName = cd->name();
+ else if (nd) fullName = nd->name();
+ if (!fullName.isEmpty()) fullName+="::";
+ fullName+=md->name();
if (al)
{
mergeArguments(md->argumentList(),al);
@@ -2209,6 +2327,8 @@ static void addMemberDocs(Entry *root,
doc+=root->doc;
}
md->setDocumentation(doc);
+ addTodoItem(root,"member",fullName);
+ addTestItem(root,"member",fullName);
}
else
{
@@ -2256,6 +2376,8 @@ static void addMemberDocs(Entry *root,
md->setBodyDef(fd);
}
+ addTodoItem(root,"member",fullName);
+ addTestItem(root,"member",fullName);
}
//md->setDefFile(root->fileName);
@@ -3131,6 +3253,8 @@ static void findMember(Entry *root,QCString funcDecl,QCString related,bool overl
mn->inSort(md);
cd->insertMember(md);
cd->insertUsedFile(root->fileName);
+ addTodoItem(root,"member",cd->name()+"::"+md->name());
+ addTestItem(root,"member",cd->name()+"::"+md->name());
}
}
else // unrelated function with the same name as a member
@@ -3247,6 +3371,8 @@ static void findMember(Entry *root,QCString funcDecl,QCString related,bool overl
mn->inSort(md);
cd->insertMember(md);
cd->insertUsedFile(root->fileName);
+ addTodoItem(root,"member",cd->name()+"::"+md->name());
+ addTestItem(root,"member",cd->name()+"::"+md->name());
if (newMemberName)
{
//printf("Adding memberName=%s\n",mn->memberName());
@@ -3482,11 +3608,15 @@ static void findEnums(Entry *root)
}
nd->insertMember(md);
md->setNamespace(nd);
+ addTodoItem(root,"member",nd->name()+"::"+md->name());
+ addTestItem(root,"member",nd->name()+"::"+md->name());
}
else if (isGlobal)
{
md->setDefinition(name);
fd->insertMember(md);
+ addTodoItem(root,"member",md->name());
+ addTestItem(root,"member",md->name());
}
else if (cd)
{
@@ -3500,6 +3630,8 @@ static void findEnums(Entry *root)
}
cd->insertMember(md);
cd->insertUsedFile(root->fileName);
+ addTodoItem(root,"member",cd->name()+"::"+md->name());
+ addTestItem(root,"member",cd->name()+"::"+md->name());
}
md->setDocumentation(root->doc);
md->setBriefDescription(root->brief);
@@ -4252,15 +4384,18 @@ static void buildPageList(Entry *root)
baseName=baseName.left(baseName.length()-4);
else if (baseName.right(5)==".html")
baseName=baseName.left(baseName.length()-5);
+
+ QCString title=root->args.stripWhiteSpace();
pi=new PageInfo(root->fileName,root->startLine,
- baseName, root->doc,
- root->args.stripWhiteSpace());
+ baseName, root->doc,title);
QCString pageName;
if (Config::caseSensitiveNames)
pageName=pi->name.copy();
else
pageName=pi->name.lower();
setFileNameForSections(root->anchors,pageName);
+ addTodoItem(root,"page",pageName,title);
+ addTestItem(root,"page",pageName,title);
pageList.append(pi);
pageDict.insert(baseName,pi);
@@ -4271,7 +4406,7 @@ static void buildPageList(Entry *root)
// a page name is a label as well!
SectionInfo *si=new SectionInfo(
pi->name,pi->title,SectionInfo::Section);
- si->fileName=pageName+".html";
+ si->fileName=pageName;
//printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,si->fileName.data());
//printf("Adding section info %s\n",pi->name.data());
sectionDict.insert(pageName,si);
@@ -4279,6 +4414,13 @@ static void buildPageList(Entry *root)
}
}
}
+ else if (root->section == Entry::MAINPAGEDOC_SEC)
+ {
+ QCString title=root->args.stripWhiteSpace();
+ if (title.isEmpty()) title=theTranslator->trMainPage();
+ addTodoItem(root,"page","index",title);
+ addTestItem(root,"page","index",title);
+ }
EntryListIterator eli(*root->sublist);
Entry *e;
for (;(e=eli.current());++eli)
@@ -4294,10 +4436,16 @@ static void findMainPage(Entry *root)
if (mainPage==0)
{
//printf("Found main page! \n======\n%s\n=======\n",root->doc.data());
+ QCString title=root->args.stripWhiteSpace();
mainPage = new PageInfo(root->fileName,root->startLine,
- "index", root->doc,
- root->args.stripWhiteSpace());
+ "index", root->doc,title);
setFileNameForSections(root->anchors,"index");
+
+ // a page name is a label as well!
+ SectionInfo *si=new SectionInfo(
+ mainPage->name,mainPage->title,SectionInfo::Section);
+ si->fileName="index";
+ sectionDict.insert("index",si);
}
else
{
@@ -4331,6 +4479,14 @@ static void resolveUserReferences()
// si->definition->getOutputFileBase().data());
si->fileName=si->definition->getOutputFileBase().copy();
}
+ // hack: the items of a todo/test list are all fragments from different files,
+ // so the resulting section's all have the wrong file name (not from the
+ // todo/test list, but from the file in which they are defined). We correct this
+ // here by looking at the generated section labels!
+ if (si->label.left(5)=="_todo" || si->label.left(5)=="_test")
+ {
+ si->fileName=si->label.mid(1,4); // extract "todo" or "test"
+ }
}
}
@@ -4408,7 +4564,7 @@ static void buildExampleList(Entry *root)
PageInfo *pi=new PageInfo(root->fileName,root->startLine,
root->name,root->doc,root->args);
setFileNameForSections(root->anchors,
- convertSlashes(pi->name,TRUE)+"-example"
+ convertFileName(pi->name)+"-example"
);
exampleList.inSort(pi);
exampleDict.insert(root->name,pi);
@@ -4440,7 +4596,7 @@ static void generateExampleDocs()
while (pi)
{
msg("Generating docs for example %s...\n",pi->name.data());
- QCString n=convertSlashes(pi->name,TRUE)+"-example";
+ QCString n=convertFileName(pi->name)+"-example";
startFile(*outputList,n,"Example Documentation");
startTitle(*outputList,n);
outputList->docify(pi->name);
@@ -5604,12 +5760,6 @@ int main(int argc,char **argv)
msg("Building example list...\n");
buildExampleList(root);
- msg("Building page list...\n");
- buildPageList(root);
-
- msg("Search for main page...\n");
- findMainPage(root);
-
msg("Searching for documented variables...\n");
buildVarList(root);
@@ -5636,6 +5786,12 @@ int main(int argc,char **argv)
findMemberDocumentation(root); // may introduce new members !
transferRelatedFunctionDocumentation();
+ msg("Building page list...\n");
+ buildPageList(root);
+
+ msg("Search for main page...\n");
+ findMainPage(root);
+
msg("Freeing entry tree\n");
delete root;
@@ -5793,6 +5949,12 @@ int main(int argc,char **argv)
writeGraphicalClassHierarchy(*outputList);
}
+ if (Config::generateXML)
+ {
+ msg("Generating XML output\n");
+ generateXML();
+ }
+
if (formulaList.count()>0 && Config::generateHtml)
{
msg("Generating bitmaps for formulas in HTML...\n");
@@ -5812,9 +5974,11 @@ int main(int argc,char **argv)
HtmlHelp::getInstance()->finalize();
}
+
if (Config::generateHtml) removeDoxFont(Config::htmlOutputDir);
if (Config::generateRTF) removeDoxFont(Config::rtfOutputDir);
delete tag;
+
return 0;
}
diff --git a/src/doxygen.dtd b/src/doxygen.dtd
new file mode 100644
index 0000000..a479ee5
--- /dev/null
+++ b/src/doxygen.dtd
@@ -0,0 +1,115 @@
+<?xml encoding="ISO-8859-1"?>
+<!-- DTD describing the grammar used in doxygen's XML output -->
+
+<!-- standard character entities -->
+<!ENTITY lt "&#38;#60;">
+<!ENTITY gt "&#62;">
+<!ENTITY amp "&#38;#38;">
+<!ENTITY apos "&#39;">
+<!ENTITY quot "&#34;">
+
+<!-- required attributes for compounds -->
+<!ENTITY % compound-req.att
+ 'id ID #REQUIRED
+ type (group|file|namespace|
+ class|struct|union|
+ interface|dispinterface|
+ valuetype|library) #REQUIRED'
+>
+<!-- required attributes for references -->
+<!ENTITY % ref-req.att 'idref IDREF #REQUIRED'
+>
+<!-- required attributes for inheritance relations -->
+<!ENTITY % inheritcompref-req.att
+ '%ref-req.att;
+ prot (public|protected|private) #REQUIRED
+ virt (non-virtual|virtual) #REQUIRED'
+>
+
+<!-- required attributes for member sections -->
+<!ENTITY % sec-req.att 'type (user
+ |public-type
+ |public-func
+ |public-attrib
+ |public-slot
+ |public-static-func
+ |public-static-attrib
+ |protected-type
+ |protected-func
+ |protected-attrib
+ |protected-slot
+ |protected-static-func
+ |protected-static-attrib
+ |private-type
+ |private-func
+ |private-attrib
+ |private-slot
+ |private-static-func
+ |private-static-attrib
+ |signal
+ |friend
+ |related
+ |define|prototype|typedef|enum|func|var
+ ) #REQUIRED
+ '
+>
+<!-- required attributes for members -->
+<!ENTITY % mem-req.att 'id ID #REQUIRED'>
+
+<!-- optional attributes for function -->
+<!ENTITY % func-opt.att 'virt (virtual|pure-virtual) #IMPLIED'>
+
+<!-- elements -->
+<!ELEMENT doxygen (compoundlist?)>
+<!ELEMENT compoundlist (compounddef)+>
+<!ELEMENT compounddef (compoundname,
+ basecompoundlist?,
+ derivedcompoundlist?,
+ sectionlist?
+ )
+>
+<!ATTLIST compounddef %compound-req.att;>
+<!ELEMENT basecompoundlist (basecompoundref)+>
+<!ELEMENT derivedcompoundlist (derivedcompoundref)+>
+<!ELEMENT compoundref (#PCDATA)>
+<!ATTLIST compoundref %ref-req.att;>
+<!ELEMENT memberref (#PCDATA)>
+<!ATTLIST memberref %ref-req.att;>
+<!ELEMENT basecompoundref EMPTY>
+<!ATTLIST basecompoundref %inheritcompref-req.att;>
+<!ELEMENT derivedcompoundref EMPTY>
+<!ATTLIST derivedcompoundref %inheritcompref-req.att;>
+<!ELEMENT sectionlist (sectiondef)+>
+<!ELEMENT sectiondef (memberlist)>
+<!ATTLIST sectiondef %sec-req.att;>
+<!ELEMENT memberlist (functiondef|variabledef|typedef|definedef|enumdef)+>
+<!ELEMENT functiondef (type?,name,paramlist)>
+<!ATTLIST functiondef %mem-req.att; %func-opt.att;>
+<!ELEMENT variabledef (type,name,array?,initializer?)>
+<!ATTLIST variabledef %mem-req.att;>
+<!ELEMENT typedef (type,name)>
+<!ATTLIST typedef %mem-req.att;>
+<!ELEMENT definedef (name,defparamlist?,initializer?)>
+<!ATTLIST definedef %mem-req.att;>
+<!ELEMENT enumdef (name,enumvaluelist)>
+<!ATTLIST enumdef %mem-req.att;>
+<!ELEMENT slotdef (type,name,paramlist)>
+<!ATTLIST slotdef %mem-req.att;>
+<!ELEMENT signaldef (type,name,paramlist)>
+<!ATTLIST signaldef %mem-req.att;>
+<!ELEMENT paramlist (param)*>
+<!ELEMENT param (attributes?,type,declname?,defname?,array?,defval?)>
+<!ELEMENT defparamlist (defarg)*>
+<!ELEMENT defarg (#PCDATA)>
+<!ELEMENT enumvaluelist (enumvalue)*>
+<!ELEMENT enumvalue (name,initializer?)>
+<!ELEMENT name (#PCDATA)>
+<!ELEMENT compoundname (#PCDATA)>
+<!ELEMENT declname (#PCDATA)>
+<!ELEMENT defname (#PCDATA)>
+<!ELEMENT type (#PCDATA|memberref|compoundref|compounddef)*>
+<!ELEMENT defval (#PCDATA|memberref|compoundref)*>
+<!ELEMENT initializer (#PCDATA|memberref|compoundref)*>
+<!ELEMENT array (#PCDATA)>
+<!ELEMENT attributes (#PCDATA)>
+
diff --git a/src/doxygen.pro.in b/src/doxygen.pro.in
index 81d0817..0fb674e 100644
--- a/src/doxygen.pro.in
+++ b/src/doxygen.pro.in
@@ -25,7 +25,8 @@ HEADERS = doxygen.h scanner.h classdef.h classlist.h memberdef.h \
namespacedef.h version.h language.h translator.h \
translator_nl.h translator_se.h translator_cz.h translator_fr.h \
translator_it.h formula.h debug.h membergroup.h htmlhelp.h \
- translator_ru.h translator_pl.h dot.h rtfgen.h
+ translator_ru.h translator_pl.h dot.h rtfgen.h xml.h xml_dtd.h \
+ reflist.h
SOURCES = doxygen.cpp scanner.cpp classdef.cpp classlist.cpp memberdef.cpp \
membername.cpp index.cpp memberlist.cpp \
entry.cpp logos.cpp instdox.cpp message.cpp code.cpp \
@@ -35,7 +36,9 @@ SOURCES = doxygen.cpp scanner.cpp classdef.cpp classlist.cpp memberdef.cpp
tag.cpp filename.cpp declinfo.cpp defargs.cpp define.cpp \
diagram.cpp gifenc.cpp image.cpp namespacedef.cpp \
version.cpp language.cpp definition.cpp formula.cpp debug.cpp \
- membergroup.cpp htmlhelp.cpp dot.cpp rtfgen.cpp
+ membergroup.cpp htmlhelp.cpp dot.cpp rtfgen.cpp xml.cpp \
+ reflist.cpp
win32:INCLUDEPATH += .
+win32:LIBS += shell32.lib
TARGET = ../bin/doxygen
OBJECTS_DIR = ../objects
diff --git a/src/doxygen.t b/src/doxygen.t
index f887a68..1d6fc2f 100644
--- a/src/doxygen.t
+++ b/src/doxygen.t
@@ -75,3 +75,5 @@ sub GenerateDep {
$(YACC) -l -d -p cppExpYY constexp.y -o ce_parse.c
-rm ce_parse.c
+xml_dtd.h: doxygen.dtd
+ cat doxygen.dtd | sed -e "s/\"/\\\\\"/g" -e "s/^/\"/g" -e "s/$$/\\\\n\"/g" >xml_dtd.h
diff --git a/src/entry.cpp b/src/entry.cpp
index ceee6ca..1c4ef6d 100644
--- a/src/entry.cpp
+++ b/src/entry.cpp
@@ -73,6 +73,8 @@ Entry::Entry(const Entry &e)
memSpec = e.memSpec;
initializer = e.initializer;
initLines = e.initLines;
+ todoId = e.todoId;
+ testId = e.testId;
sublist = new QList<Entry>;
sublist->setAutoDelete(TRUE);
extends = new QList<BaseInfo>;
@@ -214,6 +216,8 @@ void Entry::reset()
bodyLine = -1;
endBodyLine = -1;
mGrpId = -1;
+ todoId = 0;
+ testId = 0;
section = EMPTY_SEC;
sig = FALSE;
virt = Normal;
diff --git a/src/entry.h b/src/entry.h
index 5c98a8c..1494bae 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -197,6 +197,8 @@ class Entry
QList<QCString> *anchors; // list of anchors defined in this entry
QCString fileName; // file this entry was extracted from
int startLine; // start line of entry in the source
+ int todoId; // id of the todo item of this entry
+ int testId; // id of the test item of this entry
static int num; // counts the total number of entries
private:
Entry &operator=(const Entry &);
diff --git a/src/filedef.cpp b/src/filedef.cpp
index eefb1ad..e35875f 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -39,8 +39,8 @@ FileDef::FileDef(const char *p,const char *nm,const char *lref)
{
path=p;
filepath=path+nm;
- filename=nameToFile(nm);
- diskname=filename.copy();
+ filename=nameToFile(nm,TRUE);
+ diskname=nameToFile(nm,FALSE);
setReference(lref);
classList = new ClassList;
includeList = new QList<IncludeInfo>;
@@ -388,16 +388,6 @@ void FileDef::writeDocumentation(OutputList &ol)
enumMembers.writeDocumentation(ol,name());
}
- //enumValMembers.countDocMembers();
- //if (enumValMembers.totalCount()>0 )
- //{
- // ol.writeRuler();
- // ol.startGroupHeader();
- // parseText(ol,theTranslator->trEnumerationValueDocumentation());
- // ol.endGroupHeader();
- // enumValMembers.writeDocumentation(ol,name());
- //}
-
funcMembers.countDocMembers();
if (funcMembers.totalCount()>0 )
{
@@ -532,10 +522,10 @@ void FileDef::insertMember(MemberDef *md)
enumMembers.append(md);
break;
case MemberDef::EnumValue:
- if (Config::sortMembersFlag)
- enumValMembers.inSort(md);
- else
- enumValMembers.append(md);
+ //if (Config::sortMembersFlag)
+ // enumValMembers.inSort(md);
+ //else
+ // enumValMembers.append(md);
break;
case MemberDef::Prototype:
if (Config::sortMembersFlag)
@@ -658,33 +648,44 @@ void FileDef::addIncludedByDependency(FileDef *fd,const char *incName,bool local
}
}
-//-----------------------------------------------------------------------------
-
-#if 0
-/*! Creates a file list. */
-FileList::FileList() : QList<FileDef>()
-{
-}
-
-/*! Destroys a file list */
-FileList::~FileList()
+void FileDef::generateXMLSection(QTextStream &t,MemberList *ml,const char *type)
{
+ if (ml->count()>0)
+ {
+ t << " <sectiondef type=\"" << type << "\">" << endl;
+ t << " <memberlist>" << endl;
+ MemberListIterator mli(*ml);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ md->generateXML(t,this);
+ }
+ t << " </memberlist>" << endl;
+ t << " </sectiondef>" << endl;
+ }
}
-/*! Compares two files by name. */
-int FileList::compareItems(GCI item1, GCI item2)
+void FileDef::generateXML(QTextStream &t)
{
- FileDef *f1=(FileDef *)item1;
- FileDef *f2=(FileDef *)item2;
- ASSERT(f1!=0 && f2!=0);
- return Config::fullPathNameFlag ?
- stricmp(f1->absFilePath(),f2->absFilePath()) :
- stricmp(f1->name(),f2->name());
+ t << " <compounddef id=\""
+ << getOutputFileBase() << "\" type=\"file\">" << endl;
+ t << " <compoundname>";
+ writeXMLString(t,name());
+ t << "</compoundname>" << endl;
+ int numMembers = defineMembers.count()+protoMembers.count()+
+ typedefMembers.count()+enumMembers.count()+
+ funcMembers.count()+varMembers.count();
+ if (numMembers>0)
+ {
+ t << " <sectionlist>" << endl;
+ generateXMLSection(t,&defineMembers,"define");
+ generateXMLSection(t,&protoMembers,"prototype");
+ generateXMLSection(t,&typedefMembers,"typedef");
+ generateXMLSection(t,&enumMembers,"enum");
+ generateXMLSection(t,&funcMembers,"func");
+ generateXMLSection(t,&varMembers,"var");
+ t << " </sectionlist>" << endl;
+ }
+ t << " </compounddef>" << endl;
}
-/*! Create a file list iterator. */
-FileListIterator::FileListIterator(const FileList &cllist) :
- QListIterator<FileDef>(cllist)
-{
-}
-#endif
diff --git a/src/filedef.h b/src/filedef.h
index 03bc919..ff9f5b5 100644
--- a/src/filedef.h
+++ b/src/filedef.h
@@ -131,6 +131,9 @@ class FileDef : public Definition
void addMembersToMemberGroup();
void distributeMemberGroupDocumentation();
+ void generateXML(QTextStream &t);
+ void generateXMLSection(QTextStream &t,MemberList *ml,const char *type);
+
protected:
void addMemberListToGroup(MemberList *,bool (MemberDef::*)() const);
@@ -140,7 +143,6 @@ class FileDef : public Definition
MemberList protoMembers;
MemberList typedefMembers;
MemberList enumMembers;
- MemberList enumValMembers;
MemberList funcMembers;
MemberList varMembers;
diff --git a/src/filename.cpp b/src/filename.cpp
index 86db34f..e5f224a 100644
--- a/src/filename.cpp
+++ b/src/filename.cpp
@@ -28,13 +28,6 @@ FileName::~FileName()
{
}
-//static QCString convertSlashes(const char *s)
-//{
-// QCString result=s;
-// int i,l=result.length();
-// for (i=0;i<l;i++) if (result.at(i)=='/') result.at(i)='_';
-// return result;
-//}
void FileName::generateDiskNames()
{
@@ -48,7 +41,7 @@ void FileName::generateDiskNames()
// skip references
while (fd && fd->isReference()) fd=next();
// name if unique, so diskname is simply the name
- fd->diskname=name;
+ fd->diskname=convertFileName(name);
}
else if (count>1) // multiple occurrences of the same file name
{
@@ -90,7 +83,7 @@ void FileName::generateDiskNames()
{
QCString prefix = fd->path.right(fd->path.length()-j-1);
fd->setName(prefix+name);
- fd->diskname=convertSlashes(prefix+name);
+ fd->diskname=convertFileName(prefix+name);
}
fd=next();
}
diff --git a/src/formula.cpp b/src/formula.cpp
index d7e444c..f35fd47 100644
--- a/src/formula.cpp
+++ b/src/formula.cpp
@@ -17,6 +17,9 @@
#include <stdlib.h>
#include <unistd.h>
+#ifdef _WIN32
+#include <windows.h>
+#endif
#include "qtbc.h"
#include <qfile.h>
@@ -165,29 +168,58 @@ void FormulaList::generateBitmaps(const char *path)
const double scaleFactor = 16.0/3.0;
int gx = (((int)((x2-x1)*scaleFactor))+3)&~2;
int gy = (((int)((y2-y1)*scaleFactor))+3)&~2;
- char gsCmd[256];
// Then we run ghostscript to convert the postscript to a pixmap
// The pixmap is a truecolor image, where only black and white are
// used.
#ifdef _WIN32
- sprintf(gsCmd,"gswin32 -q -g%dx%d -r%dx%dx -sDEVICE=ppmraw "
- "-sOutputFile=%s.pnm -DNOPAUSE -- %s.ps",
- gx,gy,(int)(scaleFactor*72),(int)(scaleFactor*72),
- formBase.data(),formBase.data()
+ char gsArgs[256];
+ sprintf(gsArgs,"-q -g%dx%d -r%dx%dx -sDEVICE=ppmraw "
+ "-sOutputFile=%s.pnm -DNOPAUSE -- %s.ps",
+ gx,gy,(int)(scaleFactor*72),(int)(scaleFactor*72),
+ formBase.data(),formBase.data()
);
+ // gswin32 is a GUI api which will pop up a window and run
+ // asynchronously. To prevent both, we use ShellExecuteEx and
+ // WaitForSingleObject (thanks to Robert Golias for the code)
+ SHELLEXECUTEINFO sInfo = {
+ sizeof(SHELLEXECUTEINFO), /* structure size */
+ SEE_MASK_NOCLOSEPROCESS, /* leave the process running */
+ NULL, /* window handle */
+ NULL, /* action to perform: open */
+ "gswin32.exe", /* file to execute */
+ gsArgs, /* argument list */
+ NULL, /* use current working dir */
+ SW_HIDE /* minimize on start-up */
+ 0, /* application instance handle */
+ NULL, /* ignored: id list */
+ NULL, /* ignored: class name */
+ NULL, /* ignored: key class */
+ 0, /* ignored: hot key */
+ NULL, /* ignored: icon */
+ NULL /* resulting application handle */
+ };
+ if (!ShellExecuteEx(&sInfo))
+ {
+ err("Problem running ghostscript. Check your installation!\n");
+ return;
+ }
+ else if (sInfo.hProcess) /* executable was launched, wait for it to finish */
+ {
+ WaitForSingleObject(sInfo.hProcess,INFINITE);
+ }
#else
+ char gsCmd[256];
sprintf(gsCmd,"gs -q -g%dx%d -r%dx%dx -sDEVICE=ppmraw "
"-sOutputFile=%s.pnm -DNOPAUSE -- %s.ps",
gx,gy,(int)(scaleFactor*72),(int)(scaleFactor*72),
formBase.data(),formBase.data()
);
-#endif
- //printf("Running ghostscript...\n");
if (iSystem(gsCmd)!=0)
{
err("Problem running ghostscript. Check your installation!\n");
return;
}
+#endif
f.setName(formBase+".pnm");
uint imageX=0,imageY=0;
// we read the generated image again, to obtain the pixel data.
diff --git a/src/index.cpp b/src/index.cpp
index 9e13091..c56d265 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -578,7 +578,7 @@ int countNamespaces()
NamespaceDef *nd;
for (;(nd=nli.current());++nli)
{
- if (nd->isLinkableInProject() && nd->countMembers()>0) count++;
+ if (nd->isLinkableInProject()) count++;
}
return count;
}
@@ -614,7 +614,7 @@ void writeNamespaceIndex(OutputList &ol)
NamespaceDef *nd=namespaceList.first();
while (nd)
{
- if (nd->isLinkableInProject() && nd->countMembers()>0)
+ if (nd->isLinkableInProject())
{
ol.writeStartAnnoItem("namespace",nd->getOutputFileBase(),0,nd->name());
ol.docify(" (");
@@ -1386,7 +1386,7 @@ void writeExampleIndex(OutputList &ol)
while (pi)
{
ol.writeListItem();
- QCString n=convertSlashes(pi->name,TRUE)+"-example";
+ QCString n=convertFileName(pi->name)+"-example";
if (!pi->title.isEmpty())
{
ol.writeObjectLink(0,n,0,pi->title);
@@ -1513,7 +1513,7 @@ void writeGroupList(OutputList &ol)
void writeGraphInfo(OutputList &ol)
{
- if (!Config::haveDotFlag) return;
+ if (!Config::haveDotFlag || !Config::generateHtml) return;
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
generateGraphLegend(Config::htmlOutputDir);
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index 1f2e1a2..721176c 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -157,10 +157,20 @@ void LatexGenerator::init()
<< "refman.ps: refman.dvi" << endl
<< "\tdvips -o refman.ps refman.dvi" << endl
<< endl
- << "refman.pdf: refman.ps" << endl
- << "\tps2pdf refman.ps refman.pdf" << endl
- << endl
- << "refman_2on1.ps: refman.ps" << endl
+ << "refman.pdf: refman.ps" << endl;
+ if (Config::usePDFLatexFlag) // use pdflatex instead of latex
+ {
+ t << "\tpdflatex refman.tex" << endl;
+ t << "\tmakeindex refman.idx" << endl;
+ t << "\tpdflatex refman.tex" << endl << endl;
+ }
+ else // otherwise use ps2pdf: not as nice :(
+ // especially from the font point of view
+ {
+ t << "\tps2pdf refman.ps refman.pdf" << endl << endl;
+ }
+
+ t << "refman_2on1.ps: refman.ps" << endl
<< "\tpsnup -2 refman.ps >refman_2on1.ps" << endl
<< endl
<< "refman_2on1.pdf: refman_2on1.ps" << endl
@@ -185,7 +195,7 @@ static void writeDefaultHeaderPart1(QTextStream &t)
if (Config::latexBatchModeFlag) t << "\\batchmode" << endl;
if (Config::paperType=="a4wide") paperName="a4"; else paperName=Config::paperType;
t << "\\documentclass[" << paperName << "paper";
- if (Config::pdfHyperFlag) t << ",ps2pdf";
+ //if (Config::pdfHyperFlag) t << ",ps2pdf";
t << "]{";
if (Config::compactLatexFlag) t << "article"; else t << "book";
t << "}\n";
@@ -197,12 +207,20 @@ static void writeDefaultHeaderPart1(QTextStream &t)
"\\usepackage{doxygen}\n";
if (Config::pdfHyperFlag)
{
- t << "\\usepackage{times}" << endl
- << "\\usepackage[backref=true," << endl
+ t << "\\usepackage{times}" << endl;
+ t << "\\ifx\\pdfoutput\\undefined" << endl
+ << "\\usepackage[ps2pdf," << endl
+ << " pagebackref=true," << endl
+ << " colorlinks=true," << endl
+ << " linkcolor=blue" << endl
+ << " ]{hyperref}" << endl
+ << "\\else" << endl
+ << "\\usepackage[pdftex," << endl
<< " pagebackref=true," << endl
<< " colorlinks=true," << endl
<< " linkcolor=blue" << endl
- << " ]{hyperref}" << endl;
+ << " ]{hyperref}" << endl
+ << "\\fi" << endl;
}
// Try to get the command for switching on the language
// support
@@ -479,7 +497,7 @@ void LatexGenerator::startIndexSection(IndexSections is)
bool found=FALSE;
while (nd && !found)
{
- if (nd->isLinkableInProject() && nd->countMembers()>0)
+ if (nd->isLinkableInProject())
{
if (Config::compactLatexFlag) t << "\\section"; else t << "\\chapter";
t << "{"; // Namespace Documentation}\n":
@@ -560,7 +578,9 @@ void LatexGenerator::endIndexSection(IndexSections is)
}
break;
case isMainPage:
- t << "}\n\\input{index}\n";
+ t << "}\n\\label{index}";
+ if (Config::pdfHyperFlag) t << "\\hypertarget{index}{}";
+ t << "\\input{index}\n";
break;
case isModuleIndex:
t << "}\n\\input{modules}\n";
@@ -610,7 +630,7 @@ void LatexGenerator::endIndexSection(IndexSections is)
bool found=FALSE;
while (nd && !found)
{
- if (nd->isLinkableInProject() && nd->countMembers()>0)
+ if (nd->isLinkableInProject())
{
t << "}\n\\input{" << nd->getOutputFileBase() << "}\n";
found=TRUE;
@@ -619,7 +639,7 @@ void LatexGenerator::endIndexSection(IndexSections is)
}
while (nd)
{
- if (nd->isLinkableInProject() && nd->countMembers()>0)
+ if (nd->isLinkableInProject())
{
if (Config::compactLatexFlag) t << "\\input"; else t << "\\include";
t << "{" << nd->getOutputFileBase() << "}\n";
@@ -686,13 +706,13 @@ void LatexGenerator::endIndexSection(IndexSections is)
PageInfo *pi=exampleList.first();
if (pi)
{
- t << "\\input{" << convertSlashes(pi->name,TRUE) << "-example}\n";
+ t << "\\input{" << convertFileName(pi->name) << "-example}\n";
pi=exampleList.next();
}
while (pi)
{
if (Config::compactLatexFlag) t << "\\input" ; else t << "\\include";
- t << "{" << convertSlashes(pi->name,TRUE) << "-example}\n";
+ t << "{" << convertFileName(pi->name) << "-example}\n";
pi=exampleList.next();
}
}
@@ -1076,7 +1096,7 @@ void LatexGenerator::writeSectionRef(const char *,const char *lab,
if (strcmp(lab,text)!=0) // lab!=text
{
// todo: don't hardcode p. here!
- t << "{\\bf " << text << "} (p.\\,\\pageref{" << lab << "})";
+ t << "{\\bf " << text << "} {\\rm (p.\\,\\pageref{" << lab << "})}";
}
else
{
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index 396692a..d64225c 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -29,6 +29,8 @@
#include "membergroup.h"
#include "scanner.h"
#include "groupdef.h"
+#include "defargs.h"
+#include "xml.h"
//-----------------------------------------------------------------------------
@@ -117,13 +119,13 @@ static void writeDefArgumentList(OutputList &ol,ClassDef *cd,
{
QCString n=a->type.left(vp);
if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
- linkifyText(ol,scopeName,md->name(),n);
+ linkifyText(TextGeneratorOLImpl(ol),scopeName,md->name(),n);
}
else // non-function pointer type
{
QCString n=a->type;
if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
- linkifyText(ol,scopeName,md->name(),n);
+ linkifyText(TextGeneratorOLImpl(ol),scopeName,md->name(),n);
}
if (!a->name.isEmpty()) // argument has a name
{
@@ -143,14 +145,14 @@ static void writeDefArgumentList(OutputList &ol,ClassDef *cd,
if (vp!=-1) // write the part of the argument type
// that comes after the name
{
- linkifyText(ol,scopeName,md->name(),a->type.right(a->type.length()-vp));
+ linkifyText(TextGeneratorOLImpl(ol),scopeName,md->name(),a->type.right(a->type.length()-vp));
}
if (!a->defval.isEmpty()) // write the default value
{
QCString n=a->defval;
if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
ol.docify(" = ");
- linkifyText(ol,scopeName,md->name(),n);
+ linkifyText(TextGeneratorOLImpl(ol),scopeName,md->name(),n);
}
a=argList->next();
if (a)
@@ -639,20 +641,20 @@ void MemberDef::writeDeclaration(OutputList &ol,
{
if (getAnonymousEnumType()) // type is an anonymous enum
{
- linkifyText(ol,cname,name(),ltype.left(i),TRUE);
+ linkifyText(TextGeneratorOLImpl(ol),cname,name(),ltype.left(i),TRUE);
ol+=*getAnonymousEnumType()->enumDecl();
- linkifyText(ol,cname,name(),ltype.right(ltype.length()-i-l),TRUE);
+ linkifyText(TextGeneratorOLImpl(ol),cname,name(),ltype.right(ltype.length()-i-l),TRUE);
}
else
{
ltype = ltype.left(i) + " { ... } " + ltype.right(ltype.length()-i-l);
- linkifyText(ol,cname,name(),ltype,TRUE);
+ linkifyText(TextGeneratorOLImpl(ol),cname,name(),ltype,TRUE);
}
}
}
else
{
- linkifyText(ol,cname,name(),ltype,TRUE);
+ linkifyText(TextGeneratorOLImpl(ol),cname,name(),ltype,TRUE);
}
bool htmlOn = ol.isEnabled(OutputGenerator::Html);
if (htmlOn && Config::htmlAlignMemberFlag && !ltype.isEmpty())
@@ -679,7 +681,9 @@ void MemberDef::writeDeclaration(OutputList &ol,
//if (manOn) ol.enable(OutputGenerator::Man);
}
else
+ {
ol.insertMemberAlign();
+ }
// write name
if (!name().isEmpty() && name().at(0)!='@')
@@ -734,7 +738,7 @@ void MemberDef::writeDeclaration(OutputList &ol,
{
if (!isDefine()) ol.writeString(" ");
//ol.docify(argsString());
- linkifyText(ol,cname,name(),argsString());
+ linkifyText(TextGeneratorOLImpl(ol),cname,name(),argsString());
}
if (excpString())
@@ -748,12 +752,12 @@ void MemberDef::writeDeclaration(OutputList &ol,
if (!isDefine())
{
ol.writeString(" = ");
- linkifyText(ol,cname,name(),init.simplifyWhiteSpace());
+ linkifyText(TextGeneratorOLImpl(ol),cname,name(),init.simplifyWhiteSpace());
}
else
{
ol.writeNonBreakableSpace();
- linkifyText(ol,cname,name(),init);
+ linkifyText(TextGeneratorOLImpl(ol),cname,name(),init);
}
}
@@ -860,9 +864,9 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
{
htmlHelp->addIndexItem(cname,name(),cfname,anchor());
}
- linkifyText(ol,scopeName,name(),ldef.left(i));
+ linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),ldef.left(i));
ol+=*vmd->enumDecl();
- linkifyText(ol,scopeName,name(),ldef.right(ldef.length()-i-l));
+ linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),ldef.right(ldef.length()-i-l));
found=TRUE;
}
@@ -886,7 +890,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
// last ei characters of ldef contain pointer/reference specifiers
int ni=ldef.find("::",si);
if (ni>=ei) ei=ni+2;
- linkifyText(ol,scopeName,name(),ldef.right(ldef.length()-ei));
+ linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),ldef.right(ldef.length()-ei));
}
}
else
@@ -943,25 +947,25 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
}
}
ol.startMemberDocName();
- linkifyText(ol,scopeName,name(),ldef);
+ linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),ldef);
writeDefArgumentList(ol,cd,scopeName,this);
if (!init.isEmpty() && initLines==0 && maxInitLines>0) // add initializer
{
if (!isDefine())
{
ol.docify(" = ");
- linkifyText(ol,scopeName,name(),init.simplifyWhiteSpace());
+ linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),init.simplifyWhiteSpace());
}
else
{
ol.writeNonBreakableSpace();
- linkifyText(ol,scopeName,name(),init);
+ linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),init);
}
}
if (excpString()) // add exception list
{
ol.docify(" ");
- linkifyText(ol,scopeName,name(),excpString());
+ linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),excpString());
}
}
@@ -1389,3 +1393,180 @@ QCString MemberDef::getScopeString() const
else if (getNamespaceDef()) result=getNamespaceDef()->name();
return result;
}
+
+void MemberDef::generateXML(QTextStream &t,Definition *def)
+{
+ if (mtype==EnumValue) return;
+
+ QCString scopeName;
+ if (getClassDef())
+ scopeName=getClassDef()->name();
+ else if (getNamespaceDef())
+ scopeName=getNamespaceDef()->name();
+
+ t << " <";
+ enum { define_t,variable_t,typedef_t,enum_t,function_t } xmlType;
+ switch (mtype)
+ {
+ case Define: t << "definedef"; xmlType=define_t; break;
+ case EnumValue: // fall through
+ case Variable: t << "variabledef"; xmlType=variable_t; break;
+ case Typedef: t << "typedef"; xmlType=typedef_t; break;
+ case Enumeration: t << "enumdef"; xmlType=enum_t; break;
+ case Function: // fall through
+ case Signal: // fall through
+ case Prototype: // fall through
+ case Friend: // fall through
+ case Slot: t << "functiondef"; xmlType=function_t; break;
+ }
+ t << " id=\"";
+ t << def->getOutputFileBase()
+ << ":"
+ << anchor();
+ t << "\"";
+ if (xmlType==function_t && virtualness()!=Normal)
+ // functions has an extra "virt" attribute
+ {
+ t << " virt=\"";
+ switch (virtualness())
+ {
+ case Virtual: t << "virtual"; break;
+ case Pure: t << "pure-virtual"; break;
+ default: ASSERT(0);
+ }
+ t << "\"";
+ }
+ t << ">" << endl;
+
+ if (xmlType!=define_t && xmlType!=enum_t && // These don't have types.
+ (xmlType!=function_t || !type.isEmpty()) // Type is optional here.
+ )
+ {
+ t << " <type>";
+ if (xmlType==typedef_t && type.left(8)=="typedef ")
+ linkifyText(TextGeneratorXMLImpl(t),scopeName,name(),
+ type.right(type.length()-8)); // strip "typedef "
+ else if (xmlType==function_t && type.left(8)=="virtual ")
+ linkifyText(TextGeneratorXMLImpl(t),scopeName,name(),
+ type.right(type.length()-8)); // strip "virtual "
+ else
+ linkifyText(TextGeneratorXMLImpl(t),scopeName,name(),type);
+ t << "</type>" << endl;
+ }
+
+ t << " <name>";
+ writeXMLString(t,name());
+ t << "</name>" << endl;
+ if (xmlType==function_t) //function
+ {
+ t << " <paramlist>" << endl;
+ ArgumentList *declAl = new ArgumentList;
+ ArgumentList *defAl = argList;
+ stringToArgumentList(args,declAl);
+ if (declAl->count()>0)
+ {
+ ArgumentListIterator declAli(*declAl);
+ ArgumentListIterator defAli(*defAl);
+ Argument *a;
+ for (declAli.toFirst();(a=declAli.current());++declAli)
+ {
+ Argument *defArg = defAli.current();
+ t << " <param>" << endl;
+ if (!a->attrib.isEmpty())
+ {
+ t << " <attributes>";
+ writeXMLString(t,a->attrib);
+ t << "</attributes>" << endl;
+ }
+ if (!a->type.isEmpty())
+ {
+ t << " <type>";
+ linkifyText(TextGeneratorXMLImpl(t),scopeName,name(),a->type);
+ t << "</type>" << endl;
+ }
+ if (!a->name.isEmpty())
+ {
+ t << " <declname>";
+ writeXMLString(t,a->name);
+ t << "</declname>" << endl;
+ }
+ if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
+ {
+ t << " <defname>";
+ writeXMLString(t,defArg->name);
+ t << "</defname>" << endl;
+ }
+ if (!a->array.isEmpty())
+ {
+ t << " <array>";
+ writeXMLString(t,a->array);
+ t << "</array>" << endl;
+ }
+ if (!a->defval.isEmpty())
+ {
+ t << " <defval>";
+ linkifyText(TextGeneratorXMLImpl(t),scopeName,name(),a->defval);
+ t << "</defval>" << endl;
+ }
+ t << " </param>" << endl;
+ if (defArg) ++defAli;
+ }
+ }
+ delete declAl;
+ t << " </paramlist>" << endl;
+ }
+ else if (xmlType==define_t && !args.isEmpty()) // define
+ {
+ t << " <defparamlist>" << endl;
+ ArgumentListIterator ali(*argList);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ t << " <defarg>" << a->type << "</defarg>" << endl;
+ }
+ t << " </defparamlist>" << endl;
+ if (!init.isEmpty())
+ {
+ t << " <initializer>";
+ linkifyText(TextGeneratorXMLImpl(t),scopeName,name(),init);
+ t << "</initializer>" << endl;
+ }
+ }
+ else if (xmlType==enum_t) // enum
+ {
+ t << " <enumvaluelist>" << endl;
+ MemberListIterator emli(*enumFields);
+ MemberDef *emd;
+ for (emli.toFirst();(emd=emli.current());++emli)
+ {
+ t << " <enumvalue>" << endl;
+ t << " <name>";
+ writeXMLString(t,emd->name());
+ t << "</name>" << endl;
+ if (!emd->init.isEmpty())
+ {
+ t << " <initializer>";
+ writeXMLString(t,emd->init);
+ t << "</initializer>" << endl;
+ }
+ t << " </enumvalue>" << endl;
+ }
+ t << " </enumvaluelist>" << endl;
+ }
+ t << " </";
+ switch (mtype)
+ {
+ case Define: t << "definedef"; break;
+ case EnumValue: // fall through
+ case Variable: t << "variabledef"; break;
+ case Typedef: t << "typedef"; break;
+ case Enumeration: t << "enumdef"; break;
+ case Function: // fall through
+ case Signal: // fall through
+ case Prototype: // fall through
+ case Friend: // fall through
+ case Slot: t << "functiondef"; break;
+ }
+ t << ">" << endl;
+}
+
diff --git a/src/memberdef.h b/src/memberdef.h
index c8cab13..0ea0877 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -35,6 +35,7 @@ class ExampleList;
class ExampleDict;
class OutputList;
class GroupDef;
+class QTextStream;
struct SourceReference
{
@@ -209,6 +210,8 @@ class MemberDef : public Definition
QCString getScopeString() const;
+ void generateXML(QTextStream &t,Definition *def);
+
private:
ClassDef *classDef; // member of or related to
FileDef *fileDef; // member of file definition
diff --git a/src/outputgen.h b/src/outputgen.h
index 5f351f0..5b309c7 100644
--- a/src/outputgen.h
+++ b/src/outputgen.h
@@ -33,13 +33,12 @@ class DotGfxHierarchyTable;
class OutputGenerator
{
public:
- enum OutputType { Html, Latex, Man, RTF };
+ enum OutputType { Html, Latex, Man, RTF, XML };
OutputGenerator();
virtual ~OutputGenerator();
virtual OutputGenerator *copy() = 0;
- //virtual OutputGenerator *clone() = 0;
virtual void append(const OutputGenerator *) = 0;
virtual void enable() = 0;
virtual void disable() = 0;
@@ -52,7 +51,6 @@ class OutputGenerator
virtual void startFile(const char *name,const char *title,bool ext) = 0;
virtual void writeFooter(int,bool) = 0;
virtual void endFile() = 0;
- //virtual void writeIndex() = 0;
virtual void startIndexSection(IndexSections) = 0;
virtual void endIndexSection(IndexSections) = 0;
virtual void startProjectNumber() = 0;
@@ -130,7 +128,6 @@ class OutputGenerator
virtual void startCodeAnchor(const char *label) = 0;
virtual void endCodeAnchor() = 0;
virtual void writeLatexSpacing() = 0;
- //virtual void writeLatexLabel(const char *clName,const char *anchor) = 0;
virtual void writeStartAnnoItem(const char *type,const char *file,
const char *path,const char *name) = 0;
virtual void writeEndAnnoItem(const char *name) = 0;
@@ -180,7 +177,6 @@ class OutputGenerator
virtual void startIndent() = 0;
virtual void endIndent() = 0;
virtual void writeSynopsis() = 0;
- //virtual void generateExternalIndex() = 0;
virtual void startClassDiagram() = 0;
virtual void endClassDiagram(ClassDiagram &,const char *,const char *) = 0;
virtual void startColorFont(uchar r,uchar g,uchar b) = 0;
diff --git a/src/reflist.cpp b/src/reflist.cpp
new file mode 100644
index 0000000..8bef347
--- /dev/null
+++ b/src/reflist.cpp
@@ -0,0 +1,86 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2000 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 "reflist.h"
+
+/*! The one and only todo list */
+RefList todoList;
+/*! The test criteria list */
+RefList testList;
+
+
+/*! Create a todo list */
+RefList::RefList()
+{
+ m_dict = 0;
+ m_dictIterator = 0;
+ m_id = 0;
+}
+
+/*! Destroy the todo list. Currently not called! */
+RefList::~RefList()
+{
+ delete m_dictIterator;
+ delete m_dict;
+}
+
+/*! Adds a new item to the list.
+ * \param text The item text.
+ * \returns A unique id for this item.
+ */
+int RefList::addRefItem()
+{
+ if (m_dict==0)
+ {
+ m_dict = new QIntDict<RefItem>(1009);
+ m_dict->setAutoDelete(TRUE);
+ m_dictIterator = new QIntDictIterator<RefItem>(*m_dict);
+ }
+ RefItem *item = new RefItem;
+ m_id++;
+ m_dict->insert(m_id,item);
+ return m_id;
+}
+
+/*! Returns an item given it's id that is obtained with addRefItem()
+ * \param itemId item's identifier.
+ * \returns A pointer to the todo item's structure.
+ */
+RefItem *RefList::getRefItem(int itemId)
+{
+ return m_dict->find(itemId);
+}
+
+/*! Returns the first item in the dictionary or 0 if
+ * non is available.
+ * Items are not sorted.
+ */
+RefItem *RefList::getFirstRefItem()
+{
+ return m_dictIterator->toFirst();
+}
+
+/*! Returns the next item in the dictionary or 0 if
+ * we are at the end of the list.
+ * Items are not sorted.
+ */
+RefItem *RefList::getNextRefItem()
+{
+ return m_dictIterator->operator++();
+}
+
diff --git a/src/reflist.h b/src/reflist.h
new file mode 100644
index 0000000..f0d9958
--- /dev/null
+++ b/src/reflist.h
@@ -0,0 +1,55 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2000 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 _REFLIST_H
+#define _REFLIST_H
+
+#include "qtbc.h"
+#include <qintdict.h>
+
+/*! This struct represents an item in the list of references. */
+struct RefItem
+{
+ RefItem() : written(FALSE) {}
+ QCString text; //!< text of the item.
+ QCString listAnchor; //!< anchor in the list
+ bool written;
+};
+
+/*! Singleton for the one and only RefList */
+class RefList
+{
+ public:
+ int addRefItem();
+ RefItem *getRefItem(int todoItemId);
+ RefItem *getFirstRefItem();
+ RefItem *getNextRefItem();
+
+ RefList();
+ ~RefList();
+
+ private:
+ int m_id;
+ QIntDict<RefItem> *m_dict;
+ QIntDictIterator<RefItem> *m_dictIterator;
+};
+
+extern RefList todoList;
+extern RefList testList;
+
+#endif
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index 5239ffd..8ea9fb0 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -666,7 +666,7 @@ void RTFGenerator::startIndexSection(IndexSections is)
bool found=FALSE;
while (nd && !found)
{
- if (nd->isLinkableInProject() && nd->countMembers()>0)
+ if (nd->isLinkableInProject())
{
beginRTFChapter();
found=TRUE;
@@ -840,7 +840,7 @@ void RTFGenerator::endIndexSection(IndexSections is)
bool found=FALSE;
while (nd && !found)
{
- if (nd->isLinkableInProject() && nd->countMembers()>0)
+ if (nd->isLinkableInProject())
{
t << "\\par " << Rtf_Style["Reset"] << endl;
t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
@@ -852,7 +852,7 @@ void RTFGenerator::endIndexSection(IndexSections is)
}
while (nd)
{
- if (nd->isLinkableInProject() && nd->countMembers()>0)
+ if (nd->isLinkableInProject())
{
t << "\\par " << Rtf_Style["Reset"] << endl;
beginRTFSection();
@@ -941,7 +941,7 @@ void RTFGenerator::endIndexSection(IndexSections is)
{
t << "\\par " << Rtf_Style["Reset"] << endl;
t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
- t << convertSlashes(pi->name,TRUE);
+ t << convertFileName(pi->name);
t << "-example.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
pi=exampleList.next();
}
@@ -950,7 +950,7 @@ void RTFGenerator::endIndexSection(IndexSections is)
t << "\\par " << Rtf_Style["Reset"] << endl;
beginRTFSection();
t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
- t << convertSlashes(pi->name,TRUE);
+ t << convertFileName(pi->name);
t << "-example.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
pi=exampleList.next();
}
diff --git a/src/scanner.l b/src/scanner.l
index ba99f5b..33a4f07 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -42,6 +42,7 @@
#include "language.h"
#include "outputlist.h"
#include "membergroup.h"
+#include "reflist.h"
#ifndef WIN32
#include <unistd.h>
@@ -93,9 +94,10 @@ static int roundCount = 0 ;
static int curlyCount = 0 ;
static int squareCount = 0 ;
static int ifCount = 0 ;
-static int todoAnchor = 0 ;
static int todoStartContext = 0;
static QCString todoString = 0;
+static int testStartContext = 0;
+static QCString testString = 0;
static Entry* current_root = 0 ;
static Entry* global_root = 0 ;
static Entry* current = 0 ;
@@ -237,6 +239,7 @@ static void initParser()
//-----------------------------------------------------------------------------
void scanString(const char *s);
+void internalParseDocument(const char *s);
//-----------------------------------------------------------------------------
@@ -897,11 +900,12 @@ static int yyread(char *buf,int max_size)
%}
CMD ("\\"|"@")
+SECTIONCMD {CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note"|"remark"[s]?|"todo"|"test"|"ingroup")
BN [ \t\n\r]
BL [ \t\r]*"\n"
B [ \t]
BS ^(({B}*"//")?)(({B}*"*"+)?){B}*
-FILE ([a-z_A-Z0-9\.\\:\/\-\+]+)|("\""[^\n\"]+"\"")
+FILE ([a-z_A-Z0-9\\:\/\-\+]+("."[a-z_A-Z0-9\\:\/\-\+]+)*)|("\""[^\n\"]+"\"")
FILEMASK [a-z_A-Z0-9\.\\:\/\-\+]+"."[a-z_A-Z0-9\.\-\+]*[a-z_A-Z0-9\-\+]
ID [a-z_A-Z][a-z_A-Z0-9]*
SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
@@ -1086,6 +1090,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
%x DocLatexImageName
%x DocLatexImageWidth
%x TodoParam
+%x TestParam
%x SectionLabel
%x SectionTitle
%x SkipTemplate
@@ -1278,7 +1283,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
"in documentation."
);
}
-<DocScan>{CMD}"addindex"/{BN} {
+<DocScan>{CMD}"addindex"{B}+ {
BEGIN(DocIndexWord);
}
<DocScan>"\\form#"[0-9]+ {
@@ -1529,6 +1534,46 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
outDoc->writeDescItem();
}
}
+<DocScan>"\\todo "[0-9]+ { // this tag is generated in an earlier pass
+ if (Config::generateTodoList)
+ {
+ QCString numStr=yytext;
+ numStr=numStr.right(numStr.length()-6);
+ bool ok; int num = numStr.toUInt(&ok);
+ RefItem *item = todoList.getRefItem(num);
+ ASSERT(item!=0);
+ endArgumentList();
+ if (inBlock()) endBlock();
+ outDoc->startDescList();
+ outDoc->startBold();
+ outDoc->writeObjectLink(0,"todo",item->listAnchor,theTranslator->trTodo()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ internalParseDocument(item->text);
+ outDoc->endDescList();
+ }
+ }
+<DocScan>"\\test "[0-9]+ { // this tag is generated in an earlier pass
+ if (Config::generateTestList)
+ {
+ QCString numStr=yytext;
+ numStr=numStr.right(numStr.length()-6);
+ bool ok; int num = numStr.toUInt(&ok);
+ RefItem *item = testList.getRefItem(num);
+ ASSERT(item!=0);
+ endArgumentList();
+ if (inBlock()) endBlock();
+ outDoc->startDescList();
+ outDoc->startBold();
+ outDoc->writeObjectLink(0,"test",item->listAnchor,theTranslator->trTest()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ internalParseDocument(item->text);
+ outDoc->endDescList();
+ }
+ }
<DocScan>{CMD}"deprecated"/{BN} {
endArgumentList();
if (!inDeprecatedBlock)
@@ -1560,6 +1605,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
scanString(tagName+": ");
outDoc->endBold();
outDoc->endDescTitle();
+ outDoc->writeDescItem();
scanString(tagText);
outDoc->endDescList();
}
@@ -1760,7 +1806,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
}
BEGIN(DocScan);
}
-<DocRefName>{SCOPENAME} {
+<DocRefName>{SCOPENAME}|{FILE} {
QCString ref=yytext;
SectionInfo *sec;
if ((sec=sectionDict[ref]))
@@ -1789,7 +1835,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
}
BEGIN(DocScan);
}
-<DocRefName>{SCOPENAME}{B}+/"\"" {
+<DocRefName>({SCOPENAME}|{FILE}){B}+/"\"" {
sectionRef=yytext;
sectionRef=sectionRef.stripWhiteSpace();
BEGIN(DocRefArgStart);
@@ -1922,7 +1968,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
generateRef(*outDoc,className,yytext,inSeeBlock);
BEGIN(DocScan);
}
-<DocScan,DocRefName>{SCOPEMASK}("()")? {
+<DocScan,DocRefName>{SCOPEMASK}("()")? {
generateRef(*outDoc,className,yytext,inSeeBlock);
BEGIN(DocScan);
}
@@ -2178,7 +2224,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
}
<DocEmphasis>{WORD} {
outDoc->startEmphasis();
- linkifyText(*outDoc,className,0,yytext,FALSE,FALSE);
+ linkifyText(TextGeneratorOLImpl(*outDoc),className,0,yytext,FALSE,FALSE);
outDoc->endEmphasis();
BEGIN( DocScan );
}
@@ -2196,7 +2242,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
}
<DocBold>{WORD} {
outDoc->startBold();
- linkifyText(*outDoc,className,0,yytext,FALSE,FALSE);
+ linkifyText(TextGeneratorOLImpl(*outDoc),className,0,yytext,FALSE,FALSE);
outDoc->endBold();
BEGIN( DocScan );
}
@@ -2208,7 +2254,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
}
<DocCode>{WORD} {
outDoc->startTypewriter();
- linkifyText(*outDoc,className,0,yytext,FALSE,FALSE);
+ linkifyText(TextGeneratorOLImpl(*outDoc),className,0,yytext,FALSE,FALSE);
outDoc->endTypewriter();
BEGIN( DocScan );
}
@@ -4233,7 +4279,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
current->brief+=".";
BEGIN( tmpDocType );
}
-<JavaDoc>{CMD}("image"|"author"|"internal"|"version"|"date"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note") {
+<JavaDoc>{B}*/{SECTIONCMD} {
current->doc+=yytext;
BEGIN( tmpDocType );
}
@@ -4381,50 +4427,74 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
}
<SkipHtmlComment>"--"[!]?">" { BEGIN(lastSkipHtmlCommentContext); }
<SkipHtmlComment>.
-<LineDoc,Doc,JavaDoc,ClassDoc,PageDoc>{CMD}"todo"{B}+ {
+<AfterDoc,AfterDocLine,LineDoc,Doc,JavaDoc,ClassDoc,PageDoc>{CMD}"todo"/[^a-z_A-Z0-9] {
todoStartContext = YY_START;
- todoString.resize(0);
- BEGIN(TodoParam);
+ lastBriefContext = TodoParam; // this is where we will continue at the end of the argument
+ todoString = current->brief.copy(); // these will be swapped later on.
+ BEGIN(ClassDocBrief);
}
-<TodoParam>[^*/\n]+ {
- todoString+=yytext;
+<AfterDoc,AfterDocLine,LineDoc,Doc,JavaDoc,ClassDoc,PageDoc>{CMD}"test"/[^a-z_A-Z0-9] {
+ testStartContext = YY_START;
+ lastBriefContext = TestParam; // this is where we will continue at the end of the argument
+ testString = current->brief.copy(); // these will be swapped later on.
+ BEGIN(ClassDocBrief);
}
+<TodoParam>\n |
<TodoParam>. {
- todoString+=*yytext;
- }
-<TodoParam>"\n"|"*/" {
- char anchorLabel[12];
- sprintf(anchorLabel,"_todo%06d",todoAnchor++);
- QCString todoItemNum;
- todoItemNum.sprintf("%d",todoAnchor);
- sectionType=SectionInfo::Anchor;
- sectionLabel=anchorLabel;
- addSection();
- current->doc += "\\anchor "+sectionLabel+"\n";
- current->doc += "<p><b>\\link todo ";
- current->doc += theTranslator->trTodo();
- current->doc += ":\\endlink </b>";
- current->doc += todoString + "<p>";
- Entry *page = new Entry;
- page->section = Entry::PAGEDOC_SEC;
- page->fileName = yyFileName;
- page->startLine = yyLineNr;
- page->name = "todo";
- page->args = theTranslator->trTodoList();
- page->doc += "\\ref ";
- page->doc += anchorLabel;
- page->doc += " \""+todoItemNum+"\"\n"+todoString+"<p>";
- global_root->addSubEntry(page);
- if (*yytext=='*')
- {
- unput('/');unput('*');
+ if (current->todoId!=0)
+ {
+ RefItem *item = todoList.getRefItem(current->todoId);
+ item->text += "<p>";
+ item->text += current->brief;
}
else
{
- unput('\n');
+ int todoItemId = todoList.addRefItem();
+ char anchorLabel[12];
+ sprintf(anchorLabel,"_todo%06d",todoItemId);
+ RefItem *item = todoList.getRefItem(todoItemId);
+ item->text = current->brief.copy();
+ item->listAnchor = anchorLabel;
+ current->todoId = todoItemId;
+ QCString todoCmdString;
+ todoCmdString.sprintf("\\todo %d\n",todoItemId);
+ current->doc += todoCmdString;
+ sectionType=SectionInfo::Anchor;
+ sectionLabel=anchorLabel;
+ addSection();
}
+ unput(*yytext);
+ current->brief = todoString.copy(); // restore orginial brief desc.
BEGIN(todoStartContext);
- }
+ }
+<TestParam>\n |
+<TestParam>. {
+ if (current->testId!=0)
+ {
+ RefItem *item = testList.getRefItem(current->testId);
+ item->text += "<p>";
+ item->text += current->brief;
+ }
+ else
+ {
+ int testItemId = testList.addRefItem();
+ char anchorLabel[12];
+ sprintf(anchorLabel,"_test%06d",testItemId);
+ RefItem *item = testList.getRefItem(testItemId);
+ item->text = current->brief.copy();
+ item->listAnchor = anchorLabel;
+ current->testId = testItemId;
+ QCString testCmdString;
+ testCmdString.sprintf("\\test %d\n",testItemId);
+ current->doc += testCmdString;
+ sectionType=SectionInfo::Anchor;
+ sectionLabel=anchorLabel;
+ addSection();
+ }
+ unput(*yytext);
+ current->brief = testString.copy(); // restore orginial brief desc.
+ BEGIN(testStartContext);
+ }
<ExampleDocArg1>{FILE} {
current->name = stripQuotes(yytext);
BEGIN( ExampleDoc );
@@ -4715,7 +4785,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
<Doc,JavaDoc,LineDoc,ExampleDoc,PageDoc,ClassDoc>^{B}*"//"
<Doc,ExampleDoc,PageDoc,ClassDoc>"//" { current->doc += yytext; }
<LineDoc,JavaDoc>"//" { current->brief += yytext; }
-<Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc>("\\\\"|"@@")"f"[$\[\]] {
+<Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief>("\\\\"|"@@")"f"[$\[\]] {
current->doc += &yytext[1];
}
<Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief>{CMD}"f$" {
@@ -4766,6 +4836,18 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
BEGIN( lastDocContext );
}
else if (YY_START==ClassDocBrief &&
+ lastBriefContext==TodoParam)
+ {
+ unput('/');unput('*'); // make sure we have something to read
+ BEGIN( TodoParam );
+ }
+ else if (YY_START==ClassDocBrief &&
+ lastBriefContext==TestParam)
+ {
+ unput('/');unput('*'); // make sure we have something to read
+ BEGIN( TestParam );
+ }
+ else if (YY_START==ClassDocBrief &&
lastBriefContext==Doc)
{
current->doc += "\n\n";
@@ -4799,18 +4881,18 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
<PageDocTitle>\n { yyLineNr++; current->args+=" "; }
<PageDocTitle>[^\n\<] { current->args+=yytext; }
<PageDocTitle>"</"{TITLE}">" { BEGIN( PageDoc ); }
-<ClassDoc,LineDoc,Doc,JavaDoc>{CMD}"ingroup"{B}+ {
+<ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc>{CMD}"ingroup"{B}+ {
lastGroupContext = YY_START;
lineCount();
BEGIN( GroupName );
}
-<ClassDoc,LineDoc,Doc,JavaDoc>{CMD}"nosubgrouping"/[^a-z_A-Z0-9] {
+<ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc>{CMD}"nosubgrouping"/[^a-z_A-Z0-9] {
current->subGrouping = FALSE;
}
-<ClassDoc,LineDoc,Doc,JavaDoc>{CMD}"showinitializer"/[^a-z_A-Z0-9] {
+<ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc>{CMD}"showinitializer"/[^a-z_A-Z0-9] {
current->initLines = 100000; // ON
}
-<ClassDoc,LineDoc,Doc,JavaDoc>{CMD}"hideinitializer"/[^a-z_A-Z0-9] {
+<ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc>{CMD}"hideinitializer"/[^a-z_A-Z0-9] {
current->initLines = 0; // OFF
}
<GroupName>{ID} {
@@ -4837,16 +4919,46 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
<ClassDocBrief>{BS}({BL}|"\\n\\n") {
current->brief=current->brief.stripWhiteSpace();
if (!current->doc.isEmpty()) current->doc+="<p>";
- yyLineNr++;
+ if (lastBriefContext==TodoParam || lastBriefContext==TestParam)
+ {
+ unput('\n');
+ }
+ else
+ {
+ yyLineNr++;
+ }
BEGIN( lastBriefContext );
}
-<ClassDocBrief>"\n" { yyLineNr++ ; current->brief += " "; }
+<ClassDocBrief>"\n" {
+ // allow \todo in brief description
+ if (lastBriefContext==TodoParam &&
+ (todoStartContext==LineDoc ||
+ todoStartContext==AfterDocLine
+ )
+ )
+ {
+ unput('\n'); // make sure we have something to read
+ BEGIN( TodoParam );
+ }
+ else if
+ (lastBriefContext==TestParam &&
+ (testStartContext==LineDoc ||
+ testStartContext==AfterDocLine
+ )
+ )
+ {
+ unput('\n'); // make sure we have something to read
+ BEGIN( TestParam );
+ }
+ else
+ {
+ current->brief += " ";
+ yyLineNr++ ;
+ }
+ }
<ClassDocBrief>"<"{BR}{ATTR}">"
-<ClassDocBrief>{BS}/{CMD}"ingroup" {
+<ClassDocBrief>{BS}/{SECTIONCMD} {
current->brief=current->brief.stripWhiteSpace();
- BEGIN( lastBriefContext );
- }
-<ClassDocBrief>{BS}/{CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see") {
BEGIN( lastBriefContext );
}
<ClassDocBrief>{BS}/{CMD}("brief"|"short"){BN}+ {
@@ -4971,14 +5083,33 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
BEGIN(AfterDoc);
}
<AfterDocLine>. { current->brief+=yytext; }
+<AfterDocBrief>{BS}({BL}|"\\n\\n") {
+ current->brief=current->brief.stripWhiteSpace();
+ yyLineNr++;
+ BEGIN( AfterDoc );
+ }
<AfterDocBrief>"/*"|"//" { current->brief+=yytext; }
-<AfterDocBrief>^{B}*"*"+/[^/\n]
+<AfterDocBrief>{B}*/{SECTIONCMD} {
+ current->brief=current->brief.stripWhiteSpace();
+ BEGIN( AfterDoc );
+ }
<AfterDocBrief>\n { current->brief+=yytext; yyLineNr++; }
<AfterDocBrief>. { current->brief+=*yytext; }
-<AfterDocBrief>^{B}*"*"/[^/\n]{BL} { yyLineNr++;
+
+ /*
+<AfterDocBrief>"<"{BR}{ATTR}">"
+<AfterDocBrief>{BS}/{CMD}"ingroup" {
+ current->brief=current->brief.stripWhiteSpace();
+ BEGIN( lastBriefContext );
+ }
+<AfterDocBrief>{BS}/{SECTIONCMD} {
+ BEGIN( lastBriefContext );
+ }
+<AfterDocBrief>{BS}/[^/\n]{BL} { yyLineNr++;
if (!current->brief.stripWhiteSpace().isEmpty())
BEGIN(AfterDoc);
}
+ */
<AfterDocBrief>"*/" {
if (afterDocTerminator!=0)
unput(afterDocTerminator);
@@ -5032,11 +5163,11 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
unput('/');unput('*');
BEGIN( tmpDocType );
}
-<Doc,JavaDoc,ClassDoc,PageDoc,ExampleDoc,ReadFormulaShort,ReadFormulaLong,ClassDocBrief>^{B}*(("//"{B}*)?)"*"+[ \t]*"-"{B}+ {
+<Doc,JavaDoc,ClassDoc,PageDoc,ExampleDoc,ReadFormulaShort,ReadFormulaLong,ClassDocBrief,AfterDoc,AfterDocBrief>^{B}*(("//"{B}*)?)"*"+[ \t]*"-"{B}+ {
current->doc += yytext;
}
-<Doc,JavaDoc,ClassDoc,PageDoc,ExampleDoc,ReadFormulaShort,ReadFormulaLong,ClassDocBrief>^{B}*(("//"{B}*)?)"*"+/[^/]
-<Doc,JavaDoc,ClassDoc,PageDoc,ExampleDoc,ReadFormulaShort,ReadFormulaLong,ClassDocBrief>^{B}*(("//"{B}*)?)"*"+{B}+ {
+<Doc,JavaDoc,ClassDoc,PageDoc,ExampleDoc,ReadFormulaShort,ReadFormulaLong,ClassDocBrief,AfterDoc,AfterDocBrief>^{B}*(("//"{B}*)?)"*"+/[^/]
+<Doc,JavaDoc,ClassDoc,PageDoc,ExampleDoc,ReadFormulaShort,ReadFormulaLong,ClassDocBrief,AfterDoc,AfterDocBrief>^{B}*(("//"{B}*)?)"*"+{B}+ {
current->doc+=' ';
}
<DefLineDoc,LineDoc,ClassDoc,Doc>"/*" { current->doc += yytext; }
@@ -5097,6 +5228,25 @@ void scanString(const char *s)
BEGIN( oldRule );
}
+void internalParseDocument(const char *s)
+{
+ const char *oldInputString = inputString;
+ int oldInputPosition = inputPosition;
+ int oldRule = YY_START;
+ YY_BUFFER_STATE oldBuffer = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_create_buffer(scanYYin, YY_BUF_SIZE));
+ inputString = s;
+ inputPosition = 0;
+ BEGIN( DocScan );
+ scanYYlex();
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(oldBuffer);
+ inputString = oldInputString;
+ inputPosition = oldInputPosition;
+ BEGIN( oldRule );
+}
+
+
//----------------------------------------------------------------------------
static void newDocState()
diff --git a/src/translator.h b/src/translator.h
index cb2e2ab..25d25d6 100644
--- a/src/translator.h
+++ b/src/translator.h
@@ -977,6 +977,22 @@ class Translator
{
return "legend";
}
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTestList()
+ {
+ return "Test List";
+ }
+
};
#endif
diff --git a/src/translator_de.h b/src/translator_de.h
index a48251b..44d2ec5 100644
--- a/src/translator_de.h
+++ b/src/translator_de.h
@@ -560,7 +560,7 @@ class TranslatorGerman : public Translator
bool single)
{ // here s is one of " Class", " Struct" or " Union"
// single is true implies a single file
- QCString result=(QCString)"Die Dokumentation für diese";
+ QCString result=(QCString)"Die Dokumentation f&uuml;r diese";
switch(compType)
{
case ClassDef::Class: result+=" Klasse"; break;
@@ -634,10 +634,11 @@ class TranslatorGerman : public Translator
{
return (QCString)"Zusammengeh&ouml;rigkeiten von "+clName+":";
}
+ //RK: Apparently Jens missed the Umlaut here. Corrected that.
/*! this text is put before an include dependency graph */
virtual QCString trInclDepGraph(const char *fName)
{
- return (QCString)"Include-Abhängikeitsdiagramm f&uuml;r "+fName+":";
+ return (QCString)"Include-Abh&auml;ngikeitsdiagramm f&uuml;r "+fName+":";
}
/*! header that is put before the list of constructor/destructors. */
virtual QCString trConstructorDocumentation()
@@ -700,9 +701,10 @@ class TranslatorGerman : public Translator
// new since 1.1.0
//////////////////////////////////////////////////////////////////////////
+ //RK: had to change here because of the new command \remark
virtual QCString trNote()
{
- return "Bemerkung";
+ return "Zu beachten";
}
virtual QCString trPublicTypes()
@@ -742,9 +744,123 @@ class TranslatorGerman : public Translator
return "Statische private Attribute";
}
- //////////////////////////////////////////////////////////////////////////
- // new since 1.1.1
- //////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+//RK: Started from here
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTodo()
+ {
+ return "Noch zu erledigen";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTodoList()
+ {
+ return "Liste der zu erledigenden Dinge";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ virtual QCString trReferencedBy()
+ {
+ return "Wird benutzt von";
+ }
+ virtual QCString trRemarks()
+ {
+ return "Bemerkungen";
+ }
+ virtual QCString trAttention()
+ {
+ return "Achtung";
+ }
+ virtual QCString trInclByDepGraph()
+ {
+ return "Dieser Graph zeigt, welche Datei direkt oder "
+ "indirekt diese Datei enth&auml;lt:";
+ }
+ virtual QCString trSince()
+ {
+ return "Seit";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ virtual QCString trLegendTitle()
+ {
+ return "Erkl&auml;rung des Graphen";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ virtual QCString trLegendDocs()
+ {
+ return
+ "Diese Seite erkl&auml;rt die Interpretation der von doxygen "
+ "erzeugten Graphen.<p>\n"
+ "Beispiel:\n"
+ "\\code\n"
+ "/*! Wegen Verk&uuml;rzung unsichtbare Klasse */\n"
+ "class Invisible { };\n\n"
+ "/*! Klasse verk&uuml;rzt dargestellt, Vererbunsbeziehung ist versteckt */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* Nicht mit doxygen-Kommentaren dokumentierte Klasse */\n"
+ "class Undocumented { };\n\n"
+ "/*! Mithilfe &ouml;ffentlicher Vererbung vererbte Klasse */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! Mithilfe gesch&uumltzter Vererbung vererbte Klasse */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! Mithilfe privater Vererbung vererbte Klasse */\n"
+ "class PrivateBase { };\n\n"
+ "/*! Von der Klasse Inherited benutzte Klasse */\n"
+ "class Used { };\n\n"
+ "/*! Superklasse, die von mehreren anderen Klassen erbt */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Setzen des Tags \\c MAX_DOT_GRAPH_HEIGHT in der Konfigurationsdatei "
+ "auf 200 liefert den folgenden Graphen:"
+ "<p><center><img src=\"graph_legend.gif\"></center>\n"
+ "<p>\n"
+ "Die Rechtecke in obigem Graphen bedeuten:\n"
+ "<ul>\n"
+ "<li>Ein schwarz gef&uuml;lltes Rechteck stellt die Struktur oder "
+ "Klasse dar, f&uuml;die der Graph erzeug wurde.\n"
+ "<li>Ein Rechteck mit schwarzem Rahmen kennzeichnet eine dokumentierte "
+ " Struktur oder Klasse.\n"
+ "<li>Ein Rechteck mit grauem Rahmen kennzeichnet eine undokumentierte "
+ " Struktur oder Klasse.\n"
+ "<li>Ein Rechteck mit rotem Rahmen kennzeichnet eine dokumentierte "
+ " Struktur oder Klasse, f&uuml;r die nicht alle Vererbungs-/"
+ "Enthaltenseinsbeziehungen dargestellt werden. Ein Graph wird gek&uuml;rzt, "
+ "wenn er nicht in die angegebenen Schranken passt."
+ "</ul>\n"
+ "Die Pfeile bedeuten:\n"
+ "<ul>\n"
+ "<li>Ein dunkelblauer Pfeil stellt eine &ouml;ffentliche Vererbungsbeziehung "
+ "zwischen zwei Klassen dar.\n"
+ "<li>Ein dunkelgr&uuml;ner Pfeil stellt gesch&uuml;tzte Vererbung dar.\n"
+ "<li>Ein dunkelroter Pfeil stellt private Vererbung dar.\n"
+ "<li>Ein gestrichelter violetter Pfeil beutet, dass eine Klasse in einer "
+ "anderen enthalten ist oder von einer anderen benutzt wird. Am Pfeil "
+ "stehen die Variable(n), mit deren Hilfe auf die Struktur oder Klasse "
+ "an der Pfeilspize zugegriffen werden kann. \n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ virtual QCString trLegend()
+ {
+ return "Legende";
+ }
};
diff --git a/src/translator_nl.h b/src/translator_nl.h
index 1112ce8..d366cc5 100644
--- a/src/translator_nl.h
+++ b/src/translator_nl.h
@@ -696,6 +696,22 @@ class TranslatorDutch : public Translator
{
return "legenda";
}
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the todo list */
+ virtual QCString trTestList()
+ {
+ return "Test Lijst";
+ }
+
};
#endif
diff --git a/src/util.cpp b/src/util.cpp
index 8d29fd4..1870400 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -282,7 +282,16 @@ ClassDef *getResolvedClass(const char *name)
else
{
//printf("getClass: subst %s->%s\n",name,subst->data());
- return classDict[subst->data()];
+ int i;
+ ClassDef *cd = classDict[subst->data()];
+ if (cd==0 && (i=subst->find('<'))>0) // try unspecialized version as well
+ {
+ return classDict[subst->left(i)];
+ }
+ else
+ {
+ return cd;
+ }
}
}
else
@@ -291,6 +300,20 @@ ClassDef *getResolvedClass(const char *name)
}
}
+static bool findOperator(const QCString &s,int i)
+{
+ int b = s.findRev("operator",i);
+ if (b==-1) return FALSE; // not found
+ b+=8;
+ while (b<i) // check if there are only spaces inbetween
+ // the operator and the >
+ {
+ if (!isspace(s.at(b))) return FALSE;
+ b++;
+ }
+ return TRUE;
+}
+
QCString removeRedundantWhiteSpace(const QCString &s)
{
if (s.isEmpty()) return s;
@@ -301,15 +324,15 @@ QCString removeRedundantWhiteSpace(const QCString &s)
{
char c=s.at(i);
if (i<l-2 && c=='<' && // current char is a <
- (isId(s.at(i+1)) || isspace(s.at(i+1))) && // next char is a id char or space
- (i<8 || s.mid(i-8,8)!="operator") // string in front is not "operator"
+ (isId(s.at(i+1)) || isspace(s.at(i+1))) && // next char is an id char or space
+ (i<8 || !findOperator(s,i)) // string in front is not "operator"
)
{
result+="< "; // insert extra space for layouting (nested) templates
}
else if (i>0 && c=='>' && // current char is a >
- (isId(s.at(i-1)) || isspace(s.at(i-1))) && // prev char is a id char or space
- (i<8 || s.mid(i-8,8)!="operator") // string in front is not "operator"
+ (isId(s.at(i-1)) || isspace(s.at(i-1))) && // prev char is an id char or space
+ (i<8 || !findOperator(s,i)) // string in front is not "operator"
)
{
result+=" >"; // insert extra space for layouting (nested) templates
@@ -346,7 +369,8 @@ bool leftScopeMatch(const QCString &scope, const QCString &name)
);
}
-void linkifyText(OutputList &ol,const char *scName,const char *name,const char *text,bool autoBreak,bool external)
+
+void linkifyText(const TextGeneratorIntf &out,const char *scName,const char *name,const char *text,bool autoBreak,bool external)
{
//printf("scope=`%s' name=`%s' Text: `%s'\n",scName,name,text);
static QRegExp regExp("[a-z_A-Z][a-z_A-Z0-9:]*");
@@ -373,18 +397,22 @@ void linkifyText(OutputList &ol,const char *scName,const char *name,const char *
if (i==-1) i=splitText.find(' ');
if (i!=-1) // add a link-break at i in case of Html output
{
- ol.docify(splitText.left(i+1));
- ol.pushGeneratorState();
- ol.disableAllBut(OutputGenerator::Html);
- ol.lineBreak();
- ol.popGeneratorState();
- ol.docify(splitText.right(splitLength-i-1));
+ //ol.docify(splitText.left(i+1));
+ //ol.pushGeneratorState();
+ //ol.disableAllBut(OutputGenerator::Html);
+ //ol.lineBreak();
+ //ol.popGeneratorState();
+ //ol.docify(splitText.right(splitLength-i-1));
+ out.writeString(splitText.left(i+1));
+ out.writeBreak();
+ out.writeString(splitText.right(splitLength-i-1));
}
floatingIndex=splitLength-i-1;
}
else
{
- ol.docify(txtStr.mid(skipIndex,newIndex-skipIndex));
+ //ol.docify(txtStr.mid(skipIndex,newIndex-skipIndex));
+ out.writeString(txtStr.mid(skipIndex,newIndex-skipIndex));
}
// get word from string
QCString word=txtStr.mid(newIndex,matchLen);
@@ -422,7 +450,8 @@ void linkifyText(OutputList &ol,const char *scName,const char *name,const char *
// add link to the result
if (external ? cd->isLinkable() : cd->isLinkableInProject())
{
- ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,word);
+ //ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,word);
+ out.writeLink(cd->getReference(),cd->getOutputFileBase(),0,word);
found=TRUE;
}
}
@@ -450,7 +479,9 @@ void linkifyText(OutputList &ol,const char *scName,const char *name,const char *
if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
if (d && (external ? d->isLinkable() : d->isLinkableInProject()))
{
- ol.writeObjectLink(d->getReference(),d->getOutputFileBase(),
+ //ol.writeObjectLink(d->getReference(),d->getOutputFileBase(),
+ // md->anchor(),word);
+ out.writeLink(d->getReference(),d->getOutputFileBase(),
md->anchor(),word);
found=TRUE;
}
@@ -458,19 +489,22 @@ void linkifyText(OutputList &ol,const char *scName,const char *name,const char *
if (!found) // add word to the result
{
- ol.docify(word);
+ //ol.docify(word);
+ out.writeString(word);
}
}
else
{
- ol.docify(word);
+ //ol.docify(word);
+ out.writeString(word);
}
// set next start point in the string
skipIndex=index=newIndex+matchLen;
floatingIndex+=matchLen;
}
// add last part of the string to the result.
- ol.docify(txtStr.right(txtStr.length()-skipIndex));
+ //ol.docify(txtStr.right(txtStr.length()-skipIndex));
+ out.writeString(txtStr.right(txtStr.length()-skipIndex));
}
@@ -2016,7 +2050,7 @@ bool generateLink(OutputList &ol,const char *clName,
}
else if ((pi=exampleDict[linkRef])) // link to an example
{
- ol.writeObjectLink(0,convertSlashes(pi->name,TRUE)+"-example",0,lt);
+ ol.writeObjectLink(0,convertFileName(pi->name)+"-example",0,lt);
return TRUE;
}
else if ((gd=groupDict[linkRef])) // link to a group
@@ -2034,6 +2068,7 @@ bool generateLink(OutputList &ol,const char *clName,
{
// link to documented input file
ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,lt);
+ writePageRef(ol,fd->getOutputFileBase(),0);
return TRUE;
}
else // probably a class or member reference
@@ -2084,13 +2119,13 @@ QCString substituteClassNames(const QCString &s)
//----------------------------------------------------------------------
-QCString convertSlashes(const QCString &s,bool dots)
+QCString convertFileName(const QCString &s)
{
QCString result;
int i,l=s.length();
for (i=0;i<l;i++)
{
- if (s.at(i)!='/' && (!dots || s.at(i)!='.'))
+ if (s.at(i)!='/' && s.at(i)!='.')
{
if (Config::caseSensitiveNames)
{
@@ -2299,7 +2334,7 @@ bool hasVisibleRoot(BaseClassList *bcl)
return FALSE;
}
-QCString convertNameToFile(const char *name)
+QCString convertNameToFile(const char *name,bool allowDots)
{
QCString result;
char c;
@@ -2316,6 +2351,7 @@ QCString convertNameToFile(const char *name)
case '|': result+="_p_"; break;
case '!': result+="_e_"; break;
case ',': result+="_x_"; break;
+ case '.': if (allowDots) result+="."; else result+="_"; break;
case ' ': break;
default:
if (Config::caseSensitiveNames)
@@ -2325,6 +2361,7 @@ QCString convertNameToFile(const char *name)
break;
}
}
+ //printf("convertNameToFile(%s)=`%s'\n",name,result.data());
return result;
}
diff --git a/src/util.h b/src/util.h
index 3d683d8..97db3d9 100644
--- a/src/util.h
+++ b/src/util.h
@@ -23,6 +23,9 @@
#include <qtextstream.h>
#include <ctype.h>
+#include "outputlist.h"
+#include "xml.h"
+
class ClassDef;
class FileDef;
class MemberList;
@@ -36,12 +39,69 @@ class ClassList;
class BaseClassList;
class GroupDef;
class NamespaceList;
+class OutputList;
+
+class TextGeneratorIntf
+{
+ public:
+ virtual void writeString(const char *) const = 0;
+ virtual void writeBreak() const = 0;
+ virtual void writeLink(const char *extRef,const char *file,
+ const char *anchor,const char *text
+ ) const = 0;
+};
+
+class TextGeneratorOLImpl : public TextGeneratorIntf
+{
+ public:
+ TextGeneratorOLImpl(OutputList &ol) : m_ol(ol) {}
+ void writeString(const char *s) const
+ { m_ol.docify(s); }
+ void writeBreak() const
+ {
+ m_ol.pushGeneratorState();
+ m_ol.disableAllBut(OutputGenerator::Html);
+ m_ol.lineBreak();
+ m_ol.popGeneratorState();
+ }
+ void writeLink(const char *extRef,const char *file,
+ const char *anchor,const char *text
+ ) const
+ {
+ m_ol.writeObjectLink(extRef,file,anchor,text);
+ }
+ private:
+ OutputList &m_ol;
+};
+
+class TextGeneratorXMLImpl : public TextGeneratorIntf
+{
+ public:
+ TextGeneratorXMLImpl(QTextStream &t) : m_t(t) {}
+ void writeString(const char *s) const
+ {
+ writeXMLString(m_t,s);
+ }
+ void writeBreak() const {}
+ void writeLink(const char *extRef,const char *file,
+ const char *anchor,const char *text
+ ) const
+ {
+ if (extRef==0)
+ { writeXMLLink(m_t,file,anchor,text); }
+ else // external references are not supported for XML
+ { writeXMLString(m_t,text); }
+ }
+ private:
+ QTextStream &m_t;
+};
+
+extern void linkifyText(const TextGeneratorIntf &ol,const char *clName,const char *name,
+ const char *text,bool autoBreak=FALSE,bool external=TRUE);
extern void setAnchors(char id,MemberList *ml,int groupId=-1);
extern QCString fileToString(const char *name);
extern QCString dateToString(bool);
-extern void linkifyText(OutputList &ol,const char *clName,const char *name,
- const char *text,bool autoBreak=FALSE,bool external=TRUE);
extern bool getDefs(const QCString &scopeName,const QCString &memberName,
const char *, MemberDef *&md,
ClassDef *&cd,FileDef *&fd,
@@ -58,7 +118,7 @@ extern bool matchArguments(ArgumentList *,ArgumentList *,
NamespaceList *usingList=0);
extern void mergeArguments(ArgumentList *,ArgumentList *);
extern QCString substituteClassNames(const QCString &s);
-extern QCString convertSlashes(const QCString &s,bool dots=FALSE);
+extern QCString convertFileName(const QCString &s);
extern QCString substitute(const char *s,const char *src,const char *dst);
extern QCString resolveDefines(const char *n);
extern ClassDef *getClass(const char *key);
@@ -92,7 +152,7 @@ QCString removeAnnonymousScopes(const QCString &s);
void initClassHierarchy(ClassList *cl);
bool hasVisibleRoot(BaseClassList *bcl);
int minClassDistance(ClassDef *cd,ClassDef *bcd,int level=0);
-QCString convertNameToFile(const char *name);
+QCString convertNameToFile(const char *name,bool allowDots=FALSE);
void extractNamespaceName(const QCString &scopeName,
QCString &className,QCString &namespaceName);
QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &templ);
diff --git a/src/xml.cpp b/src/xml.cpp
new file mode 100644
index 0000000..fd2cf45
--- /dev/null
+++ b/src/xml.cpp
@@ -0,0 +1,139 @@
+/******************************************************************************
+ *
+ *
+ *
+ *
+ * Copyright (C) 1997-2000 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 "qtbc.h"
+#include "xml.h"
+#include "doxygen.h"
+#include "message.h"
+#include "config.h"
+#include "classlist.h"
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qtextstream.h>
+
+const char dtd_data[]=
+#include "xml_dtd.h"
+;
+
+void generateDTD()
+{
+ QCString fileName=Config::outputDir+"/xml/doxygen.dtd";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ QTextStream t(&f);
+ t << dtd_data;
+}
+
+void writeXMLString(QTextStream &t,const char *s)
+{
+ if (s==0) return;
+ const char *p=s;
+ char c;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '<': t << "&lt;"; break;
+ case '>': t << "&gt;"; break;
+ case '&': t << "&amp;"; break;
+ case '\'': t << "&apos;"; break;
+ case '"': t << "&quot;"; break;
+ default: t << c; break;
+ }
+ }
+}
+
+void writeXMLLink(QTextStream &t,const char *compoundId,const char *memId,
+ const char *text)
+{
+ if (memId==0)
+ {
+ t << "<compoundref idref=\"" << compoundId << "\">";
+ writeXMLString(t,text);
+ t << "</compoundref>";
+ }
+ else
+ {
+ t << "<memberref idref=\"" << compoundId << ":" << memId << "\">";
+ writeXMLString(t,text);
+ t << "</memberref>";
+ }
+}
+
+void generateXML()
+{
+ QDir dir(Config::outputDir);
+ if (!dir.exists())
+ {
+ dir.setPath(QDir::currentDirPath());
+ if (!dir.mkdir(Config::outputDir))
+ {
+ err("Cannot create directory %s\n",Config::outputDir.data());
+ return;
+ }
+ }
+ QDir xmlDir(Config::outputDir+"/xml");
+ if (!xmlDir.exists() && !xmlDir.mkdir(Config::outputDir+"/xml"))
+ {
+ err("Could not create xml directory in %s\n",Config::outputDir.data());
+ return;
+ }
+ generateDTD();
+
+ QCString fileName=Config::outputDir+"/xml/doxygen.xml";
+ QFile f(fileName);
+ if (!f.open(IO_WriteOnly))
+ {
+ err("Cannot open file %s for writing!\n",fileName.data());
+ return;
+ }
+ QTextStream t(&f);
+ t << "<?xml version='1.0' encoding='ISO-8859-1' standalone='no'?>" << endl;
+ t << "<!DOCTYPE doxygen SYSTEM \"doxygen.dtd\">" << endl;
+ t << "<doxygen>" << endl;
+ if (classList.count()+inputNameList.count()>0)
+ {
+ t << " <compoundlist>" << endl;
+ ClassListIterator cli(classList);
+ ClassDef *cd;
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
+ cd->generateXML(t);
+ }
+ FileNameListIterator fnli(inputNameList);
+ FileName *fn;
+ for (;(fn=fnli.current());++fnli)
+ {
+ FileNameIterator fni(*fn);
+ FileDef *fd;
+ for (;(fd=fni.current());++fni)
+ {
+ fd->generateXML(t);
+ }
+ }
+ t << " </compoundlist>" << endl;
+ }
+ t << "</doxygen>" << endl;
+}
+
+
diff --git a/src/xml.h b/src/xml.h
new file mode 100644
index 0000000..ee0f85f
--- /dev/null
+++ b/src/xml.h
@@ -0,0 +1,25 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2000 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.
+ *
+ */
+
+#ifndef XML_H
+#define XML_H
+
+class QTextStream;
+
+void generateXML();
+void writeXMLString(QTextStream &t,const char *s);
+void writeXMLLink(QTextStream &t,const char *compoundRef,const char *memAnchor,
+ const char *text);
+
+#endif
diff --git a/src/xml_dtd.h b/src/xml_dtd.h
new file mode 100644
index 0000000..f43db77
--- /dev/null
+++ b/src/xml_dtd.h
@@ -0,0 +1,115 @@
+"<?xml encoding=\"ISO-8859-1\"?>\n"
+"<!-- DTD describing the grammar used in doxygen's XML output -->\n"
+"\n"
+"<!-- standard character entities -->\n"
+"<!ENTITY lt \"&#38;#60;\"> \n"
+"<!ENTITY gt \"&#62;\"> \n"
+"<!ENTITY amp \"&#38;#38;\"> \n"
+"<!ENTITY apos \"&#39;\"> \n"
+"<!ENTITY quot \"&#34;\"> \n"
+"\n"
+"<!-- required attributes for compounds -->\n"
+"<!ENTITY % compound-req.att \n"
+" 'id ID #REQUIRED\n"
+" type (group|file|namespace|\n"
+" class|struct|union|\n"
+" interface|dispinterface|\n"
+" valuetype|library) #REQUIRED'\n"
+">\n"
+"<!-- required attributes for references -->\n"
+"<!ENTITY % ref-req.att 'idref IDREF #REQUIRED'\n"
+">\n"
+"<!-- required attributes for inheritance relations -->\n"
+"<!ENTITY % inheritcompref-req.att\n"
+" '%ref-req.att;\n"
+" prot (public|protected|private) #REQUIRED\n"
+" virt (non-virtual|virtual) #REQUIRED'\n"
+">\n"
+"\n"
+"<!-- required attributes for member sections -->\n"
+"<!ENTITY % sec-req.att 'type (user\n"
+" |public-type\n"
+" |public-func\n"
+" |public-attrib\n"
+" |public-slot\n"
+" |public-static-func\n"
+" |public-static-attrib\n"
+" |protected-type\n"
+" |protected-func\n"
+" |protected-attrib\n"
+" |protected-slot\n"
+" |protected-static-func\n"
+" |protected-static-attrib\n"
+" |private-type\n"
+" |private-func\n"
+" |private-attrib\n"
+" |private-slot\n"
+" |private-static-func\n"
+" |private-static-attrib\n"
+" |signal\n"
+" |friend\n"
+" |related\n"
+" |define|prototype|typedef|enum|func|var\n"
+" ) #REQUIRED\n"
+" '\n"
+">\n"
+"<!-- required attributes for members -->\n"
+"<!ENTITY % mem-req.att 'id ID #REQUIRED'>\n"
+"\n"
+"<!-- optional attributes for function -->\n"
+"<!ENTITY % func-opt.att 'virt (virtual|pure-virtual) #IMPLIED'>\n"
+"\n"
+"<!-- elements -->\n"
+"<!ELEMENT doxygen (compoundlist?)>\n"
+"<!ELEMENT compoundlist (compounddef)+>\n"
+"<!ELEMENT compounddef (compoundname,\n"
+" basecompoundlist?, \n"
+" derivedcompoundlist?, \n"
+" sectionlist? \n"
+" )\n"
+">\n"
+"<!ATTLIST compounddef %compound-req.att;>\n"
+"<!ELEMENT basecompoundlist (basecompoundref)+>\n"
+"<!ELEMENT derivedcompoundlist (derivedcompoundref)+>\n"
+"<!ELEMENT compoundref (#PCDATA)>\n"
+"<!ATTLIST compoundref %ref-req.att;>\n"
+"<!ELEMENT memberref (#PCDATA)>\n"
+"<!ATTLIST memberref %ref-req.att;>\n"
+"<!ELEMENT basecompoundref EMPTY>\n"
+"<!ATTLIST basecompoundref %inheritcompref-req.att;>\n"
+"<!ELEMENT derivedcompoundref EMPTY>\n"
+"<!ATTLIST derivedcompoundref %inheritcompref-req.att;>\n"
+"<!ELEMENT sectionlist (sectiondef)+>\n"
+"<!ELEMENT sectiondef (memberlist)>\n"
+"<!ATTLIST sectiondef %sec-req.att;>\n"
+"<!ELEMENT memberlist (functiondef|variabledef|typedef|definedef|enumdef)+>\n"
+"<!ELEMENT functiondef (type?,name,paramlist)>\n"
+"<!ATTLIST functiondef %mem-req.att; %func-opt.att;>\n"
+"<!ELEMENT variabledef (type,name,array?,initializer?)>\n"
+"<!ATTLIST variabledef %mem-req.att;>\n"
+"<!ELEMENT typedef (type,name)>\n"
+"<!ATTLIST typedef %mem-req.att;>\n"
+"<!ELEMENT definedef (name,defparamlist?,initializer?)>\n"
+"<!ATTLIST definedef %mem-req.att;>\n"
+"<!ELEMENT enumdef (name,enumvaluelist)>\n"
+"<!ATTLIST enumdef %mem-req.att;>\n"
+"<!ELEMENT slotdef (type,name,paramlist)>\n"
+"<!ATTLIST slotdef %mem-req.att;>\n"
+"<!ELEMENT signaldef (type,name,paramlist)>\n"
+"<!ATTLIST signaldef %mem-req.att;>\n"
+"<!ELEMENT paramlist (param)*>\n"
+"<!ELEMENT param (attributes?,type,declname?,defname?,array?,defval?)>\n"
+"<!ELEMENT defparamlist (defarg)*>\n"
+"<!ELEMENT defarg (#PCDATA)>\n"
+"<!ELEMENT enumvaluelist (enumvalue)*>\n"
+"<!ELEMENT enumvalue (name,initializer?)>\n"
+"<!ELEMENT name (#PCDATA)>\n"
+"<!ELEMENT compoundname (#PCDATA)>\n"
+"<!ELEMENT declname (#PCDATA)>\n"
+"<!ELEMENT defname (#PCDATA)>\n"
+"<!ELEMENT type (#PCDATA|memberref|compoundref|compounddef)*>\n"
+"<!ELEMENT defval (#PCDATA|memberref|compoundref)*>\n"
+"<!ELEMENT initializer (#PCDATA|memberref|compoundref)*>\n"
+"<!ELEMENT array (#PCDATA)>\n"
+"<!ELEMENT attributes (#PCDATA)>\n"
+"\n"