summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2007-07-19 13:04:41 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2007-07-19 13:04:41 (GMT)
commit29a8f144739c86ffad8db2f0c09de66bb641d2e2 (patch)
tree7c115c97f09109f537a6eb50b9baa3c0cd91d07d /src
parent01147699a7fb267e9d9247bdfb640f46e2164d3a (diff)
downloadDoxygen-29a8f144739c86ffad8db2f0c09de66bb641d2e2.zip
Doxygen-29a8f144739c86ffad8db2f0c09de66bb641d2e2.tar.gz
Doxygen-29a8f144739c86ffad8db2f0c09de66bb641d2e2.tar.bz2
Release-1.5.2-20070719
Diffstat (limited to 'src')
-rw-r--r--src/classdef.cpp67
-rw-r--r--src/classdef.h1
-rw-r--r--src/cmdmapper.cpp3
-rw-r--r--src/commentcnv.l2
-rw-r--r--src/commentscan.l4
-rw-r--r--src/config.l10
-rw-r--r--src/definition.cpp6
-rw-r--r--src/docparser.cpp8
-rw-r--r--src/dot.cpp152
-rw-r--r--src/dot.h5
-rw-r--r--src/doxygen.cpp70
-rw-r--r--src/entry.cpp136
-rw-r--r--src/entry.h1
-rw-r--r--src/filedef.cpp5
-rw-r--r--src/htmlgen.cpp187
-rw-r--r--src/htmlgen.h12
-rw-r--r--src/latexgen.cpp52
-rw-r--r--src/latexgen.h11
-rw-r--r--src/mangen.cpp66
-rw-r--r--src/mangen.h11
-rw-r--r--src/marshal.cpp2
-rw-r--r--src/memberdef.cpp39
-rw-r--r--src/memberdef.h1
-rw-r--r--src/namespacedef.cpp4
-rw-r--r--src/outputgen.h14
-rw-r--r--src/outputlist.h25
-rw-r--r--src/pyscanner.l11
-rw-r--r--src/rtfdocvisitor.cpp35
-rw-r--r--src/rtfgen.cpp106
-rw-r--r--src/rtfgen.h12
-rw-r--r--src/scanner.l203
-rw-r--r--src/textdocvisitor.cpp9
-rw-r--r--src/textdocvisitor.h6
-rw-r--r--src/util.cpp159
-rw-r--r--src/util.h3
35 files changed, 1030 insertions, 408 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp
index bbfe3e8..1991a4a 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -85,6 +85,9 @@ class ClassDefImpl
/*! Template arguments of this class */
ArgumentList *tempArgs;
+ /*! Type constraints for template parameters */
+ ArgumentList *typeConstraints;
+
/*! Files that were used for generating the class documentation. */
QStrList files;
@@ -189,6 +192,7 @@ void ClassDefImpl::init(const char *defFileName, const char *name,
allMemberNameInfoSDict = 0;
incInfo=0;
tempArgs=0;
+ typeConstraints=0;
prot=Public;
nspace=0;
fileDef=0;
@@ -244,6 +248,7 @@ ClassDefImpl::~ClassDefImpl()
delete variableInstances;
delete templBaseClassNames;
delete tempArgs;
+ delete typeConstraints;
}
// constructs a new class definition
@@ -870,6 +875,7 @@ void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &pageType
{
ol.pushGeneratorState();
ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::RTF);
ol.newParagraph();
ol.enableAll();
ol.disableAllBut(OutputGenerator::Man);
@@ -879,12 +885,12 @@ void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &pageType
// write documentation
if (!documentation().isEmpty())
{
- ol.pushGeneratorState();
- ol.disableAllBut(OutputGenerator::RTF);
- ol.newParagraph();
- ol.popGeneratorState();
- ol.parseDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
+ //ol.newParagraph();
+ ol.parseDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE);
}
+ // write type constraints
+ writeTypeConstraints(ol,this,m_impl->typeConstraints);
+
// write examples
if (exampleFlag && m_impl->exampleSDict)
{
@@ -894,7 +900,7 @@ void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &pageType
writeExample(ol,m_impl->exampleSDict);
ol.endSimpleSect();
}
- ol.newParagraph();
+ //ol.newParagraph();
writeSourceDef(ol,name());
ol.endTextBlock();
}
@@ -1021,17 +1027,6 @@ void ClassDef::writeClassDiagrams(OutputList &ol)
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;
}
@@ -1048,7 +1043,8 @@ void ClassDef::writeClassDiagrams(OutputList &ol)
renderDiagram = TRUE;
}
- if (Config_getBool("CLASS_DIAGRAMS") && renderDiagram)
+ if (renderDiagram) // if we already show the inheritance relations graphically,
+ // then hide the text version
{
ol.disableAllBut(OutputGenerator::Man);
}
@@ -1138,7 +1134,7 @@ void ClassDef::writeClassDiagrams(OutputList &ol)
ol.newParagraph();
}
- if (Config_getBool("CLASS_DIAGRAMS") && renderDiagram)
+ if (renderDiagram)
{
ol.enableAll();
}
@@ -1153,15 +1149,6 @@ void ClassDef::writeClassDiagrams(OutputList &ol)
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();
}
}
@@ -1229,8 +1216,10 @@ void ClassDef::writeDocumentation(OutputList &ol)
if (!Config_getBool("DETAILS_AT_TOP"))
{
ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),TRUE,FALSE);
- ol.writeString(" \n");
ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.writeString(" \n");
+ ol.enable(OutputGenerator::RTF);
ol.disableAllBut(OutputGenerator::Html);
ol.startTextLink(0,"_details");
@@ -1329,12 +1318,13 @@ void ClassDef::writeDocumentation(OutputList &ol)
writeClassDiagrams(ol);
// write link to list of all members (HTML only)
- if (m_impl->allMemberNameInfoSDict &&
+ if (m_impl->allMemberNameInfoSDict &&
!Config_getBool("OPTIMIZE_OUTPUT_FOR_C")
)
{
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
+ ol.newParagraph();
ol.startTextLink(getMemberListFileName(),0);
ol.parseText(theTranslator->trListOfAllMembers());
ol.endTextLink();
@@ -1345,11 +1335,11 @@ void ClassDef::writeDocumentation(OutputList &ol)
ol.endTextBlock();
// write detailed description if the user wants it near the top
- if (Config_getBool("DETAILS_AT_TOP")) {
+ if (Config_getBool("DETAILS_AT_TOP"))
+ {
writeDetailedDescription(ol,pageType,exampleFlag);
}
-
///////////////////////////////////////////////////////////////////////////
//// Member declarations + brief descriptions
///////////////////////////////////////////////////////////////////////////
@@ -1866,6 +1856,19 @@ void ClassDef::setTemplateArguments(ArgumentList *al)
}
}
+void ClassDef::setTypeConstraints(ArgumentList *al)
+{
+ if (al==0) return;
+ if (!m_impl->typeConstraints) delete m_impl->typeConstraints;
+ m_impl->typeConstraints = new ArgumentList;
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ m_impl->typeConstraints->append(new Argument(*a));
+ }
+}
+
/*! Returns \c TRUE iff this class or a class inheriting from this class
* is \e not defined in an external tag file.
*/
diff --git a/src/classdef.h b/src/classdef.h
index b03ae52..1cfccc2 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -294,6 +294,7 @@ class ClassDef : public Definition
void setTemplateArguments(ArgumentList *al);
void setTemplateBaseClassNames(QDict<int> *templateNames);
void setTemplateMaster(ClassDef *tm);
+ void setTypeConstraints(ArgumentList *al);
void addMembersToTemplateInstance(ClassDef *cd,const char *templSpec);
void makeTemplateArgument(bool b=TRUE);
void setCategoryOf(ClassDef *cd);
diff --git a/src/cmdmapper.cpp b/src/cmdmapper.cpp
index c4469c7..e6f74f0 100644
--- a/src/cmdmapper.cpp
+++ b/src/cmdmapper.cpp
@@ -26,6 +26,7 @@ CommandMap cmdMap[] =
{ "arg", CMD_LI },
{ "attention", CMD_ATTENTION },
{ "author", CMD_AUTHOR },
+ { "authors", CMD_AUTHORS },
{ "b", CMD_BOLD },
{ "c", CMD_CODE },
{ "code", CMD_STARTCODE },
@@ -89,8 +90,6 @@ CommandMap cmdMap[] =
{ "verbinclude", CMD_VERBINCLUDE },
{ "version", CMD_VERSION },
{ "warning", CMD_WARNING },
- { "author", CMD_AUTHOR },
- { "authors", CMD_AUTHORS },
{ "throws", CMD_EXCEPTION },
{ "\\", CMD_BSLASH },
{ "@", CMD_AT },
diff --git a/src/commentcnv.l b/src/commentcnv.l
index b12d9d8..465c951 100644
--- a/src/commentcnv.l
+++ b/src/commentcnv.l
@@ -168,6 +168,7 @@ static void endCondSection()
}
}
+#if 0
/** remove and executes cond and endcond commands in \a s */
static QCString handleCondCmdInAliases(const QCString &s)
{
@@ -223,6 +224,7 @@ static QCString handleCondCmdInAliases(const QCString &s)
result+=s.right(s.length()-p);
return result;
}
+#endif
/** copies string \a s with length \a len to the output, while
* replacing any alias commands found in the string.
diff --git a/src/commentscan.l b/src/commentscan.l
index 553b93a..9a7f698 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -198,6 +198,7 @@ static DocCmdMap docCmdMap[] =
{ "arg", 0, TRUE },
{ "attention", 0, TRUE },
{ "author", 0, TRUE },
+ { "authors", 0, TRUE },
{ "date", 0, TRUE },
{ "dotfile", 0, TRUE },
{ "htmlinclude", 0, TRUE },
@@ -212,7 +213,9 @@ static DocCmdMap docCmdMap[] =
{ "param", 0, TRUE },
{ "post", 0, TRUE },
{ "pre", 0, TRUE },
+ { "remark", 0, TRUE },
{ "remarks", 0, TRUE },
+ { "result", 0, TRUE },
{ "return", 0, TRUE },
{ "returns", 0, TRUE },
{ "retval", 0, TRUE },
@@ -220,6 +223,7 @@ static DocCmdMap docCmdMap[] =
{ "see", 0, TRUE },
{ "since", 0, TRUE },
{ "throw", 0, TRUE },
+ { "throws", 0, TRUE },
{ "until", 0, TRUE },
{ "verbinclude", 0, TRUE },
{ "version", 0, TRUE },
diff --git a/src/config.l b/src/config.l
index e3faf84..cb73dfb 100644
--- a/src/config.l
+++ b/src/config.l
@@ -2222,6 +2222,16 @@ void Config::create()
FALSE
);
cb->addDependency("GENERATE_HTML");
+ cb = addBool(
+ "HTML_DYNAMIC_SECTIONS",
+ "If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML \n"
+ "documentation will contain sections that can be hidden and shown after the \n"
+ "page has loaded. For this to work a browser that supports \n"
+ "JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox \n"
+ "Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). \n",
+ FALSE
+ );
+ cb->addDependency("GENERATE_HTML");
cs = addString(
"CHM_FILE",
"If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can \n"
diff --git a/src/definition.cpp b/src/definition.cpp
index bfcfbad..668e566 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -551,7 +551,7 @@ void Definition::writeSourceDef(OutputList &ol,const char *)
QCString lineStr,anchorStr;
lineStr.sprintf("%d",m_impl->body->startLine);
anchorStr.sprintf(Htags::useHtags ? "L%d" : "l%05d",m_impl->body->startLine);
- ol.newParagraph();
+ ol.startParagraph();
if (lineMarkerPos<fileMarkerPos) // line marker before file marker
{
// write text left from linePos marker
@@ -616,6 +616,7 @@ void Definition::writeSourceDef(OutputList &ol,const char *)
ol.parseText(refText.right(
refText.length()-lineMarkerPos-2));
}
+ ol.endParagraph();
}
else
{
@@ -691,7 +692,7 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName,
ol.pushGeneratorState();
if (Config_getBool("SOURCE_BROWSER") && members)
{
- ol.newParagraph();
+ ol.startParagraph();
ol.parseText(text);
ol.docify(" ");
@@ -772,6 +773,7 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName,
}
ol.parseText(ldefLine.right(ldefLine.length()-index));
ol.writeString(".");
+ ol.endParagraph();
}
ol.popGeneratorState();
}
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 01d88ae..e9d16af 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -368,11 +368,15 @@ static void checkUndocumentedParams()
}
if (g_memberDef->inheritsDocsFrom())
{
- warn_doc_error(g_memberDef->getDefFileName(),g_memberDef->getDefLine(),errMsg);
+ warn_doc_error(g_memberDef->getDefFileName(),
+ g_memberDef->getDefLine(),
+ substitute(errMsg,"%","%%"));
}
else
{
- warn_doc_error(g_memberDef->docFile(),g_memberDef->docLine(),errMsg);
+ warn_doc_error(g_memberDef->docFile(),
+ g_memberDef->docLine(),
+ substitute(errMsg,"%","%%"));
}
}
}
diff --git a/src/dot.cpp b/src/dot.cpp
index 603fc38..412eeda 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -242,7 +242,7 @@ static bool readBoundingBoxEPS(const char *fileName,int *width,int *height)
{
int numBytes = f.readLine(buf,maxLineLen-1); // read line
buf[numBytes]='\0';
- if (strncmp(buf,bb.data(),bb.length()-1)==0) // found PageBoundBox string
+ if (strncmp(buf,bb.data(),bb.length()-1)==0) // found PageBoundingBox string
{
int x,y;
if (sscanf(buf+bb.length(),"%d %d %d %d",&x,&y,width,height)!=4)
@@ -543,7 +543,6 @@ static QCString escapeTooltip(const QCString &tooltip)
switch(c)
{
case '\\': result+="\\\\"; break;
- case '"': result+="\\\""; break;
default: result+=c; break;
}
}
@@ -1398,44 +1397,98 @@ void DotClassGraph::determineTruncatedNodes(QList<DotNode> &queue,bool includePa
}
}
-void DotClassGraph::determineVisibleNodes(QList<DotNode> &queue,
- int &maxNodes,bool includeParents)
+bool DotClassGraph::determineVisibleNodes(DotNode *rootNode,
+ int maxNodes,bool includeParents)
{
- while (queue.count()>0 && maxNodes>0)
+ QList<DotNode> childQueue;
+ QList<DotNode> parentQueue;
+ QArray<int> childTreeWidth;
+ QArray<int> parentTreeWidth;
+ childQueue.append(rootNode);
+ if (includeParents) parentQueue.append(rootNode);
+ bool firstNode=TRUE; // flag to force reprocessing rootNode in the parent loop
+ // despite being marked visible in the child loop
+ while ((childQueue.count()>0 || parentQueue.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 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
+ if (childQueue.count()>0)
{
- //printf(" Marked as visible!\n");
- n->markAsVisible();
- maxNodes--;
- // add direct children
- if (n->m_children)
+ DotNode *n = childQueue.take(0);
+ int distance = n->distance();
+ if (!n->isVisible() && distance<maxDistance) // not yet processed
{
- QListIterator<DotNode> li(*n->m_children);
- DotNode *dn;
- for (li.toFirst();(dn=li.current());++li)
+ if (distance>0)
{
- queue.append(dn);
+ int oldSize=(int)childTreeWidth.size();
+ if (distance>oldSize)
+ {
+ childTreeWidth.resize(QMAX(childTreeWidth.size(),(uint)distance));
+ int i; for (i=oldSize;i<distance;i++) childTreeWidth[i]=0;
+ }
+ childTreeWidth[distance-1]+=n->label().length();
+ }
+ n->markAsVisible();
+ maxNodes--;
+ // add direct children
+ if (n->m_children)
+ {
+ QListIterator<DotNode> li(*n->m_children);
+ DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ childQueue.append(dn);
+ }
}
}
- // add direct parents
- if (n->m_parents && includeParents)
+ }
+ if (includeParents && parentQueue.count()>0)
+ {
+ DotNode *n = parentQueue.take(0);
+ if ((!n->isVisible() || firstNode) && n->distance()<maxDistance) // not yet processed
{
- QListIterator<DotNode> li(*n->m_parents);
- DotNode *dn;
- for (li.toFirst();(dn=li.current());++li)
+ firstNode=FALSE;
+ int distance = n->distance();
+ if (distance>0)
{
- queue.append(dn);
+ int oldSize = (int)parentTreeWidth.size();
+ if (distance>oldSize)
+ {
+ parentTreeWidth.resize(QMAX(parentTreeWidth.size(),(uint)distance));
+ int i; for (i=oldSize;i<distance;i++) parentTreeWidth[i]=0;
+ }
+ parentTreeWidth[distance-1]+=n->label().length();
+ }
+ n->markAsVisible();
+ maxNodes--;
+ // add direct parents
+ if (n->m_parents)
+ {
+ QListIterator<DotNode> li(*n->m_parents);
+ DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ parentQueue.append(dn);
+ }
}
}
}
}
+ int maxWidth=0;
+ int maxHeight=(int)QMAX(childTreeWidth.size(),parentTreeWidth.size());
+ uint i;
+ for (i=0;i<childTreeWidth.size();i++)
+ {
+ if (childTreeWidth[i]>maxWidth) maxWidth=childTreeWidth[i];
+ }
+ for (i=0;i<parentTreeWidth.size();i++)
+ {
+ if (parentTreeWidth[i]>maxWidth) maxWidth=parentTreeWidth[i];
+ }
+ //printf("max tree width=%d, max tree height=%d\n",maxWidth,maxHeight);
+ return maxWidth>80 && maxHeight<12; // used metric to decide to render the tree
+ // from left to right instead of top to bottom,
+ // with the idea to render very wide trees in
+ // left to right order.
}
void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,bool base,int distance)
@@ -1564,19 +1617,17 @@ DotClassGraph::DotClassGraph(ClassDef *cd,DotNode::GraphType t)
if (t==DotNode::Inheritance) buildGraph(cd,m_startNode,FALSE,1);
//}
- static int nodes = Config_getInt("DOT_GRAPH_MAX_NODES");
- int maxNodes = nodes;
+ static 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;
+ //openNodeQueue.append(m_startNode);
+ m_lrRank = determineVisibleNodes(m_startNode,maxNodes,t==DotNode::Inheritance);
QList<DotNode> openNodeQueue;
openNodeQueue.append(m_startNode);
- determineVisibleNodes(openNodeQueue,maxNodes,t==DotNode::Inheritance);
- openNodeQueue.clear();
- openNodeQueue.append(m_startNode);
determineTruncatedNodes(openNodeQueue,t==DotNode::Inheritance);
m_diskName = cd->getFileBase().copy();
@@ -1733,7 +1784,7 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
GraphOutputFormat format,
const char *path,
const char *relPath,
- bool isTBRank,
+ bool /*isTBRank*/,
bool generateImageMap)
{
QDir d(path);
@@ -1772,7 +1823,7 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
m_graphType,
baseName,
format,
- !isTBRank,
+ m_lrRank, //!isTBRank,
m_graphType==DotNode::Inheritance,
TRUE
)
@@ -1853,20 +1904,33 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
}
else if (format==EPS) // produce tex to include the .eps image
{
- int width,height;
+ int width=420,height=600;
if (!readBoundingBoxEPS(baseName+".eps",&width,&height))
{
err("Error: Could not extract bounding box from .eps!\n");
QDir::setCurrent(oldDir);
return baseName;
}
- int maxWidth = 420; /* approx. page width in points */
+ //printf("Got EPS size %d,%d\n",width,height);
+ int maxWidth = 400; /* approx. page width in points, excl. margins */
+ int maxHeight = 400; /* approx. page height in points, excl. margins */
out << "\\nopagebreak\n"
"\\begin{figure}[H]\n"
"\\begin{center}\n"
- "\\leavevmode\n"
- "\\includegraphics[width=" << QMIN(width/2,maxWidth)
- << "pt]{" << baseName << "}\n"
+ "\\leavevmode\n";
+ if (width>maxWidth)
+ {
+ out << "\\includegraphics[width=" << maxWidth << "pt]";
+ }
+ else if (height>maxHeight)
+ {
+ out << "\\includegraphics[height=" << maxHeight << "pt]";
+ }
+ else
+ {
+ out << "\\includegraphics[width=" << width/2 << "pt]";
+ }
+ out << "{" << baseName << "}\n"
"\\end{center}\n"
"\\end{figure}\n";
}
@@ -2204,7 +2268,7 @@ void DotInclDepGraph::writeXML(QTextStream &t)
int DotCallGraph::m_curNodeNumber = 0;
-void DotCallGraph::buildGraph(DotNode *n,MemberDef *md)
+void DotCallGraph::buildGraph(DotNode *n,MemberDef *md,int distance)
{
LockingPtr<MemberSDict> refs = m_inverse ? md->getReferencedByMembers() : md->getReferencesMembers();
if (!refs.isNull())
@@ -2223,6 +2287,7 @@ void DotCallGraph::buildGraph(DotNode *n,MemberDef *md)
{
n->addChild(bn,0,0,0);
bn->addParent(n);
+ bn->setDistance(distance);
}
else
{
@@ -2246,9 +2311,10 @@ void DotCallGraph::buildGraph(DotNode *n,MemberDef *md)
);
n->addChild(bn,0,0,0);
bn->addParent(n);
+ bn->setDistance(distance);
m_usedNodes->insert(uniqueId,bn);
- buildGraph(bn,rmd);
+ buildGraph(bn,rmd,distance+1);
}
}
}
@@ -2259,8 +2325,9 @@ void DotCallGraph::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--;
@@ -2329,9 +2396,10 @@ DotCallGraph::DotCallGraph(MemberDef *md,bool inverse)
uniqueId.data(),
TRUE // root node
);
+ m_startNode->setDistance(0);
m_usedNodes = new QDict<DotNode>(1009);
m_usedNodes->insert(uniqueId,m_startNode);
- buildGraph(m_startNode,md);
+ buildGraph(m_startNode,md,1);
static int nodes = Config_getInt("DOT_GRAPH_MAX_NODES");
int maxNodes = nodes;
diff --git a/src/dot.h b/src/dot.h
index 6632aef..db52ddc 100644
--- a/src/dot.h
+++ b/src/dot.h
@@ -168,7 +168,7 @@ class DotClassGraph
private:
void buildGraph(ClassDef *cd,DotNode *n,bool base,int distance);
- void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes,bool includeParents);
+ bool determineVisibleNodes(DotNode *rootNode,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,
@@ -179,6 +179,7 @@ class DotClassGraph
static int m_curNodeNumber;
DotNode::GraphType m_graphType;
QCString m_diskName;
+ bool m_lrRank;
};
/** @brief Representation of an include dependency graph */
@@ -216,7 +217,7 @@ class DotCallGraph
~DotCallGraph();
QCString writeGraph(QTextStream &t, GraphOutputFormat f,
const char *path,const char *relPath,bool writeImageMap=TRUE);
- void buildGraph(DotNode *n,MemberDef *md);
+ void buildGraph(DotNode *n,MemberDef *md,int distance);
bool isTrivial() const;
bool isTooBig() const;
void determineVisibleNodes(QList<DotNode> &queue, int &maxNodes);
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 3042aa0..54ace8a 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -1164,6 +1164,7 @@ static void addClassToContext(EntryNav *rootNav)
cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
cd->setIsObjectiveC(root->objc);
cd->setHidden(root->hidden);
+ cd->setTypeConstraints(root->typeConstr);
//printf("new ClassDef %s tempArgList=%p specScope=%s\n",fullName.data(),root->tArgList,root->scopeSpec.data());
ArgumentList *tArgList =
@@ -1357,6 +1358,8 @@ static void buildNamespaceList(EntryNav *rootNav)
rootNav->loadEntry(g_storage);
Entry *root = rootNav->entry();
+ //printf("** buildNamespaceList(%s)\n",root->name.data());
+
QCString fullName = root->name;
if (root->section==Entry::PACKAGEDOC_SEC)
{
@@ -1422,6 +1425,7 @@ static void buildNamespaceList(EntryNav *rootNav)
nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
nd->addSectionsToDefinition(root->anchors);
+ nd->setHidden(root->hidden);
//printf("Adding namespace to group\n");
addNamespaceToGroups(root,nd);
@@ -2577,6 +2581,7 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd,
const QCString &rname,bool isFriend)
{
Entry *root = rootNav->entry();
+ FileDef *fd=rootNav->fileDef();
int l,i;
static QRegExp re("([a-z_A-Z0-9: ]*[ *]*[ ]*");
@@ -2598,7 +2603,8 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd,
else mtype=MemberDef::Function;
// strip redundant template specifier for constructors
- if ((i=name.find('<'))!=-1 && name.find('>')!=-1)
+ if ((fd==0 || getLanguageFromFileName(fd->name())==SrcLangExt_Cpp) &&
+ (i=name.find('<')!=-1) && name.find('>')!=-1)
{
name=name.left(i);
}
@@ -2622,7 +2628,7 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd,
md->setBodySegment(root->bodyLine,root->endBodyLine);
md->setMemberSpecifiers(root->spec);
md->setMemberGroupId(root->mGrpId);
- FileDef *fd=rootNav->fileDef();
+ md->setTypeConstraints(root->typeConstr);
md->setBodyDef(fd);
md->setFileDef(fd);
//md->setScopeTemplateArguments(root->tArgList);
@@ -2964,6 +2970,7 @@ static void buildFunctionList(EntryNav *rootNav)
md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
md->setPrototype(root->proto);
md->setDocsForDefinition(!root->proto);
+ md->setTypeConstraints(root->typeConstr);
//md->setBody(root->body);
md->setBodySegment(root->bodyLine,root->endBodyLine);
FileDef *fd=rootNav->fileDef();
@@ -5539,6 +5546,7 @@ static void findMember(EntryNav *rootNav,
md->setTagInfo(rootNav->tagInfo());
md->setMemberClass(cd);
md->setTemplateSpecialization(TRUE);
+ md->setTypeConstraints(root->typeConstr);
md->setDefinition(funcDecl);
md->enableCallGraph(root->callGraph);
md->enableCallerGraph(root->callerGraph);
@@ -5599,6 +5607,7 @@ static void findMember(EntryNav *rootNav,
root->protection,root->virt,root->stat,TRUE,
mtype,tArgList,root->argList);
md->setTagInfo(rootNav->tagInfo());
+ md->setTypeConstraints(root->typeConstr);
md->setMemberClass(cd);
md->setDefinition(funcDecl);
md->enableCallGraph(root->callGraph);
@@ -9288,7 +9297,7 @@ void parseInput()
cleanUpDoxygen();
exit(1);
}
-
+
QCString &xmlOutput = Config_getString("XML_OUTPUT");
bool &generateXml = Config_getBool("GENERATE_XML");
if (xmlOutput.isEmpty() && generateXml)
@@ -9709,6 +9718,21 @@ void parseInput()
msg("Computing dependencies between directories...\n");
computeDirDependencies();
}
+
+ msg("Counting data structures...\n");
+ countDataStructures();
+
+ msg("Resolving user defined references...\n");
+ resolveUserReferences();
+
+ msg("Finding anchors and sections in the documentation...\n");
+ findSectionsInDocumentation();
+
+ transferFunctionReferences();
+
+ msg("Combining using relations...\n");
+ combineUsingRelations();
+
}
void generateOutput()
@@ -9734,31 +9758,6 @@ void generateOutput()
initDocParser();
- //{
- // QCString fileName = Config_getString("HTML_OUTPUT")+"/filetree.html";
- // QFile f(fileName);
- // if (f.open(IO_WriteOnly))
- // {
- // QTextStream t(&f);
- // t << "<html>\n";
- // t << " <head>\n";
- // t << " <style type=\"text/css\">\n";
- // t << " <!--\n";
- // t << " .directory { font-size: 10pt; font-weight: bold; }\n";
- // t << " .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; }\n";
- // t << " .directory p { margin: 0px; white-space: nowrap; }\n";
- // t << " .directory div { display: visible; margin: 0px; }\n";
- // t << " .directory img { vertical-align: middle; }\n";
- // t << " -->\n";
- // t << " </style>\n";
- // t << " </head>\n";
- // t << " <body>\n";
- // generateFileTree(t);
- // t << " </body>\n";
- // t << "</html>\n";
- // }
- //}
-
outputList = new OutputList(TRUE);
if (Config_getBool("GENERATE_HTML"))
{
@@ -9766,6 +9765,7 @@ void generateOutput()
HtmlGenerator::init();
if (Config_getBool("GENERATE_HTMLHELP")) HtmlHelp::getInstance()->initialize();
if (Config_getBool("GENERATE_TREEVIEW")) FTVHelp::getInstance()->initialize();
+ if (Config_getBool("HTML_DYNAMIC_SECTIONS")) HtmlGenerator::generateSectionImages();
copyStyleSheet();
}
if (Config_getBool("GENERATE_LATEX"))
@@ -9842,18 +9842,6 @@ void generateOutput()
// count the number of documented elements in the lists we have built.
// If the result is 0 we do not generate the lists and omit the
// corresponding links in the index.
- msg("Counting data structures...\n");
- countDataStructures();
-
- msg("Resolving user defined references...\n");
- resolveUserReferences();
-
- msg("Combining using relations...\n");
- combineUsingRelations();
-
- msg("Finding anchors and sections in the documentation...\n");
- findSectionsInDocumentation();
-
msg("Generating index page...\n");
writeIndex(*outputList);
@@ -9865,7 +9853,6 @@ void generateOutput()
{
generateFileSources();
}
- transferFunctionReferences();
msg("Generating file documentation...\n");
generateFileDocs();
@@ -9958,6 +9945,7 @@ void generateOutput()
if (Config_getBool("GENERATE_HTML") && Config_getBool("DOT_CLEANUP")) removeDoxFont(Config_getString("HTML_OUTPUT"));
if (Config_getBool("GENERATE_RTF") && Config_getBool("DOT_CLEANUP")) removeDoxFont(Config_getString("RTF_OUTPUT"));
+
if (Config_getBool("GENERATE_XML"))
{
msg("Generating XML output...\n");
diff --git a/src/entry.cpp b/src/entry.cpp
index 77830c0..edb54c1 100644
--- a/src/entry.cpp
+++ b/src/entry.cpp
@@ -27,122 +27,6 @@
#define HEADER ('D'<<24)+('O'<<16)+('X'<<8)+'!'
-#if 0
-static bool saveEntry(Entry *e,StorageIntf *f)
-{
- marshalUInt(f,HEADER);
- marshalInt(f,(int)e->protection);
- marshalInt(f,(int)e->mtype);
- marshalInt(f,e->spec);
- marshalInt(f,e->initLines);
- marshalBool(f,e->stat);
- marshalBool(f,e->explicitExternal);
- marshalBool(f,e->proto);
- marshalBool(f,e->subGrouping);
- marshalBool(f,e->callGraph);
- marshalBool(f,e->callerGraph);
- marshalInt(f,(int)e->virt);
- marshalQCString(f,e->args);
- marshalQCString(f,e->bitfields);
- marshalArgumentList(f,e->argList);
- marshalArgumentLists(f,e->tArgLists);
- marshalQGString(f,e->program);
- marshalQGString(f,e->initializer);
- marshalQCString(f,e->includeFile);
- marshalQCString(f,e->includeName);
- marshalQCString(f,e->doc);
- marshalInt(f,e->docLine);
- marshalQCString(f,e->docFile);
- marshalQCString(f,e->brief);
- marshalInt(f,e->briefLine);
- marshalQCString(f,e->briefFile);
- marshalQCString(f,e->inbodyDocs);
- marshalInt(f,e->inbodyLine);
- marshalQCString(f,e->inbodyFile);
- marshalQCString(f,e->relates);
- marshalBool(f,e->relatesDup);
- marshalQCString(f,e->read);
- marshalQCString(f,e->write);
- marshalQCString(f,e->inside);
- marshalQCString(f,e->exception);
- marshalInt(f,e->bodyLine);
- marshalInt(f,e->endBodyLine);
- marshalInt(f,e->mGrpId);
- marshalBaseInfoList(f,e->extends);
- marshalGroupingList(f,e->groups);
- marshalSectionInfoList(f,e->anchors);
- marshalQCString(f,e->fileName);
- marshalInt(f,e->startLine);
- marshalItemInfoList(f,e->sli);
- marshalBool(f,e->objc);
- marshalBool(f,e->hidden);
- marshalInt(f,(int)e->groupDocType);
- return TRUE;
-}
-
-static bool loadEntry(Entry *e,StorageIntf *f)
-{
- uint header=unmarshalUInt(f);
- if (header!=HEADER)
- {
- printf("Internal error: Invalid header %x for entry in storage file %s\n",
- header,Doxygen::entryDBFileName.data());
- exit(1);
- }
- e->protection = (Protection)unmarshalInt(f);
- e->mtype = (MethodTypes)unmarshalInt(f);
- e->spec = unmarshalInt(f);
- e->initLines = unmarshalInt(f);
- e->stat = unmarshalBool(f);
- e->explicitExternal = unmarshalBool(f);
- e->proto = unmarshalBool(f);
- e->subGrouping = unmarshalBool(f);
- e->callGraph = unmarshalBool(f);
- e->callerGraph = unmarshalBool(f);
- e->virt = (Specifier)unmarshalInt(f);
- e->args = unmarshalQCString(f);
- e->bitfields = unmarshalQCString(f);
- delete e->argList;
- e->argList = unmarshalArgumentList(f);
- e->tArgLists = unmarshalArgumentLists(f);
- e->program = unmarshalQGString(f);
- e->initializer = unmarshalQGString(f);
- e->includeFile = unmarshalQCString(f);
- e->includeName = unmarshalQCString(f);
- e->doc = unmarshalQCString(f);
- e->docLine = unmarshalInt(f);
- e->docFile = unmarshalQCString(f);
- e->brief = unmarshalQCString(f);
- e->briefLine = unmarshalInt(f);
- e->briefFile = unmarshalQCString(f);
- e->inbodyDocs = unmarshalQCString(f);
- e->inbodyLine = unmarshalInt(f);
- e->inbodyFile = unmarshalQCString(f);
- e->relates = unmarshalQCString(f);
- e->relatesDup = unmarshalBool(f);
- e->read = unmarshalQCString(f);
- e->write = unmarshalQCString(f);
- e->inside = unmarshalQCString(f);
- e->exception = unmarshalQCString(f);
- e->bodyLine = unmarshalInt(f);
- e->endBodyLine = unmarshalInt(f);
- e->mGrpId = unmarshalInt(f);
- delete e->extends;
- e->extends = unmarshalBaseInfoList(f);
- delete e->groups;
- e->groups = unmarshalGroupingList(f);
- delete e->anchors;
- e->anchors = unmarshalSectionInfoList(f);
- e->fileName = unmarshalQCString(f);
- e->startLine = unmarshalInt(f);
- e->sli = unmarshalItemInfoList(f);
- e->objc = unmarshalBool(f);
- e->hidden = unmarshalBool(f);
- e->groupDocType = (Entry::GroupDocType)unmarshalInt(f);
- return TRUE;
-}
-#endif
-
//------------------------------------------------------------------
/*! the argument list is documented if one of its
@@ -181,6 +65,7 @@ Entry::Entry()
argList->setAutoDelete(TRUE);
//printf("Entry::Entry() tArgList=0\n");
tArgLists = 0;
+ typeConstr = 0;
mGrpId = -1;
tagInfo = 0;
sli = 0;
@@ -245,6 +130,8 @@ Entry::Entry(const Entry &e)
anchors = new QList<SectionInfo>;
argList = new ArgumentList;
argList->setAutoDelete(TRUE);
+ typeConstr = new ArgumentList;
+ typeConstr->setAutoDelete(TRUE);
tArgLists = 0;
groupDocType = e.groupDocType;
@@ -290,6 +177,16 @@ Entry::Entry(const Entry &e)
argList->volatileSpecifier = e.argList->volatileSpecifier;
argList->pureSpecifier = e.argList->pureSpecifier;
+ // deep copy type contraint list
+ if (e.typeConstr)
+ {
+ QListIterator<Argument> tcli(*e.typeConstr);
+ for (;(a=tcli.current());++tcli)
+ {
+ typeConstr->append(new Argument(*a));
+ }
+ }
+
// deep copy template argument lists
if (e.tArgLists)
{
@@ -391,9 +288,10 @@ void Entry::reset()
groups->clear();
anchors->clear();
argList->clear();
- if (tagInfo) { delete tagInfo; tagInfo=0; }
- if (tArgLists) { delete tArgLists; tArgLists=0; }
- if (sli) { delete sli; sli=0; }
+ if (tagInfo) { delete tagInfo; tagInfo=0; }
+ if (tArgLists) { delete tArgLists; tArgLists=0; }
+ if (sli) { delete sli; sli=0; }
+ if (typeConstr) { delete typeConstr; typeConstr=0; }
//if (mtArgList) { delete mtArgList; mtArgList=0; }
}
diff --git a/src/entry.h b/src/entry.h
index ede809c..1a51944 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -349,6 +349,7 @@ class Entry
QCString write; //!< property write accessor
QCString inside; //!< name of the class in which documents are found
QCString exception; //!< throw specification
+ ArgumentList *typeConstr; //!< where clause (C#) for type constraints
int bodyLine; //!< line number of the definition in the source
int endBodyLine; //!< line number where the definition ends
int mGrpId; //!< member group id
diff --git a/src/filedef.cpp b/src/filedef.cpp
index 45b7ea6..3588a45 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -168,6 +168,7 @@ void FileDef::writeDetailedDocumentation(OutputList &ol)
ol.startGroupHeader();
ol.parseText(theTranslator->trDetailedDescription());
ol.endGroupHeader();
+ ol.startTextBlock();
if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
{
ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
@@ -192,7 +193,7 @@ void FileDef::writeDetailedDocumentation(OutputList &ol)
//printf("Writing source ref for file %s\n",name().data());
if (Config_getBool("SOURCE_BROWSER"))
{
- ol.newParagraph();
+ ol.startParagraph();
QCString refText = theTranslator->trDefinedInSourceFile();
int fileMarkerPos = refText.find("@0");
if (fileMarkerPos!=-1) // should always pass this.
@@ -203,7 +204,9 @@ void FileDef::writeDetailedDocumentation(OutputList &ol)
ol.parseText(refText.right(
refText.length()-fileMarkerPos-2)); // text right from marker 2
}
+ ol.endParagraph();
}
+ ol.endTextBlock();
}
}
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index d923186..5442ed7 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -46,7 +46,7 @@ static const char defaultStyleSheet[] =
#include "doxygen_css.h"
;
-const char search_script[]=
+static const char search_script[]=
#include "search_php.h"
;
@@ -488,7 +488,29 @@ static void writeTabData(const char *dir)
}
}
-//-----------------------------------------------------------------------
+//------------------------------------------------------------------------
+
+unsigned char open_gif[] = {
+ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x09, 0x00, 0x09, 0x00, 0xf0, 0x00,
+ 0x00, 0x8e, 0xaf, 0xc4, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x09, 0x00,
+ 0x00, 0x02, 0x0d, 0x8c, 0x8f, 0xa9, 0xcb, 0xe0, 0xff, 0x02, 0x8c, 0x66,
+ 0x26, 0x7a, 0x51, 0x01, 0x00, 0x3b
+};
+unsigned int open_gif_len = 54;
+
+unsigned char closed_gif[] = {
+ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x09, 0x00, 0x09, 0x00, 0xf0, 0x00,
+ 0x00, 0x8e, 0xaf, 0xc4, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x09, 0x00,
+ 0x00, 0x02, 0x10, 0x8c, 0x03, 0xa7, 0x98, 0xcb, 0xad, 0x80, 0x84, 0x66,
+ 0xca, 0x38, 0x57, 0xd6, 0xf4, 0xd0, 0x02, 0x00, 0x3b
+};
+unsigned int closed_gif_len = 57;
+
+
+
+//------------------------- Pictures for the Tabs ------------------------
HtmlGenerator::HtmlGenerator() : OutputGenerator()
{
@@ -598,6 +620,54 @@ void HtmlGenerator::writeFooterFile(QFile &file)
<< "</html>\n";
}
+static void generateDynamicSections(QTextStream &t,const QCString &relPath)
+{
+ if (Config_getBool("HTML_DYNAMIC_SECTIONS"))
+ {
+ t <<
+ "<script type=\"text/javascript\">\n"
+ "<!--\n"
+ "function changeDisplayState (e){\n"
+ " var num=this.id.replace(/[^[0-9]/g,'');\n"
+ " var button=this.firstChild;\n"
+ " var sectionDiv=document.getElementById('dynsection'+num);\n"
+ " if (sectionDiv.style.display=='none'||sectionDiv.style.display==''){\n"
+ " sectionDiv.style.display='block';\n"
+ " button.src='" << relPath << "open.gif';\n"
+ " }else{\n"
+ " sectionDiv.style.display='none';\n"
+ " button.src='" << relPath << "closed.gif';\n"
+ " }\n"
+ "}\n"
+ "function initDynSections(){\n"
+ " var divs=document.getElementsByTagName('div');\n"
+ " var sectionCounter=1;\n"
+ " for(var i=0;i<divs.length-1;i++){\n"
+ " if(divs[i].className=='dynheader'&&divs[i+1].className=='dynsection'){\n"
+ " var header=divs[i];\n"
+ " var section=divs[i+1];\n"
+ " var button=header.firstChild;\n"
+ " if (button!='IMG'){\n"
+ " divs[i].insertBefore(document.createTextNode(' '),divs[i].firstChild);\n"
+ " button=document.createElement('img');\n"
+ " divs[i].insertBefore(button,divs[i].firstChild);\n"
+ " }\n"
+ " header.style.cursor='pointer';\n"
+ " header.onclick=changeDisplayState;\n"
+ " header.id='dynheader'+sectionCounter;\n"
+ " button.src='" << relPath << "closed.gif';\n"
+ " section.id='dynsection'+sectionCounter;\n"
+ " section.style.display='none';\n"
+ " sectionCounter++;\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "window.onload = initDynSections;\n"
+ "-->\n"
+ "</script>\n";
+ }
+}
+
void HtmlGenerator::startFile(const char *name,const char *,
const char *title)
@@ -635,9 +705,9 @@ void HtmlGenerator::startFile(const char *name,const char *,
}
t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
<< versionString << " -->" << endl;
+ generateDynamicSections(t,relPath);
}
-
static void writePageFooter(QTextStream &t,const QCString &lastTitle,
const QCString relPath)
{
@@ -751,6 +821,16 @@ void HtmlGenerator::newParagraph()
t << endl << "<p>" << endl;
}
+void HtmlGenerator::startParagraph()
+{
+ t << endl << "<p>";
+}
+
+void HtmlGenerator::endParagraph()
+{
+ t << "</p>" << endl;
+}
+
void HtmlGenerator::writeString(const char *text)
{
t << text;
@@ -1033,18 +1113,22 @@ void HtmlGenerator::writeChar(char c)
void HtmlGenerator::startClassDiagram()
{
- t << "<p>";
+ //t << "<p>";
+ t << "<div class=\"dynheader\">" << endl;
}
void HtmlGenerator::endClassDiagram(ClassDiagram &d,
const char *fileName,const char *name)
{
+ t << "</div>" << endl;
+ t << "<div class=\"dynsection\">" << endl;
t << "\n<p><center><img src=\""
<< relPath << fileName << ".png\" usemap=\"#" << name << "_map\""
<< " border=\"0\" alt=\"\"></center>" << endl
<< "<map name=\"" << name << "_map\">" << endl;
d.writeImage(t,dir,relPath,fileName);
+ t << "</div>" << endl;
}
@@ -1402,49 +1486,75 @@ void HtmlGenerator::endMemberDoc(bool hasArgs)
void HtmlGenerator::startDotGraph()
{
+ t << "<div class=\"dynheader\">" << endl;
}
void HtmlGenerator::endDotGraph(DotClassGraph &g)
{
+ t << "</div>" << endl;
+ t << "<div class=\"dynsection\">" << endl;
g.writeGraph(t,BITMAP,dir,relPath);
+ if (Config_getBool("GENERATE_LEGEND"))
+ {
+ t << "<center><font size=\"2\">[";
+ startHtmlLink(relPath+"graph_legend"+Doxygen::htmlFileExtension);
+ t << theTranslator->trLegend();
+ endHtmlLink();
+ t << "]</font></center>";
+ }
+ t << "</div>" << endl;
}
void HtmlGenerator::startInclDepGraph()
{
+ t << "<div class=\"dynheader\">" << endl;
}
void HtmlGenerator::endInclDepGraph(DotInclDepGraph &g)
{
+ t << "</div>" << endl;
+ t << "<div class=\"dynsection\">" << endl;
g.writeGraph(t,BITMAP,dir,relPath);
+ t << "</div>" << endl;
}
-
void HtmlGenerator::startGroupCollaboration()
{
+ t << "<div class=\"dynheader\">" << endl;
}
void HtmlGenerator::endGroupCollaboration(DotGroupCollaboration &g)
{
+ t << "</div>" << endl;
+ t << "<div class=\"dynsection\">" << endl;
g.writeGraph(t,BITMAP,dir,relPath);
+ t << "</div>" << endl;
}
-
void HtmlGenerator::startCallGraph()
{
+ t << "<div class=\"dynheader\">" << endl;
}
void HtmlGenerator::endCallGraph(DotCallGraph &g)
{
+ t << "</div>" << endl;
+ t << "<div class=\"dynsection\">" << endl;
g.writeGraph(t,BITMAP,dir,relPath);
+ t << "</div>" << endl;
}
void HtmlGenerator::startDirDepGraph()
{
+ t << "<div class=\"dynheader\">" << endl;
}
void HtmlGenerator::endDirDepGraph(DotDirDeps &g)
{
+ t << "</div>" << endl;
+ t << "<div class=\"dynsection\">" << endl;
g.writeGraph(t,BITMAP,dir,relPath);
+ t << "</div>" << endl;
}
void HtmlGenerator::writeGraphicalHierarchy(DotGfxHierarchyTable &g)
@@ -1966,3 +2076,68 @@ void HtmlGenerator::writeSearchPage()
}
}
+void HtmlGenerator::generateSectionImages()
+{
+ {
+ QCString fileName = Config_getString("HTML_OUTPUT")+"/open.gif";
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ {
+ f.writeBlock((char*)open_gif,open_gif_len);
+ }
+ }
+ {
+ QCString fileName = Config_getString("HTML_OUTPUT")+"/closed.gif";
+ QFile f(fileName);
+ if (f.open(IO_WriteOnly))
+ {
+ f.writeBlock((char*)closed_gif,closed_gif_len);
+ }
+ }
+}
+
+void HtmlGenerator::startConstraintList(const char *header)
+{
+ t << "<div class=\"typeconstraint\">" << endl;
+ t << "<dl compact><dt><b>" << header << "</b><dt><dd>" << endl;
+ t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">" << endl;
+}
+
+void HtmlGenerator::startConstraintParam()
+{
+ t << "<tr><td valign=\"top\"><em>";
+}
+
+void HtmlGenerator::endConstraintParam()
+{
+ t << "</em></td>";
+}
+
+void HtmlGenerator::startConstraintType()
+{
+ t << "<td>&nbsp;:</td><td valign=\"top\"><em>";
+}
+
+void HtmlGenerator::endConstraintType()
+{
+ t << "</em></td>";
+}
+
+void HtmlGenerator::startConstraintDocs()
+{
+ t << "<td>&nbsp;";
+}
+
+void HtmlGenerator::endConstraintDocs()
+{
+ t << "</td></tr>" << endl;
+}
+
+void HtmlGenerator::endConstraintList()
+{
+ t << "</table>" << endl;
+ t << "</dl>" << endl;
+ t << "</div>" << endl;
+}
+
+
diff --git a/src/htmlgen.h b/src/htmlgen.h
index 8ca87d0..5c318be 100644
--- a/src/htmlgen.h
+++ b/src/htmlgen.h
@@ -63,6 +63,8 @@ class HtmlGenerator : public OutputGenerator
void endTitle() { t << "</h1>"; }
void newParagraph();
+ void startParagraph();
+ void endParagraph();
void writeString(const char *text);
void startIndexList();
void endIndexList();
@@ -219,6 +221,15 @@ class HtmlGenerator : public OutputGenerator
void startParameterList(bool);
void endParameterList();
+ void startConstraintList(const char *);
+ void startConstraintParam();
+ void endConstraintParam();
+ void startConstraintType();
+ void endConstraintType();
+ void startConstraintDocs();
+ void endConstraintDocs();
+ void endConstraintList();
+
void startFontClass(const char *s) { t << "<span class=\"" << s << "\">"; }
void endFontClass() { t << "</span>"; }
@@ -227,6 +238,7 @@ class HtmlGenerator : public OutputGenerator
void linkableSymbol(int,const char *,Definition *,Definition *) {}
static void writeSearchPage();
+ static void generateSectionImages();
private:
QCString lastTitle;
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index ab06be0..356c7b4 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -873,6 +873,15 @@ void LatexGenerator::newParagraph()
t << endl << endl;
}
+void LatexGenerator::startParagraph()
+{
+ t << endl << endl;
+}
+
+void LatexGenerator::endParagraph()
+{
+}
+
void LatexGenerator::writeString(const char *text)
{
t << text;
@@ -1598,3 +1607,46 @@ void LatexGenerator::printDoc(DocNode *n,const char *langExt)
delete visitor;
}
+void LatexGenerator::startConstraintList(const char *header)
+{
+ t << "\\begin{Desc}\n\\item[";
+ docify(header);
+ t << "]";
+ t << "\\begin{description}" << endl;
+}
+
+void LatexGenerator::startConstraintParam()
+{
+ t << "\\item[{\\em ";
+}
+
+void LatexGenerator::endConstraintParam()
+{
+}
+
+void LatexGenerator::startConstraintType()
+{
+ t << "} : {\\em ";
+}
+
+void LatexGenerator::endConstraintType()
+{
+ t << "}]";
+}
+
+void LatexGenerator::startConstraintDocs()
+{
+}
+
+void LatexGenerator::endConstraintDocs()
+{
+}
+
+void LatexGenerator::endConstraintList()
+{
+ t << "\\end{description}" << endl;
+ t << "\\end{Desc}" << endl;
+}
+
+
+
diff --git a/src/latexgen.h b/src/latexgen.h
index 214256f..c130d75 100644
--- a/src/latexgen.h
+++ b/src/latexgen.h
@@ -61,6 +61,8 @@ class LatexGenerator : public OutputGenerator
void endTitle() { t << "}"; }
void newParagraph();
+ void startParagraph();
+ void endParagraph();
void writeString(const char *text);
void startIndexList() { t << "\\begin{CompactList}" << endl; }
void endIndexList() { t << "\\end{CompactList}" << endl; }
@@ -210,6 +212,15 @@ class LatexGenerator : public OutputGenerator
void startParameterList(bool) {}
void endParameterList() {}
+ void startConstraintList(const char *);
+ void startConstraintParam();
+ void endConstraintParam();
+ void startConstraintType();
+ void endConstraintType();
+ void startConstraintDocs();
+ void endConstraintDocs();
+ void endConstraintList();
+
void startFontClass(const char *) {}
void endFontClass() {}
diff --git a/src/mangen.cpp b/src/mangen.cpp
index f8bfb57..220dee2 100644
--- a/src/mangen.cpp
+++ b/src/mangen.cpp
@@ -179,6 +179,21 @@ void ManGenerator::newParagraph()
paragraph=TRUE;
}
+void ManGenerator::startParagraph()
+{
+ if (!paragraph)
+ {
+ if (!firstCol) t << endl;
+ t << ".PP" << endl;
+ firstCol=TRUE;
+ }
+ paragraph=TRUE;
+}
+
+void ManGenerator::endParagraph()
+{
+}
+
void ManGenerator::writeString(const char *text)
{
docify(text);
@@ -640,3 +655,54 @@ void ManGenerator::printDoc(DocNode *n,const char *langExt)
paragraph = FALSE;
}
+void ManGenerator::startConstraintList(const char *header)
+{
+ if (!firstCol)
+ { t << endl << ".PP" << endl;
+ firstCol=TRUE; paragraph=TRUE;
+ col=0;
+ }
+ paragraph=FALSE;
+ startBold();
+ docify(header);
+ endBold();
+ paragraph=TRUE;
+}
+
+void ManGenerator::startConstraintParam()
+{
+ writeListItem();
+ startEmphasis();
+}
+
+void ManGenerator::endConstraintParam()
+{
+ endEmphasis();
+ t << " : ";
+}
+
+void ManGenerator::startConstraintType()
+{
+ startEmphasis();
+}
+
+void ManGenerator::endConstraintType()
+{
+ endEmphasis();
+}
+
+void ManGenerator::startConstraintDocs()
+{
+}
+
+void ManGenerator::endConstraintDocs()
+{
+ t << endl; firstCol=TRUE;
+}
+
+void ManGenerator::endConstraintList()
+{
+}
+
+
+
diff --git a/src/mangen.h b/src/mangen.h
index 38b566a..45ef306 100644
--- a/src/mangen.h
+++ b/src/mangen.h
@@ -60,6 +60,8 @@ class ManGenerator : public OutputGenerator
void endTitle();
void newParagraph();
+ void startParagraph();
+ void endParagraph();
void writeString(const char *text);
void startIndexList() {}
void endIndexList() { newParagraph(); }
@@ -268,6 +270,15 @@ class ManGenerator : public OutputGenerator
//void startSectionRefList() {}
//void endSectionRefList() {}
+ void startConstraintList(const char *);
+ void startConstraintParam();
+ void endConstraintParam();
+ void startConstraintType();
+ void endConstraintType();
+ void startConstraintDocs();
+ void endConstraintDocs();
+ void endConstraintList();
+
void writeCodeAnchor(const char *) {}
void linkableSymbol(int,const char *,Definition *,Definition *) {}
diff --git a/src/marshal.cpp b/src/marshal.cpp
index a08c20a..a11a25f 100644
--- a/src/marshal.cpp
+++ b/src/marshal.cpp
@@ -390,6 +390,7 @@ void marshalEntry(StorageIntf *s,Entry *e)
marshalQCString(s,e->write);
marshalQCString(s,e->inside);
marshalQCString(s,e->exception);
+ marshalArgumentList(s,e->typeConstr);
marshalInt(s,e->bodyLine);
marshalInt(s,e->endBodyLine);
marshalInt(s,e->mGrpId);
@@ -774,6 +775,7 @@ Entry * unmarshalEntry(StorageIntf *s)
e->write = unmarshalQCString(s);
e->inside = unmarshalQCString(s);
e->exception = unmarshalQCString(s);
+ e->typeConstr = unmarshalArgumentList(s);
e->bodyLine = unmarshalInt(s);
e->endBodyLine = unmarshalInt(s);
e->mGrpId = unmarshalInt(s);
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index dffbb82..bc8c76e 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -346,6 +346,7 @@ class MemberDefImpl
ArgumentList *declArgList; // argument list of this member declaration
ArgumentList *tArgList; // template argument list of function template
+ ArgumentList *typeConstraints; // type constraints for template parameters
MemberDef *templateMaster;
QList<ArgumentList> *defTmpArgLists; // lists of template argument lists
// (for template functions in nested template classes)
@@ -410,6 +411,7 @@ MemberDefImpl::MemberDefImpl() :
defArgList(0),
declArgList(0),
tArgList(0),
+ typeConstraints(0),
defTmpArgLists(0),
classSectionSDict(0)
{
@@ -422,6 +424,7 @@ MemberDefImpl::~MemberDefImpl()
delete enumFields;
delete defArgList;
delete tArgList;
+ delete typeConstraints;
delete defTmpArgLists;
delete classSectionSDict;
delete declArgList;
@@ -2014,10 +2017,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
// write class that contains a member that is reimplemented by this one
if (bcd->isLinkable())
{
- ol.disable(OutputGenerator::RTF);
- ol.newParagraph();
- ol.enableAll();
-
+ ol.startParagraph();
QCString reimplFromLine;
if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
{
@@ -2062,6 +2062,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
{
err("Error: translation error: no marker in trReimplementsFromList()\n");
}
+ ol.endParagraph();
}
//ol.writeString(".");
@@ -2087,9 +2088,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
{
mli.toFirst();
// write the list of classes that overwrite this member
- ol.disable(OutputGenerator::RTF);
- ol.newParagraph();
- ol.enable(OutputGenerator::RTF);
+ ol.startParagraph();
QCString reimplInLine;
if (m_impl->virt==Pure || (m_impl->classDef && m_impl->classDef->compoundType()==ClassDef::Interface))
@@ -2137,6 +2136,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
index=newIndex+matchLen;
}
ol.parseText(reimplInLine.right(reimplInLine.length()-index));
+ ol.endParagraph();
}
}
@@ -2150,6 +2150,11 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
ol.endSimpleSect();
}
+ if (m_impl->typeConstraints)
+ {
+ writeTypeConstraints(ol,this,m_impl->typeConstraints);
+ }
+
// write reference to the source
writeSourceDef(ol,cname);
writeSourceRefs(ol,cname);
@@ -2635,7 +2640,8 @@ bool MemberDef::isDestructor() const
}
else // other languages
{
- return name().find('~')!=-1 && name().find("operator")==-1;
+ return (name().find('~')!=-1 || name().find('!')!=-1) // The ! is for C++/CLI
+ && name().find("operator")==-1;
}
}
@@ -2780,6 +2786,21 @@ void MemberDef::setDeclArgumentList(ArgumentList *al)
m_impl->declArgList = al;
}
+void MemberDef::setTypeConstraints(ArgumentList *al)
+{
+ if (al==0) return;
+ makeResident();
+ if (m_impl->typeConstraints) delete m_impl->typeConstraints;
+ m_impl->typeConstraints = new ArgumentList;
+ m_impl->typeConstraints->setAutoDelete(TRUE);
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ m_impl->typeConstraints->append(new Argument(*a));
+ }
+}
+
void MemberDef::findSectionsInDocumentation()
{
makeResident();
@@ -3648,6 +3669,7 @@ void MemberDef::flushToDisk() const
marshalArgumentList (Doxygen::symbolStorage,m_impl->defArgList);
marshalArgumentList (Doxygen::symbolStorage,m_impl->declArgList);
marshalArgumentList (Doxygen::symbolStorage,m_impl->tArgList);
+ marshalArgumentList (Doxygen::symbolStorage,m_impl->typeConstraints);
marshalObjPointer (Doxygen::symbolStorage,m_impl->templateMaster);
marshalArgumentLists(Doxygen::symbolStorage,m_impl->defTmpArgLists);
marshalObjPointer (Doxygen::symbolStorage,m_impl->cachedAnonymousType);
@@ -3746,6 +3768,7 @@ void MemberDef::loadFromDisk() const
m_impl->defArgList = unmarshalArgumentList (Doxygen::symbolStorage);
m_impl->declArgList = unmarshalArgumentList (Doxygen::symbolStorage);
m_impl->tArgList = unmarshalArgumentList (Doxygen::symbolStorage);
+ m_impl->typeConstraints = unmarshalArgumentList (Doxygen::symbolStorage);
m_impl->templateMaster = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
m_impl->defTmpArgLists = unmarshalArgumentLists(Doxygen::symbolStorage);
m_impl->cachedAnonymousType = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
diff --git a/src/memberdef.h b/src/memberdef.h
index c396346..385b353 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -281,6 +281,7 @@ class MemberDef : public Definition
void setArgumentList(ArgumentList *al);
void setDeclArgumentList(ArgumentList *al);
void setDefinitionTemplateParameterLists(QList<ArgumentList> *lists);
+ void setTypeConstraints(ArgumentList *al);
// namespace related members
void setNamespace(NamespaceDef *nd);
diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp
index fe69505..d021764 100644
--- a/src/namespacedef.cpp
+++ b/src/namespacedef.cpp
@@ -259,7 +259,7 @@ void NamespaceDef::writeDetailedDocumentation(OutputList &ol)
if (!documentation().isEmpty())
{
ol.parseDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
- ol.newParagraph();
+ //ol.newParagraph();
}
ol.endTextBlock();
}
@@ -321,8 +321,10 @@ void NamespaceDef::writeDocumentation(OutputList &ol)
ol.popGeneratorState();
}
ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::RTF);
ol.newParagraph();
ol.enable(OutputGenerator::Man);
+ ol.enable(OutputGenerator::RTF);
ol.writeSynopsis();
ol.endTextBlock();
diff --git a/src/outputgen.h b/src/outputgen.h
index 0a7c06c..9118ef4 100644
--- a/src/outputgen.h
+++ b/src/outputgen.h
@@ -132,6 +132,11 @@ class BaseOutputDocInterface : public CodeOutputInterface
/*! Starts a new paragraph */
virtual void newParagraph() = 0;
+ /*! Starts a new paragraph */
+ virtual void startParagraph() = 0;
+ /*! End a paragraph */
+ virtual void endParagraph() = 0;
+
/*! Writes a link to an object in the documentation.
* \param ref If this is non-zero, the object is to be found in
* an external documentation file.
@@ -376,6 +381,15 @@ class OutputGenerator : public BaseOutputDocInterface
virtual void startParameterList(bool) = 0;
virtual void endParameterList() = 0;
+ virtual void startConstraintList(const char *) = 0;
+ virtual void startConstraintParam() = 0;
+ virtual void endConstraintParam() = 0;
+ virtual void startConstraintType() = 0;
+ virtual void endConstraintType() = 0;
+ virtual void startConstraintDocs() = 0;
+ virtual void endConstraintDocs() = 0;
+ virtual void endConstraintList() = 0;
+
protected:
QTextStream fs;
QByteArray a;
diff --git a/src/outputlist.h b/src/outputlist.h
index 4a8a0d7..30f8e64 100644
--- a/src/outputlist.h
+++ b/src/outputlist.h
@@ -97,6 +97,10 @@ class OutputList : public OutputDocInterface
{ forall(&OutputGenerator::endTitle); }
void newParagraph()
{ forall(&OutputGenerator::newParagraph); }
+ void startParagraph()
+ { forall(&OutputGenerator::startParagraph); }
+ void endParagraph()
+ { forall(&OutputGenerator::endParagraph); }
void writeString(const char *text)
{ forall(&OutputGenerator::writeString,text); }
void startIndexList()
@@ -370,6 +374,25 @@ class OutputList : public OutputDocInterface
{ forall(&OutputGenerator::startParameterList,openBracket); }
void endParameterList()
{ forall(&OutputGenerator::endParameterList); }
+
+ void startConstraintList(const char *header)
+ { forall(&OutputGenerator::startConstraintList,header); }
+ void startConstraintParam()
+ { forall(&OutputGenerator::startConstraintParam); }
+ void endConstraintParam()
+ { forall(&OutputGenerator::endConstraintParam); }
+ void startConstraintType()
+ { forall(&OutputGenerator::startConstraintType); }
+ void endConstraintType()
+ { forall(&OutputGenerator::endConstraintType); }
+ void startConstraintDocs()
+ { forall(&OutputGenerator::startConstraintDocs); }
+ void endConstraintDocs()
+ { forall(&OutputGenerator::endConstraintDocs); }
+ void endConstraintList()
+ { forall(&OutputGenerator::endConstraintList); }
+
+
void startFontClass(const char *c)
{ forall(&OutputGenerator::startFontClass,c); }
void endFontClass()
@@ -396,6 +419,8 @@ class OutputList : public OutputDocInterface
}
void linkableSymbol(int,const char *,Definition *,Definition *) {}
+
+
private:
void debug();
void clear();
diff --git a/src/pyscanner.l b/src/pyscanner.l
index 913f88e..ed3f10b 100644
--- a/src/pyscanner.l
+++ b/src/pyscanner.l
@@ -1000,6 +1000,7 @@ STARTDOCSYMS ^{B}"##"/[^#]
// prepend scope in case of nested classes
if (current_root->section&Entry::SCOPE_MASK)
{
+ printf("*** Prepending scope %s to class %s\n",current_root->name.data(),current->name.data());
current->name.prepend(current_root->name+"::");
}
@@ -1476,11 +1477,15 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt)
QFileInfo fi(fileName);
g_moduleScope = findPackageScope(fileName);
- if (!g_moduleScope.isEmpty())
+ QString baseName=fi.baseName();
+ if (baseName!="__init__") // package initializer file is not a package itself
{
- g_moduleScope+="::";
+ if (!g_moduleScope.isEmpty())
+ {
+ g_moduleScope+="::";
+ }
+ g_moduleScope+=baseName;
}
- g_moduleScope+=fi.baseName();
current = new Entry;
current->name = g_moduleScope;
diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp
index 05fe40d..e835811 100644
--- a/src/rtfdocvisitor.cpp
+++ b/src/rtfdocvisitor.cpp
@@ -259,7 +259,7 @@ void RTFDocVisitor::visit(DocLineBreak *)
{
if (m_hide) return;
DBG_RTF("{\\comment RTFDocVisitor::visit(DocLineBreak)}\n");
- m_t << "\\par\n";
+ m_t << "\\par";
m_lastIsPara=TRUE;
}
@@ -310,7 +310,7 @@ void RTFDocVisitor::visit(DocStyleChange *s)
else
{
m_insidePre=FALSE;
- m_t << "\\par" << endl;
+ m_t << "\\par";
m_t << "}" << endl;
}
m_lastIsPara=TRUE;
@@ -442,7 +442,7 @@ void RTFDocVisitor::visit(DocInclude *inc)
inc->text().latin1(),
inc->isExample(),
inc->exampleFile(), &fd);
- m_t << "\\par" << endl;
+ m_t << "\\par";
m_t << "}" << endl;
}
break;
@@ -454,7 +454,7 @@ void RTFDocVisitor::visit(DocInclude *inc)
->parseCode(m_ci,inc->context(),
inc->text().latin1(),inc->isExample(),
inc->exampleFile());
- m_t << "\\par" << endl;
+ m_t << "\\par";
m_t << "}" << endl;
break;
case DocInclude::DontInclude:
@@ -466,7 +466,7 @@ void RTFDocVisitor::visit(DocInclude *inc)
m_t << "\\par" << endl;
m_t << rtf_Style_Reset << getStyle("CodeExample");
filter(inc->text());
- m_t << "\\par" << endl;
+ m_t << "\\par";
m_t << "}" << endl;
break;
}
@@ -506,7 +506,7 @@ void RTFDocVisitor::visit(DocIncOperator *op)
popEnabled();
if (!m_hide)
{
- m_t << "\\par" << endl;
+ m_t << "\\par";
m_t << "}" << endl;
}
m_lastIsPara=TRUE;
@@ -553,7 +553,7 @@ void RTFDocVisitor::visitPost(DocAutoList *)
{
if (m_hide) return;
DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocAutoList)}\n");
- m_t << "\\par" << endl;
+ m_t << "\\par";
m_t << "}" << endl;
m_lastIsPara=TRUE;
}
@@ -593,7 +593,8 @@ void RTFDocVisitor::visitPost(DocPara *p)
{
if (m_hide) return;
DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocPara)}\n");
- if (!p->isLast() && // omit <p> for last paragraph
+ if (!m_lastIsPara &&
+ !p->isLast() && // omit <p> for last paragraph
!(p->parent() && // and for parameters & sections
p->parent()->kind()==DocNode::Kind_ParamSect
)
@@ -669,7 +670,7 @@ void RTFDocVisitor::visitPre(DocSimpleSect *s)
if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs)
{
m_t << ":";
- m_t << "\\par" << endl;
+ m_t << "\\par";
m_t << "}"; // end bold
incIndentLevel();
m_t << rtf_Style_Reset << getStyle("DescContinue");
@@ -779,7 +780,7 @@ void RTFDocVisitor::visitPost(DocHtmlList *)
{
if (m_hide) return;
DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlList)}\n");
- m_t << "\\par" << endl << "}" << endl;
+ m_t << "\\par" << "}" << endl;
m_lastIsPara=TRUE;
}
@@ -858,7 +859,7 @@ void RTFDocVisitor::visitPost(DocHtmlDescData *)
{
if (m_hide) return;
DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescData)}\n");
- m_t << "\\par" << endl;
+ m_t << "\\par";
m_t << "}" << endl;
decIndentLevel();
m_lastIsPara=TRUE;
@@ -959,7 +960,7 @@ void RTFDocVisitor::visitPost(DocInternal *)
{
if (m_hide) return;
DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocInternal)}\n");
- m_t << "\\par" << endl;
+ m_t << "\\par";
decIndentLevel();
m_t << "}"; // end desc
m_lastIsPara=TRUE;
@@ -1025,7 +1026,7 @@ void RTFDocVisitor::visitPost(DocHtmlHeader *)
{
if (m_hide) return;
DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlHeader)}\n");
- m_t << "\\par" << endl;
+ m_t << "\\par";
m_t << "}" << endl; // end section
m_lastIsPara=TRUE;
}
@@ -1131,8 +1132,8 @@ void RTFDocVisitor::visitPost(DocSecRefList *)
if (m_hide) return;
DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSecRefList)}\n");
decIndentLevel();
- m_t << "\\par" << endl;
- m_t << "}";
+ m_t << "\\par";
+ m_t << "}" << endl;
m_lastIsPara=TRUE;
}
@@ -1177,7 +1178,7 @@ void RTFDocVisitor::visitPre(DocParamSect *s)
ASSERT(0);
}
m_t << ":";
- m_t << "\\par" << endl;
+ m_t << "\\par";
m_t << "}" << endl;
incIndentLevel();
m_t << rtf_Style_Reset << getStyle("DescContinue");
@@ -1268,7 +1269,7 @@ void RTFDocVisitor::visitPre(DocXRefItem *x)
filter(x->title());
}
m_t << ":";
- m_t << "\\par" << endl;
+ m_t << "\\par";
m_t << "}"; // end bold
incIndentLevel();
m_t << rtf_Style_Reset << getStyle("DescContinue");
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index f6fb8af..37e2ddd 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -852,6 +852,7 @@ void RTFGenerator::lineBreak()
{
DBG_RTF(t << "{\\comment (lineBreak)}" << endl)
t << "\\par" << endl;
+ m_omitParagraph = TRUE;
}
void RTFGenerator::writeString(const char *text)
@@ -863,16 +864,16 @@ void RTFGenerator::startIndexList()
{
DBG_RTF(t << "{\\comment (startIndexList)}" << endl)
t << "{" << endl;
+ t << "\\par" << endl;
incrementIndentLevel();
t << rtf_Style_Reset << rtf_LCList_DepthStyle() << endl;
- newParagraph();
m_omitParagraph = TRUE;
}
void RTFGenerator::endIndexList()
{
DBG_RTF(t << "{\\comment (endIndexList)}" << endl)
- newParagraph();
+ t << "\\par";
t << "}";
decrementIndentLevel();
m_omitParagraph = TRUE;
@@ -881,6 +882,7 @@ void RTFGenerator::endIndexList()
/*! start bullet list */
void RTFGenerator::startItemList()
{
+ newParagraph();
DBG_RTF(t << "{\\comment (startItemList level=" << m_listLevel << ") }" << endl)
t << "{";
incrementIndentLevel();
@@ -954,8 +956,8 @@ void RTFGenerator::endIndexItem(const char *ref,const char *fn)
{
t << endl;
}
- newParagraph();
m_omitParagraph = TRUE;
+ newParagraph();
}
//void RTFGenerator::writeIndexFileItem(const char *,const char *text)
@@ -1048,17 +1050,19 @@ void RTFGenerator::startIndexKey()
void RTFGenerator::endIndexKey()
{
+ DBG_RTF(t << "{\\comment (endIndexKey)}" << endl)
}
void RTFGenerator::startIndexValue(bool hasBrief)
{
+ DBG_RTF(t << "{\\comment (startIndexValue)}" << endl)
t << " ";
if (hasBrief) t << "(";
}
void RTFGenerator::endIndexValue(const char *name,bool hasBrief)
{
- DBG_RTF(t << "{\\comment (endIndexKey)}" << endl)
+ DBG_RTF(t << "{\\comment (endIndexValue)}" << endl)
if (hasBrief) t << ")";
t << "} ";
if (name)
@@ -1071,6 +1075,7 @@ void RTFGenerator::endIndexValue(const char *name,bool hasBrief)
{
t << endl;
}
+ m_omitParagraph=FALSE;
newParagraph();
}
@@ -1353,7 +1358,7 @@ void RTFGenerator::startGroupHeader()
void RTFGenerator::endGroupHeader()
{
DBG_RTF(t <<"{\\comment endGroupHeader}" << endl)
- newParagraph();
+ t << "\\par" << endl;
t << rtf_Style_Reset << endl;
}
@@ -1496,7 +1501,9 @@ void RTFGenerator::endMemberDescription()
endEmphasis();
newParagraph();
decrementIndentLevel();
- t << "\\par}" << endl;
+ //t << "\\par";
+ t << "}" << endl;
+ //m_omitParagraph = TRUE;
}
void RTFGenerator::startDescList(SectionTypes)
@@ -1714,6 +1721,7 @@ void RTFGenerator::writeChar(char c)
void RTFGenerator::startClassDiagram()
{
+ DBG_RTF(t <<"{\\comment startClassDiagram }" << endl)
}
void RTFGenerator::endClassDiagram(ClassDiagram &d,
@@ -1987,9 +1995,9 @@ void RTFGenerator::startTextBlock(bool dense)
}
}
-void RTFGenerator::endTextBlock(bool paraBreak)
+void RTFGenerator::endTextBlock(bool /*paraBreak*/)
{
- if (paraBreak) newParagraph();
+ newParagraph();
DBG_RTF(t << "{\\comment endTextBlock}" << endl)
t << "}" << endl;
//m_omitParagraph = TRUE;
@@ -1999,12 +2007,26 @@ void RTFGenerator::newParagraph()
{
if (!m_omitParagraph)
{
- DBG_RTF(t << "{\\comment (newParagraph)}" << endl)
+ DBG_RTF(t << "{\\comment (newParagraph)}" << endl)
t << "\\par" << endl;
}
m_omitParagraph = FALSE;
}
+void RTFGenerator::startParagraph()
+{
+ DBG_RTF(t << "{\\comment startParagraph}" << endl)
+ newParagraph();
+ t << "{" << endl;
+}
+
+void RTFGenerator::endParagraph()
+{
+ DBG_RTF(t << "{\\comment endParagraph}" << endl)
+ t << "}\\par" << endl;
+ m_omitParagraph = TRUE;
+}
+
void RTFGenerator::startMemberSubtitle()
{
DBG_RTF(t << "{\\comment startMemberSubtitle}" << endl)
@@ -2496,6 +2518,7 @@ void RTFGenerator::printDoc(DocNode *n,const char *langExt)
RTFDocVisitor *visitor = new RTFDocVisitor(t,*this,langExt);
n->accept(visitor);
delete visitor;
+ m_omitParagraph = TRUE;
}
void RTFGenerator::rtfwriteRuler_doubleline()
@@ -2545,3 +2568,68 @@ void RTFGenerator::postProcess(QByteArray &a)
enc.resize(off);
a = enc;
}
+
+void RTFGenerator::startConstraintList(const char *header)
+{
+ DBG_RTF(t << "{\\comment (startConstraintList)}" << endl)
+ t << "{"; // ends at endConstraintList
+ t << "{";
+ startBold();
+ newParagraph();
+ docify(header);
+ endBold();
+ t << "}";
+ newParagraph();
+ incrementIndentLevel();
+ t << rtf_Style_Reset << rtf_DList_DepthStyle();
+}
+
+void RTFGenerator::startConstraintParam()
+{
+ DBG_RTF(t << "{\\comment (startConstraintParam)}" << endl)
+ startEmphasis();
+}
+
+void RTFGenerator::endConstraintParam()
+{
+ DBG_RTF(t << "{\\comment (endConstraintParam)}" << endl)
+ endEmphasis();
+ t << " : ";
+}
+
+void RTFGenerator::startConstraintType()
+{
+ DBG_RTF(t << "{\\comment (startConstraintType)}" << endl)
+ startEmphasis();
+}
+
+void RTFGenerator::endConstraintType()
+{
+ DBG_RTF(t << "{\\comment (endConstraintType)}" << endl)
+ endEmphasis();
+ t << " ";
+}
+
+void RTFGenerator::startConstraintDocs()
+{
+ DBG_RTF(t << "{\\comment (startConstraintDocs)}" << endl)
+}
+
+void RTFGenerator::endConstraintDocs()
+{
+ DBG_RTF(t << "{\\comment (endConstraintDocs)}" << endl)
+ newParagraph();
+}
+
+void RTFGenerator::endConstraintList()
+{
+ DBG_RTF(t << "{\\comment (endConstraintList)}" << endl)
+ newParagraph();
+ decrementIndentLevel();
+ m_omitParagraph = TRUE;
+ t << "}";
+}
+
+
+
+
diff --git a/src/rtfgen.h b/src/rtfgen.h
index 2183237..577cc40 100644
--- a/src/rtfgen.h
+++ b/src/rtfgen.h
@@ -64,6 +64,8 @@ class RTFGenerator : public OutputGenerator
void endTitle() {}
void newParagraph();
+ void startParagraph();
+ void endParagraph();
void writeString(const char *text);
void startIndexList();
void endIndexList();
@@ -255,6 +257,16 @@ class RTFGenerator : public OutputGenerator
void startParameterList(bool) {}
void endParameterList() {}
+ void startConstraintList(const char *);
+ void startConstraintParam();
+ void endConstraintParam();
+ void startConstraintType();
+ void endConstraintType();
+ void startConstraintDocs();
+ void endConstraintDocs();
+ void endConstraintList();
+
+
void startFontClass(const char *) {}
void endFontClass() {}
diff --git a/src/scanner.l b/src/scanner.l
index 8fd1672..09c52fb 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -68,6 +68,7 @@ static int lastClassTemplSpecContext;
static int lastPreLineCtrlContext;
static int lastSkipVerbStringContext;
static int lastCommentInArgContext;
+static int lastCSConstraint;
static Protection protection;
static Protection baseProt;
static int sharpCount = 0 ;
@@ -82,6 +83,7 @@ static Entry* current = 0 ;
static Entry* previous = 0 ;
static Entry* tempEntry = 0 ;
static Entry* firstTypedefEntry = 0 ;
+static Entry* memspecEntry = 0 ;
static int yyLineNr = 1 ;
static int anonCount = 0 ;
static int anonNSCount = 0 ;
@@ -303,7 +305,7 @@ static QCString stripQuotes(const char *s)
static void startCommentBlock(bool);
static void handleCommentBlock(const QCString &doc,bool brief);
-static void handleParametersCommentBlocks();
+static void handleParametersCommentBlocks(ArgumentList *al);
//-----------------------------------------------------------------
@@ -359,7 +361,6 @@ static void prependScope()
for (talsi.toLast();(srcAl=talsi.current());--talsi)
{
ArgumentList *dstAl = new ArgumentList;
- dstAl->setAutoDelete(TRUE);
QListIterator<Argument> tali(*srcAl);
Argument *a;
for (;(a=tali.current());++tali)
@@ -544,7 +545,7 @@ FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]+
ID "$"?[a-z_A-Z][a-z_A-Z0-9]*
LABELID [a-z_A-Z][a-z_A-Z0-9\-]*
SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
-SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID})
+SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID})
TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,]*">")?
FTSCOPE {ID}("<"[a-z_A-Z0-9\*\&,]*">")?
CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID})
@@ -572,7 +573,8 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
%x DefineEnd
%x CompoundName
%x ClassVar
-%x CSConstraint
+%x CSConstraintName
+%x CSConstraintType
%x ClassCategory
%x ClassTemplSpec
%x CliPropertyType
@@ -1477,7 +1479,6 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
current->tArgLists->setAutoDelete(TRUE);
}
ArgumentList *al = new ArgumentList;
- al->setAutoDelete(TRUE);
current->spec |= (yytext[0]=='g') ? Entry::Generic : Entry::Template;
current->tArgLists->append(al);
currentArgumentList = al;
@@ -2052,11 +2053,6 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
}
<FindMembers,FindFields>("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") {
- //Entry *tmp = current;
- //if (previous)
- //{
- // current = previous;
- //}
//handleGroupStartCommand(current->name);
if (previous && previous->section==Entry::GROUPDOC_SEC)
{
@@ -2866,6 +2862,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
else
{
current_root->addSubEntry( current ) ;
+ memspecEntry = current;
current = new Entry(*current);
if (current->section==Entry::NAMESPACE_SEC ||
(current->spec==Entry::Interface) ||
@@ -2874,6 +2871,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
{ // namespaces and interfaces and java classes ends with a closing bracket without semicolon
current->reset();
initEntry();
+ memspecEntry = 0;
BEGIN( FindMembers ) ;
}
else
@@ -2934,6 +2932,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
current->args = current->args.simplifyWhiteSpace();
current->type = current->type.simplifyWhiteSpace();
current_root->addSubEntry( current ) ;
+ memspecEntry = current;
current = new Entry(*current);
unput(';');
BEGIN( MemberSpec ) ;
@@ -3004,60 +3003,73 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
//printf("msName=%s current->name=%s\n",msName.data(),current->name.data());
if (!msName.isEmpty() && msName!=current->name) // skip typedef T {} T;
{
- Entry *varEntry=new Entry;
- varEntry->protection = current->protection ;
- varEntry->mtype = current->mtype;
- varEntry->virt = current->virt;
- varEntry->stat = current->stat;
- varEntry->section = Entry::VARIABLE_SEC;
- varEntry->name = msName.stripWhiteSpace();
- varEntry->type = current->type.simplifyWhiteSpace()+" ";
- varEntry->args = msArgs; //current->args.simplifyWhiteSpace();
- //if (!current->name.isEmpty() && current->name[0]!='@' &&
- // current->parent->section & Entry::COMPOUND_MASK)
- // varEntry->type+=current->parent->name+"::";
- if (isTypedef)
+ static bool optimizeForC = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
+ // case 1: typedef struct _S { ... } S_t;
+ // -> omit typedef and use S_t as the struct name
+ if (optimizeForC &&
+ isTypedef &&
+ (current->spec&(Entry::Struct|Entry::Union)) &&
+ msType.stripWhiteSpace().isEmpty() &&
+ memspecEntry)
{
- varEntry->type.prepend("typedef ");
- // //printf("current->name = %s %s\n",current->name.data(),msName.data());
- // if (!current->name.isEmpty() && current->name.at(0)!='@')
- // {
- // //printf("2>>>>>>>>>> adding %s->%s\n",msName.data(),current->name.data());
- // QCString scope;
- // if (current_root->section & Entry::SCOPE_MASK) scope=current_root->name;
- // Doxygen::typedefDict.insert(msName,new TypedefInfo(current->name,scope));
- // }
+ memspecEntry->name=msName;
}
- varEntry->type+=current->name+msType;
- varEntry->fileName = yyFileName;
- varEntry->startLine = yyLineNr;
- varEntry->doc = current->doc.copy();
- varEntry->brief = current->brief.copy();
- varEntry->mGrpId = current->mGrpId;
-
- // deep copy group list
- QListIterator<Grouping> gli(*current->groups);
- Grouping *g;
- for (;(g=gli.current());++gli)
- {
- varEntry->groups->append(new Grouping(*g));
- }
- if (current->sli) // copy special list items
+ else // case 2: create a typedef field
{
- QListIterator<ListItemInfo> li(*current->sli);
- ListItemInfo *lii;
- for (li.toFirst();(lii=li.current());++li)
+ Entry *varEntry=new Entry;
+ varEntry->protection = current->protection ;
+ varEntry->mtype = current->mtype;
+ varEntry->virt = current->virt;
+ varEntry->stat = current->stat;
+ varEntry->section = Entry::VARIABLE_SEC;
+ varEntry->name = msName.stripWhiteSpace();
+ varEntry->type = current->type.simplifyWhiteSpace()+" ";
+ varEntry->args = msArgs;
+ if (isTypedef)
{
- varEntry->addSpecialListItem(lii->type,lii->itemId);
+ varEntry->type.prepend("typedef ");
+ // //printf("current->name = %s %s\n",current->name.data(),msName.data());
+ }
+ if (optimizeForC &&
+ isTypedef &&
+ (current->spec&(Entry::Struct|Entry::Union)) &&
+ memspecEntry
+ ) // case 1: use S_t as type for pS_t in "typedef struct _S {} S_t, *pS_t;"
+ {
+ varEntry->type+=memspecEntry->name+msType;
+ }
+ else // case 2: use _S as type for for pS_t
+ {
+ varEntry->type+=current->name+msType;
+ }
+ varEntry->fileName = yyFileName;
+ varEntry->startLine = yyLineNr;
+ varEntry->doc = current->doc.copy();
+ varEntry->brief = current->brief.copy();
+ varEntry->mGrpId = current->mGrpId;
+
+ // deep copy group list
+ QListIterator<Grouping> gli(*current->groups);
+ Grouping *g;
+ for (;(g=gli.current());++gli)
+ {
+ varEntry->groups->append(new Grouping(*g));
+ }
+ if (current->sli) // copy special list items
+ {
+ QListIterator<ListItemInfo> li(*current->sli);
+ ListItemInfo *lii;
+ for (li.toFirst();(lii=li.current());++li)
+ {
+ varEntry->addSpecialListItem(lii->type,lii->itemId);
+ }
}
- //delete current->sli;
- //current->sli = 0;
- }
- //printf("Add: type=`%s',name=`%s',args=`%s' brief=%s doc=%s\n",
- // varEntry->type.data(),varEntry->name.data(),
- // varEntry->args.data(),varEntry->brief.data(),varEntry->doc.data());
- current_root->addSubEntry(varEntry);
+ //printf("Add: type=`%s',name=`%s',args=`%s' brief=%s doc=%s\n",
+ // varEntry->type.data(),varEntry->name.data(),
+ // varEntry->args.data(),varEntry->brief.data(),varEntry->doc.data());
+ current_root->addSubEntry(varEntry);
+ }
}
if (*yytext==';')
{
@@ -3066,6 +3078,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
msArgs.resize(0);
isTypedef=FALSE;
firstTypedefEntry=0;
+ memspecEntry=0;
current->reset();
initEntry();
BEGIN( FindMembers );
@@ -3272,7 +3285,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
*copyArgString+=*yytext;
fullArgString+=*yytext;
stringToArgumentList(fullArgString,current->argList);
- handleParametersCommentBlocks();
+ handleParametersCommentBlocks(current->argList);
/* remember the current documentation block, since
we could overwrite it with the documentation of
@@ -3295,7 +3308,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
unput(yytext[i]);
}
stringToArgumentList(fullArgString,current->argList);
- handleParametersCommentBlocks();
+ handleParametersCommentBlocks(current->argList);
BEGIN( currentArgumentContext );
}
else // not a define
@@ -3347,7 +3360,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
*copyArgString+=*yytext;
fullArgString+=*yytext;
stringToArgumentList(fullArgString,current->argList);
- handleParametersCommentBlocks();
+ handleParametersCommentBlocks(current->argList);
BEGIN( currentArgumentContext );
}
else
@@ -3657,7 +3670,16 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
yyLineNr++;
}
<FuncQual>{ID} { // typically a K&R style C function
- if (checkForKnRstyleC())
+ if (insideCS && strcmp(yytext,"where")==0)
+ {
+ // type contraint for a method
+ delete current->typeConstr;
+ current->typeConstr = new ArgumentList;
+ current->typeConstr->append(new Argument);
+ lastCSConstraint = YY_START;
+ BEGIN( CSConstraintName );
+ }
+ else if (checkForKnRstyleC())
{
//fprintf(stderr,"===> got a K&R style function\n");
current->args = yytext;
@@ -4181,7 +4203,11 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
}
else if (insideCS && strcmp(yytext,"where")==0) // C# type contraint
{
- BEGIN( CSConstraint );
+ delete current->typeConstr;
+ current->typeConstr = new ArgumentList;
+ current->typeConstr->append(new Argument);
+ lastCSConstraint = YY_START;
+ BEGIN( CSConstraintName );
}
else
{
@@ -4216,14 +4242,53 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
BEGIN( FindMembers );
}
}
-<CSConstraint>"{" {
+<CSConstraintType,CSConstraintName>("/*"[*!]|"//"[/!])("<"?) { // special comment
+ fullArgString.resize(0);
+ lastCopyArgChar='#'; // end marker
+ lastCommentInArgContext=YY_START;
+ if (yytext[1]=='/')
+ BEGIN( CopyArgCommentLine );
+ else
+ BEGIN( CopyArgComment );
+ }
+<CSConstraintType,CSConstraintName>"#" { // artifically inserted token to signal end of comment block
+ current->typeConstr->last()->docs = fullArgString;
+ }
+<CSConstraintType>"{" { // end of type constraint reached
+ // parse documentation of the constraints
+ handleParametersCommentBlocks(current->typeConstr);
unput('{');
- BEGIN( ClassVar );
+ BEGIN( lastCSConstraint );
}
-<CSConstraint>\n {
+<CSConstraintName>":" {
+ BEGIN( CSConstraintType );
+ }
+<CSConstraintName>{ID} {
+ // parameter name
+ current->typeConstr->last()->name=yytext;
+ }
+<CSConstraintType>"where" { // another constraint for a different param
+ current->typeConstr->append(new Argument);
+ BEGIN( CSConstraintName );
+ }
+<CSConstraintType>({ID}".")*{ID}("<"{ID}">")?("()")? {
+ if (current->typeConstr->last()->type.isEmpty())
+ // first type constraint for this parameter
+ {
+ current->typeConstr->last()->type=yytext;
+ }
+ else // new type constraint for same parameter
+ {
+ QCString name = current->typeConstr->last()->name;
+ current->typeConstr->append(new Argument);
+ current->typeConstr->last()->name=name;
+ current->typeConstr->last()->type=yytext;
+ }
+ }
+<CSConstraintName,CSConstraintType>\n {
yyLineNr++;
}
-<CSConstraint>. {
+<CSConstraintName,CSConstraintType>. {
}
<ClassCategory>{ID} {
current->name+=yytext;
@@ -5000,10 +5065,10 @@ static void handleCommentBlock(const QCString &doc,bool brief)
}
}
-static void handleParametersCommentBlocks()
+static void handleParametersCommentBlocks(ArgumentList *al)
{
//printf(">>>>>>> handleParametersCommentBlocks()\n");
- ArgumentListIterator ali(*current->argList);
+ ArgumentListIterator ali(*al);
Argument *a;
for (ali.toFirst();(a=ali.current());++ali)
{
diff --git a/src/textdocvisitor.cpp b/src/textdocvisitor.cpp
index fe5573b..9e5cd21 100644
--- a/src/textdocvisitor.cpp
+++ b/src/textdocvisitor.cpp
@@ -71,8 +71,13 @@ void TextDocVisitor::filter(const char *str)
c=*p++;
switch(c)
{
- case '\n': m_t << " "; break;
- default: m_t << c;
+ case '\n': m_t << " "; break;
+ case '"': m_t << "&quot;"; break;
+ case '\'': m_t << "&apos;"; break;
+ case '<': m_t << "&lt;"; break;
+ case '>': m_t << "&gt;"; break;
+ case '&': m_t << "&amp;"; break;
+ default: m_t << c;
}
}
}
diff --git a/src/textdocvisitor.h b/src/textdocvisitor.h
index cf7788a..8e70da9 100644
--- a/src/textdocvisitor.h
+++ b/src/textdocvisitor.h
@@ -36,11 +36,11 @@ class TextDocVisitor : public DocVisitor
// visitor functions for leaf nodes
//--------------------------------------
- void visit(DocWord *w) { m_t << w->word(); }
- void visit(DocLinkedWord *w) { m_t << w->word(); }
+ void visit(DocWord *w) { filter(w->word()); }
+ void visit(DocLinkedWord *w) { filter(w->word()); }
void visit(DocWhiteSpace *) { m_t << " "; }
void visit(DocSymbol *);
- void visit(DocURL *u) { m_t << u->url(); }
+ void visit(DocURL *u) { filter(u->url()); }
void visit(DocLineBreak *) { m_t << " "; }
void visit(DocHorRuler *) {}
void visit(DocStyleChange *) {}
diff --git a/src/util.cpp b/src/util.cpp
index 0723ae4..fde2dab 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -500,10 +500,11 @@ ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md,
ip--;
}
type=type.left(ip+1);
+ type.stripPrefix("const "); // strip leading "const"
+ type.stripPrefix("struct "); // strip leading "struct"
+ type.stripPrefix("union "); // strip leading "union"
int sp=0;
- if (type.stripPrefix("const ")) sp+=6; // strip leading "const"
- if (type.stripPrefix("struct ")) sp+=7; // strip leading "struct"
- if (type.stripPrefix("union ")) sp+=6; // strip leading "union"
+ tl=type.length(); // length may have been changed
while (sp<tl && type.at(sp)==' ') sp++;
MemberDef *memTypeDef = 0;
ClassDef *result = getResolvedClassRec(md->getOuterScope(),
@@ -697,9 +698,13 @@ static Definition *followPath(Definition *start,FileDef *fileScope,const QCStrin
}
}
Definition *next = current->findInnerCompound(qualScopePart);
- //printf("++ Looking for %s inside %s result %p\n",qualScopePart.data(),current->name().data(),next?next->name().data():"<null>");
+ //printf("++ Looking for %s inside %s result %s\n",
+ // qualScopePart.data(),
+ // current->name().data(),
+ // next?next->name().data():"<null>");
if (next==0) // failed to follow the path
{
+ //printf("==> next==0!\n");
if (current->definitionType()==Definition::TypeNamespace)
{
current = endOfPathIsUsedClass(
@@ -715,6 +720,7 @@ static Definition *followPath(Definition *start,FileDef *fileScope,const QCStrin
else // continue to follow scope
{
current = next;
+ //printf("==> current = %p\n",current);
}
ps=is+l;
}
@@ -1295,6 +1301,7 @@ ClassDef *getResolvedClassRec(Definition *scope,
if (di->definitionType()==DefinitionIntf::TypeSymbolList) // not a unique name
{
+ //printf(" name is not unique\n");
DefinitionListIterator dli(*(DefinitionList*)di);
Definition *d;
int count=0;
@@ -1307,6 +1314,7 @@ ClassDef *getResolvedClassRec(Definition *scope,
}
else // unique name
{
+ //printf(" name is unique\n");
Definition *d = (Definition *)di;
getResolvedSymbol(scope,fileScope,d,explicitScopePart,
minDistance,bestMatch,bestTypedef,bestTemplSpec,
@@ -1426,12 +1434,29 @@ QCString removeRedundantWhiteSpace(const QCString &s)
{
nextChar:
char c=s.at(i);
- if ((csp==0 && (i==0 || !isId(constScope[i-1])) || (csp>0 && csp<6)) &&
- c==constScope[csp]
- ) csp++; else csp=0;
- if ((vsp==0 && (i==0 || !isId(virtualScope[i-1])) || (vsp>0 && vsp<8)) &&
- c==virtualScope[vsp]
- ) vsp++; else vsp=0;
+
+ // search for "const"
+ if (csp<6 && c==constScope[csp] && // character matches substring "const"
+ (csp>0 || // if it is the first character
+ i==0 || // the previous may not be a digit
+ !isId(s.at(i-1))
+ )
+ )
+ csp++;
+ else // reset counter
+ csp=0;
+
+ // search for "virtual"
+ if (vsp<8 && c==virtualScope[vsp] && // character matches substring "virtual"
+ (vsp>0 || // if it is the first character
+ i==0 || // the previous may not be a digit
+ !isId(s.at(i-1))
+ )
+ )
+ vsp++;
+ else // reset counter
+ vsp=0;
+
if (c=='"') // quoted string
{
i++;
@@ -1478,30 +1503,40 @@ nextChar:
result+=' ';
result+=s.at(i);
}
- else if (c=='t' && csp==5 && (i<5 || !isId(s.at(i-5))) &&
- !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ || s.at(i+1)==')' ||
- s.at(i+1)==',' || s.at(i+1)=='\0'))
+ else if (c=='t' && csp==5 /*&& (i<5 || !isId(s.at(i-5)))*/ &&
+ !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ ||
+ s.at(i+1)==')' ||
+ s.at(i+1)==',' ||
+ s.at(i+1)=='\0'
+ )
+ )
// prevent const ::A from being converted to const::A
{
result+="t ";
if (s.at(i+1)==' ') i++;
csp=0;
}
- else if (c==':' && csp==6 && (i<6 || !isId(s.at(i-6)))) // replace const::A by const ::A
+ else if (c==':' && csp==6 /*&& (i<6 || !isId(s.at(i-6)))*/)
+ // replace const::A by const ::A
{
result+=" :";
csp=0;
}
- else if (c=='l' && vsp==7 && (i<7 || !isId(s.at(i-7))) &&
- !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ || s.at(i+1)==')' ||
- s.at(i+1)==',' || s.at(i+1)=='\0'))
+ else if (c=='l' && vsp==7 /*&& (i<7 || !isId(s.at(i-7)))*/ &&
+ !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ ||
+ s.at(i+1)==')' ||
+ s.at(i+1)==',' ||
+ s.at(i+1)=='\0'
+ )
+ )
// prevent virtual ::A from being converted to virtual::A
{
result+="l ";
if (s.at(i+1)==' ') i++;
vsp=0;
}
- else if (c==':' && vsp==8 && (i<8 || !isId(s.at(i-8)))) // replace virtual::A by virtual ::A
+ else if (c==':' && vsp==8 /*&& (i<8 || !isId(s.at(i-8)))*/)
+ // replace virtual::A by virtual ::A
{
result+=" :";
vsp=0;
@@ -1552,7 +1587,7 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope,
bool keepSpaces)
{
//printf("`%s'\n",text);
- static QRegExp regExp("[a-z_A-Z][~a-z_A-Z0-9.:]*");
+ static QRegExp regExp("[a-z_A-Z][~!a-z_A-Z0-9.:]*");
QCString txtStr=text;
int strLen = txtStr.length();
//printf("linkifyText scope=%s fileScope=%s strtxt=%s strlen=%d\n",
@@ -1571,7 +1606,7 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope,
)
{
// add non-word part to the result
- floatingIndex+=newIndex-skipIndex;
+ floatingIndex+=newIndex-skipIndex+matchLen;
bool insideString=FALSE;
int i;
for (i=index;i<newIndex;i++)
@@ -1579,24 +1614,28 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope,
if (txtStr.at(i)=='"') insideString=!insideString;
}
- if (strLen>30 && floatingIndex>25 && autoBreak) // try to insert a split point
+ //printf("floatingIndex=%d strlen=%d autoBreak=%d\n",floatingIndex,strLen,autoBreak);
+ if (strLen>25 && floatingIndex>20 && autoBreak) // try to insert a split point
{
QCString splitText = txtStr.mid(skipIndex,newIndex-skipIndex);
int splitLength = splitText.length();
- int i=splitText.find('<');
- if (i==-1) i=splitText.find(',');
+ int offset=1;
+ i=splitText.find(',');
+ if (i==-1) { i=splitText.find('<'); if (i!=-1) offset=0; }
+ if (i==-1) i=splitText.find('>');
if (i==-1) i=splitText.find(' ');
+ //printf("splitText=[%s] len=%d i=%d offset=%d\n",splitText.data(),splitLength,i,offset);
if (i!=-1) // add a link-break at i in case of Html output
{
- out.writeString(splitText.left(i+1),keepSpaces);
+ out.writeString(splitText.left(i+offset),keepSpaces);
out.writeBreak();
- out.writeString(splitText.right(splitLength-i-1),keepSpaces);
+ out.writeString(splitText.right(splitLength-i-offset),keepSpaces);
+ floatingIndex=splitLength-i-offset+matchLen;
}
else
{
out.writeString(splitText,keepSpaces);
}
- floatingIndex=splitLength-i-1;
}
else
{
@@ -1686,7 +1725,6 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope,
// set next start point in the string
//printf("index=%d/%d\n",index,txtStr.length());
skipIndex=index=newIndex+matchLen;
- floatingIndex+=matchLen;
}
// add last part of the string to the result.
//ol.docify(txtStr.right(txtStr.length()-skipIndex));
@@ -2893,14 +2931,17 @@ static QCString stripDeclKeywords(const QCString &s)
// forward decl for circular dependencies
static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type);
-QCString getCanonicalTemplateSpec(Definition *d,FileDef *,const QCString& spec)
+QCString getCanonicalTemplateSpec(Definition *d,FileDef *fs,const QCString& spec)
{
+
QCString templSpec = spec.stripWhiteSpace();
- //if (!templSpec.isEmpty() && templSpec.at(0) == '<')
- //{
- // templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace());
- //}
- QCString resolvedType = resolveTypeDef(d,spec);
+ // this part had been commented out before... but it is needed to match for instance
+ // std::list<std::string> against list<string> so it is now back again!
+ if (!templSpec.isEmpty() && templSpec.at(0) == '<')
+ {
+ templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace());
+ }
+ QCString resolvedType = resolveTypeDef(d,templSpec);
if (!resolvedType.isEmpty()) // not known as a typedef either
{
templSpec = resolvedType;
@@ -2926,6 +2967,8 @@ static QCString getCanonicalTypeForIdentifier(
{
symName=word;
}
+ //printf("getCanonicalTypeForIdentifier(%s,[%s->%s]) start\n",
+ // word.data(),tSpec?tSpec->data():"<none>",templSpec.data());
ClassDef *cd = 0;
MemberDef *mType = 0;
@@ -2942,7 +2985,7 @@ static QCString getCanonicalTypeForIdentifier(
}
if (cd && cd->isUsedOnly()) cd=0; // ignore types introduced by usage relations
- //printf(" symbol=%s word=%s cd=%s d=%s fs=%s cd->isTemplate=%d\n",
+ //printf(" getCanonicalTypeForIdentifer: symbol=%s word=%s cd=%s d=%s fs=%s cd->isTemplate=%d\n",
// symName.data(),
// word.data(),
// cd?cd->name().data():"<none>",
@@ -3020,6 +3063,7 @@ static QCString getCanonicalTypeForIdentifier(
result = resolvedType;
}
}
+ //printf("getCanonicalTypeForIdentifier [%s]->[%s]\n",word.data(),result.data());
return result;
}
@@ -3038,7 +3082,7 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type)
type.stripPrefix("typename ");
type = removeRedundantWhiteSpace(type);
- //printf("extractCanonicalType(type=%s) def=%s file=%s\n",type.data(),
+ //printf("extractCanonicalType(type=%s) start: def=%s file=%s\n",type.data(),
// d ? d->name().data() : "<null>",fs ? fs->name().data() : "<null>");
static QRegExp id("[a-z_A-Z][:a-z_A-Z0-9]*");
@@ -3112,7 +3156,7 @@ static bool matchArgument2(
if (srcA->array!=dstA->array) // nomatch for char[] against char
{
NOMATCH
- return FALSE;
+ return FALSE;
}
QCString sSrcName = " "+srcA->name;
QCString sDstName = " "+dstA->name;
@@ -3147,14 +3191,14 @@ static bool matchArgument2(
if (srcA->canType==dstA->canType)
{
MATCH
- return TRUE;
+ return TRUE;
}
else
{
//printf(" Canonical types do not match [%s]<->[%s]\n",
// srcA->canType.data(),dstA->canType.data());
NOMATCH
- return FALSE;
+ return FALSE;
}
}
@@ -3173,12 +3217,12 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr
if (match)
{
MATCH
- return TRUE;
+ return TRUE;
}
else
{
NOMATCH
- return FALSE;
+ return FALSE;
}
}
@@ -3190,7 +3234,7 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr
a->type = "void";
srcAl->append(a);
MATCH
- return TRUE;
+ return TRUE;
}
if ( dstAl->count()==0 && srcAl->count()==1 &&
srcAl->getFirst()->type=="void" )
@@ -3199,13 +3243,13 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr
a->type = "void";
dstAl->append(a);
MATCH
- return TRUE;
+ return TRUE;
}
if (srcAl->count() != dstAl->count())
{
NOMATCH
- return FALSE; // different number of arguments -> no match
+ return FALSE; // different number of arguments -> no match
}
if (checkCV)
@@ -3213,12 +3257,12 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr
if (srcAl->constSpecifier != dstAl->constSpecifier)
{
NOMATCH
- return FALSE; // one member is const, the other not -> no match
+ return FALSE; // one member is const, the other not -> no match
}
if (srcAl->volatileSpecifier != dstAl->volatileSpecifier)
{
NOMATCH
- return FALSE; // one member is volatile, the other not -> no match
+ return FALSE; // one member is volatile, the other not -> no match
}
}
@@ -3233,11 +3277,11 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr
)
{
NOMATCH
- return FALSE;
+ return FALSE;
}
}
MATCH
- return TRUE; // all arguments match
+ return TRUE; // all arguments match
}
@@ -5953,6 +5997,7 @@ SrcLangExt getLanguageFromFileName(const QCString fileName)
extLookup.insert(".idl", new int(SrcLangExt_IDL));
extLookup.insert(".ddl", new int(SrcLangExt_IDL));
extLookup.insert(".odl", new int(SrcLangExt_IDL));
+ extLookup.insert(".ddl", new int(SrcLangExt_IDL));
extLookup.insert(".java", new int(SrcLangExt_Java));
extLookup.insert(".jsl", new int(SrcLangExt_Java));
extLookup.insert(".as", new int(SrcLangExt_Java));
@@ -6243,4 +6288,24 @@ QCString expandAlias(const QCString &aliasName,const QCString &aliasValue)
return result;
}
+void writeTypeConstraints(OutputList &ol,Definition *d,ArgumentList *al)
+{
+ if (al==0) return;
+ ol.startConstraintList("Type constraints"); // TODO: add to translator!
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ ol.startConstraintParam();
+ ol.parseText(a->name);
+ ol.endConstraintParam();
+ ol.startConstraintType();
+ linkifyText(TextGeneratorOLImpl(ol),d,0,0,a->type);
+ ol.endConstraintType();
+ ol.startConstraintDocs();
+ ol.parseDoc(d->docFile(),d->docLine(),d,0,a->docs,TRUE,FALSE);
+ ol.endConstraintDocs();
+ }
+ ol.endConstraintList();
+}
diff --git a/src/util.h b/src/util.h
index 545d183..8d36a6f 100644
--- a/src/util.h
+++ b/src/util.h
@@ -343,5 +343,8 @@ QCString replaceAliasArguments(const QCString &aliasValue,const QCString &argLis
QCString resolveAliasCmd(const QCString aliasCmd);
QCString expandAlias(const QCString &aliasName,const QCString &aliasValue);
+void writeTypeConstraints(OutputList &ol,Definition *d,ArgumentList *al);
+
+
#endif