Commit 0625007c authored by dimitri's avatar dimitri

Release-1.3.9.1-20041114

parent 670c8a43
DOXYGEN Version 1.3.9.1 DOXYGEN Version 1.3.9.1-20041114
Please read the installation section of the manual Please read the installation section of the manual
(http://www.doxygen.org/install.html) for instructions. (http://www.doxygen.org/install.html) for instructions.
-------- --------
Dimitri van Heesch (28 October 2004) Dimitri van Heesch (14 November 2004)
DOXYGEN Version 1.3.9.1 DOXYGEN Version 1.3.9.1_20041114
Please read INSTALL for compilation instructions. Please read INSTALL for compilation instructions.
...@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives. ...@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives.
Enjoy, Enjoy,
Dimitri van Heesch (dimitri@stack.nl) (28 October 2004) Dimitri van Heesch (dimitri@stack.nl) (14 November 2004)
1.3.9.1 1.3.9.1-20041114
...@@ -51,6 +51,7 @@ documentation: ...@@ -51,6 +51,7 @@ documentation:
\refitem cmdcategory \\category \refitem cmdcategory \\category
\refitem cmdclass \\class \refitem cmdclass \\class
\refitem cmdcode \\code \refitem cmdcode \\code
\refitem cmdcond \\cond
\refitem cmdcopydoc \\copydoc \refitem cmdcopydoc \\copydoc
\refitem cmddate \\date \refitem cmddate \\date
\refitem cmddef \\def \refitem cmddef \\def
...@@ -65,6 +66,7 @@ documentation: ...@@ -65,6 +66,7 @@ documentation:
\refitem cmdelseif \\elseif \refitem cmdelseif \\elseif
\refitem cmdem \\em \refitem cmdem \\em
\refitem cmdendcode \\endcode \refitem cmdendcode \\endcode
\refitem cmdendcond \\endcond
\refitem cmdenddot \\enddot \refitem cmdenddot \\enddot
\refitem cmdendhtmlonly \\endhtmlonly \refitem cmdendhtmlonly \\endhtmlonly
\refitem cmdendif \\endif \refitem cmdendif \\endif
...@@ -223,6 +225,7 @@ doxygen. Unrecognized commands are treated as normal text. ...@@ -223,6 +225,7 @@ doxygen. Unrecognized commands are treated as normal text.
\sa section \ref cmdclass "\\class". \sa section \ref cmdclass "\\class".
<hr>
\section cmdclass \class <name> [<header-file>] [<header-name>] \section cmdclass \class <name> [<header-file>] [<header-name>]
\addindex \\class \addindex \\class
...@@ -754,6 +757,72 @@ See section \ref memgroup for an example. ...@@ -754,6 +757,72 @@ See section \ref memgroup for an example.
sectioning command is encountered. See section \ref cmdauthor "\\author" sectioning command is encountered. See section \ref cmdauthor "\\author"
for an example. for an example.
<hr>
\section cmdcond \cond [<section-label>]
\addindex \\cond
Starts a conditional section that ends with a corresponding
\ref cmdendcond "\\endcond" command, which is typically found in
another comment block. The main purpose of this pair of
commands is to (conditionally) exclude part of a file from processing
(traditionally this could only be achieved using C processor commands).
The section between \\cond and \\endcond commands can be included by
adding its section label to the \ref cfg_enabled_sections "ENABLED_SECTIONS"
configuration option. If the section label is omitted, the section will
be excluded from processing unconditionally.
For conditional sections within a comment block one should
use a \ref cmdif "\\if" ... \ref cmdendif "\\endif" block.
Conditional sections can be nested. In this case a nested section will only
be shown if it and its containing section are included.
Here is an example showing the commands in action:
\verbatim
/** An interface */
class Intf
{
public:
/** A method */
virtual void func() = 0;
/// @cond TEST
/** A method used for testing */
virtual void test() = 0;
/// @endcond
};
/// @cond DEV
/*
* The implementation of the interface
*/
class Implementation : public Intf
{
public:
void func();
/// @cond TEST
void test();
/// @endcond
/// @cond
/** This method is obsolete and does
* not show up in the documentation.
*/
void obsolete();
/// @endcond
};
/// @endcond
\endverbatim
The output will be different depending on whether \c ENABLED_SECTIONS
is empty, \c TEST, \c DEV, or \c DEV \c TEST.
<hr> <hr>
\section cmddate \date { date description } \section cmddate \date { date description }
...@@ -803,11 +872,19 @@ See section \ref memgroup for an example. ...@@ -803,11 +872,19 @@ See section \ref memgroup for an example.
\sa sections \ref cmdendif "\\endif", \ref cmdifnot "\\ifnot", \sa sections \ref cmdendif "\\endif", \ref cmdifnot "\\ifnot",
\ref cmdelse "\\else", and \ref cmdelseif "\\elseif". \ref cmdelse "\\else", and \ref cmdelseif "\\elseif".
<hr>
\section cmdendcond \endcond
\addindex \\endcond
Ends a conditional section that was started by \ref cmdcond "\\cond".
\sa \ref cmdcond "\\cond".
<hr> <hr>
\section cmdendif \endif \section cmdendif \endif
\addindex \\endif \addindex \\endif
Ends a conditional section that was started with \c \\if or \c \\ifnot Ends a conditional section that was started by \c \\if or \c \\ifnot
For each \c \\if or \c \\ifnot one and only one matching \c \\endif must follow. For each \c \\if or \c \\ifnot one and only one matching \c \\endif must follow.
\sa \ref cmdif "\\if", and \ref cmdifnot "\\ifnot". \sa \ref cmdif "\\if", and \ref cmdifnot "\\ifnot".
......
...@@ -73,6 +73,7 @@ followed by the descriptions of the tags grouped by category. ...@@ -73,6 +73,7 @@ followed by the descriptions of the tags grouped by category.
\refitem cfg_compact_rtf COMPACT_RTF \refitem cfg_compact_rtf COMPACT_RTF
\refitem cfg_create_subdirs CREATE_SUBDIRS \refitem cfg_create_subdirs CREATE_SUBDIRS
\refitem cfg_details_at_top DETAILS_AT_TOP \refitem cfg_details_at_top DETAILS_AT_TOP
\refitem cfg_directory_graph DIRECTORY_GRAPH
\refitem cfg_disable_index DISABLE_INDEX \refitem cfg_disable_index DISABLE_INDEX
\refitem cfg_distribute_group_doc DISTRIBUTE_GROUP_DOC \refitem cfg_distribute_group_doc DISTRIBUTE_GROUP_DOC
\refitem cfg_dot_image_format DOT_IMAGE_FORMAT \refitem cfg_dot_image_format DOT_IMAGE_FORMAT
...@@ -609,7 +610,8 @@ function's detailed documentation block. ...@@ -609,7 +610,8 @@ function's detailed documentation block.
\addindex ENABLED_SECTIONS \addindex ENABLED_SECTIONS
The \c ENABLED_SECTIONS tag can be used to enable conditional The \c ENABLED_SECTIONS tag can be used to enable conditional
documentation sections, marked by \ref cmdif "\\if" \<section-label\> ... documentation sections, marked by \ref cmdif "\\if" \<section-label\> ...
\ref cmdendif "\\endif" blocks. \ref cmdendif "\\endif" and \ref cmdcond "\\cond" \<section-label\> ...
\ref cmdendcond "\\endcond" blocks.
\anchor cfg_max_initializer_lines \anchor cfg_max_initializer_lines
<dt>\c MAX_INITIALIZER_LINES <dd> <dt>\c MAX_INITIALIZER_LINES <dd>
...@@ -1583,10 +1585,18 @@ TAGFILES = file1=loc1 "file2 = loc2" ... </pre> ...@@ -1583,10 +1585,18 @@ TAGFILES = file1=loc1 "file2 = loc2" ... </pre>
If the \c GRAPHICAL_HIERARCHY and \c HAVE_DOT tags are set to \c YES then If the \c GRAPHICAL_HIERARCHY and \c HAVE_DOT tags are set to \c YES then
doxygen will graphical hierarchy of all classes instead of a textual one. doxygen will graphical hierarchy of all classes instead of a textual one.
\anchor cfg_directory_graph
<dt>\c DIRECTORY_GRAPH <dd>
\addindex DIRECTORY_GRAPH
If the \c DIRECTORY_GRAPH, \c SHOW_DIRECTORIES and \c HAVE_DOT options are set
to \c YES then doxygen will show the dependencies a directory has on other directories
in a graphical way. The dependency relations are determined by the #include
relations between the files in the directories.
\anchor cfg_dot_image_format \anchor cfg_dot_image_format
<dt>\c DOT_IMAGE_FORMAT <dd> <dt>\c DOT_IMAGE_FORMAT <dd>
\addindex DOT_IMAGE_FORMAT \addindex DOT_IMAGE_FORMAT
The DOT_IMAGE_FORMAT tag can be used to set the image format of the images The \c DOT_IMAGE_FORMAT tag can be used to set the image format of the images
generated by dot. Possible values are gif, jpg, and png. generated by dot. Possible values are gif, jpg, and png.
If left blank png will be used. If left blank png will be used.
......
...@@ -79,7 +79,13 @@ document either the class or namespace. ...@@ -79,7 +79,13 @@ document either the class or namespace.
<li><b>How can I make doxygen ignore some code fragment?</b> <li><b>How can I make doxygen ignore some code fragment?</b>
<p> <p>
You can use Doxygen's preprocessor for this:
The new and easiest way is to add one comment block
with a \ref cmdcond "\\cond" command at the start and one comment block
with a \ref cmdendcond "\\endcond" command at the end of the piece of
code that should be ignored. This should be within the same file of course.
But you can also use Doxygen's preprocessor for this:
If you put If you put
\verbatim \verbatim
#ifndef DOXYGEN_SHOULD_SKIP_THIS #ifndef DOXYGEN_SHOULD_SKIP_THIS
...@@ -97,7 +103,10 @@ as <code>PREPROCESSING = YES</code>. ...@@ -97,7 +103,10 @@ as <code>PREPROCESSING = YES</code>.
<li><b>How can I change what is after the <code>\#include</code> in the class documentation?</b> <li><b>How can I change what is after the <code>\#include</code> in the class documentation?</b>
You can document your class like In most cases you can use STRIP_FROM_INC_PATH to strip a user defined
part of a path.
You can also document your class as follows
\verbatim \verbatim
/*! \class MyClassName include.h path/include.h /*! \class MyClassName include.h path/include.h
......
doc/infoflow.gif

12.2 KB | W: | H:

doc/infoflow.gif

23.9 KB | W: | H:

doc/infoflow.gif
doc/infoflow.gif
doc/infoflow.gif
doc/infoflow.gif
  • 2-up
  • Swipe
  • Onion skin
...@@ -385,7 +385,9 @@ Currently, I have only compiled doxygen for Windows using Microsoft's ...@@ -385,7 +385,9 @@ 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++ (version 6.0). For other compilers you may need to edit the
perl script in <code>wintools/make.pl</code> a bit. 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 Let me know what you had to change if you got Doxygen working with another
compiler. compiler. If you have Visual Studio you can also use the .dsw file found in
the <code>wintools</code> directory. Note that this file is not maintained
by me, so it might be outdated a little.
If you have Visual C++ 6.0, and the source distribution, you can easily If you have Visual C++ 6.0, and the source distribution, you can easily
build doxygen using the project files in the \c wintools directory. If build doxygen using the project files in the \c wintools directory. If
...@@ -462,57 +464,16 @@ Here is what is required: ...@@ -462,57 +464,16 @@ Here is what is required:
commerical version of Qt. commerical version of Qt.
For doxywizard, a complete Qt library is For doxywizard, a complete Qt library is
still a requirement however. You can download the non-commercial version still a requirement however. A commercial license to build
from Troll-Tech web-site. See doxygen download page for a link. doxywizard with the latest Qt library was kindly donated to me
by the nice people at <a href="http://www.trolltech.com">TrollTech</a>.
<li>To generate LaTeX documentation or formulas in HTML you need the tools: See doxygen download page for a link.
<code>latex</code>, <code>dvips</code> and <code>gswin32</code>.
To get these working under Windows
install the fpTeX distribution. You can find more info at:
http://www.fptex.org/ and download it from CTAN or one of its mirrors.
In the Netherlands for example this would be:
ftp://ftp.easynet.nl/mirror/CTAN/systems/win32/fptex/
Make sure the tools are available from a dos box, by adding the
directory they are in to the search path.
For your information, the LaTeX is freely available set of so
called macros and styles on the top of the famous TeX program
(by famous Donald Knuth) and the accompanied utilities (all
available for free). It is used for high quality
typesetting. The result -- in the form of so called
<code>DVI</code> (DeVice Independent) file -- can be printed or
displayed on various devices preserving exactly the same look up
to the capability of the device. The <code>dvips</code> allows you
to convert the <code>dvi</code> to the high quality PostScript
(i.e. PostScript that can be processed by utilities like
<code>psnup</code>, <code>psbook</code>, <code>psselect</code>,
and others). The derived version of TeX (the pdfTeX) can be used
to produce PDF output instead of DVI, or the PDF can be produced
from PostScript using the utility <code>ps2pdf</code>.
If you want to use MikTeX then you need to select at least the
medium size installation. For really old versions of MikTex or minimal
installations, you may need to download the fancyhdr package separately.
You can find it at:
ftp://ftp.tex.ac.uk/tex-archive/macros/latex/contrib/supported/fancyhdr/
<li>If you want to generate compressed HTML help
(see \ref cfg_generate_htmlhelp "GENERATE_HTMLHELP") in the
config file, then you need the Microsoft HTML help workshop.
You can download it at:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/htmlhelp/html/vsconHH1Start.asp
<li>If you used WinZip to extract the tar archive it will (apparently) not <li>If you used WinZip to extract the tar archive it will (apparently) not
create empty folders, so you have to add the folders create empty folders, so you have to add the folders
<code>objects</code> and <code>bin</code> manually in the root of the <code>objects</code> and <code>bin</code> manually in the root of the
distribution before compiling. distribution before compiling.
<li><a href="http://www.research.att.com/sw/tools/graphviz/">
the Graph visualization toolkit version 1.8.10</a><br>
\latexonly(see {\tt http://www.research.att.com/sw/tools/graphviz/})\endlatexonly.
Needed for the include dependency graphs, the graphical inheritance graphs,
and the collaboration graphs.
</ul> </ul>
...@@ -577,23 +538,66 @@ To install doxygen, just copy the binaries from the <code>bin</code> directory ...@@ -577,23 +538,66 @@ To install doxygen, just copy the binaries from the <code>bin</code> directory
to a location somewhere in the path. Alternatively, you can include to a location somewhere in the path. Alternatively, you can include
the <code>bin</code> directory of the distribution to the path. the <code>bin</code> directory of the distribution to the path.
<!-- There are a couple of tools you may want to install to use all of doxygen's
For running doxywizard you need to install the non-commercial version of features:
the Qt library first. This library can be downloaded from
http://www.trolltech.com/products/download/qt-win-noncomm.html <ul>
--> <li>To generate LaTeX documentation or formulas in HTML you need the tools:
<code>latex</code>, <code>dvips</code> and <code>gswin32</code>.
To get these working under Windows
install the fpTeX distribution. You can find more info at:
http://www.fptex.org/ and download it from CTAN or one of its mirrors.
In the Netherlands for example this would be:
ftp://ftp.easynet.nl/mirror/CTAN/systems/win32/fptex/
Make sure the tools are available from a dos box, by adding the
directory they are in to the search path.
For your information, the LaTeX is freely available set of so
called macros and styles on the top of the famous TeX program
(by famous Donald Knuth) and the accompanied utilities (all
available for free). It is used for high quality
typesetting. The result -- in the form of so called
<code>DVI</code> (DeVice Independent) file -- can be printed or
displayed on various devices preserving exactly the same look up
to the capability of the device. The <code>dvips</code> allows you
to convert the <code>dvi</code> to the high quality PostScript
(i.e. PostScript that can be processed by utilities like
<code>psnup</code>, <code>psbook</code>, <code>psselect</code>,
and others). The derived version of TeX (the pdfTeX) can be used
to produce PDF output instead of DVI, or the PDF can be produced
from PostScript using the utility <code>ps2pdf</code>.
If you want to use MikTeX then you need to select at least the
medium size installation. For really old versions of MikTex or minimal
installations, you may need to download the fancyhdr package separately.
You can find it at:
ftp://ftp.tex.ac.uk/tex-archive/macros/latex/contrib/supported/fancyhdr/
<li>If you want to generate compressed HTML help
(see \ref cfg_generate_htmlhelp "GENERATE_HTMLHELP") in the
config file, then you need the Microsoft HTML help workshop.
You can download it at:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/htmlhelp/html/vsconHH1Start.asp
<li><a href="http://www.research.att.com/sw/tools/graphviz/">
the Graph visualization toolkit version 1.8.10</a><br>
\latexonly(see {\tt http://www.research.att.com/sw/tools/graphviz/})\endlatexonly.
Needed for the include dependency graphs, the graphical inheritance graphs,
and the collaboration graphs.
</ul>
\section build_tools Tools used to develop doxygen \section build_tools Tools used to develop doxygen
Doxygen was developed and tested under Linux using the following Doxygen was developed and tested under Linux using the following
open-source tools: open-source tools:
<ul> <ul>
<li>GCC version 2.95.3 <li>GCC version 3.3.1
<li>GNU flex version 2.5.4 <li>GNU flex version 2.5.4
<li>GNU bison version 1.35 <li>GNU bison version 1.75
<li>GNU make version 3.79.1 <li>GNU make version 3.80
<li>Perl version 5.005_03 <li>Perl version 5.8.1
<li>VIM version 5.8 <li>VIM version 6.2
<li>Mozilla 1.0 <li>Mozilla 1.0
<li>Troll Tech's tmake version 1.3 (included in the distribution) <li>Troll Tech's tmake version 1.3 (included in the distribution)
<li>teTeX version 1.0 <li>teTeX version 1.0
......
...@@ -23,7 +23,7 @@ text fragments, generated by doxygen, can be produced in languages other ...@@ -23,7 +23,7 @@ text fragments, generated by doxygen, can be produced in languages other
than English (the default). The output language is chosen through the than English (the default). The output language is chosen through the
configuration file (with default name and known as Doxyfile). configuration file (with default name and known as Doxyfile).
Currently (version 1.3.9), 30 languages Currently (version 1.3.9.1), 30 languages
are supported (sorted alphabetically): are supported (sorted alphabetically):
Afrikaans, Brazilian Portuguese, Catalan, Chinese, Chinese Afrikaans, Brazilian Portuguese, Catalan, Chinese, Chinese
Traditional, Croatian, Czech, Danish, Dutch, English, Finnish, French, Traditional, Croatian, Czech, Danish, Dutch, English, Finnish, French,
...@@ -210,7 +210,7 @@ when the translator was updated. ...@@ -210,7 +210,7 @@ when the translator was updated.
<td>Serbian</td> <td>Serbian</td>
<td>Dejan Milosavljevic</td> <td>Dejan Milosavljevic</td>
<td>dmilos at email dot com</td> <td>dmilos at email dot com</td>
<td>1.3.8</td> <td>up-to-date</td>
</tr> </tr>
<tr bgcolor="#ffffff"> <tr bgcolor="#ffffff">
<td>Slovak</td> <td>Slovak</td>
...@@ -318,7 +318,7 @@ when the translator was updated. ...@@ -318,7 +318,7 @@ when the translator was updated.
\hline \hline
Russian & Alexandr Chelpanov & {\tt\tiny cav@cryptopro.ru} & up-to-date \\ Russian & Alexandr Chelpanov & {\tt\tiny cav@cryptopro.ru} & up-to-date \\
\hline \hline
Serbian & Dejan Milosavljevic & {\tt\tiny dmilos@email.com} & 1.3.8 \\ Serbian & Dejan Milosavljevic & {\tt\tiny dmilos@email.com} & up-to-date \\
\hline \hline
Slovak & Stanislav Kudl\'{a}\v{c} & {\tt\tiny skudlac@pobox.sk} & 1.2.18 \\ Slovak & Stanislav Kudl\'{a}\v{c} & {\tt\tiny skudlac@pobox.sk} & 1.2.18 \\
\hline \hline
......
...@@ -74,8 +74,30 @@ and specify the macro definitions after ...@@ -74,8 +74,30 @@ and specify the macro definitions after
the \ref cfg_predefined "PREDEFINED" or the \ref cfg_predefined "PREDEFINED" or
\ref cfg_expand_as_defined "EXPAND_AS_DEFINED" tag. \ref cfg_expand_as_defined "EXPAND_AS_DEFINED" tag.
As an example, suppose you have the following obfuscated code fragment A typically example where some help from the preprocessor is needed is
of an abstract base class called \c IUnknown: when dealing with Microsoft's __declspec language extension. Here is an
example function.
\verbatim
extern "C" void __declspec(dllexport) ErrorMsg( String aMessage,...);
\endverbatim
When nothing is done, doxygen will be confused and see __declspec as
some sort of function. To help doxygen one typically uses the following
preprocessor settings:
\verbatim
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = __declspec(x)=
\endverbatim
This will make sure the __declspec(dllexport) is removed before doxygen
parses the source code.
For a more complex example, suppose you have the following obfuscated
code fragment of an abstract base class called \c IUnknown:
\verbatim \verbatim
/*! A reference to an IID */ /*! A reference to an IID */
......
(1.3.9) (1.3.9.1)
Doxygen supports the following 30 languages (sorted alphabetically): Doxygen supports the following 30 languages (sorted alphabetically):
...@@ -8,7 +8,7 @@ German, Greek, Hungarian, Italian, Japanese (+En), Korean (+En), ...@@ -8,7 +8,7 @@ German, Greek, Hungarian, Italian, Japanese (+En), Korean (+En),
Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, Serbian, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, Serbian,
Slovak, Slovene, Spanish, Swedish, and Ukrainian. Slovak, Slovene, Spanish, Swedish, and Ukrainian.
Of them, 13 translators are up-to-date, 17 translators are based on Of them, 14 translators are up-to-date, 16 translators are based on
some adapter class, and 2 are English based. some adapter class, and 2 are English based.
---------------------------------------------------------------------- ----------------------------------------------------------------------
...@@ -29,6 +29,7 @@ still may be some details listed even for them: ...@@ -29,6 +29,7 @@ still may be some details listed even for them:
TranslatorItalian TranslatorItalian
TranslatorPolish TranslatorPolish
TranslatorRussian TranslatorRussian
TranslatorSerbian
TranslatorSwedish TranslatorSwedish
---------------------------------------------------------------------- ----------------------------------------------------------------------
...@@ -42,7 +43,6 @@ must be implemented to become up-to-date: ...@@ -42,7 +43,6 @@ must be implemented to become up-to-date:
TranslatorDanish 1.3.9 6 methods to implement TranslatorDanish 1.3.9 6 methods to implement
TranslatorAfrikaans 1.3.9 6 methods to implement TranslatorAfrikaans 1.3.9 6 methods to implement
TranslatorSpanish 1.3.8 7 methods to implement TranslatorSpanish 1.3.8 7 methods to implement
TranslatorSerbian 1.3.8 7 methods to implement
TranslatorLithuanian 1.3.8 7 methods to implement TranslatorLithuanian 1.3.8 7 methods to implement
TranslatorKorean 1.3.8 7 methods to implement TranslatorKorean 1.3.8 7 methods to implement
TranslatorChinesetraditional 1.3.8 7 methods to implement TranslatorChinesetraditional 1.3.8 7 methods to implement
...@@ -452,22 +452,6 @@ TranslatorRomanian (TranslatorAdapter_1_2_16) 22 methods to implement ...@@ -452,22 +452,6 @@ TranslatorRomanian (TranslatorAdapter_1_2_16) 22 methods to implement
virtual QCString trRTFTableOfContents() virtual QCString trRTFTableOfContents()
TranslatorSerbian (TranslatorAdapter_1_3_8) 7 methods to implement
-----------------
Implements 194 of the required methods.
Missing methods (should be implemented):
virtual QCString trDirIndex()
virtual QCString trDirDocumentation()
virtual QCString trDirectories()
virtual QCString trDirDescription()
virtual QCString trSourceFile(QCString & filename)
virtual QCString trDirReference(const char * dirName)
virtual QCString trDir(bool first_capital, bool singular)
TranslatorSlovak (TranslatorAdapter_1_2_18) 20 methods to implement TranslatorSlovak (TranslatorAdapter_1_2_18) 20 methods to implement
---------------- ----------------
......
Summary: A documentation system for C/C++. Summary: A documentation system for C/C++.
Name: doxygen Name: doxygen
Version: 1.3.9.1 Version: 1.3.9.1_20041114
Release: 1 Release: 1
Epoch: 1 Epoch: 1
Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz
......
...@@ -20,7 +20,8 @@ ...@@ -20,7 +20,8 @@
class BufStr; class BufStr;
extern void convertCppComments(BufStr *inBuf,BufStr *outBuf); extern void convertCppComments(BufStr *inBuf,BufStr *outBuf,
const char *fileName);
#endif #endif
...@@ -22,19 +22,36 @@ ...@@ -22,19 +22,36 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <qstack.h>
#include <qregexp.h>
#include "bufstr.h" #include "bufstr.h"
#include "debug.h" #include "debug.h"
#include "message.h" #include "message.h"
#include "config.h" #include "config.h"
#include "doxygen.h" #include "doxygen.h"
static BufStr *g_inBuf; struct CondCtx
static BufStr *g_outBuf; {
CondCtx(int line,QCString id,bool b)
: lineNr(line),sectionId(id), skip(b) {}
int lineNr;
QCString sectionId;
bool skip;
};
static BufStr * g_inBuf;
static BufStr * g_outBuf;
static int g_inBufPos; static int g_inBufPos;
static int g_col; static int g_col;
static int g_blockHeadCol; static int g_blockHeadCol;
static bool g_mlBrief; static bool g_mlBrief;
static int g_readLineCtx; static int g_readLineCtx;
static bool g_skip;
static QCString g_fileName;
static int g_lineNr;
static int g_condCtx;
static QStack<CondCtx> g_condStack;
static void replaceCommentMarker(const char *s,int len) static void replaceCommentMarker(const char *s,int len)
{ {
...@@ -44,6 +61,7 @@ static void replaceCommentMarker(const char *s,int len) ...@@ -44,6 +61,7 @@ static void replaceCommentMarker(const char *s,int len)
while ((c=*p) && (c==' ' || c=='\t' || c=='\n')) while ((c=*p) && (c==' ' || c=='\t' || c=='\n'))
{ {
g_outBuf->addChar(c); g_outBuf->addChar(c);
g_lineNr += c=='\n';
p++; p++;
} }
// replace start of comment marker by spaces // replace start of comment marker by spaces
...@@ -82,20 +100,115 @@ static inline int computeIndent(const char *s) ...@@ -82,20 +100,115 @@ static inline int computeIndent(const char *s)
static inline void copyToOutput(const char *s,int len) static inline void copyToOutput(const char *s,int len)
{ {
g_outBuf->addArray(s,len);
int i; int i;
if (g_skip) // only add newlines.
{
for (i=0;i<len;i++)
{
if (s[i]=='\n')
{
g_outBuf->addChar('\n');
g_lineNr++;
}
}
}
else
{
g_outBuf->addArray(s,len);
static int tabSize=Config_getInt("TAB_SIZE"); static int tabSize=Config_getInt("TAB_SIZE");
for (i=0;i<len;i++) for (i=0;i<len;i++)
{ {
switch (s[i]) switch (s[i])
{ {
case '\n': g_col=0; break; case '\n': g_col=0; g_lineNr++; break;
case '\t': g_col+=tabSize-(g_col%tabSize); break; case '\t': g_col+=tabSize-(g_col%tabSize); break;
default: g_col++; break; default: g_col++; break;
} }
} }
}
}
static void startCondSection(const char *sectId)
{
g_condStack.push(new CondCtx(g_lineNr,sectId,g_skip));
if (Config_getList("ENABLED_SECTIONS").find(sectId)!=-1)
{
//printf("*** Section is enabled!\n");
}
else
{
//printf("*** Section is disabled!\n");
g_skip=TRUE;
}
}
static void endCondSection()
{
if (g_condStack.isEmpty())
{
warn(g_fileName,g_lineNr,"Found \\endcond command without matching \\cond");
g_skip=FALSE;
}
else
{
CondCtx *ctx = g_condStack.pop();
g_skip=ctx->skip;
}
}
/** remove and executes \\cond and \\endcond commands in \a s */
static QCString handleCondCmdInAliases(const QCString &s)
{
QCString result;
//printf("handleCondCmdInAliases(%s)\n",s.data());
static QRegExp cmdPat("[\\\\@][a-z_A-Z][a-z_A-Z0-9]*");
int p=0,i,l;
while ((i=cmdPat.match(s,p,&l))!=-1)
{
result+=s.mid(p,i-p);
QCString cmd = s.mid(i+1,l-1);
//printf("Found command %s\n",cmd.data());
if (cmd=="cond")
{
int sp=i+l,ep;
const char *arg=s.data()+sp;
char c;
// skip spaces
while ((c=*arg) && (c==' ' || c=='\t')) arg++,sp++;
// read argument
if (*arg=='\n') // no arg
{
startCondSection(" ");
ep=sp;
}
else // get argument
{
while ((c=*arg) && isId(c)) arg++,ep++;
if (ep>sp)
{
QCString id = s.mid(sp,ep-sp);
//printf("Found conditional section id %s\n",id.data());
startCondSection(id);
}
}
p=ep;
}
else if (cmd=="endcond")
{
endCondSection();
p=i+l;
}
else
{
result+=s.mid(i,l);
p=i+l;
}
}
result+=s.right(s.length()-p);
return result;
} }
#undef YY_INPUT #undef YY_INPUT
#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
...@@ -122,6 +235,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) ...@@ -122,6 +235,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
%x CComment %x CComment
%x Verbatim %x Verbatim
%x ReadLine %x ReadLine
%x CondLine
%% %%
...@@ -213,17 +327,6 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) ...@@ -213,17 +327,6 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
copyToOutput(yytext,yyleng); copyToOutput(yytext,yyleng);
BEGIN(Scan); BEGIN(Scan);
} }
<CComment>[\\@][a-z_A-Z][a-z_A-Z0-9]* { // expand alias
QCString *pValue=Doxygen::aliasDict[yytext+1];
if (pValue)
{
copyToOutput(pValue->data(),pValue->length());
}
else
{
copyToOutput(yytext,yyleng);
}
}
<CComment>. { <CComment>. {
copyToOutput(yytext,yyleng); copyToOutput(yytext,yyleng);
} }
...@@ -276,11 +379,47 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) ...@@ -276,11 +379,47 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
copyToOutput(yytext,yyleng); copyToOutput(yytext,yyleng);
BEGIN(g_readLineCtx); BEGIN(g_readLineCtx);
} }
<ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9]* { // expand alias <CComment,ReadLine>("\\\\"|"@@")[a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command
copyToOutput(yytext,yyleng);
}
<CComment,ReadLine>[\\@]"cond"[ \t]+ { // conditional section
g_condCtx = YY_START;
BEGIN(CondLine);
}
<CComment,ReadLine>[\\@]"endcond"/[^a-z_A-Z0-9] { // end of conditional section
bool oldSkip=g_skip;
endCondSection();
if (YY_START==CComment && oldSkip && !g_skip)
{
//printf("** Adding start of comment!\n");
g_outBuf->addChar('/');
g_outBuf->addChar('*');
}
}
<CondLine>[a-z_A-Z][a-z_A-Z0-9.\-]* {
bool oldSkip=g_skip;
startCondSection(yytext);
if (g_condCtx==CComment && !oldSkip && g_skip)
{
//printf("** Adding terminator for comment!\n");
g_outBuf->addChar('*');
g_outBuf->addChar('/');
}
BEGIN(g_condCtx);
}
<CondLine>[ \t]*
<CComment,ReadLine>[\\@]"cond"[ \t]*\n |
<CondLine>. { // forgot section id?
startCondSection(" "); // fake section id causing the section to be hidden unconditionally
if (*yytext=='\n') g_lineNr++;
if (YY_START==CondLine) BEGIN(g_condCtx);
}
<CComment,ReadLine>[\\@][a-z_A-Z][a-z_A-Z0-9]* { // expand alias
QCString *pValue=Doxygen::aliasDict[yytext+1]; QCString *pValue=Doxygen::aliasDict[yytext+1];
if (pValue) if (pValue)
{ {
copyToOutput(pValue->data(),pValue->length()); QCString val = handleCondCmdInAliases(*pValue);
copyToOutput(val.data(),val.length());
} }
else else
{ {
...@@ -320,16 +459,28 @@ void replaceComment(int offset) ...@@ -320,16 +459,28 @@ void replaceComment(int offset)
* -# It converts multi-line C++ style comment blocks (that are aligned) * -# It converts multi-line C++ style comment blocks (that are aligned)
* to C style comment blocks (if MULTILINE_CPP_IS_BRIEF is set to NO). * to C style comment blocks (if MULTILINE_CPP_IS_BRIEF is set to NO).
* -# It replaces aliases with their definition (see ALIASES) * -# It replaces aliases with their definition (see ALIASES)
* -# It handles conditional sections (\cond...\endcond blocks)
*/ */
void convertCppComments(BufStr *inBuf,BufStr *outBuf) void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName)
{ {
g_inBuf = inBuf; g_inBuf = inBuf;
g_outBuf = outBuf; g_outBuf = outBuf;
g_inBufPos = 0; g_inBufPos = 0;
g_col = 0; g_col = 0;
g_mlBrief = Config_getBool("MULTILINE_CPP_IS_BRIEF"); g_mlBrief = Config_getBool("MULTILINE_CPP_IS_BRIEF");
g_skip = FALSE;
g_fileName = fileName;
g_lineNr = 0;
g_condStack.clear();
g_condStack.setAutoDelete(TRUE);
BEGIN(Scan); BEGIN(Scan);
yylex(); yylex();
while (!g_condStack.isEmpty())
{
CondCtx *ctx = g_condStack.pop();
warn(g_fileName,ctx->lineNr,"Conditional section with %s does not have "
"a corresponding \\endcond command within this file.",ctx->sectionId.data());
}
if (Debug::isFlagSet(Debug::CommentCnv)) if (Debug::isFlagSet(Debug::CommentCnv))
{ {
msg("-------------\n%s\n-------------\n",g_outBuf->data()); msg("-------------\n%s\n-------------\n",g_outBuf->data());
......
...@@ -2697,6 +2697,15 @@ void Config::create() ...@@ -2697,6 +2697,15 @@ void Config::create()
TRUE TRUE
); );
cb->addDependency("HAVE_DOT"); cb->addDependency("HAVE_DOT");
cb = addBool(
"DIRECTORY_GRAPH",
"If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES \n"
"then doxygen will show the dependencies a directory has on other directories \n"
"in a graphical way. The dependency relations are determined by the #include\n"
"relations between the files in the directories.\n",
TRUE
);
cb->addDependency("HAVE_DOT");
ce = addEnum( ce = addEnum(
"DOT_IMAGE_FORMAT", "DOT_IMAGE_FORMAT",
"The DOT_IMAGE_FORMAT tag can be used to set the image format of the images \n" "The DOT_IMAGE_FORMAT tag can be used to set the image format of the images \n"
......
...@@ -57,6 +57,8 @@ static int labelToEnumValue(const char *l) ...@@ -57,6 +57,8 @@ static int labelToEnumValue(const char *l)
return Debug::PrintTree; return Debug::PrintTree;
else if (label=="time") else if (label=="time")
return Debug::Time; return Debug::Time;
else if (label=="extcmd")
return Debug::ExtCmd;
else else
return 0; return 0;
} }
......
...@@ -31,7 +31,8 @@ class Debug ...@@ -31,7 +31,8 @@ class Debug
CommentCnv = 0x00000020, CommentCnv = 0x00000020,
Validate = 0x00000040, Validate = 0x00000040,
PrintTree = 0x00000080, PrintTree = 0x00000080,
Time = 0x00000100 Time = 0x00000100,
ExtCmd = 0x00000200
}; };
static void print(DebugMask mask,int prio,const char *fmt,...); static void print(DebugMask mask,int prio,const char *fmt,...);
static void setFlag(const char *label); static void setFlag(const char *label);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "outputlist.h" #include "outputlist.h"
#include "language.h" #include "language.h"
#include "message.h" #include "message.h"
#include "dot.h"
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// method implementation // method implementation
...@@ -27,7 +28,6 @@ DirDef::DirDef(const char *path) : Definition(path,1,path) ...@@ -27,7 +28,6 @@ DirDef::DirDef(const char *path) : Definition(path,1,path)
m_shortName = m_shortName.mid(pi+1); m_shortName = m_shortName.mid(pi+1);
} }
m_subdirs.setAutoDelete(TRUE);
m_fileList = new FileList; m_fileList = new FileList;
m_classSDict = new ClassSDict(17); m_classSDict = new ClassSDict(17);
m_usedDirs = new QDict<UsedDir>(257); m_usedDirs = new QDict<UsedDir>(257);
...@@ -141,6 +141,21 @@ void DirDef::writeDocumentation(OutputList &ol) ...@@ -141,6 +141,21 @@ void DirDef::writeDocumentation(OutputList &ol)
Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl; Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
} }
// write graph dependency graph
if (Config_getBool("DIRECTORY_GRAPH") && Config_getBool("HAVE_DOT"))
{
DotDirDeps dirDep(this);
if (!dirDep.isTrivial())
{
msg("Generating dependency graph for directory %s\n",displayName().data());
ol.disable(OutputGenerator::Man);
ol.newParagraph();
ol.startDirDepGraph();
//TODO: ol.parseText(theTranslator->trDirDepGraph());
ol.endDirDepGraph(dirDep);
ol.enableAll();
}
}
ol.startMemberSections(); ol.startMemberSections();
// write subdir list // write subdir list
...@@ -154,7 +169,7 @@ void DirDef::writeDocumentation(OutputList &ol) ...@@ -154,7 +169,7 @@ void DirDef::writeDocumentation(OutputList &ol)
while (dd) while (dd)
{ {
ol.startMemberItem(0); ol.startMemberItem(0);
ol.parseText(theTranslator->trDir(FALSE,TRUE)); ol.parseText(theTranslator->trDir(FALSE,TRUE)+" ");
ol.insertMemberAlign(); ol.insertMemberAlign();
ol.writeObjectLink(dd->getReference(),dd->getOutputFileBase(),0,dd->shortName()); ol.writeObjectLink(dd->getReference(),dd->getOutputFileBase(),0,dd->shortName());
ol.endMemberItem(); ol.endMemberItem();
...@@ -232,13 +247,11 @@ void DirDef::writeDocumentation(OutputList &ol) ...@@ -232,13 +247,11 @@ void DirDef::writeDocumentation(OutputList &ol)
ol.popGeneratorState(); ol.popGeneratorState();
} }
void DirDef::writePathFragment(OutputList &ol) void DirDef::writePathFragment(OutputList &ol) const
{ {
if (getOuterScope()!=Doxygen::globalScope && if (m_parent)
getOuterScope()->definitionType()==Definition::TypeDir)
{ {
//printf("getOuterScope %s\n",getOuterScope()->name().data()); m_parent->writePathFragment(ol);
((DirDef*)getOuterScope())->writePathFragment(ol);
ol.writeString("&nbsp;/&nbsp;"); ol.writeString("&nbsp;/&nbsp;");
} }
ol.writeObjectLink(getReference(),getOutputFileBase(),0,shortName()); ol.writeObjectLink(getReference(),getOutputFileBase(),0,shortName());
...@@ -276,7 +289,8 @@ void DirDef::setLevel() ...@@ -276,7 +289,8 @@ void DirDef::setLevel()
/** Add as "uses" dependency between \a this dir and \a dir, /** Add as "uses" dependency between \a this dir and \a dir,
* that was caused by a dependency on file \a fd. * that was caused by a dependency on file \a fd.
*/ */
void DirDef::addUsesDependency(DirDef *dir,FileDef *fd,bool inherited) void DirDef::addUsesDependency(DirDef *dir,FileDef *srcFd,
FileDef *dstFd,bool inherited)
{ {
if (this==dir) return; // do not add self-dependencies if (this==dir) return; // do not add self-dependencies
//printf(" > add dependency %s->%s due to %s\n",shortName().data(), //printf(" > add dependency %s->%s due to %s\n",shortName().data(),
...@@ -287,11 +301,12 @@ void DirDef::addUsesDependency(DirDef *dir,FileDef *fd,bool inherited) ...@@ -287,11 +301,12 @@ void DirDef::addUsesDependency(DirDef *dir,FileDef *fd,bool inherited)
UsedDir *usedDir = m_usedDirs->find(dir->getOutputFileBase()); UsedDir *usedDir = m_usedDirs->find(dir->getOutputFileBase());
if (usedDir) // dir dependency already present if (usedDir) // dir dependency already present
{ {
FileDef *usedFd = usedDir->findFile(fd->getOutputFileBase()); FilePair *usedPair = usedDir->findFilePair(
if (usedFd==0) // new file dependency srcFd->getOutputFileBase()+dstFd->getOutputFileBase());
if (usedPair==0) // new file dependency
{ {
//printf(" => new file\n"); //printf(" => new file\n");
usedDir->addFile(fd); usedDir->addFileDep(srcFd,dstFd);
added=TRUE; added=TRUE;
} }
else else
...@@ -303,19 +318,19 @@ void DirDef::addUsesDependency(DirDef *dir,FileDef *fd,bool inherited) ...@@ -303,19 +318,19 @@ void DirDef::addUsesDependency(DirDef *dir,FileDef *fd,bool inherited)
{ {
//printf(" => new file\n"); //printf(" => new file\n");
usedDir = new UsedDir(dir,inherited); usedDir = new UsedDir(dir,inherited);
usedDir->addFile(fd); usedDir->addFileDep(srcFd,dstFd);
m_usedDirs->insert(dir->getOutputFileBase(),usedDir); m_usedDirs->insert(dir->getOutputFileBase(),usedDir);
added=TRUE; added=TRUE;
} }
if (added && dir->parent()) if (added && dir->parent())
{ {
// add relation to parent of used dir // add relation to parent of used dir
addUsesDependency(dir->parent(),fd,inherited); addUsesDependency(dir->parent(),srcFd,dstFd,inherited);
} }
if (parent()) if (parent())
{ {
// add relation for the parent of this dir as well // add relation for the parent of this dir as well
parent()->addUsesDependency(dir,fd,TRUE); parent()->addUsesDependency(dir,srcFd,dstFd,TRUE);
} }
} }
...@@ -345,7 +360,7 @@ void DirDef::computeDependencies() ...@@ -345,7 +360,7 @@ void DirDef::computeDependencies()
if (usedDir) if (usedDir)
{ {
// add dependency: thisDir->usedDir // add dependency: thisDir->usedDir
addUsesDependency(usedDir,ii->fileDef,FALSE); addUsesDependency(usedDir,fd,ii->fileDef,FALSE);
} }
} }
} }
...@@ -364,31 +379,46 @@ bool DirDef::isParentOf(DirDef *dir) const ...@@ -364,31 +379,46 @@ bool DirDef::isParentOf(DirDef *dir) const
return FALSE; return FALSE;
} }
bool DirDef::depGraphIsTrivial() const
{
return FALSE;
}
//----------------------------------------------------------------------
int FilePairDict::compareItems(GCI item1,GCI item2)
{
FilePair *left = (FilePair*)item1;
FilePair *right = (FilePair*)item2;
int orderHi = stricmp(left->source()->name(),right->source()->name());
int orderLo = stricmp(left->destination()->name(),right->destination()->name());
return orderHi==0 ? orderLo : orderHi;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
UsedDir::UsedDir(DirDef *dir,bool inherited) : UsedDir::UsedDir(DirDef *dir,bool inherited) :
m_dir(dir), m_inherited(inherited) m_dir(dir), m_filePairs(7), m_inherited(inherited)
{ {
m_filePairs.setAutoDelete(TRUE);
} }
UsedDir::~UsedDir() UsedDir::~UsedDir()
{ {
} }
void UsedDir::addFile(FileDef *fd) void UsedDir::addFileDep(FileDef *srcFd,FileDef *dstFd)
{ {
m_files.insert(fd->getOutputFileBase(),fd); m_filePairs.inSort(srcFd->getOutputFileBase()+dstFd->getOutputFileBase(),
new FilePair(srcFd,dstFd));
} }
FileDef *UsedDir::findFile(const char *name) FilePair *UsedDir::findFilePair(const char *name)
{ {
QCString n=name; QCString n=name;
return n.isEmpty() ? 0 : m_files.find(n); return n.isEmpty() ? 0 : m_filePairs.find(n);
} }
//----------------------------------------------------------------------
// helper functions
DirDef *DirDef::createNewDir(const char *path) DirDef *DirDef::createNewDir(const char *path)
{ {
ASSERT(path!=0); ASSERT(path!=0);
...@@ -442,13 +472,27 @@ void DirDef::writeDepGraph(QTextStream &t) ...@@ -442,13 +472,27 @@ void DirDef::writeDepGraph(QTextStream &t)
{ {
t << "digraph G {\n"; t << "digraph G {\n";
t << " compound=true\n"; t << " compound=true\n";
t << " node [ fontsize=10, fontname=\"Helvetica\"];\n";
t << " edge [ labelfontsize=9, labelfontname=\"Helvetica\"];\n";
QDict<DirDef> dirsInGraph(257); QDict<DirDef> dirsInGraph(257);
dirsInGraph.insert(getOutputFileBase(),this); dirsInGraph.insert(getOutputFileBase(),this);
if (parent())
{
t << " subgraph cluster" << parent()->getOutputFileBase() << " {\n";
t << " graph [ bgcolor=\"#ddddee\", pencolor=\"black\", label=\""
<< parent()->shortName()
<< "\" fontname=\"Helvetica\", fontsize=10, URL=\"";
t << parent()->getOutputFileBase() << Doxygen::htmlFileExtension;
t << "\"]\n";
}
if (isCluster()) if (isCluster())
{ {
t << " subgraph cluster" << getOutputFileBase() << " {\n"; t << " subgraph cluster" << getOutputFileBase() << " {\n";
t << " graph [ bgcolor=\"#eeeeff\", pencolor=\"black\", label=\"\""
<< " URL=\"" << getOutputFileBase() << Doxygen::htmlFileExtension
<< "\"];\n";
t << " " << getOutputFileBase() << " [shape=plaintext label=\"" t << " " << getOutputFileBase() << " [shape=plaintext label=\""
<< shortName() << "\"];\n"; << shortName() << "\"];\n";
...@@ -461,8 +505,15 @@ void DirDef::writeDepGraph(QTextStream &t) ...@@ -461,8 +505,15 @@ void DirDef::writeDepGraph(QTextStream &t)
<< sdir->shortName() << "\""; << sdir->shortName() << "\"";
if (sdir->isCluster()) if (sdir->isCluster())
{ {
t << " color=\"red\" fillcolor=\"white\" style=\"filled\""; t << " color=\"red\"";
} }
else
{
t << " color=\"black\"";
}
t << " fillcolor=\"white\" style=\"filled\"";
t << " URL=\"" << sdir->getOutputFileBase()
<< Doxygen::htmlFileExtension << "\"";
t << "];\n"; t << "];\n";
dirsInGraph.insert(sdir->getOutputFileBase(),sdir); dirsInGraph.insert(sdir->getOutputFileBase(),sdir);
} }
...@@ -470,7 +521,14 @@ void DirDef::writeDepGraph(QTextStream &t) ...@@ -470,7 +521,14 @@ void DirDef::writeDepGraph(QTextStream &t)
} }
else else
{ {
t << getOutputFileBase() << " [shape=box label=\"" << shortName() << "\"];\n"; t << " " << getOutputFileBase() << " [shape=box, label=\""
<< shortName() << "\", style=\"filled\", fillcolor=\"#eeeeff\","
<< " pencolor=\"black\", URL=\"" << getOutputFileBase()
<< Doxygen::htmlFileExtension << "\"];\n";
}
if (parent())
{
t << " }\n";
} }
// add nodes for other used directories // add nodes for other used directories
...@@ -500,7 +558,8 @@ void DirDef::writeDepGraph(QTextStream &t) ...@@ -500,7 +558,8 @@ void DirDef::writeDepGraph(QTextStream &t)
{ {
t << " color=\"red\" fillcolor=\"white\" style=\"filled\""; t << " color=\"red\" fillcolor=\"white\" style=\"filled\"";
} }
t << "];\n"; t << " URL=\"" << usedDir->getOutputFileBase()
<< Doxygen::htmlFileExtension << "\"];\n";
dirsInGraph.insert(usedDir->getOutputFileBase(),usedDir); dirsInGraph.insert(usedDir->getOutputFileBase(),usedDir);
break; break;
} }
...@@ -523,11 +582,20 @@ void DirDef::writeDepGraph(QTextStream &t) ...@@ -523,11 +582,20 @@ void DirDef::writeDepGraph(QTextStream &t)
!usedDir->isParentOf(dir) && // don't point to own parent !usedDir->isParentOf(dir) && // don't point to own parent
dirsInGraph.find(usedDir->getOutputFileBase())) // only point to nodes that are in the graph dirsInGraph.find(usedDir->getOutputFileBase())) // only point to nodes that are in the graph
{ {
int nrefs = udir->files().count(); QCString relationName;
relationName.sprintf("dir_%06d_%06d",dir->m_dirCount,usedDir->m_dirCount);
if (Doxygen::dirRelations.find(relationName)==0)
{
// new relation
Doxygen::dirRelations.append(relationName,
new DirRelation(relationName,dir,udir));
}
int nrefs = udir->filePairs().count();
t << " " << dir->getOutputFileBase() << "->" t << " " << dir->getOutputFileBase() << "->"
<< usedDir->getOutputFileBase(); << usedDir->getOutputFileBase();
t << " [headlabel=\"" << nrefs << "\" headhref=\"http://www.doxygen.org\"]"; t << " [headlabel=\"" << nrefs << "\", labeldistance=1.5";
t << ";\n"; t << " headhref=\"" << relationName << Doxygen::htmlFileExtension
<< "\"];\n";
} }
} }
} }
...@@ -535,6 +603,85 @@ void DirDef::writeDepGraph(QTextStream &t) ...@@ -535,6 +603,85 @@ void DirDef::writeDepGraph(QTextStream &t)
t << "}\n"; t << "}\n";
} }
//----------------------------------------------------------------------
static void writePartialDirPath(OutputList &ol,const DirDef *root,const DirDef *target)
{
if (target->parent()!=root)
{
writePartialDirPath(ol,root,target->parent());
ol.writeString("&nbsp;/&nbsp;");
}
ol.writeObjectLink(target->getReference(),target->getOutputFileBase(),0,target->shortName());
}
static void writePartialFilePath(OutputList &ol,const DirDef *root,const FileDef *fd)
{
if (fd->getDirDef() && fd->getDirDef()!=root)
{
writePartialDirPath(ol,root,fd->getDirDef());
ol.writeString("&nbsp;/&nbsp;");
}
if (fd->isLinkable())
{
ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,fd->name());
}
else
{
ol.startBold();
ol.docify(fd->name());
ol.endBold();
}
}
void DirRelation::writeDocumentation(OutputList &ol)
{
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
QCString shortTitle=m_src->shortName()+" &rarr; "+
m_dst->dir()->shortName()+" Relation";//theTranslator->trDirRelation(m_shortName);
QCString title=m_src->displayName()+" -> "+
m_dst->dir()->shortName()+" Relation";//theTranslator->trDirRelation(m_dispName);
startFile(ol,getOutputFileBase(),getOutputFileBase(),title);
// write navigation path
m_src->writeNavigationPath(ol);
//startTitle(ol,getOutputFileBase());
// ol.parseText(shortTitle);
//endTitle(ol,getOutputFileBase(),title);
ol.writeString("<h3>"+shortTitle+"</h3>");
ol.writeString("<table class=\"dirtab\">");
ol.writeString("<tr class=\"dirtab\">");
ol.writeString("<th class=\"dirtab\">File in ");
m_src->writePathFragment(ol);
ol.writeString("</th>");
ol.writeString("<th class=\"dirtab\">Includes file in ");
m_dst->dir()->writePathFragment(ol);
ol.writeString("</th>");
ol.writeString("</tr>");
SDict<FilePair>::Iterator fpi(m_dst->filePairs());
FilePair *fp;
for (fpi.toFirst();(fp=fpi.current());++fpi)
{
ol.writeString("<tr class=\"dirtab\">");
ol.writeString("<td class=\"dirtab\">");
writePartialFilePath(ol,m_src,fp->source());
ol.writeString("</td>");
ol.writeString("<td class=\"dirtab\">");
writePartialFilePath(ol,m_dst->dir(),fp->destination());
ol.writeString("</td>");
ol.writeString("</tr>");
}
ol.writeString("</table>");
endFile(ol);
ol.popGeneratorState();
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// external functions // external functions
...@@ -678,5 +825,14 @@ void generateDirDocs(OutputList &ol) ...@@ -678,5 +825,14 @@ void generateDirDocs(OutputList &ol)
{ {
dir->writeDocumentation(ol); dir->writeDocumentation(ol);
} }
if (Config_getBool("DIRECTORY_GRAPH"))
{
SDict<DirRelation>::Iterator rdi(Doxygen::dirRelations);
DirRelation *dr;
for (rdi.toFirst();(dr=rdi.current());++rdi)
{
dr->writeDocumentation(ol);
}
}
} }
...@@ -34,12 +34,14 @@ class QTextStream; ...@@ -34,12 +34,14 @@ class QTextStream;
class DirDef; class DirDef;
/** A list of directories */
class DirList : public QList<DirDef> class DirList : public QList<DirDef>
{ {
public: public:
int compareItems(GCI item1,GCI item2); int compareItems(GCI item1,GCI item2);
}; };
/** A directory */
class DirDef : public Definition class DirDef : public Definition
{ {
public: public:
...@@ -63,23 +65,25 @@ class DirDef : public Definition ...@@ -63,23 +65,25 @@ class DirDef : public Definition
DirDef *parent() const { return m_parent; } DirDef *parent() const { return m_parent; }
const QDict<UsedDir> *usedDirs() const { return m_usedDirs; } const QDict<UsedDir> *usedDirs() const { return m_usedDirs; }
bool isParentOf(DirDef *dir) const; bool isParentOf(DirDef *dir) const;
bool depGraphIsTrivial() const;
// generate output // generate output
void writeDetailedDocumentation(OutputList &ol); void writeDetailedDocumentation(OutputList &ol);
void writeDocumentation(OutputList &ol); void writeDocumentation(OutputList &ol);
void writeNavigationPath(OutputList &ol); void writeNavigationPath(OutputList &ol);
void writeDepGraph(QTextStream &t); void writeDepGraph(QTextStream &t);
void writePathFragment(OutputList &ol) const;
static DirDef *mergeDirectoryInTree(const QCString &path); static DirDef *mergeDirectoryInTree(const QCString &path);
bool visited; bool visited;
private: private:
friend void computeDirDependencies(); friend void computeDirDependencies();
void writePathFragment(OutputList &ol);
void setLevel(); void setLevel();
static DirDef *createNewDir(const char *path); static DirDef *createNewDir(const char *path);
static bool matchPath(const QCString &path,QStrList &l); static bool matchPath(const QCString &path,QStrList &l);
void addUsesDependency(DirDef *usedDir,FileDef *fd,bool inherited); void addUsesDependency(DirDef *usedDir,FileDef *srcFd,
FileDef *dstFd,bool inherited);
void computeDependencies(); void computeDependencies();
DirList m_subdirs; DirList m_subdirs;
...@@ -93,23 +97,59 @@ class DirDef : public Definition ...@@ -93,23 +97,59 @@ class DirDef : public Definition
QDict<UsedDir> *m_usedDirs; QDict<UsedDir> *m_usedDirs;
}; };
class FilePair
{
public:
FilePair(FileDef *src,FileDef *dst) : m_src(src), m_dst(dst) {}
const FileDef *source() const { return m_src; }
const FileDef *destination() const { return m_dst; }
private:
FileDef *m_src;
FileDef *m_dst;
};
class FilePairDict : public SDict<FilePair>
{
public:
FilePairDict(int size) : SDict<FilePair>(size) {}
int compareItems(GCI item1,GCI item2);
};
/** Usage information of a directory . */
class UsedDir class UsedDir
{ {
public: public:
UsedDir(DirDef *dir,bool inherited); UsedDir(DirDef *dir,bool inherited);
virtual ~UsedDir(); virtual ~UsedDir();
void addFile(FileDef *fd); void addFileDep(FileDef *srcFd,FileDef *dstFd);
FileDef *findFile(const char *name); FilePair *findFilePair(const char *name);
const QDict<FileDef> &files() const { return m_files; } const FilePairDict &filePairs() const { return m_filePairs; }
const DirDef *dir() const { return m_dir; } const DirDef *dir() const { return m_dir; }
bool inherited() const { return m_inherited; } bool inherited() const { return m_inherited; }
private: private:
DirDef *m_dir; DirDef *m_dir;
QDict<FileDef> m_files; FilePairDict m_filePairs;
bool m_inherited; bool m_inherited;
}; };
/** A usage relation between two direction. */
class DirRelation
{
public:
DirRelation(const QCString &name,DirDef *src,UsedDir *dst)
: m_name(name), m_src(src), m_dst(dst) {}
DirDef *source() const { return m_src; }
UsedDir *destination() const { return m_dst; }
void writeDocumentation(OutputList &ol);
QCString getOutputFileBase() const { return m_name; }
private:
QCString m_name;
DirDef *m_src;
UsedDir *m_dst;
};
inline int DirList::compareItems(GCI item1,GCI item2) inline int DirList::compareItems(GCI item1,GCI item2)
{ {
return stricmp(((DirDef *)item1)->shortName(),((DirDef *)item2)->shortName()); return stricmp(((DirDef *)item1)->shortName(),((DirDef *)item2)->shortName());
......
...@@ -4367,7 +4367,7 @@ reparsetoken: ...@@ -4367,7 +4367,7 @@ reparsetoken:
k!=DocNode::Kind_SimpleSect && k!=DocNode::Kind_SimpleSect &&
k!=DocNode::Kind_AutoList && k!=DocNode::Kind_AutoList &&
k!=DocNode::Kind_SimpleList && k!=DocNode::Kind_SimpleList &&
k!=DocNode::Kind_Verbatim && /*k!=DocNode::Kind_Verbatim &&*/
k!=DocNode::Kind_HtmlHeader && k!=DocNode::Kind_HtmlHeader &&
k!=DocNode::Kind_ParamSect && k!=DocNode::Kind_ParamSect &&
k!=DocNode::Kind_XRefItem k!=DocNode::Kind_XRefItem
...@@ -4518,7 +4518,7 @@ reparsetoken: ...@@ -4518,7 +4518,7 @@ reparsetoken:
} }
else if (retval==RetVal_OK) else if (retval==RetVal_OK)
{ {
// the command ended normally, keep scanner for new tokens. // the command ended normally, keep scanning for new tokens.
retval = 0; retval = 0;
} }
else if (retval==TK_LISTITEM || retval==TK_ENDLIST || retval==TK_WORD) else if (retval==TK_LISTITEM || retval==TK_ENDLIST || retval==TK_WORD)
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "scanner.h" #include "scanner.h"
#include "defargs.h" #include "defargs.h"
#include "docparser.h" #include "docparser.h"
#include "debug.h"
#include <qdir.h> #include <qdir.h>
#include <qfile.h> #include <qfile.h>
...@@ -1927,7 +1928,7 @@ DotInclDepGraph::DotInclDepGraph(FileDef *fd,int maxRecursionDepth,bool inverse) ...@@ -1927,7 +1928,7 @@ DotInclDepGraph::DotInclDepGraph(FileDef *fd,int maxRecursionDepth,bool inverse)
m_diskName = fd->getFileBase().copy(); m_diskName = fd->getFileBase().copy();
QCString tmp_url=fd->getReference()+"$"+fd->getFileBase(); QCString tmp_url=fd->getReference()+"$"+fd->getFileBase();
m_startNode = new DotNode(m_curNodeNumber++, m_startNode = new DotNode(m_curNodeNumber++,
fd->name(), fd->docName(),
tmp_url.data(), tmp_url.data(),
0, // distance 0, // distance
TRUE // root node TRUE // root node
...@@ -1965,7 +1966,7 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out, ...@@ -1965,7 +1966,7 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
err("Error: Output dir %s does not exist!\n",path); exit(1); err("Error: Output dir %s does not exist!\n",path); exit(1);
} }
QCString oldDir = convertToQCString(QDir::currentDirPath()); QCString oldDir = convertToQCString(QDir::currentDirPath());
// go to the output directory (i.e. path) // go to the html output directory (i.e. path)
QDir::setCurrent(d.absPath()); QDir::setCurrent(d.absPath());
QDir thisDir; QDir thisDir;
...@@ -1978,12 +1979,12 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out, ...@@ -1978,12 +1979,12 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT"); QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
QCString md5 = computeMd5Signature(m_startNode, // root QCString md5 = computeMd5Signature(m_startNode, // root
DotNode::Dependency, // gt DotNode::CallGraph, // gt
format, // format format, // format
FALSE, // lrRank TRUE, // lrRank
FALSE, // renderParents FALSE, // renderParents
QMIN(m_recDepth,m_maxDistance), // maxDist QMIN(m_recDepth,m_maxDistance), // maxDist
!m_inverse // backArrows FALSE // backArrows
); );
if (checkAndUpdateMd5Signature(baseName,md5) || if (checkAndUpdateMd5Signature(baseName,md5) ||
!QFileInfo(baseName+".map").exists() !QFileInfo(baseName+".map").exists()
...@@ -1993,11 +1994,11 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out, ...@@ -1993,11 +1994,11 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
QMIN(m_recDepth,m_maxDistance), // maxDist QMIN(m_recDepth,m_maxDistance), // maxDist
baseName, // baseName baseName, // baseName
thisDir, // thisDir thisDir, // thisDir
DotNode::Dependency, // gt DotNode::CallGraph, // gt
format, // format format, // format
FALSE, // lrRank TRUE, // lrRank
FALSE, // renderParents FALSE, // renderParents
!m_inverse // backArrows FALSE // backArrows
); );
if (format==BITMAP) if (format==BITMAP)
{ {
...@@ -2045,8 +2046,6 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out, ...@@ -2045,8 +2046,6 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
} }
} }
} }
if (Config_getBool("DOT_CLEANUP")) thisDir.remove(baseName+".dot");
} }
if (format==BITMAP && generateImageMap) if (format==BITMAP && generateImageMap)
...@@ -2054,7 +2053,6 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out, ...@@ -2054,7 +2053,6 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
out << "<p><center><img src=\"" << relPath << baseName << "." out << "<p><center><img src=\"" << relPath << baseName << "."
<< imgExt << "\" border=\"0\" usemap=\"#" << imgExt << "\" border=\"0\" usemap=\"#"
<< mapName << "_map\" alt=\""; << mapName << "_map\" alt=\"";
if (m_inverse) out << "Included by dependency graph"; else out << "Include dependency graph";
out << "\">"; out << "\">";
out << "</center>" << endl; out << "</center>" << endl;
QString tmpstr; QString tmpstr;
...@@ -2066,6 +2064,7 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out, ...@@ -2066,6 +2064,7 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
out << tmpstr; out << tmpstr;
out << "</map>" << endl; out << "</map>" << endl;
} }
//thisDir.remove(baseName+".map");
} }
else if (format==EPS) else if (format==EPS)
{ {
...@@ -2076,7 +2075,6 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out, ...@@ -2076,7 +2075,6 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
QDir::setCurrent(oldDir); QDir::setCurrent(oldDir);
return baseName; return baseName;
} }
int maxWidth = 420; /* approx. page width in points */ int maxWidth = 420; /* approx. page width in points */
out << "\\begin{figure}[H]\n" out << "\\begin{figure}[H]\n"
...@@ -2088,6 +2086,8 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out, ...@@ -2088,6 +2086,8 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
"\\end{figure}\n"; "\\end{figure}\n";
} }
if (Config_getBool("DOT_CLEANUP")) thisDir.remove(baseName+".dot");
QDir::setCurrent(oldDir); QDir::setCurrent(oldDir);
return baseName; return baseName;
} }
...@@ -2338,7 +2338,7 @@ bool DotCallGraph::isTrivial() const ...@@ -2338,7 +2338,7 @@ bool DotCallGraph::isTrivial() const
//------------------------------------------------------------- //-------------------------------------------------------------
DotDirDeps::DotDirDeps(DirDef *) DotDirDeps::DotDirDeps(DirDef *dir) : m_dir(dir)
{ {
} }
...@@ -2346,6 +2346,142 @@ DotDirDeps::~DotDirDeps() ...@@ -2346,6 +2346,142 @@ DotDirDeps::~DotDirDeps()
{ {
} }
QCString DotDirDeps::writeGraph(QTextStream &out,
GraphOutputFormat format,
const char *path,
const char *relPath,
bool generateImageMap)
{
QDir d(path);
// store the original directory
if (!d.exists())
{
err("Error: Output dir %s does not exist!\n",path); exit(1);
}
QCString oldDir = convertToQCString(QDir::currentDirPath());
// go to the html output directory (i.e. path)
QDir::setCurrent(d.absPath());
QDir thisDir;
QCString baseName=m_dir->getOutputFileBase()+"_dep";
QCString mapName=baseName;
QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
// todo: create check, update md5 checksum
{
QFile f(baseName+".dot");
if (!f.open(IO_WriteOnly))
{
err("Cannot create file %s.dot for writing!\n",baseName.data());
}
QTextStream t(&f);
m_dir->writeDepGraph(t);
f.close();
if (format==BITMAP)
{
// run dot to create a bitmap image
QCString dotArgs(maxCmdLine);
QCString imgName=baseName+"."+imgExt;
dotArgs.sprintf("\"%s.dot\" -T%s -o \"%s\"",
baseName.data(),imgExt.data(),imgName.data());
if (generateImageMap)
{
// run dot also to create an image map
dotArgs+=QCString(maxCmdLine).sprintf(" -Timap -o \"%s.map\"",
baseName.data());
}
if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0)
{
err("Problems running dot. Check your installation!\n");
QDir::setCurrent(oldDir);
return baseName;
}
checkDotResult(imgName);
}
else if (format==EPS)
{
// run dot to create a .eps image
QCString dotArgs(maxCmdLine);
dotArgs.sprintf("-Tps \"%s.dot\" -o \"%s.eps\"",
baseName.data(),baseName.data());
if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0)
{
err("Problems running dot. Check your installation!\n");
QDir::setCurrent(oldDir);
return baseName;
}
if (Config_getBool("USE_PDFLATEX"))
{
QCString epstopdfArgs(maxCmdLine);
epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",
baseName.data(),baseName.data());
if (iSystem("epstopdf",epstopdfArgs,TRUE)!=0)
{
err("Error: Problems running epstopdf. Check your TeX installation!\n");
QDir::setCurrent(oldDir);
return baseName;
}
}
}
}
if (format==BITMAP && generateImageMap)
{
out << "<p><center><img src=\"" << relPath << baseName << "."
<< imgExt << "\" border=\"0\" usemap=\"#"
<< mapName << "_map\" alt=\"";
out << m_dir->displayName();
out << "\">";
out << "</center>" << endl;
QString tmpstr;
QTextOStream tmpout(&tmpstr);
convertMapFile(tmpout,baseName+".map",relPath,TRUE);
if (!tmpstr.isEmpty())
{
out << "<map name=\"" << mapName << "_map\">" << endl;
out << tmpstr;
out << "</map>" << endl;
}
else
{
//printf("Map is empty!\n");
}
//thisDir.remove(baseName+".map");
}
else if (format==EPS)
{
int width,height;
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 */
out << "\\begin{figure}[H]\n"
"\\begin{center}\n"
"\\leavevmode\n"
"\\includegraphics[width=" << QMIN(width/2,maxWidth)
<< "pt]{" << baseName << "}\n"
"\\end{center}\n"
"\\end{figure}\n";
}
if (Config_getBool("DOT_CLEANUP")) thisDir.remove(baseName+".dot");
QDir::setCurrent(oldDir);
return baseName;
}
bool DotDirDeps::isTrivial() const
{
return m_dir->depGraphIsTrivial();
}
//------------------------------------------------------------- //-------------------------------------------------------------
void generateGraphLegend(const char *path) void generateGraphLegend(const char *path)
......
...@@ -207,6 +207,14 @@ class DotDirDeps ...@@ -207,6 +207,14 @@ class DotDirDeps
public: public:
DotDirDeps(DirDef *dir); DotDirDeps(DirDef *dir);
~DotDirDeps(); ~DotDirDeps();
bool isTrivial() const;
QCString writeGraph(QTextStream &out,
GraphOutputFormat format,
const char *path,
const char *relPath,
bool writeImageMap=TRUE);
private:
DirDef *m_dir;
}; };
void generateGraphLegend(const char *path); void generateGraphLegend(const char *path);
......
...@@ -122,6 +122,7 @@ bool Doxygen::outputToWizard=FALSE; ...@@ -122,6 +122,7 @@ bool Doxygen::outputToWizard=FALSE;
QDict<int> * Doxygen::htmlDirMap = 0; QDict<int> * Doxygen::htmlDirMap = 0;
QCache<LookupInfo> Doxygen::lookupCache(20000,20000); QCache<LookupInfo> Doxygen::lookupCache(20000,20000);
DirSDict Doxygen::directories(17); DirSDict Doxygen::directories(17);
SDict<DirRelation> Doxygen::dirRelations(257);
static StringList inputFiles; static StringList inputFiles;
static StringDict excludeNameDict(1009); // sections static StringDict excludeNameDict(1009); // sections
...@@ -4738,6 +4739,7 @@ static void findMember(Entry *root, ...@@ -4738,6 +4739,7 @@ static void findMember(Entry *root,
NamespaceSDict::Iterator nsdi(*nnl); NamespaceSDict::Iterator nsdi(*nnl);
for (nsdi.toFirst();(nnd=nsdi.current());++nsdi) for (nsdi.toFirst();(nnd=nsdi.current());++nsdi)
{ {
Debug::print(Debug::FindMembers,0," adding used namespace %s\n",nnd->qualifiedName().data());
nl->append(nnd->qualifiedName(),nnd); nl->append(nnd->qualifiedName(),nnd);
} }
} }
...@@ -4751,6 +4753,7 @@ static void findMember(Entry *root, ...@@ -4751,6 +4753,7 @@ static void findMember(Entry *root,
NamespaceSDict::Iterator nsdi(*fnl); NamespaceSDict::Iterator nsdi(*fnl);
for (nsdi.toFirst();(fnd=nsdi.current());++nsdi) for (nsdi.toFirst();(fnd=nsdi.current());++nsdi)
{ {
Debug::print(Debug::FindMembers,0," adding used namespace %s\n",fnd->qualifiedName().data());
nl->append(fnd->qualifiedName(),fnd); nl->append(fnd->qualifiedName(),fnd);
} }
} }
...@@ -4766,6 +4769,7 @@ static void findMember(Entry *root, ...@@ -4766,6 +4769,7 @@ static void findMember(Entry *root,
Definition *ncd; Definition *ncd;
for (csdi.toFirst();(ncd=csdi.current());++csdi) for (csdi.toFirst();(ncd=csdi.current());++csdi)
{ {
Debug::print(Debug::FindMembers,0," adding used class %s\n",ncd->qualifiedName().data());
cl->append(ncd->qualifiedName(),ncd); cl->append(ncd->qualifiedName(),ncd);
} }
} }
...@@ -4779,6 +4783,7 @@ static void findMember(Entry *root, ...@@ -4779,6 +4783,7 @@ static void findMember(Entry *root,
Definition *fcd; Definition *fcd;
for (csdi.toFirst();(fcd=csdi.current());++csdi) for (csdi.toFirst();(fcd=csdi.current());++csdi)
{ {
Debug::print(Debug::FindMembers,0," adding used class %s\n",fcd->qualifiedName().data());
cl->append(fcd->qualifiedName(),fcd); cl->append(fcd->qualifiedName(),fcd);
} }
} }
...@@ -7330,10 +7335,7 @@ static void readFiles(BufStr &output) ...@@ -7330,10 +7335,7 @@ static void readFiles(BufStr &output)
bufPtr->addChar('\n'); /* to prevent problems under Windows ? */ bufPtr->addChar('\n'); /* to prevent problems under Windows ? */
//if (!multiLineIsBrief) convertCppComments(&tempBuf,&output,fileName);
//{
convertCppComments(&tempBuf,&output);
//}
s=inputFiles.next(); s=inputFiles.next();
//printf("-------> adding new line\n"); //printf("-------> adding new line\n");
...@@ -7552,6 +7554,126 @@ static void readFormulaRepository() ...@@ -7552,6 +7554,126 @@ static void readFormulaRepository()
} }
} }
//----------------------------------------------------------------------------
static QDict<void> aliasesProcessed;
static QCString expandAliasesRec(const QCString s)
{
QCString result;
static QRegExp cmdPat("[\\\\@][a-z_A-Z][a-z_A-Z0-9]*");
QCString value=s;
int i,p=0,l;
while ((i=cmdPat.match(value,p,&l))!=-1)
{
result+=value.mid(p,i-p);
QCString cmd=value.mid(i+1,l-1);
//printf("Found command '%s'\n",cmd.data());
QCString *aliasText=Doxygen::aliasDict.find(cmd);
if (aliasesProcessed.find(cmd)==0 && aliasText) // expand the alias
{
aliasesProcessed.insert(cmd,(void *)0x8);
result+=expandAliasesRec(*aliasText);
aliasesProcessed.remove(cmd);
}
else // command is not an alias
{
result+=value.mid(i,l);
}
p=i+l;
}
result+=value.right(value.length()-p);
//printf("expandAliases '%s'->'%s'\n",s.data(),result.data());
return result;
}
static void expandAliases()
{
QDictIterator<QCString> adi(Doxygen::aliasDict);
QCString *s;
for (adi.toFirst();(s=adi.current());++adi)
{
aliasesProcessed.clear();
*s = expandAliasesRec(*s);
}
}
//----------------------------------------------------------------------------
static void escapeAliases()
{
QDictIterator<QCString> adi(Doxygen::aliasDict);
QCString *s;
for (adi.toFirst();(s=adi.current());++adi)
{
QCString value=*s,newValue;
int in,p=0;
// for each \n in the alias command value
while ((in=value.find("\\n",p))!=-1)
{
newValue+=value.mid(p,in-p);
// expand \n's except if \n is part of a built-in command.
if (value.mid(in,5)!="\\note" &&
value.mid(in,5)!="\\name" &&
value.mid(in,10)!="\\namespace" &&
value.mid(in,14)!="\\nosubgrouping"
)
{
newValue+="\\_linebr ";
}
else
{
newValue+="\\n";
}
p=in+2;
}
newValue+=value.mid(p,value.length()-p);
*s=newValue;
//printf("Alias %s has value %s\n",adi.currentKey().data(),s->data());
}
}
//----------------------------------------------------------------------------
static void readAliases()
{
// add aliases to a dictionary
Doxygen::aliasDict.setAutoDelete(TRUE);
QStrList &aliasList = Config_getList("ALIASES");
const char *s=aliasList.first();
while (s)
{
if (Doxygen::aliasDict[s]==0)
{
QCString alias=s;
int i=alias.find('=');
if (i>0)
{
QCString name=alias.left(i).stripWhiteSpace();
QCString value=alias.right(alias.length()-i-1);
//printf("Alias: found name=`%s' value=`%s'\n",name.data(),value.data());
if (!name.isEmpty())
{
QCString *dn=Doxygen::aliasDict[name];
if (dn==0) // insert new alias
{
Doxygen::aliasDict.insert(name,new QCString(value));
}
else // overwrite previous alias
{
*dn=value;
}
}
}
}
s=aliasList.next();
}
expandAliases();
escapeAliases();
aliasesProcessed.clear();
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// print the usage of doxygen // print the usage of doxygen
...@@ -7620,6 +7742,8 @@ void initDoxygen() ...@@ -7620,6 +7742,8 @@ void initDoxygen()
Doxygen::memGrpInfoDict.setAutoDelete(TRUE); Doxygen::memGrpInfoDict.setAutoDelete(TRUE);
Doxygen::tagDestinationDict.setAutoDelete(TRUE); Doxygen::tagDestinationDict.setAutoDelete(TRUE);
Doxygen::lookupCache.setAutoDelete(TRUE); Doxygen::lookupCache.setAutoDelete(TRUE);
Doxygen::directories.setAutoDelete(TRUE);
Doxygen::dirRelations.setAutoDelete(TRUE);
} }
void cleanUpDoxygen() void cleanUpDoxygen()
...@@ -8088,60 +8212,8 @@ void parseInput() ...@@ -8088,60 +8212,8 @@ void parseInput()
s=expandAsDefinedList.next(); s=expandAsDefinedList.next();
} }
// add aliases to a dictionary // read aliases and store them in a dictionary
Doxygen::aliasDict.setAutoDelete(TRUE); readAliases();
QStrList &aliasList = Config_getList("ALIASES");
s=aliasList.first();
while (s)
{
if (Doxygen::aliasDict[s]==0)
{
QCString alias=s;
int i=alias.find('=');
if (i>0)
{
QCString name=alias.left(i).stripWhiteSpace();
QCString value=alias.right(alias.length()-i-1);
QCString newValue;
int in,p=0;
// for each \n in the alias command value
while ((in=value.find("\\n",p))!=-1)
{
newValue+=value.mid(p,in-p);
// expand \n's except if \n is part of a built-in command.
if (value.mid(in,5)!="\\note" &&
value.mid(in,5)!="\\name" &&
value.mid(in,10)!="\\namespace" &&
value.mid(in,14)!="\\nosubgrouping"
)
{
newValue+="\n";
}
else
{
newValue+="\\n";
}
p=in+2;
}
newValue+=value.mid(p,value.length()-p);
value=newValue;
//printf("Alias: found name=`%s' value=`%s'\n",name.data(),value.data());
if (!name.isEmpty())
{
QCString *dn=Doxygen::aliasDict[name];
if (dn==0) // insert new alias
{
Doxygen::aliasDict.insert(name,new QCString(value));
}
else // overwrite previous alias
{
*dn=value;
}
}
}
}
s=aliasList.next();
}
/************************************************************************** /**************************************************************************
* Handle Tag Files * * Handle Tag Files *
...@@ -8448,8 +8520,11 @@ void parseInput() ...@@ -8448,8 +8520,11 @@ void parseInput()
msg("Adding todo/test/bug list items...\n"); msg("Adding todo/test/bug list items...\n");
addListReferences(); addListReferences();
if (Config_getBool("SHOW_DIRECTORIES"))
{
msg("Computing dependencies between directories...\n"); msg("Computing dependencies between directories...\n");
computeDirDependencies(); computeDirDependencies();
}
} }
void generateOutput() void generateOutput()
......
...@@ -115,6 +115,7 @@ class Doxygen ...@@ -115,6 +115,7 @@ class Doxygen
static QDict<int> *htmlDirMap; static QDict<int> *htmlDirMap;
static QCache<LookupInfo> lookupCache; static QCache<LookupInfo> lookupCache;
static DirSDict directories; static DirSDict directories;
static SDict<DirRelation> dirRelations;
}; };
void initDoxygen(); void initDoxygen();
......
...@@ -319,8 +319,16 @@ static const char *defaultStyleSheet = ...@@ -319,8 +319,16 @@ static const char *defaultStyleSheet =
"}\n" "}\n"
"a:visited {\n" "a:visited {\n"
" color: #3D2185;\n" " color: #3D2185;\n"
"}\n"
".dirtab { padding: 4px;\n"
" border-collapse: collapse;\n"
" border: 1px solid #b0b0b0;\n"
"}\n"
"TH.dirtab { background: #eeeeff;\n"
" font-weight: bold;\n"
"}\n"; "}\n";
static QCString g_header; static QCString g_header;
static QCString g_footer; static QCString g_footer;
...@@ -1246,6 +1254,15 @@ void HtmlGenerator::endCallGraph(DotCallGraph &g) ...@@ -1246,6 +1254,15 @@ void HtmlGenerator::endCallGraph(DotCallGraph &g)
g.writeGraph(t,BITMAP,dir,relPath); g.writeGraph(t,BITMAP,dir,relPath);
} }
void HtmlGenerator::startDirDepGraph()
{
}
void HtmlGenerator::endDirDepGraph(DotDirDeps &g)
{
g.writeGraph(t,BITMAP,dir,relPath);
}
void HtmlGenerator::writeGraphicalHierarchy(DotGfxHierarchyTable &g) void HtmlGenerator::writeGraphicalHierarchy(DotGfxHierarchyTable &g)
{ {
g.writeGraph(t,dir); g.writeGraph(t,dir);
......
...@@ -192,6 +192,8 @@ class HtmlGenerator : public OutputGenerator ...@@ -192,6 +192,8 @@ class HtmlGenerator : public OutputGenerator
void endInclDepGraph(DotInclDepGraph &g); void endInclDepGraph(DotInclDepGraph &g);
void startCallGraph(); void startCallGraph();
void endCallGraph(DotCallGraph &g); void endCallGraph(DotCallGraph &g);
void startDirDepGraph();
void endDirDepGraph(DotDirDeps &g);
void writeGraphicalHierarchy(DotGfxHierarchyTable &g); void writeGraphicalHierarchy(DotGfxHierarchyTable &g);
void startTextBlock(bool) {} void startTextBlock(bool) {}
......
...@@ -175,6 +175,26 @@ void HtmlHelpIndex::writeFields(QTextStream &t) ...@@ -175,6 +175,26 @@ void HtmlHelpIndex::writeFields(QTextStream &t)
if (level2Started) t << " </UL>" << endl; if (level2Started) t << " </UL>" << endl;
level2Started=FALSE; level2Started=FALSE;
// <Antony>
// Added this code so that an item with only one subitem is written
// without any subitem.
// For example:
// a1, b1 -> will create only a1, not separate subitem for b1
// a2, b2
// a2, b3
QCString nextLevel1;
IndexField* fnext = ++ifli;
if (fnext)
{
nextLevel1 = fnext->name.left(fnext->name.find('?'));
--ifli;
}
if (level1 != nextLevel1)
{
level2 = "";
}
// </Antony>
if (level2.isEmpty()) if (level2.isEmpty())
{ {
t << " <LI><OBJECT type=\"text/sitemap\">"; t << " <LI><OBJECT type=\"text/sitemap\">";
...@@ -189,7 +209,9 @@ void HtmlHelpIndex::writeFields(QTextStream &t) ...@@ -189,7 +209,9 @@ void HtmlHelpIndex::writeFields(QTextStream &t)
if (f->link) if (f->link)
{ {
t << " <LI><OBJECT type=\"text/sitemap\">"; t << " <LI><OBJECT type=\"text/sitemap\">";
t << "<param name=\"Local\" value=\"" << f->url << Doxygen::htmlFileExtension << "\">"; t << "<param name=\"Local\" value=\"" << f->url << Doxygen::htmlFileExtension;
if (!f->anchor.isEmpty()) t << "#" << f->anchor;
t << "\">";
t << "<param name=\"Name\" value=\"" << level1 << "\">" t << "<param name=\"Name\" value=\"" << level1 << "\">"
"</OBJECT>\n"; "</OBJECT>\n";
} }
...@@ -530,6 +552,6 @@ void HtmlHelp::addIndexItem(const char *level1, const char *level2, ...@@ -530,6 +552,6 @@ void HtmlHelp::addIndexItem(const char *level1, const char *level2,
const char *ref, const char *anchor) const char *ref, const char *anchor)
{ {
index->addItem(level1,level2,ref,anchor,TRUE); index->addItem(level1,level2,ref,anchor,TRUE);
index->addItem(level2,level1,ref,anchor,FALSE); index->addItem(level2,level1,ref,anchor,TRUE);
} }
...@@ -1457,6 +1457,15 @@ void LatexGenerator::endCallGraph(DotCallGraph &g) ...@@ -1457,6 +1457,15 @@ void LatexGenerator::endCallGraph(DotCallGraph &g)
g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),relPath); g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),relPath);
} }
void LatexGenerator::startDirDepGraph()
{
}
void LatexGenerator::endDirDepGraph(DotDirDeps &g)
{
g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),relPath);
}
void LatexGenerator::startDescription() void LatexGenerator::startDescription()
{ {
t << "\\begin{description}" << endl; t << "\\begin{description}" << endl;
......
...@@ -185,6 +185,8 @@ class LatexGenerator : public OutputGenerator ...@@ -185,6 +185,8 @@ class LatexGenerator : public OutputGenerator
void endInclDepGraph(DotInclDepGraph &); void endInclDepGraph(DotInclDepGraph &);
void startCallGraph(); void startCallGraph();
void endCallGraph(DotCallGraph &); void endCallGraph(DotCallGraph &);
void startDirDepGraph();
void endDirDepGraph(DotDirDeps &g);
void writeGraphicalHierarchy(DotGfxHierarchyTable &) {} void writeGraphicalHierarchy(DotGfxHierarchyTable &) {}
void startTextBlock(bool) {} void startTextBlock(bool) {}
......
...@@ -231,6 +231,8 @@ class ManGenerator : public OutputGenerator ...@@ -231,6 +231,8 @@ class ManGenerator : public OutputGenerator
void endInclDepGraph(DotInclDepGraph &) {} void endInclDepGraph(DotInclDepGraph &) {}
void startCallGraph() {} void startCallGraph() {}
void endCallGraph(DotCallGraph &) {} void endCallGraph(DotCallGraph &) {}
void startDirDepGraph() {}
void endDirDepGraph(DotDirDeps &) {}
void writeGraphicalHierarchy(DotGfxHierarchyTable &) {} void writeGraphicalHierarchy(DotGfxHierarchyTable &) {}
void startTextBlock(bool) {} void startTextBlock(bool) {}
......
...@@ -30,6 +30,7 @@ class ClassDiagram; ...@@ -30,6 +30,7 @@ class ClassDiagram;
class DotClassGraph; class DotClassGraph;
class DotInclDepGraph; class DotInclDepGraph;
class DotCallGraph; class DotCallGraph;
class DotDirDeps;
class DotGfxHierarchyTable; class DotGfxHierarchyTable;
class DocNode; class DocNode;
class MemberDef; class MemberDef;
...@@ -339,6 +340,8 @@ class OutputGenerator : public BaseOutputDocInterface ...@@ -339,6 +340,8 @@ class OutputGenerator : public BaseOutputDocInterface
virtual void endInclDepGraph(DotInclDepGraph &g) = 0; virtual void endInclDepGraph(DotInclDepGraph &g) = 0;
virtual void startCallGraph() = 0; virtual void startCallGraph() = 0;
virtual void endCallGraph(DotCallGraph &g) = 0; virtual void endCallGraph(DotCallGraph &g) = 0;
virtual void startDirDepGraph() = 0;
virtual void endDirDepGraph(DotDirDeps &g) = 0;
virtual void writeGraphicalHierarchy(DotGfxHierarchyTable &g) = 0; virtual void writeGraphicalHierarchy(DotGfxHierarchyTable &g) = 0;
//virtual void startQuickIndexItem(const char *s,const char *l) = 0; //virtual void startQuickIndexItem(const char *s,const char *l) = 0;
//virtual void endQuickIndexItem() = 0; //virtual void endQuickIndexItem() = 0;
......
...@@ -266,6 +266,7 @@ FORALL1(int a1,a1) ...@@ -266,6 +266,7 @@ FORALL1(int a1,a1)
FORALL1(DotClassGraph &a1,a1) FORALL1(DotClassGraph &a1,a1)
FORALL1(DotInclDepGraph &a1,a1) FORALL1(DotInclDepGraph &a1,a1)
FORALL1(DotCallGraph &a1,a1) FORALL1(DotCallGraph &a1,a1)
FORALL1(DotDirDeps &a1,a1)
FORALL1(DotGfxHierarchyTable &a1,a1) FORALL1(DotGfxHierarchyTable &a1,a1)
FORALL1(SectionTypes a1,a1) FORALL1(SectionTypes a1,a1)
#if defined(HAS_BOOL_TYPE) || defined(Q_HAS_BOOL_TYPE) #if defined(HAS_BOOL_TYPE) || defined(Q_HAS_BOOL_TYPE)
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
class ClassDiagram; class ClassDiagram;
class DotClassGraph; class DotClassGraph;
class DotDirDeps;
class DotInclDepGraph; class DotInclDepGraph;
class DotGfxHierarchyTable; class DotGfxHierarchyTable;
class SectionDict; class SectionDict;
...@@ -322,6 +323,10 @@ class OutputList : public OutputDocInterface ...@@ -322,6 +323,10 @@ class OutputList : public OutputDocInterface
{ forall(&OutputGenerator::startCallGraph); } { forall(&OutputGenerator::startCallGraph); }
void endCallGraph(DotCallGraph &g) void endCallGraph(DotCallGraph &g)
{ forall(&OutputGenerator::endCallGraph,g); } { forall(&OutputGenerator::endCallGraph,g); }
void startDirDepGraph()
{ forall(&OutputGenerator::startDirDepGraph); }
void endDirDepGraph(DotDirDeps &g)
{ forall(&OutputGenerator::endDirDepGraph,g); }
void writeGraphicalHierarchy(DotGfxHierarchyTable &g) void writeGraphicalHierarchy(DotGfxHierarchyTable &g)
{ forall(&OutputGenerator::writeGraphicalHierarchy,g); } { forall(&OutputGenerator::writeGraphicalHierarchy,g); }
void startTextBlock(bool dense=FALSE) void startTextBlock(bool dense=FALSE)
...@@ -387,6 +392,7 @@ class OutputList : public OutputDocInterface ...@@ -387,6 +392,7 @@ class OutputList : public OutputDocInterface
FORALLPROTO1(DotClassGraph &); FORALLPROTO1(DotClassGraph &);
FORALLPROTO1(DotInclDepGraph &); FORALLPROTO1(DotInclDepGraph &);
FORALLPROTO1(DotCallGraph &); FORALLPROTO1(DotCallGraph &);
FORALLPROTO1(DotDirDeps &);
FORALLPROTO1(DotGfxHierarchyTable &); FORALLPROTO1(DotGfxHierarchyTable &);
FORALLPROTO1(SectionTypes); FORALLPROTO1(SectionTypes);
#if defined(HAS_BOOL_TYPE) || defined(Q_HAS_BOOL_TYPE) #if defined(HAS_BOOL_TYPE) || defined(Q_HAS_BOOL_TYPE)
......
...@@ -1079,7 +1079,7 @@ static void readIncludeFile(const QCString &inc) ...@@ -1079,7 +1079,7 @@ static void readIncludeFile(const QCString &inc)
if (g_yyFileDef) if (g_yyFileDef)
{ {
//printf("Adding include dependency %s->%s\n",oldFileDef->name().data(),incFileName.data()); //printf("Adding include dependency %s->%s\n",oldFileDef->name().data(),incFileName.data());
g_yyFileDef->addIncludedByDependency(oldFileDef,oldFileDef->name(),localInclude,g_isImported); g_yyFileDef->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,g_isImported);
} }
} }
FileState *fs=new FileState; FileState *fs=new FileState;
...@@ -1114,7 +1114,7 @@ static void readIncludeFile(const QCString &inc) ...@@ -1114,7 +1114,7 @@ static void readIncludeFile(const QCString &inc)
if (fd) if (fd)
{ {
//printf("Adding include dependency (2) %s->%s ambig=%d\n",oldFileDef->name().data(),fd->name().data(),ambig); //printf("Adding include dependency (2) %s->%s ambig=%d\n",oldFileDef->name().data(),fd->name().data(),ambig);
fd->addIncludedByDependency(oldFileDef,oldFileDef->name(),localInclude,g_isImported); fd->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,g_isImported);
} }
} }
if (Debug::isFlagSet(Debug::Preprocessor)) if (Debug::isFlagSet(Debug::Preprocessor))
......
...@@ -2258,6 +2258,28 @@ void RTFGenerator::endCallGraph(DotCallGraph &g) ...@@ -2258,6 +2258,28 @@ void RTFGenerator::endCallGraph(DotCallGraph &g)
DBG_RTF(t << "{\\comment (endCallGraph)}" << endl) DBG_RTF(t << "{\\comment (endCallGraph)}" << endl)
} }
void RTFGenerator::startDirDepGraph()
{
DBG_RTF(t << "{\\comment (startDirDepGraph)}" << endl)
}
void RTFGenerator::endDirDepGraph(DotDirDeps &g)
{
newParagraph();
QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
relPath,FALSE);
// display the file
t << "{" << endl;
t << rtf_Style_Reset << endl;
t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
t << fileName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
t << "}" << endl;
DBG_RTF(t << "{\\comment (endDirDepGraph)}" << endl)
}
/** Tests the integrity of the result by counting brackets. /** Tests the integrity of the result by counting brackets.
* *
*/ */
......
...@@ -227,6 +227,8 @@ class RTFGenerator : public OutputGenerator ...@@ -227,6 +227,8 @@ class RTFGenerator : public OutputGenerator
void endInclDepGraph(DotInclDepGraph &); void endInclDepGraph(DotInclDepGraph &);
void startCallGraph(); void startCallGraph();
void endCallGraph(DotCallGraph &); void endCallGraph(DotCallGraph &);
void startDirDepGraph();
void endDirDepGraph(DotDirDeps &g);
void writeGraphicalHierarchy(DotGfxHierarchyTable &) {} void writeGraphicalHierarchy(DotGfxHierarchyTable &) {}
void startMemberGroupHeader(bool); void startMemberGroupHeader(bool);
......
...@@ -5612,6 +5612,10 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] ...@@ -5612,6 +5612,10 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
unput('/');unput('*'); unput('/');unput('*');
BEGIN( tmpDocType ); BEGIN( tmpDocType );
} }
<Doc,JavaDoc,LineDoc,ClassDocBrief,AfterDocBrief,AfterDocLine,CopyArgCommentLine,ClassDoc,PageDoc,AfterDoc,CopyArgComment>"\\_linebr " {
// used to compensate for misalignments due to \n's inside ALIASES
current->doc += '\n';
}
<Doc,JavaDoc,ClassDoc,PageDoc,ReadFormulaShort,ReadFormulaLong,AfterDoc>^{B}*(("//"{B}*)?)"*"+[ \t]*"-"("#")?{B}+ { <Doc,JavaDoc,ClassDoc,PageDoc,ReadFormulaShort,ReadFormulaLong,AfterDoc>^{B}*(("//"{B}*)?)"*"+[ \t]*"-"("#")?{B}+ {
current->doc += yytext; current->doc += yytext;
} }
......
...@@ -234,7 +234,7 @@ class SDict ...@@ -234,7 +234,7 @@ class SDict
/*! Returns the number of items stored in the dictionary /*! Returns the number of items stored in the dictionary
*/ */
int count() int count() const
{ {
return m_list->count(); return m_list->count();
} }
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "groupdef.h" #include "groupdef.h"
#include "reflist.h" #include "reflist.h"
#include "pagedef.h" #include "pagedef.h"
#include "debug.h"
#if !defined(_WIN32) || defined(__CYGWIN__) #if !defined(_WIN32) || defined(__CYGWIN__)
#include <unistd.h> #include <unistd.h>
...@@ -140,7 +141,7 @@ int iSystem(const char *command,const char *args,bool isBatchFile) ...@@ -140,7 +141,7 @@ int iSystem(const char *command,const char *args,bool isBatchFile)
} }
fullCmd += " "; fullCmd += " ";
fullCmd += args; fullCmd += args;
//printf("iSystem: Executing %s\n",fullCmd.data()); Debug::print(Debug::ExtCmd,0,"Executing external command \"%s\"\n",fullCmd.data());
#if !defined(_WIN32) || defined(__CYGWIN__) #if !defined(_WIN32) || defined(__CYGWIN__)
isBatchFile=isBatchFile; isBatchFile=isBatchFile;
...@@ -2597,6 +2598,172 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl, ...@@ -2597,6 +2598,172 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
return TRUE; // all arguments match return TRUE; // all arguments match
} }
static QCString extractCanonicalType(Definition *d,FileDef *fs,const Argument *arg)
{
QCString type = arg->type;
QCString name = arg->name;
if ((type=="const" || type=="volatile") && !name.isEmpty())
{ // name is part of type => correct
type+=" ";
type+=name;
}
if (name=="const" || name=="volatile")
{ // name is part of type => correct
if (!type.isEmpty()) type+=" ";
type+=name;
}
// strip const and volatile keywords that are not relatevant for the type
stripIrrelevantConstVolatile(type);
// strip leading keywords
if (type.left(6)=="class ") type=type.right(type.length()-6);
else if (type.left(7)=="struct ") type=type.right(type.length()-7);
else if (type.left(6)=="union ") type=type.right(type.length()-6);
else if (type.left(5)=="enum ") type=type.right(type.length()-5);
else if (type.left(9)=="typename ") type=type.right(type.length()-9);
static QRegExp id("[a-z_A-Z][a-z_A-Z0-9]*");
QCString canType;
int i,p=0,l;
while ((i=id.match(type,p,&l))) // foreach identifier in the type
{
canType += type.mid(p,i-p);
QCString word = type.mid(i,l);
ClassDef *cd = getResolvedClass(d,fs,word);
if (cd)
{
canType+=cd->qualifiedName();
}
else
{
canType+=word;
}
p=i+l;
}
canType += type.right(type.length()-p);
return removeRedundantWhiteSpace(canType);
}
static bool matchArgument2(
Definition *srcScope,FileDef *srcFileScope,const Argument *srcA,
Definition *dstScope,FileDef *dstFileScope,const Argument *dstA
)
{
//printf("match argument start `%s|%s' <-> `%s|%s' using nsp=%p class=%p\n",
// srcA->type.data(),srcA->name.data(),
// dstA->type.data(),dstA->name.data(),
// usingNamespaces,
// usingClasses);
if (srcA->array!=dstA->array) // nomatch for char[] against char
{
NOMATCH
return FALSE;
}
QCString canonicalSrcType = extractCanonicalType(srcScope,srcFileScope,srcA);
QCString canonicalDstType = extractCanonicalType(dstScope,dstFileScope,dstA);
if (canonicalSrcType==canonicalDstType)
{
MATCH
return TRUE;
}
else
{
NOMATCH
return FALSE;
}
}
// new algorithm for argument matching
bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *srcAl,
Definition *dstScope,FileDef *dstFileScope,ArgumentList *dstAl,
bool checkCV
)
{
ASSERT(srcScope!=0 && dstScope!=0);
if (srcAl==0 || dstAl==0)
{
bool match = srcAl==dstAl; // at least one of the members is not a function
if (match)
{
MATCH
return TRUE;
}
else
{
NOMATCH
return FALSE;
}
}
// handle special case with void argument
if ( srcAl->count()==0 && dstAl->count()==1 &&
dstAl->getFirst()->type=="void" )
{ // special case for finding match between func() and func(void)
Argument *a=new Argument;
a->type = "void";
srcAl->append(a);
MATCH
return TRUE;
}
if ( dstAl->count()==0 && srcAl->count()==1 &&
srcAl->getFirst()->type=="void" )
{ // special case for finding match between func(void) and func()
Argument *a=new Argument;
a->type = "void";
dstAl->append(a);
MATCH
return TRUE;
}
if (srcAl->count() != dstAl->count())
{
NOMATCH
return FALSE; // different number of arguments -> no match
}
if (checkCV)
{
if (srcAl->constSpecifier != dstAl->constSpecifier)
{
NOMATCH
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
}
}
// so far the argument list could match, so we need to compare the types of
// all arguments.
ArgumentListIterator srcAli(*srcAl),dstAli(*dstAl);
Argument *srcA,*dstA;
for (;(srcA=srcAli.current(),dstA=dstAli.current());++srcAli,++dstAli)
{
if (!matchArgument2(srcScope,srcFileScope,srcA,
dstScope,dstFileScope,dstA)
)
{
NOMATCH
return FALSE;
}
}
MATCH
return TRUE; // all arguments match
}
// merges the initializer of two argument lists // merges the initializer of two argument lists
// pre: the types of the arguments in the list should match. // pre: the types of the arguments in the list should match.
void mergeArguments(ArgumentList *srcAl,ArgumentList *dstAl,bool forceNameOverwrite) void mergeArguments(ArgumentList *srcAl,ArgumentList *dstAl,bool forceNameOverwrite)
...@@ -2934,7 +3101,7 @@ bool getDefs(const QCString &scName,const QCString &memberName, ...@@ -2934,7 +3101,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
{ // namespace is found { // namespace is found
bool match=TRUE; bool match=TRUE;
ArgumentList *argList=0; ArgumentList *argList=0;
if (args) if (args && strcmp(args,"()")!=0)
{ {
argList=new ArgumentList; argList=new ArgumentList;
stringToArgumentList(args,argList); stringToArgumentList(args,argList);
...@@ -3001,10 +3168,10 @@ bool getDefs(const QCString &scName,const QCString &memberName, ...@@ -3001,10 +3168,10 @@ bool getDefs(const QCString &scName,const QCString &memberName,
(gd && gd->isLinkable()) || (fd && fd->isLinkable()) (gd && gd->isLinkable()) || (fd && fd->isLinkable())
) )
{ {
//printf("fd=%p gd=%p inGroup=`%d' args=`%s'\n",fd,gd,inGroup,args); //printf(" fd=%p gd=%p args=`%s'\n",fd,gd,args);
bool match=TRUE; bool match=TRUE;
ArgumentList *argList=0; ArgumentList *argList=0;
if (args && !md->isDefine()) if (args && !md->isDefine() && strcmp(args,"()")!=0)
{ {
argList=new ArgumentList; argList=new ArgumentList;
stringToArgumentList(args,argList); stringToArgumentList(args,argList);
......
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