Commit 29a8f144 authored by Dimitri van Heesch's avatar Dimitri van Heesch

Release-1.5.2-20070719

parent 01147699
DOXYGEN Version 1.5.2-20070610
DOXYGEN Version 1.5.2-20070719
Please read the installation section of the manual
(http://www.doxygen.org/install.html) for instructions.
--------
Dimitri van Heesch (10 June 2007)
Dimitri van Heesch (19 July 2007)
......@@ -54,15 +54,15 @@ install: doxywizard_install
$(INSTTOOL) -m 755 bin/doxygen $(INSTALL)/bin
$(INSTTOOL) -m 755 bin/doxytag $(INSTALL)/bin
$(INSTTOOL) -d $(INSTALL)/$(MAN1DIR)
cat doc/doxygen.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" doxygen.1
cat doc/doxygen.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > doxygen.1
$(INSTTOOL) -m 644 doxygen.1 $(INSTALL)/$(MAN1DIR)/doxygen.1
rm doxygen.1
cat doc/doxytag.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" doxytag.1
cat doc/doxytag.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > doxytag.1
$(INSTTOOL) -m 644 doxytag.1 $(INSTALL)/$(MAN1DIR)/doxytag.1
rm doxytag.1
cat doc/doxywizard.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" doxywizard.1
cat doc/doxywizard.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > doxywizard.1
$(INSTTOOL) -m 644 doxywizard.1 $(INSTALL)/$(MAN1DIR)/doxywizard.1
rm doxywizard
rm doxywizard.1
install_docs:
$(INSTTOOL) -d $(DOCDIR)
......
DOXYGEN Version 1.5.2_20070610
DOXYGEN Version 1.5.2_20070719
Please read INSTALL for compilation instructions.
......@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives.
Enjoy,
Dimitri van Heesch (dimitri@stack.nl) (10 June 2007)
Dimitri van Heesch (dimitri@stack.nl) (19 July 2007)
......@@ -22,10 +22,11 @@
*
* This example shows how to use to code parser to get cross-references information
* and it also shows how to look up symbols in a program parsed by doxygen and
* show some information about it.
* show some information about them.
*/
#include <stdlib.h>
#include <unistd.h>
#include "doxygen.h"
#include "outputgen.h"
#include "parserintf.h"
......
......@@ -20,7 +20,7 @@ doxygen_version_minor=5
doxygen_version_revision=2
#NOTE: Setting version_mmn to "NO" will omit mmn info from the package.
doxygen_version_mmn=20070610
doxygen_version_mmn=20070719
bin_dirs=`echo $PATH | sed -e "s/:/ /g"`
......@@ -238,7 +238,7 @@ if test -z "$f_platform"; then
fi
if test -z "$f_docdir"; then
f_docdir=$f_prefix/share/doc/packages/doxygen
f_docdir='$(INSTALL)/share/doc/packages/doxygen'
fi
if test "$f_plf_auto" = NO; then
......
/******************************************************************************
*
*
*
* Copyright (C) 1997-2007 by Dimitri van Heesch.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation under the terms of the GNU General Public License is hereby
* granted. No representations are made about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
* See the GNU General Public License for more details.
*
* Documents produced by Doxygen are derivative works derived from the
* input used in their production; they are not affected by this license.
*
*/
/*! \page custcmd Custom Commands
Doxygen provides a large number of \ref commands "special commands",
\ref xmlcmds "XML commands", and \ref htmlcmds "HTML commands".
that can be used to enhance or structure the documentation inside a comment block.
If you for some reason have a need to define new commands you can do
so by means of an \e alias definition.
The definition of an alias should be specified in the configuration file using
the \ref cfg_aliases "ALIASES" configuration tag.
\section custcmd_simple Simple aliases
The simplest form of an alias is a simple substitution of the form
\verbatim
name=value
\endverbatim
For example defining the following alias:
\verbatim
ALIASES += sideeffect="\par Side Effects:\n"
\endverbatim
will allow you to
put the command \\sideeffect (or \@sideeffect) in the documentation, which
will result in a user-defined paragraph with heading <b>Side Effects:</b>.
Note that you can put \\n's in the value part of an alias to insert newlines.
Also note that you can redefine existing special commands if you wish.
Some commands, such as \ref cmdxrefitem "\\xrefitem" are designed to be used in
combination with aliases.
\section custcmd_complex Aliases with arguments
Aliases can also have one or more arguments. In the alias definition you then need
to specify the number of arguments between curly braces. In the value part of the
definition you can place \\x markers, where 'x' represents the argument number starting
with 1.
Here is an example of an alias definition with a single argument:
\verbatim
ALIASES += l{1}="\ref \1"
\endverbatim
Inside a comment block you can use it as follows
\verbatim
/** See \l{SomeClass} for more information. */
\endverbatim
which would be the same as writing
\verbatim
/** See \ref SomeClass for more information. */
\endverbatim
Note that you can overload an alias by a version with multiple arguments, for instance:
\verbatim
ALIASES += l{1}="\ref \1"
ALIASES += l{2}="\ref \1 \"\2\""
\endverbatim
Note that the quotes inside the alias definition have to be escaped with a backslash.
With these alias definitions, we can write
\verbatim
/** See \l{SomeClass,Some Text} for more information. */
\endverbatim
inside the comment block and it will expand to
\verbatim
/** See \ref SomeClass "Some Text" for more information. */
\endverbatim
where the command with a single argument would still work as shown before.
Aliases can also be expressed in terms of other aliases, e.g. a new command
\\reminder can be expressed as a \\xrefitem via an intermediate \\xreflist command
as follows:
\verbatim
ALIASES += xreflist{3}="\xrefitem \1 \"\2\" \"\3\" " \
ALIASES += reminder="\xreflist{reminders,Reminder,Reminders}" \
\endverbatim
Note that if for aliases with more than one argument a comma is used as a separator,
if you want to put a comma inside the command, you will need to escape it with a backslash,
i.e.
\verbatim
\l{SomeClass,Some text\, with an escaped comma}
\endverbatim
given the alias definition of \\l in the example above.
\section custcmd_nesting Nesting custom command
You can use commands as arguments of aliases, including commands
defined using aliases.
As an example consider the following alias definitions
\verbatim
ALIASES += Bold{1}="<b>\1</b>"
ALIASES += Emph{1}="<em>\1</em>"
\endverbatim
Inside a comment block you can now use:
\verbatim
/** This is a \Bold{bold \Emph{and} Emphasized} text fragment. */
\endverbatim
which will expand to
\verbatim
/** This is a <b>bold <em>and</em> Emphasized</b> text fragment. */
\endverbatim
*/
......@@ -192,8 +192,6 @@ Thanks go to:
<li>Talin for adding support for C# style comments with XML markup.
<li>Petr Prikryl for coordinating the internationalisation support.
All language maintainers for providing translations into many languages.
<li>Gerald Steffens of <a href="http://www.e-trend.de">E-trend</a>
for financial support.
<li>The band <a href="http://www.porcupinetree.com">Porcupine Tree</a> for
providing hours of great music to listen to while coding.
<li>many, many others for suggestions, patches and bug reports.
......
......@@ -366,40 +366,61 @@ before running make.
\section install_src_windows Compiling from source on Windows
From version 1.5.0 onwards, build files are provided for Visual Studio 2005.
Also the free "Express" version of Developer Studio can be used to compile doxygen.
Alternatively, you can compile doxygen \ref install_src_unix "the Unix way" using
Also the free (as in beer) "Express" version of Developer Studio can be used to
compile doxygen. Alternatively, you can compile doxygen
\ref install_src_unix "the Unix way" using
<a href="http://en.wikipedia.org/wiki/Cygwin">Cygwin</a>
or <a href="http://www.mingw.org/">MinGW</a>.
Before you can compile doxygen you need to download and install the C++ compiler of
Visual Studio. Since Microsoft apparently wants to lure everyone into using their
.NET stuff, you need to
.NET stuff, they made things somewhat difficult when you use the Express version.
You need to
<a href="http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/">
do some manual steps</a> in order to setup a proper working environment for building
native win32 applications.
Once your environment is setup, you
can <a href="http://www.stack.nl/~dimitri/doxygen/download.html#latestsrc">download</a>
the source distribution of doxygen and unpack it.
If you don't have a tool like WinZip, then I suggest to download
<a href="http://sourceforge.net/projects/unxutils/">unxutils</a>
and untar the archive from within a command box using
native win32 applications such as Doxygen.
The next step is to install unxutils (see http://sourceforge.net/projects/unxutils).
This packages contains the tools \c flex and \c bison which are needed during the
compilation process if you use a CVS snapshot of doxygen (the official source releases
come with pre-generated sources).
Download the zip extract it to e.g. <code>c:\\tools\\unxutils</code>.
Now you need to add/adjust the following environment variables
(via Control Panel/System/Advanced/Environment Variables):
- add <code>c:\\tools\\unxutils\\usr\\local\\wbin;</code> to the start of <code>PATH</code>
- set <code>BISON_SIMPLE</code> to <code>c:\\tools\\unxutils\\usr\\share\\bison.simple</code>
Download doxygen's source tarball and put it somewhere (e.g use <code>c:\\tools</code>)
Now start a new command shell and type
\verbatim
tar zxvf doxygen-version.src.tar.gz
cd c:\tools
gunzip doxygen-x.y.z.src.tar.gz
tar xvf doxygen-x.y.z.src.tar
\endverbatim
Inside the archive you will find a \c winbuild directory containing a \c Doxygen.sln
file. Just open this file in Visual Studio. You can now build the Doxygen, Doxytag,
and Doxywizard projects for Release or Debug to compile the executables.
to unpack the sources.
Now your environment is setup to build \c doxygen and \c doxytag.
Inside the \c doxygen-x.y.z directory you will find a \c winbuild directory
containing a \c Doxygen.sln file. Open this file in Visual Studio.
You can now build the Release or Debug flavor of Doxygen and Doxytag by right-clicking
the project in the solutions explorer, and selecting Build.
Note that compiling Doxywizard currently requires a <a href="http://www.trolltech.com/products/qt/qt3">
commercial license for Qt 3</a>.
Note that compiling Doxywizard currently requires Qt version 3
(see http://www.trolltech.com/products/qt/qt3).
If you do not have a commercial license, you can build Doxywizard with the open
source version (see http://qtwin.sourceforge.net/qt3-win32/compile-msvc-2005.php),
but I have not tried this myself.
Also read the next section for additional tools you may need to install.
Also read the next section for additional tools you may need to install to run
doxygen with certain features enabled.
<!--
Currently, I have only compiled doxygen for Windows using Microsoft's
Visual C++ (version 6.0). For other compilers you may need to edit the
Visual C++ (). For other compilers you may need to edit the
perl script in <code>wintools/make.pl</code> a bit.
Let me know what you had to change if you got Doxygen working with another
compiler. If you have Visual Studio you can also use the .dsw file found in
......
......@@ -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.
*/
......
......@@ -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);
......
......@@ -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 },
......
......@@ -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.
......
......@@ -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 },
......
......@@ -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"
......
......@@ -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();
}
......
......@@ -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,"%","%%"));
}
}
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -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");
......
......@@ -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; }
}
......
......@@ -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
......
......@@ -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();
}
}
......
......@@ -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;
}
......@@ -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;
......
......@@ -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;
}
......@@ -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() {}
......
......@@ -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()
{
}
......@@ -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 *) {}
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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();
......
......@@ -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;
......
......@@ -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();
......
......@@ -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;
......
......@@ -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");
......
......@@ -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 << "}";
}
......@@ -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() {}
......
......@@ -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)
{
......
......@@ -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;
}
}
}
......
......@@ -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 *) {}
......
......@@ -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();
}
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment