summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/classdef.cpp365
-rw-r--r--src/classdef.h1
-rw-r--r--src/cmdmapper.cpp8
-rw-r--r--src/cmdmapper.h28
-rw-r--r--src/commentcnv.l77
-rw-r--r--src/config.l42
-rw-r--r--src/docparser.cpp198
-rw-r--r--src/docparser.h3
-rw-r--r--src/dot.cpp476
-rw-r--r--src/dot.h12
-rw-r--r--src/doxygen.cpp81
-rw-r--r--src/filedef.cpp6
-rw-r--r--src/htmldocvisitor.cpp10
-rw-r--r--src/htmlgen.cpp2
-rw-r--r--src/index.cpp3
-rw-r--r--src/latexgen.cpp9
-rw-r--r--src/memberdef.cpp13
-rw-r--r--src/msc.cpp6
-rw-r--r--src/namespacedef.cpp2
-rw-r--r--src/translator_cn.h3
-rw-r--r--src/util.cpp166
-rw-r--r--src/util.h11
-rw-r--r--src/xmlgen.cpp2
23 files changed, 846 insertions, 678 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp
index a5bca00..bbfe3e8 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -596,7 +596,7 @@ void ClassDef::internalInsertMember(MemberDef *md,
m_impl->isAbstract=TRUE;
}
- ::addClassMemberNameToIndex(md);
+ //::addClassMemberNameToIndex(md);
if (addToAllList &&
!(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&
md->isFriend() &&
@@ -982,6 +982,192 @@ void ClassDef::showUsedFiles(OutputList &ol)
}
+void ClassDef::writeClassDiagrams(OutputList &ol)
+{
+ // count direct inheritance relations
+ int count=0;
+ BaseClassDef *ibcd;
+ if (m_impl->inheritedBy)
+ {
+ ibcd=m_impl->inheritedBy->first();
+ while (ibcd)
+ {
+ ClassDef *icd=ibcd->classDef;
+ if ( icd->isVisibleInHierarchy()) count++;
+ ibcd=m_impl->inheritedBy->next();
+ }
+ }
+ if (m_impl->inherits)
+ {
+ ibcd=m_impl->inherits->first();
+ while (ibcd)
+ {
+ ClassDef *icd=ibcd->classDef;
+ if ( icd->isVisibleInHierarchy()) count++;
+ ibcd=m_impl->inherits->next();
+ }
+ }
+
+
+ bool renderDiagram = FALSE;
+ if (Config_getBool("HAVE_DOT") && Config_getBool("CLASS_GRAPH"))
+ // write class diagram using dot
+ {
+ DotClassGraph inheritanceGraph(this,DotNode::Inheritance);
+ if (!inheritanceGraph.isTrivial() && !inheritanceGraph.isTooBig())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.startDotGraph();
+ ol.parseText(theTranslator->trClassDiagram(displayName()));
+ ol.endDotGraph(inheritanceGraph);
+ if (Config_getBool("GENERATE_LEGEND"))
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeString("<center><font size=\"2\">[");
+ ol.startHtmlLink(relativePathToRoot(0)+"graph_legend"+Doxygen::htmlFileExtension);
+ ol.docify(theTranslator->trLegend());
+ ol.endHtmlLink();
+ ol.writeString("]</font></center>");
+ ol.popGeneratorState();
+ }
+ ol.popGeneratorState();
+ renderDiagram = TRUE;
+ }
+ }
+ else if (Config_getBool("CLASS_DIAGRAMS") && count>0)
+ // write class diagram using build-in generator
+ {
+ ClassDiagram diagram(this); // create a diagram of this class.
+ ol.startClassDiagram();
+ ol.disable(OutputGenerator::Man);
+ ol.parseText(theTranslator->trClassDiagram(displayName()));
+ ol.enable(OutputGenerator::Man);
+ ol.endClassDiagram(diagram,getOutputFileBase(),displayName());
+ renderDiagram = TRUE;
+ }
+
+ if (Config_getBool("CLASS_DIAGRAMS") && renderDiagram)
+ {
+ ol.disableAllBut(OutputGenerator::Man);
+ }
+
+ if (m_impl->inherits && (count=m_impl->inherits->count())>0)
+ {
+ //parseText(ol,theTranslator->trInherits()+" ");
+
+ QCString inheritLine = theTranslator->trInheritsList(m_impl->inherits->count());
+ QRegExp marker("@[0-9]+");
+ int index=0,newIndex,matchLen;
+ // now replace all markers in inheritLine with links to the classes
+ while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
+ {
+ ol.parseText(inheritLine.mid(index,newIndex-index));
+ bool ok;
+ uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
+ BaseClassDef *bcd=m_impl->inherits->at(entryIndex);
+ if (ok && bcd)
+ {
+ ClassDef *cd=bcd->classDef;
+ if (cd->isLinkable())
+ {
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <base";
+ if (bcd->prot==Protected)
+ {
+ Doxygen::tagFile << " protection=\"protected\"";
+ }
+ else if (bcd->prot==Private)
+ {
+ Doxygen::tagFile << " protection=\"private\"";
+ }
+ if (bcd->virt==Virtual)
+ {
+ Doxygen::tagFile << " virtualness=\"virtual\"";
+ }
+ Doxygen::tagFile << ">" << convertToXML(cd->name()) << "</base>" << endl;
+ }
+ ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->displayName()+bcd->templSpecifiers);
+ }
+ else
+ {
+ ol.docify(cd->displayName());
+ }
+ }
+ else
+ {
+ err("Error: invalid marker %d in inherits list!\n",entryIndex);
+ }
+ index=newIndex+matchLen;
+ }
+ ol.parseText(inheritLine.right(inheritLine.length()-index));
+ ol.newParagraph();
+ }
+
+ // write subclasses
+ if (m_impl->inheritedBy && (count=m_impl->inheritedBy->count())>0)
+ {
+ QCString inheritLine = theTranslator->trInheritedByList(m_impl->inheritedBy->count());
+ QRegExp marker("@[0-9]+");
+ int index=0,newIndex,matchLen;
+ // now replace all markers in inheritLine with links to the classes
+ while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
+ {
+ ol.parseText(inheritLine.mid(index,newIndex-index));
+ bool ok;
+ uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
+ BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex);
+ if (ok && bcd)
+ {
+ ClassDef *cd=bcd->classDef;
+ if (cd->isLinkable())
+ {
+ ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->displayName());
+ }
+ else
+ {
+ ol.docify(cd->displayName());
+ }
+ writeInheritanceSpecifier(ol,bcd);
+ }
+ index=newIndex+matchLen;
+ }
+ ol.parseText(inheritLine.right(inheritLine.length()-index));
+ ol.newParagraph();
+ }
+
+ if (Config_getBool("CLASS_DIAGRAMS") && renderDiagram)
+ {
+ ol.enableAll();
+ }
+
+ if (Config_getBool("HAVE_DOT") && Config_getBool("COLLABORATION_GRAPH"))
+ {
+ DotClassGraph usageImplGraph(this,DotNode::Collaboration);
+ if (!usageImplGraph.isTrivial())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.startDotGraph();
+ ol.parseText(theTranslator->trCollaborationDiagram(displayName()));
+ ol.endDotGraph(usageImplGraph);
+ if (Config_getBool("GENERATE_LEGEND"))
+ {
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeString("<center><font size=\"2\">[");
+ ol.startHtmlLink(relativePathToRoot(0)+"graph_legend"+Doxygen::htmlFileExtension);
+ ol.docify(theTranslator->trLegend());
+ ol.endHtmlLink();
+ ol.writeString("]</font></center>");
+ }
+ ol.popGeneratorState();
+ }
+ }
+
+}
+
// write all documentation for this class
void ClassDef::writeDocumentation(OutputList &ol)
{
@@ -1140,182 +1326,7 @@ void ClassDef::writeDocumentation(OutputList &ol)
}
}
-
- if (Config_getBool("CLASS_DIAGRAMS")) ol.disableAllBut(OutputGenerator::Man);
-
-
- // write super classes
- int count;
- if (m_impl->inherits && (count=m_impl->inherits->count())>0)
- {
- //parseText(ol,theTranslator->trInherits()+" ");
-
- QCString inheritLine = theTranslator->trInheritsList(m_impl->inherits->count());
- QRegExp marker("@[0-9]+");
- int index=0,newIndex,matchLen;
- // now replace all markers in inheritLine with links to the classes
- while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
- {
- ol.parseText(inheritLine.mid(index,newIndex-index));
- bool ok;
- uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
- BaseClassDef *bcd=m_impl->inherits->at(entryIndex);
- if (ok && bcd)
- {
- ClassDef *cd=bcd->classDef;
- if (cd->isLinkable())
- {
- if (!Config_getString("GENERATE_TAGFILE").isEmpty())
- {
- Doxygen::tagFile << " <base";
- if (bcd->prot==Protected)
- {
- Doxygen::tagFile << " protection=\"protected\"";
- }
- else if (bcd->prot==Private)
- {
- Doxygen::tagFile << " protection=\"private\"";
- }
- if (bcd->virt==Virtual)
- {
- Doxygen::tagFile << " virtualness=\"virtual\"";
- }
- Doxygen::tagFile << ">" << convertToXML(cd->name()) << "</base>" << endl;
- }
- ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->displayName()+bcd->templSpecifiers);
- }
- else
- {
- ol.docify(cd->displayName());
- }
- }
- else
- {
- err("Error: invalid marker %d in inherits list!\n",entryIndex);
- }
- index=newIndex+matchLen;
- }
- ol.parseText(inheritLine.right(inheritLine.length()-index));
- ol.newParagraph();
- }
-
- // write subclasses
- if (m_impl->inheritedBy && (count=m_impl->inheritedBy->count())>0)
- {
- QCString inheritLine = theTranslator->trInheritedByList(m_impl->inheritedBy->count());
- QRegExp marker("@[0-9]+");
- int index=0,newIndex,matchLen;
- // now replace all markers in inheritLine with links to the classes
- while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
- {
- ol.parseText(inheritLine.mid(index,newIndex-index));
- bool ok;
- uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
- BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex);
- if (ok && bcd)
- {
- ClassDef *cd=bcd->classDef;
- if (cd->isLinkable())
- {
- ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->displayName());
- }
- else
- {
- ol.docify(cd->displayName());
- }
- writeInheritanceSpecifier(ol,bcd);
- }
- index=newIndex+matchLen;
- }
- ol.parseText(inheritLine.right(inheritLine.length()-index));
- ol.newParagraph();
- }
-
- if (Config_getBool("CLASS_DIAGRAMS")) ol.enableAll();
-
-
- count=0;
- BaseClassDef *ibcd;
- if (m_impl->inheritedBy)
- {
- ibcd=m_impl->inheritedBy->first();
- while (ibcd)
- {
- ClassDef *icd=ibcd->classDef;
- if ( icd->isVisibleInHierarchy()) count++;
- ibcd=m_impl->inheritedBy->next();
- }
- }
- if (m_impl->inherits)
- {
- ibcd=m_impl->inherits->first();
- while (ibcd)
- {
- ClassDef *icd=ibcd->classDef;
- if ( icd->isVisibleInHierarchy()) count++;
- ibcd=m_impl->inherits->next();
- }
- }
-
-
- if (Config_getBool("HAVE_DOT") && Config_getBool("CLASS_GRAPH"))
- // write class diagram using dot
- {
- DotClassGraph inheritanceGraph(this,DotNode::Inheritance);
- if (!inheritanceGraph.isTrivial())
- {
- ol.pushGeneratorState();
- ol.disable(OutputGenerator::Man);
- ol.startDotGraph();
- ol.parseText(theTranslator->trClassDiagram(displayName()));
- ol.endDotGraph(inheritanceGraph);
- if (Config_getBool("GENERATE_LEGEND"))
- {
- ol.pushGeneratorState();
- ol.disableAllBut(OutputGenerator::Html);
- ol.writeString("<center><font size=\"2\">[");
- ol.startHtmlLink(relativePathToRoot(0)+"graph_legend"+Doxygen::htmlFileExtension);
- ol.docify(theTranslator->trLegend());
- ol.endHtmlLink();
- ol.writeString("]</font></center>");
- ol.popGeneratorState();
- }
- ol.popGeneratorState();
- }
- }
- else if (Config_getBool("CLASS_DIAGRAMS") && count>0)
- // write class diagram using build-in generator
- {
- ClassDiagram diagram(this); // create a diagram of this class.
- ol.startClassDiagram();
- ol.disable(OutputGenerator::Man);
- ol.parseText(theTranslator->trClassDiagram(displayName()));
- ol.enable(OutputGenerator::Man);
- ol.endClassDiagram(diagram,getOutputFileBase(),displayName());
- }
-
- if (Config_getBool("HAVE_DOT") && Config_getBool("COLLABORATION_GRAPH"))
- {
- DotClassGraph usageImplGraph(this,DotNode::Collaboration);
- if (!usageImplGraph.isTrivial())
- {
- ol.pushGeneratorState();
- ol.disable(OutputGenerator::Man);
- ol.startDotGraph();
- ol.parseText(theTranslator->trCollaborationDiagram(displayName()));
- ol.endDotGraph(usageImplGraph);
- if (Config_getBool("GENERATE_LEGEND"))
- {
- ol.disableAllBut(OutputGenerator::Html);
- ol.writeString("<center><font size=\"2\">[");
- ol.startHtmlLink(relativePathToRoot(0)+"graph_legend"+Doxygen::htmlFileExtension);
- ol.docify(theTranslator->trLegend());
- ol.endHtmlLink();
- ol.writeString("]</font></center>");
- }
- ol.popGeneratorState();
- }
- }
+ writeClassDiagrams(ol);
// write link to list of all members (HTML only)
if (m_impl->allMemberNameInfoSDict &&
diff --git a/src/classdef.h b/src/classdef.h
index 2153def..b03ae52 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -310,6 +310,7 @@ class ClassDef : public Definition
void mergeMembers();
void distributeMemberGroupDocumentation();
void writeDocumentation(OutputList &ol);
+ void writeClassDiagrams(OutputList &ol);
void writeDocumentationForInnerClasses(OutputList &ol);
void writeMemberDocumentation(OutputList &ol);
void writeMemberPages(OutputList &ol);
diff --git a/src/cmdmapper.cpp b/src/cmdmapper.cpp
index 352095c..c4469c7 100644
--- a/src/cmdmapper.cpp
+++ b/src/cmdmapper.cpp
@@ -162,7 +162,8 @@ CommandMap htmlTagMap[] =
{ "exception", XML_EXCEPTION },
{ "include", XML_INCLUDE },
{ "item", XML_ITEM },
- { "list", XML_LIST },
+ { "list", XML_LIST }, // type="table|bullet|number"
+ { "listheader", XML_LISTHEADER },
{ "para", XML_PARA },
{ "param", XML_PARAM },
{ "paramref", XML_PARAMREF },
@@ -172,14 +173,15 @@ CommandMap htmlTagMap[] =
{ "see", XML_SEE },
{ "seealso", XML_SEEALSO },
{ "summary", XML_SUMMARY },
+ { "term", XML_TERM },
{ "value", XML_VALUE },
{ 0, 0 }
};
//----------------------------------------------------------------------------
-Mapper *Mappers::cmdMapper = new Mapper(cmdMap);
-Mapper *Mappers::htmlTagMapper = new Mapper(htmlTagMap);
+Mapper *Mappers::cmdMapper = new Mapper(cmdMap,TRUE);
+Mapper *Mappers::htmlTagMapper = new Mapper(htmlTagMap,FALSE);
void Mappers::freeMappers()
{
diff --git a/src/cmdmapper.h b/src/cmdmapper.h
index 586e766..d5a2376 100644
--- a/src/cmdmapper.h
+++ b/src/cmdmapper.h
@@ -158,16 +158,18 @@ enum HtmlTagType
XML_INCLUDE = XML_CmdMask + 5,
XML_ITEM = XML_CmdMask + 6,
XML_LIST = XML_CmdMask + 7,
- XML_PARA = XML_CmdMask + 8,
- XML_PARAM = XML_CmdMask + 9,
- XML_PARAMREF = XML_CmdMask + 10,
- XML_PERMISSION = XML_CmdMask + 11,
- XML_REMARKS = XML_CmdMask + 12,
- XML_RETURNS = XML_CmdMask + 13,
- XML_SEE = XML_CmdMask + 14,
- XML_SEEALSO = XML_CmdMask + 15,
- XML_SUMMARY = XML_CmdMask + 16,
- XML_VALUE = XML_CmdMask + 17
+ XML_LISTHEADER = XML_CmdMask + 8,
+ XML_PARA = XML_CmdMask + 9,
+ XML_PARAM = XML_CmdMask + 10,
+ XML_PARAMREF = XML_CmdMask + 11,
+ XML_PERMISSION = XML_CmdMask + 12,
+ XML_REMARKS = XML_CmdMask + 13,
+ XML_RETURNS = XML_CmdMask + 14,
+ XML_SEE = XML_CmdMask + 15,
+ XML_SEEALSO = XML_CmdMask + 16,
+ XML_SUMMARY = XML_CmdMask + 17,
+ XML_TERM = XML_CmdMask + 18,
+ XML_VALUE = XML_CmdMask + 19
};
@@ -177,11 +179,12 @@ class Mapper
int map(const char *n)
{
QCString name=n;
+ if (!m_cs) name=name.lower();
int *result;
- return !name.isEmpty() && (result=m_map.find(name.lower())) ? *result: 0;
+ return !name.isEmpty() && (result=m_map.find(name)) ? *result: 0;
}
- Mapper(const CommandMap *cm) : m_map(89)
+ Mapper(const CommandMap *cm,bool caseSensitive) : m_map(89), m_cs(caseSensitive)
{
m_map.setAutoDelete(TRUE);
const CommandMap *p = cm;
@@ -193,6 +196,7 @@ class Mapper
}
private:
QDict<int> m_map;
+ bool m_cs;
};
struct Mappers
diff --git a/src/commentcnv.l b/src/commentcnv.l
index 9b9a946..b12d9d8 100644
--- a/src/commentcnv.l
+++ b/src/commentcnv.l
@@ -61,6 +61,10 @@ static QCString g_blockName;
static int g_lastCommentContext;
static bool g_inSpecialComment;
+static QCString g_aliasString;
+static int g_blockCount;
+static int g_lastBlockContext;
+
static void replaceCommentMarker(const char *s,int len)
{
const char *p=s;
@@ -223,27 +227,11 @@ static QCString handleCondCmdInAliases(const QCString &s)
/** copies string \a s with length \a len to the output, while
* replacing any alias commands found in the string.
*/
-static void replaceAliases(const char *s,int len)
+static void replaceAliases(const char *s)
{
- static QRegExp cmd("[@\\\\][a-z_A-Z][a-z_A-Z0-9]*");
- QCString in=s;
- int p=0,i,l;
- while ((i=cmd.match(in,p,&l))!=-1)
- {
- copyToOutput(s+p,i-p);
- QCString *pValue=Doxygen::aliasDict[in.mid(i+1,l-1)];
- if (pValue)
- {
- QCString val = handleCondCmdInAliases(*pValue);
- copyToOutput(val.data(),val.length());
- }
- else
- {
- copyToOutput(s+i,l);
- }
- p=i+l;
- }
- copyToOutput(s+p,len-p);
+ QCString result = resolveAliasCmd(s);
+ //printf("replaceAliases(%s)->'%s'\n",s,result.data());
+ copyToOutput(result,result.length());
}
@@ -274,6 +262,7 @@ void replaceComment(int offset);
%x VerbatimCode
%x ReadLine
%x CondLine
+%x ReadAliasArgs
%%
@@ -300,8 +289,7 @@ void replaceComment(int offset);
}
g_blockHeadCol=g_col;
copyToOutput("/**",3);
- //copyToOutput(yytext+i,yyleng-i);
- replaceAliases(yytext+i,yyleng-i);
+ replaceAliases(yytext+i);
g_inSpecialComment=TRUE;
BEGIN(SComment);
}
@@ -310,8 +298,7 @@ void replaceComment(int offset);
int i=17; //=strlen("//##Documentation");
g_blockHeadCol=g_col;
copyToOutput("/**",3);
- //copyToOutput(yytext+i,yyleng-i);
- replaceAliases(yytext+i,yyleng-i);
+ replaceAliases(yytext+i);
BEGIN(SComment);
}
<Scan>"//"/.*\n { /* one line C++ comment */
@@ -521,17 +508,37 @@ void replaceComment(int offset);
if (*yytext=='\n') g_lineNr++;
BEGIN(g_condCtx);
}
-<CComment,ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9]* { // expand alias
- QCString *pValue=Doxygen::aliasDict[yytext+1];
- if (pValue)
- {
- QCString val = handleCondCmdInAliases(*pValue);
- copyToOutput(val.data(),val.length());
- }
- else
- {
- copyToOutput(yytext,yyleng);
- }
+<CComment,ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9]* { // expand alias without arguments
+ replaceAliases(yytext);
+ }
+<CComment,ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9]*"{" { // expand alias with arguments
+ g_lastBlockContext=YY_START;
+ g_blockCount=1;
+ g_aliasString=yytext;
+ BEGIN( ReadAliasArgs );
+ }
+<ReadAliasArgs>[^{}\n\*]+ {
+ g_aliasString+=yytext;
+ }
+<ReadAliasArgs>\n {
+ g_aliasString+=yytext;
+ g_lineNr++;
+ }
+<ReadAliasArgs>"{" {
+ g_aliasString+=yytext;
+ g_blockCount++;
+ }
+<ReadAliasArgs>"}" {
+ g_aliasString+=yytext;
+ g_blockCount--;
+ if (g_blockCount==0)
+ {
+ replaceAliases(g_aliasString);
+ BEGIN( g_lastBlockContext );
+ }
+ }
+<ReadAliasArgs>. {
+ g_aliasString+=yytext;
}
<ReadLine>. {
copyToOutput(yytext,yyleng);
diff --git a/src/config.l b/src/config.l
index 0fad432..e3faf84 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1078,12 +1078,13 @@ void Config::check()
s=aliasList.first();
while (s)
{
- QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*[ \t]*=");
+ QRegExp re1("[a-z_A-Z][a-z_A-Z0-9]*[ \t]*="); // alias without argument
+ QRegExp re2("[a-z_A-Z][a-z_A-Z0-9]*{[0-9]*}[ \t]*="); // alias with argument
QCString alias=s;
alias=alias.stripWhiteSpace();
- if (alias.find(re)!=0)
+ if (alias.find(re1)!=0 && alias.find(re2)!=0)
{
- config_err("Illegal alias format `%s'. Use \"name=value\"\n",
+ config_err("Illegal alias format `%s'. Use \"name=value\" or \"name(n)=value\", where n is the number of arguments\n",
alias.data());
}
s=aliasList.next();
@@ -1250,16 +1251,12 @@ void Config::check()
Config_getBool("INLINE_INFO")=FALSE;
}
-#if 0
- if (Config_getString("RTF_OUTPUT_ENCODING").isEmpty())
- {
- Config_getString("RTF_OUTPUT_ENCODING")="ISO-8859-1";
- }
- if (Config_getString("LATEX_OUTPUT_ENCODING").isEmpty())
+ int &depth = Config_getInt("MAX_DOT_GRAPH_DEPTH");
+ if (depth==0)
{
- Config_getString("LATEX_OUTPUT_ENCODING")="ISO-8859-1";
+ depth=1000;
}
-#endif
+
// add default words if needed
QStrList &annotationFromBrief = Config_getList("ABBREVIATE_BRIEF");
@@ -2072,7 +2069,9 @@ void Config::create()
"If the SOURCE_BROWSER tag is set to YES then a list of source files will \n"
"be generated. Documented entities will be cross-referenced with these sources. \n"
"Note: To get rid of all source code in the generated output, make sure also \n"
- "VERBATIM_HEADERS is set to NO. \n",
+ "VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH \n"
+ "then you must also enable this option. If you don't then doxygen will produce \n"
+ "a warning and turn it on anyway \n",
FALSE
);
cb = addBool(
@@ -2895,14 +2894,27 @@ void Config::create()
"The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of \n"
"nodes that will be shown in the graph. If the number of nodes in a graph \n"
"becomes larger than this value, doxygen will truncate the graph, which is \n"
- "visualized by representing a node as a red box. Note that doxygen will always \n"
- "show the root nodes and its direct children regardless of this setting. \n",
+ "visualized by representing a node as a red box. Note that doxygen if the number \n"
+ "of direct children of the root node in a graph is already larger than \n"
+ "MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note \n"
+ "that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. \n",
0,10000, 50
);
ci->addDependency("HAVE_DOT");
+ ci = addInt(
+ "MAX_DOT_GRAPH_DEPTH",
+ "The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the \n"
+ "graphs generated by dot. A depth value of 3 means that only nodes reachable \n"
+ "from the root by following a path via at most 3 edges will be shown. Nodes \n"
+ "that lay further from the root node will be omitted. Note that setting this \n"
+ "option to 1 or 2 may greatly reduce the computation time needed for large \n"
+ "code bases. Also note that the size of a graph can be further restricted by \n"
+ "DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n",
+ 0,1000,0
+ );
+ ci->addDependency("HAVE_DOT");
addObsolete("MAX_DOT_GRAPH_WIDTH");
addObsolete("MAX_DOT_GRAPH_HEIGHT");
- addObsolete("MAX_DOT_GRAPH_DEPTH");
cb = addBool(
"DOT_TRANSPARENT",
"Set the DOT_TRANSPARENT tag to YES to generate images with a transparent \n"
diff --git a/src/docparser.cpp b/src/docparser.cpp
index da673bf..01d88ae 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -536,6 +536,18 @@ static bool insideOL(DocNode *n)
//---------------------------------------------------------------------------
+static bool insideTable(DocNode *n)
+{
+ while (n)
+ {
+ if (n->kind()==DocNode::Kind_HtmlTable) return TRUE;
+ n=n->parent();
+ }
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+
///*! Returns TRUE iff node n is a child of a language node */
//static bool insideLang(DocNode *n)
//{
@@ -2820,6 +2832,43 @@ int DocHtmlCell::parse()
return retval;
}
+int DocHtmlCell::parseXml()
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlCell::parseXml() start\n"));
+
+ // parse one or more paragraphs
+ bool isFirst=TRUE;
+ DocPara *par=0;
+ do
+ {
+ par = new DocPara(this);
+ if (isFirst) { par->markFirst(); isFirst=FALSE; }
+ m_children.append(par);
+ retval=par->parse();
+ if (retval==TK_HTMLTAG)
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==XML_ITEM && g_token->endTag) // found </item> tag
+ {
+ retval=TK_NEWPARA; // ignore the tag
+ }
+ else if (tagId==XML_DESCRIPTION && g_token->endTag) // found </description> tag
+ {
+ retval=TK_NEWPARA; // ignore the tag
+ }
+ }
+ }
+ while (retval==TK_NEWPARA);
+ if (par) par->markLast();
+
+ DBG(("DocHtmlCell::parseXml() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
//---------------------------------------------------------------------------
int DocHtmlRow::parse()
@@ -2888,6 +2937,68 @@ endrow:
return retval;
}
+int DocHtmlRow::parseXml(bool isHeading)
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlRow::parseXml() start\n"));
+
+ bool isFirst=TRUE;
+ DocHtmlCell *cell=0;
+
+ // get next token
+ int tok=doctokenizerYYlex();
+ // skip whitespace
+ while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();
+ // should find a html tag now
+ if (tok==TK_HTMLTAG)
+ {
+ int tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==XML_TERM && !g_token->endTag) // found <term> tag
+ {
+ }
+ else if (tagId==XML_DESCRIPTION && !g_token->endTag) // found <description> tag
+ {
+ }
+ else // found some other tag
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: expected <term> or <description> tag but "
+ "found <%s> instead!",g_token->name.data());
+ doctokenizerYYpushBackHtmlTag(g_token->name);
+ goto endrow;
+ }
+ }
+ else if (tok==0) // premature end of comment
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: unexpected end of comment while looking"
+ " for a html description title");
+ goto endrow;
+ }
+ else // token other than html token
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: expected <td> or <th> tag but found %s token instead!",
+ tokToString(tok));
+ goto endrow;
+ }
+
+ do
+ {
+ cell=new DocHtmlCell(this,g_token->attribs,isHeading);
+ cell->markFirst(isFirst);
+ isFirst=FALSE;
+ m_children.append(cell);
+ retval=cell->parseXml();
+ }
+ while (retval==RetVal_TableCell || retval==RetVal_TableHCell);
+ if (cell) cell->markLast(TRUE);
+
+endrow:
+ DBG(("DocHtmlRow::parseXml() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval;
+}
+
//---------------------------------------------------------------------------
int DocHtmlTable::parse()
@@ -2958,6 +3069,48 @@ getrow:
return retval==RetVal_EndTable ? RetVal_OK : retval;
}
+int DocHtmlTable::parseXml()
+{
+ int retval=RetVal_OK;
+ g_nodeStack.push(this);
+ DBG(("DocHtmlTable::parseXml() start\n"));
+
+ // get next token
+ int tok=doctokenizerYYlex();
+ // skip whitespace
+ while (tok==TK_WHITESPACE || tok==TK_NEWPARA) tok=doctokenizerYYlex();
+ // should find a html tag now
+ int tagId=0;
+ bool isHeader=FALSE;
+ if (tok==TK_HTMLTAG)
+ {
+ tagId=Mappers::htmlTagMapper->map(g_token->name);
+ if (tagId==XML_ITEM && !g_token->endTag) // found <item> tag
+ {
+ retval=RetVal_TableRow;
+ }
+ if (tagId==XML_LISTHEADER && !g_token->endTag) // found <listheader> tag
+ {
+ retval=RetVal_TableRow;
+ isHeader=TRUE;
+ }
+ }
+
+ // parse one or more rows
+ while (retval==RetVal_TableRow)
+ {
+ DocHtmlRow *tr=new DocHtmlRow(this,g_token->attribs);
+ m_children.append(tr);
+ retval=tr->parseXml(isHeader);
+ isHeader=FALSE;
+ }
+
+ DBG(("DocHtmlTable::parseXml() end\n"));
+ DocNode *n=g_nodeStack.pop();
+ ASSERT(n==this);
+ return retval==RetVal_EndTable ? RetVal_OK : retval;
+}
+
uint DocHtmlTable::numCols() const
{
uint cols=0;
@@ -4788,6 +4941,10 @@ int DocPara::handleHtmlStartTag(const QString &tagName,const HtmlAttribList &tag
break;
case XML_EXAMPLE:
case XML_DESCRIPTION:
+ if (insideTable(this))
+ {
+ retval=RetVal_TableCell;
+ }
break;
case XML_C:
handleStyleEnter(this,m_children,DocStyleChange::Code,&g_token->attribs);
@@ -4836,19 +4993,31 @@ int DocPara::handleHtmlStartTag(const QString &tagName,const HtmlAttribList &tag
}
break;
case XML_ITEM:
- if (!insideUL(this) && !insideOL(this))
+ case XML_LISTHEADER:
+ if (insideTable(this))
{
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: lonely <item> tag found");
+ retval=RetVal_TableRow;
}
- else
+ else if (insideUL(this) || insideOL(this))
{
retval=RetVal_ListItem;
}
+ else
+ {
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: lonely <item> tag found");
+ }
break;
case XML_RETURNS:
retval = handleSimpleSection(DocSimpleSect::Return,TRUE);
g_hasReturnCommand=TRUE;
break;
+ case XML_TERM:
+ m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,TRUE));
+ if (insideTable(this))
+ {
+ retval=RetVal_TableCell;
+ }
+ break;
case XML_SEE:
// I'm not sure if <see> is the same as <seealso> or if it
// should you link a member without producing a section. The
@@ -4923,14 +5092,25 @@ int DocPara::handleHtmlStartTag(const QString &tagName,const HtmlAttribList &tag
case XML_LIST:
{
QString type;
+ findAttribute(tagHtmlAttribs,"type",&type);
DocHtmlList::Type listType = DocHtmlList::Unordered;
- if (findAttribute(tagHtmlAttribs,"type",&type) && type=="number")
+ if (type=="number")
{
listType=DocHtmlList::Ordered;
}
- DocHtmlList *list = new DocHtmlList(this,tagHtmlAttribs,listType);
- m_children.append(list);
- retval=list->parseXml();
+ if (type=="table")
+ {
+ DocHtmlTable *table = new DocHtmlTable(this,tagHtmlAttribs);
+ m_children.append(table);
+ retval=table->parseXml();
+ }
+ else
+ {
+ HtmlAttribList emptyList;
+ DocHtmlList *list = new DocHtmlList(this,emptyList,listType);
+ m_children.append(list);
+ retval=list->parseXml();
+ }
}
break;
case XML_INCLUDE:
@@ -5078,6 +5258,9 @@ int DocPara::handleHtmlEndTag(const QString &tagName)
// ignore </a> tag (can be part of <a name=...></a>
break;
+ case XML_TERM:
+ m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Bold,FALSE));
+ break;
case XML_SUMMARY:
case XML_REMARKS:
case XML_PARA:
@@ -5094,6 +5277,7 @@ int DocPara::handleHtmlEndTag(const QString &tagName)
handleStyleLeave(this,m_children,DocStyleChange::Code,"c");
break;
case XML_ITEM:
+ case XML_LISTHEADER:
case XML_INCLUDE:
case XML_PERMISSION:
case XML_DESCRIPTION:
diff --git a/src/docparser.h b/src/docparser.h
index 64b382d..bd51317 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -1140,6 +1140,7 @@ class DocHtmlCell : public CompAccept<DocHtmlCell>, public DocNode
void markLast(bool v=TRUE) { m_isLast=v; }
const HtmlAttribList &attribs() const { return m_attribs; }
int parse();
+ int parseXml();
private:
DocNode * m_parent;
@@ -1179,6 +1180,7 @@ class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode
void accept(DocVisitor *v) { CompAccept<DocHtmlRow>::accept(this,v); }
const HtmlAttribList &attribs() const { return m_attribs; }
int parse();
+ int parseXml(bool header);
private:
DocNode * m_parent;
@@ -1199,6 +1201,7 @@ class DocHtmlTable : public CompAccept<DocHtmlTable>, public DocNode
bool hasCaption() { return m_caption!=0; }
const HtmlAttribList &attribs() const { return m_attribs; }
int parse();
+ int parseXml();
uint numCols() const;
void accept(DocVisitor *v);
diff --git a/src/dot.cpp b/src/dot.cpp
index 808dcca..603fc38 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -91,123 +91,6 @@ static void writeGraphFooter(QTextStream &t)
t << "}" << endl;
}
-#if 0
-/*! converts the rectangles in a server site image map into a client
- * site image map.
- * \param t the stream to which the result is written.
- * \param mapName the name of the map file.
- * \param relPath the relative path to the root of the output directory
- * (used in case CREATE_SUBDIRS is enabled).
- * \param urlOnly if FALSE the url field in the map contains an external
- * references followed by a $ and then the URL.
- * \returns TRUE if succesful.
- */
-static bool convertMapFile(QTextStream &t,const char *mapName,
- const QCString relPath, bool urlOnly=FALSE)
-{
- QFile f(mapName);
- if (!f.open(IO_ReadOnly))
- {
- err("Error opening map file %s for inclusion in the docs!\n",mapName);
- return FALSE;
- }
- const int maxLineLen=1024;
- char buf[maxLineLen];
- char url[maxLineLen];
- char ref[maxLineLen];
- int x1,y1,x2,y2;
- while (!f.atEnd())
- {
- bool isRef = FALSE;
- int numBytes = f.readLine(buf,maxLineLen);
- buf[numBytes-1]='\0';
- //printf("ReadLine `%s'\n",buf);
- if (strncmp(buf,"rect",4)==0)
- {
- // obtain the url and the coordinates in the order used by graphviz-1.5
- sscanf(buf,"rect %s %d,%d %d,%d",url,&x1,&y1,&x2,&y2);
-
- if ( strcmp(url,"\\ref") == 0 )
- {
- isRef = TRUE;
- sscanf(buf,"rect %s %s %d,%d %d,%d",ref,url,&x1,&y1,&x2,&y2);
- }
-
- // later versions of graphviz corrected the y coordinate order
- // the rule is that y2>=y1, so test and switch if needed
- if (y2<y1)
- {
- int temp=y2;
- y2=y1;
- y1=temp;
- }
- // there shouldn't be any need for this for known versions of graphviz
- // but it can't do any harm to check that x follows the rules as well
- if (x2<x1)
- {
- int temp=x2;
- x2=x1;
- x1=temp;
- }
- if (urlOnly)
- {
- t << "<area href=\"";
-
- if ( isRef )
- {
- // handle doxygen \ref tag URL reference
- QCString *dest;
- DocRef *df = new DocRef( (DocNode*) 0, url );
- if (!df->ref().isEmpty())
- {
- if ((dest=Doxygen::tagDestinationDict[df->ref()])) t << *dest << "/";
- }
- if (!df->file().isEmpty()) t << relPath << df->file() << Doxygen::htmlFileExtension;
- if (!df->anchor().isEmpty()) t << "#" << df->anchor();
- }
- else
- {
- t << url;
- }
- t << "\" shape=\"rect\" coords=\""
- << x1 << "," << y1 << "," << x2 << "," << y2 << "\""
- << " alt=\"\">" << endl;
- }
- else // name and external reference are separated by a $
- {
- char *refPtr = url;
- char *urlPtr = strchr(url,'$');
- //printf("url=`%s'\n",url);
- if (urlPtr)
- {
- QCString *dest;
- *urlPtr++='\0';
- //printf("refPtr=`%s' urlPtr=`%s'\n",refPtr,urlPtr);
- //printf("Found url=%s coords=%d,%d,%d,%d\n",url,x1,y1,x2,y2);
- t << "<area ";
- if (*refPtr!='\0')
- {
- t << "doxygen=\"" << refPtr << ":";
- if ((dest=Doxygen::tagDestinationDict[refPtr])) t << *dest << "/";
- t << "\" ";
- }
- t << "href=\"" << relPath;
- if (*refPtr!='\0')
- {
- if ((dest=Doxygen::tagDestinationDict[refPtr])) t << *dest << "/";
- }
- t << urlPtr << "\" shape=\"rect\" coords=\""
- << x1 << "," << y1 << "," << x2 << "," << y2 << "\""
- << " alt=\"\">" << endl;
- }
- }
- }
- }
-
- return TRUE;
-}
-#endif
-
/*! converts the rectangles in a client site image map into a stream
* \param t the stream to which the result is written.
* \param mapName the name of the map file.
@@ -348,45 +231,21 @@ static void resetReNumbering()
s_newNumber.resize(s_max_newNumber);
}
-#if 0
-static bool readBoundingBoxDot(const char *fileName,int *width,int *height)
-{
- QFile f(fileName);
- if (!f.open(IO_ReadOnly)) return FALSE;
- const int maxLineLen=1024;
- char buf[maxLineLen];
- while (!f.atEnd())
- {
- int numBytes = f.readLine(buf,maxLineLen);
- buf[numBytes-1]='\0';
- if (strncmp(buf,"\tgraph [bb",10)==0)
- {
- int x,y;
- if (sscanf(buf,"\tgraph [bb= \"%d,%d,%d,%d\"];",&x,&y,width,height)!=4)
- {
- return FALSE;
- }
- return TRUE;
- }
- }
- return FALSE;
-}
-#endif
-
static bool readBoundingBoxEPS(const char *fileName,int *width,int *height)
{
+ QCString bb("%%PageBoundingBox:");
QFile f(fileName);
if (!f.open(IO_ReadOnly)) return FALSE;
const int maxLineLen=1024;
char buf[maxLineLen];
while (!f.atEnd())
{
- int numBytes = f.readLine(buf,maxLineLen);
- buf[numBytes-1]='\0';
- if (strncmp(buf,"%%PageBoundingBox: ",15)==0)
+ int numBytes = f.readLine(buf,maxLineLen-1); // read line
+ buf[numBytes]='\0';
+ if (strncmp(buf,bb.data(),bb.length()-1)==0) // found PageBoundBox string
{
int x,y;
- if (sscanf(buf,"%%%%PageBoundingBox: %d %d %d %d",&x,&y,width,height)!=4)
+ if (sscanf(buf+bb.length(),"%d %d %d %d",&x,&y,width,height)!=4)
{
return FALSE;
}
@@ -396,33 +255,6 @@ static bool readBoundingBoxEPS(const char *fileName,int *width,int *height)
return FALSE;
}
-#if 0
-/*! returns TRUE if class cd is a leaf (i.e. has no visible children)
- */
-static bool isLeaf(ClassDef *cd)
-{
- BaseClassList *bcl = cd->subClasses();
- if (bcl->count()>0) // class has children, check their visibility
- {
- BaseClassListIterator bcli(*bcl);
- BaseClassDef *bcd;
- for ( ; (bcd=bcli.current()); ++bcli )
- {
- ClassDef *bClass = bcd->classDef;
- //if (bClass->isLinkable() || !isLeaf(bClass)) return FALSE;
-
- // if class is not a leaf
- if (!isLeaf(bClass)) return FALSE;
- // or class is not documented in this project
- if (!Config_getBool("ALLEXTERNALS") && !bClass->isLinkableInProject()) return FALSE;
- // or class is not documented and all ALLEXTERNALS = YES
- if (Config_getBool("ALLEXTERNALS") && !bClass->isLinkable()) return FALSE;
- }
- }
- return TRUE;
-}
-#endif
-
// since dot silently reproduces the input file when it does not
// support the PNG format, we need to check the result.
static void checkDotResult(const QCString &imgName)
@@ -583,6 +415,7 @@ DotNode::DotNode(int n,const char *lab,const char *tip, const char *url,
, m_classDef(cd)
, m_visible(FALSE)
, m_truncated(Unknown)
+ , m_distance(1000)
{
}
@@ -672,6 +505,11 @@ void DotNode::deleteNode(DotNodeList &deletedList,SDict<DotNode> *skipNodes)
}
}
+void DotNode::setDistance(int distance)
+{
+ if (distance<m_distance) m_distance = distance;
+}
+
static QCString convertLabel(const QCString &l)
{
QCString result;
@@ -847,9 +685,15 @@ void DotNode::writeArrow(QTextStream &t,
)
{
t << " Node";
- if (topDown) t << reNumberNode(cn->number(),reNumber); else t << reNumberNode(m_number,reNumber);
+ if (topDown)
+ t << reNumberNode(cn->number(),reNumber);
+ else
+ t << reNumberNode(m_number,reNumber);
t << " -> Node";
- if (topDown) t << reNumberNode(m_number,reNumber); else t << reNumberNode(cn->number(),reNumber);
+ if (topDown)
+ t << reNumberNode(m_number,reNumber);
+ else
+ t << reNumberNode(cn->number(),reNumber);
t << " [";
if (pointBack) t << "dir=back,";
t << "color=\"" << edgeColorMap[ei->m_color]
@@ -864,7 +708,7 @@ void DotNode::writeArrow(QTextStream &t,
)
{
if (pointBack)
- t << ",arrowtail=\"" <<arrowStyle[ei->m_color] << "\"";
+ t << ",arrowtail=\"" << arrowStyle[ei->m_color] << "\"";
else
t << ",arrowhead=\"" << arrowStyle[ei->m_color] << "\"";
}
@@ -1445,7 +1289,7 @@ DotGfxHierarchyTable::~DotGfxHierarchyTable()
int DotClassGraph::m_curNodeNumber = 0;
void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
- const char *label,const char *usedName,const char *templSpec,bool base)
+ const char *label,const char *usedName,const char *templSpec,bool base,int distance)
{
if (Config_getBool("HIDE_UNDOC_CLASSES") && !cd->isLinkable()) return;
@@ -1478,6 +1322,7 @@ void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
bn->addChild(n,prot,edgeStyle,label);
n->addParent(bn);
}
+ bn->setDistance(distance);
//printf(" add exiting node %s of %s\n",bn->m_label.data(),n->m_label.data());
}
else // new class
@@ -1507,11 +1352,12 @@ void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
bn->addChild(n,prot,edgeStyle,label);
n->addParent(bn);
}
+ bn->setDistance(distance);
m_usedNodes->insert(className,bn);
//printf(" add new child node `%s' to %s hidden=%d url=%s\n",
// className.data(),n->m_label.data(),cd->isHidden(),tmp_url.data());
- buildGraph(cd,bn,base);
+ buildGraph(cd,bn,base,distance+1);
}
}
@@ -1557,10 +1403,13 @@ void DotClassGraph::determineVisibleNodes(QList<DotNode> &queue,
{
while (queue.count()>0 && maxNodes>0)
{
+ static int maxDistance = Config_getInt("MAX_DOT_GRAPH_DEPTH");
DotNode *n = queue.take(0);
- //printf("*** Processing node %p queue=%d maxNodes=%d m_children=%p m_parents=%p\n",
- // n,queue.count(),maxNodes,n->m_children,n->m_parents);
- if (!n->isVisible()) // not yet processed
+ //printf("*** Processing node %p queue=%d maxNodes=%d m_children=%p "
+ // "m_parents=%p distance=%d maxDistance=%d\n",
+ // n,queue.count(),maxNodes,n->m_children,n->m_parents,n->distance(),
+ // maxDistance);
+ if (!n->isVisible() && n->distance()<maxDistance) // not yet processed
{
//printf(" Marked as visible!\n");
n->markAsVisible();
@@ -1589,7 +1438,7 @@ void DotClassGraph::determineVisibleNodes(QList<DotNode> &queue,
}
}
-void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,bool base)
+void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,bool base,int distance)
{
//printf("DocClassGraph::buildGraph(%s,distance=%d,base=%d)\n",
// cd->name().data(),distance,base);
@@ -1607,7 +1456,7 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,bool base)
//printf("-------- inheritance relation %s->%s templ=`%s'\n",
// cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data());
addClass(bcd->classDef,n,bcd->prot,0,bcd->usedName,
- bcd->templSpecifiers,base);
+ bcd->templSpecifiers,base,distance);
}
}
}
@@ -1642,14 +1491,15 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,bool base)
}
}
addClass(ucd->classDef,n,EdgeInfo::Purple,label,0,
- ucd->templSpecifiers,base);
+ ucd->templSpecifiers,base,distance);
}
}
}
// ---- Add template instantiation relations
- if (Config_getBool("TEMPLATE_RELATIONS"))
+ static bool templateRelations = Config_getBool("TEMPLATE_RELATIONS");
+ if (templateRelations)
{
if (base) // template relations for base classes
{
@@ -1663,7 +1513,7 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,bool base)
if (templInstance==cd)
{
addClass(templMaster,n,EdgeInfo::Orange,cli.currentKey(),0,
- 0,TRUE);
+ 0,TRUE,distance);
}
}
}
@@ -1678,7 +1528,7 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,bool base)
for (;(templInstance=cli.current());++cli)
{
addClass(templInstance,n,EdgeInfo::Orange,cli.currentKey(),0,
- 0,FALSE);
+ 0,FALSE,distance);
}
}
}
@@ -1703,23 +1553,25 @@ DotClassGraph::DotClassGraph(ClassDef *cd,DotNode::GraphType t)
TRUE, // is a root node
cd
);
+ m_startNode->setDistance(0);
m_usedNodes = new QDict<DotNode>(1009);
m_usedNodes->insert(className,m_startNode);
//printf("Root node %s\n",cd->name().data());
//if (m_recDepth>0)
//{
- buildGraph(cd,m_startNode,TRUE);
- if (t==DotNode::Inheritance) buildGraph(cd,m_startNode,FALSE);
+ buildGraph(cd,m_startNode,TRUE,1);
+ if (t==DotNode::Inheritance) buildGraph(cd,m_startNode,FALSE,1);
//}
- int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
- int directChildNodes = 1;
- if (m_startNode->m_children!=0)
- directChildNodes+=m_startNode->m_children->count();
- if (t==DotNode::Inheritance && m_startNode->m_parents!=0)
- directChildNodes+=m_startNode->m_parents->count();
- if (directChildNodes>maxNodes) maxNodes=directChildNodes;
+ static int nodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ int maxNodes = nodes;
+ //int directChildNodes = 1;
+ //if (m_startNode->m_children!=0)
+ // directChildNodes+=m_startNode->m_children->count();
+ //if (t==DotNode::Inheritance && m_startNode->m_parents!=0)
+ // directChildNodes+=m_startNode->m_parents->count();
+ //if (directChildNodes>maxNodes) maxNodes=directChildNodes;
QList<DotNode> openNodeQueue;
openNodeQueue.append(m_startNode);
determineVisibleNodes(openNodeQueue,maxNodes,t==DotNode::Inheritance);
@@ -1738,65 +1590,23 @@ bool DotClassGraph::isTrivial() const
return m_startNode->m_children==0;
}
-DotClassGraph::~DotClassGraph()
+bool DotClassGraph::isTooBig() const
{
- deleteNodes(m_startNode);
- delete m_usedNodes;
+ static int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ int numNodes = 0;
+ numNodes+= m_startNode->m_children ? m_startNode->m_children->count() : 0;
+ if (m_graphType==DotNode::Inheritance)
+ {
+ numNodes+= m_startNode->m_parents ? m_startNode->m_parents->count() : 0;
+ }
+ return numNodes>=maxNodes;
}
-#if 0
-void writeDotGraph(DotNode *root,
- DotNode::GraphType gt,
- GraphOutputFormat format,
- const QCString &baseName,
- bool lrRank,
- bool renderParents,
- int distance,
- bool backArrows,
- bool reNumber
- )
+DotClassGraph::~DotClassGraph()
{
- // generate the graph description for dot
- //printf("writeDotGraph(%s,%d,lrRank=%d)\n",baseName.data(),backArrows,lrRank);
- QFile f;
- f.setName(baseName+".dot");
- if (f.open(IO_WriteOnly))
- {
- QTextStream t(&f);
- writeGraphHeader(t);
- if (lrRank)
- {
- t << " rankdir=LR;" << endl;
- }
- root->clearWriteFlag();
- root->write(t,gt,format,gt!=DotNode::CallGraph,TRUE,distance,backArrows,reNumber);
- if (renderParents && root->m_parents)
- {
- //printf("rendering parents!\n");
- QListIterator<DotNode> dnli(*root->m_parents);
- DotNode *pn;
- for (dnli.toFirst();(pn=dnli.current());++dnli)
- {
- if (pn->m_distance<=distance)
- {
- root->writeArrow(t,
- gt,
- format,
- pn,
- pn->m_edgeInfo->at(pn->m_children->findRef(root)),
- FALSE,
- backArrows,
- reNumber
- );
- }
- pn->write(t,gt,format,TRUE,FALSE,distance,backArrows,reNumber);
- }
- }
- writeGraphFooter(t);
- f.close();
- }
+ deleteNodes(m_startNode);
+ delete m_usedNodes;
}
-#endif
/*! Computes a 16 byte md5 checksum for a given dot graph.
* The md5 checksum is returned as a 32 character ASCII string.
@@ -1818,10 +1628,16 @@ QCString computeMd5Signature(DotNode *root,
writeGraphHeader(md5stream);
if (lrRank)
{
- md5stream << "rankdir=LR;" << endl;
+ md5stream << " rankdir=LR;" << endl;
}
root->clearWriteFlag();
- root->write(md5stream,gt,format,gt!=DotNode::CallGraph,TRUE,backArrows,reNumber);
+ root->write(md5stream,
+ gt,
+ format,
+ gt!=DotNode::CallGraph && gt!=DotNode::Dependency,
+ TRUE,
+ backArrows,
+ reNumber);
if (renderParents && root->m_parents)
{
QListIterator<DotNode> dnli(*root->m_parents);
@@ -1892,95 +1708,6 @@ static bool updateDotGraph(DotNode *root,
return FALSE;
}
-#if 0
-static bool findMaximalDotGraph(DotNode *root,
- int maxDist,
- const QCString &baseName,
- QDir &thisDir,
- DotNode::GraphType gt,
- GraphOutputFormat format,
- bool lrRank /*=FALSE*/,
- bool renderParents /*=FALSE*/,
- bool backArrows /*=TRUE*/
- )
-{
- bool reNumber=TRUE;
- int minDistance=1; // min distance that shows only direct children.
- int curDistance; //=QMIN(2,maxDist); // current distance to try
- int maxDistance=maxDist; // max distance that show whole graph
- int width=0;
- int height=0;
- int maxDotGraphWidth = Config_getInt("MAX_DOT_GRAPH_WIDTH");
- int maxDotGraphHeight = Config_getInt("MAX_DOT_GRAPH_HEIGHT");
- int lastFit=minDistance;
-
- // binary search for the maximal inheritance depth that fits in a reasonable
- // sized image (dimensions: Config_getInt("MAX_DOT_GRAPH_WIDTH"), Config_getInt("MAX_DOT_GRAPH_HEIGHT"))
- while (minDistance<=maxDistance)
- {
- curDistance = (minDistance+maxDistance)/2;
-
- writeDotGraph(root,gt,format,baseName,lrRank,renderParents,
- curDistance,backArrows,reNumber);
-
- // create annotated dot file
- DotRunner dotRun(baseName+".dot");
- dotRun.addJob("dot",baseName+"_tmp.dot");
- if (!dotRun.run())
- {
- return FALSE;
- }
-
- // extract bounding box from the result
- readBoundingBoxDot(baseName+"_tmp.dot",&width,&height);
- width = width *96/72; // 96 pixels/inch, 72 points/inch
- height = height*96/72; // 96 pixels/inch, 72 points/inch
- //printf("Found bounding box (%d,%d) max (%d,%d)\n",width,height,
- // Config_getInt("MAX_DOT_GRAPH_WIDTH"),Config_getInt("MAX_DOT_GRAPH_HEIGHT"));
-
- // remove temporary dot file
- thisDir.remove(baseName+"_tmp.dot");
-
- bool graphFits=(width<maxDotGraphWidth && height<maxDotGraphHeight);
- if (graphFits) // graph is small enough
- {
- lastFit=curDistance;
- minDistance=curDistance+1;
- //printf("Image fits [%d-%d]\n",minDistance,maxDistance);
- }
- else // graph does not fit anymore with curDistance
- {
- //printf("Image does not fit [%d-%d]\n",minDistance,maxDistance);
- maxDistance=curDistance-1;
- }
- }
- //printf("lastFit=%d\n",lastFit);
-
- bool hasLRRank = (lrRank ||
- (minDistance==1 &&
- width>Config_getInt("MAX_DOT_GRAPH_WIDTH") &&
- !Config_getBool("UML_LOOK")
- )
- );
-
- writeDotGraph(root,
- gt,
- format,
- baseName,
- hasLRRank,
- renderParents,
- lastFit,
- backArrows,
- reNumber
- );
- if (reNumber)
- {
- resetReNumbering();
- }
- return TRUE;
-}
-#endif
-
QCString DotClassGraph::diskName() const
{
QCString result=m_diskName.copy();
@@ -2174,7 +1901,7 @@ void DotClassGraph::writeDEF(QTextStream &t)
int DotInclDepGraph::m_curNodeNumber = 0;
-void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd)
+void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd,int distance)
{
QList<IncludeInfo> *includeFiles =
m_inverse ? fd->includedByFileList() : fd->includeFileList();
@@ -2207,6 +1934,7 @@ void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd)
{
n->addChild(bn,0,0,0);
bn->addParent(n);
+ bn->setDistance(distance);
}
else
{
@@ -2214,17 +1942,19 @@ void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd)
if (bfd) tmp_url=doc || src ? bfd->getReference()+"$"+url : QCString();
QCString tooltip = fd->briefDescriptionAsTooltip();
bn = new DotNode(
- m_curNodeNumber++,
- ii->includeName,
- tooltip,
- tmp_url,
- 0 //distance
+ m_curNodeNumber++, // n
+ ii->includeName, // label
+ tooltip, // tip
+ tmp_url, // url
+ FALSE, // rootNode
+ 0 // cd
);
n->addChild(bn,0,0,0);
bn->addParent(n);
m_usedNodes->insert(in,bn);
+ bn->setDistance(distance);
- if (bfd) buildGraph(bn,bfd);
+ if (bfd) buildGraph(bn,bfd,distance+1);
}
}
}
@@ -2235,8 +1965,9 @@ void DotInclDepGraph::determineVisibleNodes(QList<DotNode> &queue, int &maxNodes
{
while (queue.count()>0 && maxNodes>0)
{
+ static int maxDistance = Config_getInt("MAX_DOT_GRAPH_DEPTH");
DotNode *n = queue.take(0);
- if (!n->isVisible()) // not yet processed
+ if (!n->isVisible() && n->distance()<maxDistance) // not yet processed
{
n->markAsVisible();
maxNodes--;
@@ -2293,15 +2024,17 @@ DotInclDepGraph::DotInclDepGraph(FileDef *fd,bool inverse)
tmp_url.data(),
TRUE // root node
);
+ m_startNode->setDistance(0);
m_usedNodes = new QDict<DotNode>(1009);
m_usedNodes->insert(fd->absFilePath(),m_startNode);
- buildGraph(m_startNode,fd);
-
- int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
- int directChildNodes = 1;
- if (m_startNode->m_children!=0)
- directChildNodes+=m_startNode->m_children->count();
- if (directChildNodes>maxNodes) maxNodes=directChildNodes;
+ buildGraph(m_startNode,fd,1);
+
+ static int nodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ int maxNodes = nodes;
+ //int directChildNodes = 1;
+ //if (m_startNode->m_children!=0)
+ // directChildNodes+=m_startNode->m_children->count();
+ //if (directChildNodes>maxNodes) maxNodes=directChildNodes;
QList<DotNode> openNodeQueue;
openNodeQueue.append(m_startNode);
determineVisibleNodes(openNodeQueue,maxNodes);
@@ -2351,10 +2084,10 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
if (updateDotGraph(m_startNode,
- DotNode::CallGraph,
+ DotNode::Dependency,
baseName,
format,
- TRUE, // lrRank
+ FALSE, // lrRank
FALSE, // renderParents
m_inverse // backArrows
)
@@ -2450,6 +2183,13 @@ bool DotInclDepGraph::isTrivial() const
return m_startNode->m_children==0;
}
+bool DotInclDepGraph::isTooBig() const
+{
+ static int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ int numNodes = m_startNode->m_children ? m_startNode->m_children->count() : 0;
+ return numNodes>=maxNodes;
+}
+
void DotInclDepGraph::writeXML(QTextStream &t)
{
QDictIterator<DotNode> dni(*m_usedNodes);
@@ -2593,11 +2333,12 @@ DotCallGraph::DotCallGraph(MemberDef *md,bool inverse)
m_usedNodes->insert(uniqueId,m_startNode);
buildGraph(m_startNode,md);
- int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
- int directChildNodes = 1;
- if (m_startNode->m_children!=0)
- directChildNodes+=m_startNode->m_children->count();
- if (directChildNodes>maxNodes) maxNodes=directChildNodes;
+ static int nodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ int maxNodes = nodes;
+ //int directChildNodes = 1;
+ //if (m_startNode->m_children!=0)
+ // directChildNodes+=m_startNode->m_children->count();
+ //if (directChildNodes>maxNodes) maxNodes=directChildNodes;
QList<DotNode> openNodeQueue;
openNodeQueue.append(m_startNode);
determineVisibleNodes(openNodeQueue,maxNodes);
@@ -2730,6 +2471,13 @@ bool DotCallGraph::isTrivial() const
return m_startNode->m_children==0;
}
+bool DotCallGraph::isTooBig() const
+{
+ static int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+ int numNodes = m_startNode->m_children ? m_startNode->m_children->count() : 0;
+ return numNodes>=maxNodes;
+}
+
//-------------------------------------------------------------
DotDirDeps::DotDirDeps(DirDef *dir) : m_dir(dir)
@@ -3433,5 +3181,5 @@ void DotGroupCollaboration::writeGraphHeader(QTextStream &t)
t << " edge [fontname=\"FreeSans.ttf\",fontsize=8,"
"labelfontname=\"FreeSans.ttf\",labelfontsize=8];\n";
t << " node [fontname=\"FreeSans.ttf\",fontsize=10,shape=record];\n";
- t << "rankdir=LR;\n";
+ t << " rankdir=LR;\n";
}
diff --git a/src/dot.h b/src/dot.h
index 030b12f..6632aef 100644
--- a/src/dot.h
+++ b/src/dot.h
@@ -82,6 +82,7 @@ class DotNode
int number() const { return m_number; }
bool isVisible() const { return m_visible; }
TruncState isTruncated() const { return m_truncated; }
+ int distance() const { return m_distance; }
private:
void colorConnectedNodes(int curColor);
@@ -89,6 +90,7 @@ class DotNode
bool hasNonReachableChildren, bool reNumber=FALSE);
void writeArrow(QTextStream &t,GraphType gt,GraphOutputFormat f,DotNode *cn,
EdgeInfo *ei,bool topDown, bool pointBack=TRUE, bool reNumber=FALSE);
+ void setDistance(int distance);
const DotNode *findDocNode() const; // only works for acyclic graphs!
void markAsVisible(bool b=TRUE) { m_visible=b; }
void markAsTruncated(bool b=TRUE) { m_truncated=b ? Truncated : Untruncated; }
@@ -106,6 +108,7 @@ class DotNode
ClassDef * m_classDef; //!< class representing this node (can be 0)
bool m_visible; //!< is the node visible in the output
TruncState m_truncated; //!< does the node have non-visible children/parents
+ int m_distance; //!< shortest path to the root node
friend class DotGfxHierarchyTable;
friend class DotClassGraph;
@@ -155,6 +158,7 @@ class DotClassGraph
DotClassGraph(ClassDef *cd,DotNode::GraphType t);
~DotClassGraph();
bool isTrivial() const;
+ bool isTooBig() const;
QCString writeGraph(QTextStream &t,GraphOutputFormat f,const char *path,
const char *relPath, bool TBRank=TRUE,bool imageMap=TRUE);
@@ -163,12 +167,12 @@ class DotClassGraph
QCString diskName() const;
private:
- void buildGraph(ClassDef *cd,DotNode *n,bool base);
+ void buildGraph(ClassDef *cd,DotNode *n,bool base,int distance);
void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes,bool includeParents);
void determineTruncatedNodes(QList<DotNode> &queue,bool includeParents);
void addClass(ClassDef *cd,DotNode *n,int prot,const char *label,
const char *usedName,const char *templSpec,
- bool base);
+ bool base,int distance);
DotNode * m_startNode;
QDict<DotNode> * m_usedNodes;
@@ -187,11 +191,12 @@ class DotInclDepGraph
const char *relPath,
bool writeImageMap=TRUE);
bool isTrivial() const;
+ bool isTooBig() const;
QCString diskName() const;
void writeXML(QTextStream &t);
private:
- void buildGraph(DotNode *n,FileDef *fd);
+ void buildGraph(DotNode *n,FileDef *fd,int distance);
void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes);
void determineTruncatedNodes(QList<DotNode> &queue);
@@ -213,6 +218,7 @@ class DotCallGraph
const char *path,const char *relPath,bool writeImageMap=TRUE);
void buildGraph(DotNode *n,MemberDef *md);
bool isTrivial() const;
+ bool isTooBig() const;
void determineVisibleNodes(QList<DotNode> &queue, int &maxNodes);
void determineTruncatedNodes(QList<DotNode> &queue);
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 12d0004..3042aa0 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -6397,7 +6397,7 @@ static void addEnumValuesToEnums(EntryNav *rootNav)
// must create them here
e->loadEntry(g_storage);
MemberDef *fmd = addVariableToFile(e,MemberDef::EnumValue,
- md->getOuterScope() ? md->getOuterScope()->name() : "",
+ md->getOuterScope() ? md->getOuterScope()->name() : QCString(),
e->name(),TRUE,0);
md->insertEnumField(fmd);
fmd->setEnumScope(md);
@@ -6659,6 +6659,43 @@ static void findDocumentedEnumValues()
findDEV(*Doxygen::functionNameSDict);
}
+//----------------------------------------------------------------------
+
+static void addMembersToIndex()
+{
+ MemberName *mn;
+ MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
+ // for each member name
+ for (mnli.toFirst();(mn=mnli.current());++mnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ // for each member definition
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ addClassMemberNameToIndex(md);
+ }
+ }
+ MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
+ // for each member name
+ for (fnli.toFirst();(mn=fnli.current());++fnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ // for each member definition
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ if (md->getNamespaceDef())
+ {
+ addNamespaceMemberNameToIndex(md);
+ }
+ else
+ {
+ addFileMemberNameToIndex(md);
+ }
+ }
+ }
+}
//----------------------------------------------------------------------
// computes the relation between all members. For each member `m'
@@ -8560,49 +8597,13 @@ void readFormulaRepository()
//----------------------------------------------------------------------------
-static QDict<void> aliasesProcessed;
-
-static QCString expandAliasesRec(const QCString s)
-{
- QCString result;
- static QRegExp cmdPat("[\\\\@][a-z_A-Z][a-z_A-Z0-9]*");
- QCString value=s;
- int i,p=0,l;
- while ((i=cmdPat.match(value,p,&l))!=-1)
- {
- result+=value.mid(p,i-p);
- QCString cmd=value.mid(i+1,l-1);
- //printf("Found command '%s'\n",cmd.data());
- QCString *aliasText=Doxygen::aliasDict.find(cmd);
- if (aliasesProcessed.find(cmd)==0 && aliasText) // expand the alias
- {
- aliasesProcessed.insert(cmd,(void *)0x8);
- result+=expandAliasesRec(*aliasText);
- aliasesProcessed.remove(cmd);
- }
- else // command is not an alias
- {
- result+=value.mid(i,l);
- }
- p=i+l;
- }
- result+=value.right(value.length()-p);
-
- //printf("expandAliases '%s'->'%s'\n",s.data(),result.data());
- return result;
-}
-
static void expandAliases()
{
QDictIterator<QCString> adi(Doxygen::aliasDict);
QCString *s;
for (adi.toFirst();(s=adi.current());++adi)
{
- aliasesProcessed.clear();
- // avoid expanding this command recursively
- aliasesProcessed.insert(adi.currentKey(),(void *)0x8);
- // expand embedded commands
- *s = expandAliasesRec(*s);
+ *s = expandAlias(adi.currentKey(),*s);
}
}
@@ -8678,7 +8679,6 @@ void readAliases()
}
expandAliases();
escapeAliases();
- aliasesProcessed.clear();
}
//----------------------------------------------------------------------------
@@ -9880,6 +9880,7 @@ void generateOutput()
writeGroupIndex(*outputList);
msg("Generating class documentation...\n");
+ addMembersToIndex();
generateClassDocs();
if (Config_getBool("HAVE_DOT") && Config_getBool("GRAPHICAL_HIERARCHY"))
@@ -9979,7 +9980,7 @@ void generateOutput()
QDir::setCurrent(Config_getString("HTML_OUTPUT"));
if (portable_system(Config_getString("HHC_LOCATION"), "index.hhp", FALSE))
{
- err("Error: failed to run html help compiler on index.hhp");
+ err("Error: failed to run html help compiler on index.hhp\n");
}
QDir::setCurrent(oldDir);
}
diff --git a/src/filedef.cpp b/src/filedef.cpp
index ecbb102..45b7ea6 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -391,7 +391,7 @@ void FileDef::writeDocumentation(OutputList &ol)
{
//printf("Graph for file %s\n",name().data());
DotInclDepGraph incDepGraph(this,FALSE);
- if (!incDepGraph.isTrivial())
+ if (!incDepGraph.isTrivial() && !incDepGraph.isTooBig())
{
ol.startTextBlock();
ol.disable(OutputGenerator::Man);
@@ -409,7 +409,7 @@ void FileDef::writeDocumentation(OutputList &ol)
{
//printf("Graph for file %s\n",name().data());
DotInclDepGraph incDepGraph(this,TRUE);
- if (!incDepGraph.isTrivial())
+ if (!incDepGraph.isTrivial() && !incDepGraph.isTooBig())
{
ol.startTextBlock();
ol.disable(OutputGenerator::Man);
@@ -723,7 +723,7 @@ void FileDef::insertMember(MemberDef *md)
m_memberLists.append(allMemberList);
}
allMemberList->append(md);
- ::addFileMemberNameToIndex(md);
+ //::addFileMemberNameToIndex(md);
switch (md->memberType())
{
case MemberDef::Variable:
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index 2b8d88d..58f06c1 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -577,18 +577,26 @@ void HtmlDocVisitor::visitPre(DocHtmlList *s)
{
if (m_hide) return;
if (s->type()==DocHtmlList::Ordered)
+ {
m_t << "<ol" << htmlAttribsToString(s->attribs()) << ">\n";
+ }
else
+ {
m_t << "<ul" << htmlAttribsToString(s->attribs()) << ">\n";
+ }
}
void HtmlDocVisitor::visitPost(DocHtmlList *s)
{
if (m_hide) return;
if (s->type()==DocHtmlList::Ordered)
+ {
m_t << "</ol>";
- else
+ }
+ else
+ {
m_t << "</ul>";
+ }
if (!s->isPreformatted()) m_t << "\n";
}
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 3dbec0e..d923186 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -873,7 +873,7 @@ void HtmlGenerator::writeCodeLink(const char *ref,const char *f,
if (f) t << f << Doxygen::htmlFileExtension;
if (anchor) t << "#" << anchor;
t << "\"";
- if (tooltip) t << " title=\"" << tooltip << "\"";
+ if (tooltip) t << " title=\"" << convertToXML(tooltip) << "\"";
t << ">";
docify(name);
t << "</a>";
diff --git a/src/index.cpp b/src/index.cpp
index dc8cdd5..c745659 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -1667,7 +1667,8 @@ void initClassMemberIndices()
void addClassMemberNameToIndex(MemberDef *md)
{
static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
- ClassDef *cd;
+ ClassDef *cd=0;
+
if (md->isLinkableInProject() &&
(cd=md->getClassDef()) &&
cd->isLinkableInProject() &&
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index a64ad22..ab06be0 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -237,21 +237,22 @@ static void writeDefaultHeaderPart1(QTextStream &t)
}
if (Config_getBool("PDF_HYPERLINKS"))
{
- t << "\\ifx\\pdfoutput\\undefined" << endl
- << "\\usepackage[ps2pdf," << endl
+ t << "\\usepackage{ifpdf}" << endl
+ << "\\ifpdf" << endl
+ << "\\usepackage[pdftex," << endl
<< " pagebackref=true," << endl
<< " colorlinks=true," << endl
<< " linkcolor=blue," << endl
<< " unicode" << endl
<< " ]{hyperref}" << endl
- << "\\usepackage{pspicture}" << endl
<< "\\else" << endl
- << "\\usepackage[pdftex," << endl
+ << "\\usepackage[ps2pdf," << endl
<< " pagebackref=true," << endl
<< " colorlinks=true," << endl
<< " linkcolor=blue," << endl
<< " unicode" << endl
<< " ]{hyperref}" << endl
+ << "\\usepackage{pspicture}" << endl
<< "\\fi" << endl;
}
// Try to get the command for switching on the language
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index d00516b..dffbb82 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -772,10 +772,15 @@ bool MemberDef::isLinkableInProject() const
static bool extractStatic = Config_getBool("EXTRACT_STATIC");
makeResident();
- if (isHidden()) return FALSE;
//printf("MemberDef::isLinkableInProject(name=%s)\n",name().data());
+ if (isHidden())
+ {
+ //printf("is hidden\n");
+ return FALSE;
+ }
if (m_impl->templateMaster)
{
+ //printf("has template master\n");
return m_impl->templateMaster->isLinkableInProject();
}
if (name().isEmpty() || name().at(0)=='@')
@@ -2157,7 +2162,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
)
{
DotCallGraph callGraph(this,FALSE);
- if (!callGraph.isTrivial())
+ if (!callGraph.isTrivial() && !callGraph.isTooBig())
{
msg("Generating call graph for function %s\n",qualifiedName().data());
ol.disable(OutputGenerator::Man);
@@ -2172,8 +2177,8 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
&& isFunction() && Config_getBool("HAVE_DOT")
)
{
- DotCallGraph callerGraph(this, true);
- if (!callerGraph.isTrivial())
+ DotCallGraph callerGraph(this, TRUE);
+ if (!callerGraph.isTrivial() && !callerGraph.isTooBig())
{
msg("Generating caller graph for function %s\n",qualifiedName().data());
ol.disable(OutputGenerator::Man);
diff --git a/src/msc.cpp b/src/msc.cpp
index aa4ad88..f68858a 100644
--- a/src/msc.cpp
+++ b/src/msc.cpp
@@ -98,7 +98,7 @@ void writeMscGraphFromFile(const char *inFile,const char *outDir,
// go to the html output directory (i.e. path)
QDir::setCurrent(outDir);
//printf("Going to dir %s\n",QDir::currentDirPath().data());
- QCString mscExe = Config_getString("MSC_PATH")+"mscgen"+portable_commandExtension();
+ QCString mscExe = Config_getString("MSCGEN_PATH")+"mscgen"+portable_commandExtension();
QCString mscArgs;
QCString extension;
if (format==MSC_BITMAP)
@@ -151,7 +151,7 @@ QString getMscImageMapFromFile(const QString& inFile, const QString& outDir,
QCString mscExe = "mscgen";
QCString mscArgs = "-T ismap -i \"";
mscArgs+=inFile + ".msc\" -o \"";
- mscArgs+=outFile + ".map\"";
+ mscArgs+=outFile + "\"";
int exitCode;
if ((exitCode=portable_system(mscExe,mscArgs,FALSE))!=0)
@@ -162,7 +162,7 @@ QString getMscImageMapFromFile(const QString& inFile, const QString& outDir,
QString result;
QTextOStream tmpout(&result);
- convertMapFile(tmpout, outFile+".map", relPath);
+ convertMapFile(tmpout, outFile, relPath);
QDir().remove(outFile);
QDir::setCurrent(oldDir);
diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp
index 1ebaaf9..fe69505 100644
--- a/src/namespacedef.cpp
+++ b/src/namespacedef.cpp
@@ -179,7 +179,7 @@ void NamespaceDef::insertMember(MemberDef *md)
m_memberLists.append(allMemberList);
}
allMemberList->append(md);
- ::addNamespaceMemberNameToIndex(md);
+ //::addNamespaceMemberNameToIndex(md);
//static bool sortBriefDocs=Config_getBool("SORT_BRIEF_DOCS");
switch(md->memberType())
{
diff --git a/src/translator_cn.h b/src/translator_cn.h
index 4c3168b..7689a0c 100644
--- a/src/translator_cn.h
+++ b/src/translator_cn.h
@@ -620,7 +620,8 @@ class TranslatorChinese : public Translator
*/
virtual QCString trNamespaces()
{
- return "Namespaces";
+ // return "Namespaces";
+ return "Ãû×Ö¿Õ¼ä";
}
//////////////////////////////////////////////////////////////////////////
diff --git a/src/util.cpp b/src/util.cpp
index 6521f81..0723ae4 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -116,8 +116,9 @@ void TextGeneratorOLImpl::writeLink(const char *extRef,const char *file,
// an inheritance tree of depth of 100000 should be enough for everyone :-)
const int maxInheritanceDepth = 100000;
-bool isId(char c)
+bool isId(int c)
{
+ if (c<0 || c>255) return FALSE;
return c=='_' || isalnum(c);
}
@@ -6080,3 +6081,166 @@ QCString parseCommentAsText(const QString &doc,const QCString &fileName,int line
return result.data();
}
+//--------------------------------------------------------------------------------------
+
+static QDict<void> aliasesProcessed;
+
+QCString expandAliasRec(const QCString s)
+{
+ QCString result;
+ static QRegExp cmdPat("[\\\\@][a-z_A-Z][a-z_A-Z0-9]*");
+ QCString value=s;
+ int i,p=0,l;
+ while ((i=cmdPat.match(value,p,&l))!=-1)
+ {
+ result+=value.mid(p,i-p);
+ QCString args = extractAliasArgs(value,i+l);
+ bool hasArgs = !args.isEmpty(); // found directly after command
+ QCString cmd;
+ if (hasArgs)
+ {
+ int numArgs = countAliasArguments(args);
+ cmd = value.mid(i+1,l-1)+QCString().sprintf("{%d}",numArgs); // alias name + {n}
+ }
+ else
+ {
+ cmd = value.mid(i+1,l-1);
+ }
+ //printf("Found command '%s' args='%s'\n",cmd.data(),args.data());
+ QCString *aliasText=Doxygen::aliasDict.find(cmd);
+ if (aliasesProcessed.find(cmd)==0 && aliasText) // expand the alias
+ {
+ //printf("is an alias!\n");
+ aliasesProcessed.insert(cmd,(void *)0x8);
+ QCString val = *aliasText;
+ if (hasArgs)
+ {
+ val = replaceAliasArguments(val,args);
+ //printf("replace '%s'->'%s' args='%s'\n",
+ // aliasText->data(),val.data(),args.data());
+ }
+ result+=expandAliasRec(val);
+ aliasesProcessed.remove(cmd);
+ p=i+l;
+ if (hasArgs) p+=args.length()+2;
+ }
+ else // command is not an alias
+ {
+ //printf("not an alias!\n");
+ result+=value.mid(i,l);
+ p=i+l;
+ }
+ }
+ result+=value.right(value.length()-p);
+
+ //printf("expandAliases '%s'->'%s'\n",s.data(),result.data());
+ return result;
+}
+
+static QCString replaceAliasArgument(const QCString &aliasValue,int paramNum,
+ const QCString &paramValue)
+{
+ QCString result = aliasValue;
+ QCString paramMarker;
+ paramMarker.sprintf("\\%d",paramNum);
+ int markerLen = paramMarker.length();
+ int p=0,i;
+ while ((i=aliasValue.find(paramMarker,p))!=-1) // search for marker
+ {
+ //printf("Found marker '%s' at %d len=%d for param '%s' in '%s'\n",
+ // paramMarker.data(),i,markerLen,paramValue.data(),aliasValue.data());
+ if (i==0 || aliasValue.at(i-1)!='\\') // found unescaped marker
+ {
+ QCString before = result.left(i);
+ QCString after = result.mid(i+markerLen);
+ result = before + paramValue + after;
+ p=i+paramValue.length();
+ }
+ else // ignore escaped markers
+ {
+ p=i+1;
+ }
+ }
+ result = expandAliasRec(substitute(result,"\\,",","));
+ //printf("replaceAliasArgument('%s',%d,'%s')->%s\n",
+ // aliasValue.data(),paramNum,paramValue.data(),result.data());
+ return result;
+}
+
+QCString replaceAliasArguments(const QCString &aliasValue,const QCString &argList)
+{
+ QCString result = aliasValue;
+ QList<QCString> args;
+ int p=0,i,c=1;
+ for (i=0;i<(int)argList.length();i++)
+ {
+ if (argList.at(i)==',' && (i==0 || argList.at(i-1)!='\\'))
+ {
+ result = replaceAliasArgument(result,c,argList.mid(p,i-p));
+ p=i+1;
+ c++;
+ }
+ }
+ if (p<(int)argList.length())
+ {
+ result = replaceAliasArgument(result,c,argList.right(argList.length()-p));
+ }
+ return result;
+}
+
+int countAliasArguments(const QCString argList)
+{
+ int count=1;
+ int l = argList.length();
+ int i;
+ for (i=0;i<l;i++)
+ {
+ if (argList.at(i)==',' && (i==0 || argList.at(i-1)!='\\')) count++;
+ }
+ return count;
+}
+
+QCString extractAliasArgs(const QCString &args,int pos)
+{
+ int i;
+ int bc=0;
+ if (args.at(pos)=='{') // alias has argument
+ {
+ for (i=pos;i<(int)args.length();i++)
+ {
+ if (args.at(i)=='{') bc++;
+ if (args.at(i)=='}') bc--;
+ if (bc==0)
+ {
+ //printf("extractAliasArgs('%s')->'%s'\n",args.data(),args.mid(pos+1,i-pos-1).data());
+ return args.mid(pos+1,i-pos-1);
+ }
+ }
+ }
+ return "";
+}
+
+QCString resolveAliasCmd(const QCString aliasCmd)
+{
+ QCString result;
+ aliasesProcessed.clear();
+ //printf("Expanding: '%s'\n",aliasCmd.data());
+ result = expandAliasRec(aliasCmd);
+ //printf("Expanding result: '%s'->'%s'\n",aliasCmd.data(),result.data());
+ return result;
+}
+
+QCString expandAlias(const QCString &aliasName,const QCString &aliasValue)
+{
+ QCString result;
+ aliasesProcessed.clear();
+ // avoid expanding this command recursively
+ aliasesProcessed.insert(aliasName,(void *)0x8);
+ // expand embedded commands
+ //printf("Expanding: '%s'->'%s'\n",aliasName.data(),aliasValue.data());
+ result = expandAliasRec(aliasValue);
+ //printf("Expanding result: '%s'->'%s'\n",aliasName.data(),result.data());
+ return result;
+}
+
+
diff --git a/src/util.h b/src/util.h
index 7f7274e..545d183 100644
--- a/src/util.h
+++ b/src/util.h
@@ -187,7 +187,7 @@ QCString showFileDefMatches(const FileNameDict *fnDict,const char *n);
int guessSection(const char *name);
-bool isId(char c);
+bool isId(int c);
QCString removeRedundantWhiteSpace(const QCString &s);
@@ -334,5 +334,14 @@ QCString transcodeCharacterStringToUTF8(const QCString &input);
QCString recodeString(const QCString &str,const char *fromEncoding,const char *toEncoding);
+QCString extractAliasArgs(const QCString &args,int pos);
+
+int countAliasArguments(const QCString argList);
+
+QCString replaceAliasArguments(const QCString &aliasValue,const QCString &argList);
+
+QCString resolveAliasCmd(const QCString aliasCmd);
+QCString expandAlias(const QCString &aliasName,const QCString &aliasValue);
+
#endif
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index 1cc8375..e66bea3 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -189,7 +189,7 @@ void writeXMLLink(QTextStream &t,const char *extRef,const char *compoundId,
if (anchorId) t << "member"; else t << "compound";
t << "\"";
if (extRef) t << " external=\"" << extRef << "\"";
- if (tooltip) t << " tooltip=\"" << tooltip << "\"";
+ if (tooltip) t << " tooltip=\"" << convertToXML(tooltip) << "\"";
t << ">";
writeXMLString(t,text);
t << "</ref>";