summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--INSTALL4
-rw-r--r--README4
-rw-r--r--VERSION2
-rw-r--r--doc/Doxyfile2
-rw-r--r--doc/arch.doc240
-rw-r--r--doc/archoverview.eps380
-rw-r--r--doc/archoverview.gifbin0 -> 7822 bytes
-rw-r--r--doc/config.doc9
-rw-r--r--doc/doxygen_manual.tex3
-rw-r--r--doc/index.doc10
-rw-r--r--doc/language.doc2
-rw-r--r--packages/rpm/doxygen.spec2
-rw-r--r--src/classdef.cpp2
-rw-r--r--src/code.l139
-rw-r--r--src/config.l9
-rw-r--r--src/doc.l2
-rw-r--r--src/dot.cpp96
-rw-r--r--src/dot.h5
-rw-r--r--src/doxygen.cpp113
-rw-r--r--src/doxytag.l1
-rw-r--r--src/entry.h2
-rw-r--r--src/htmlgen.cpp8
-rw-r--r--src/htmlgen.h2
-rw-r--r--src/latexgen.cpp12
-rw-r--r--src/latexgen.h2
-rw-r--r--src/mangen.h2
-rw-r--r--src/memberdef.cpp28
-rw-r--r--src/memberdef.h1
-rw-r--r--src/memberlist.cpp24
-rw-r--r--src/outputgen.h2
-rw-r--r--src/outputlist.h6
-rw-r--r--src/pre.l63
-rw-r--r--src/rtfgen.h2
-rw-r--r--src/scanner.l11
-rw-r--r--src/translator_en.h2
-rw-r--r--src/util.cpp87
-rw-r--r--src/util.h1
-rw-r--r--src/xmlgen.cpp106
-rwxr-xr-xtmake/lib/hpux-g++/tmake.conf2
-rwxr-xr-xtmake/lib/irix-g++/tmake.conf2
40 files changed, 1166 insertions, 224 deletions
diff --git a/INSTALL b/INSTALL
index ae41927..31d657b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,6 +1,6 @@
-DOXYGEN Version 1.2.10
+DOXYGEN Version 1.2.10-20010909
Please read the installation section of the manual for instructions.
--------
-Dimitri van Heesch (26 August 2001)
+Dimitri van Heesch (09 September 2001)
diff --git a/README b/README
index 526b78a..1f840e5 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-DOXYGEN Version 1.2.10
+DOXYGEN Version 1.2.10_20010909
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) (26 August 2001)
+Dimitri van Heesch (dimitri@stack.nl) (09 September 2001)
diff --git a/VERSION b/VERSION
index 963ed7c..eb88bd3 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.2.10
+1.2.10-20010909
diff --git a/doc/Doxyfile b/doc/Doxyfile
index ca536a7..637b172 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -36,7 +36,7 @@ INPUT = index.doc install.doc starting.doc docblocks.doc lists.doc \
doxygen_usage.doc doxytag_usage.doc doxysearch_usage.doc \
doxywizard_usage.doc \
installdox_usage.doc output.doc autolink.doc \
- config.doc commands.doc htmlcmds.doc language.doc
+ config.doc commands.doc htmlcmds.doc language.doc arch.doc
FILE_PATTERNS = *.cpp *.h *.doc
EXAMPLE_PATH = ../examples
RECURSIVE = NO
diff --git a/doc/arch.doc b/doc/arch.doc
new file mode 100644
index 0000000..3000bc5
--- /dev/null
+++ b/doc/arch.doc
@@ -0,0 +1,240 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2001 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 arch
+
+\section arch Doxygen's Internals
+
+<B>Note that this section is still under construction!</B>
+
+The following picture shows how source files are processed by doxygen.
+
+\image html archoverview.gif "Data flow overview"
+\image latex archoverview.eps "Data flow overview" width=14cm
+
+The following sections explain the steps above in more detail.
+
+<h3>Config parser</h3>
+
+The configuration file that controls the settings of a project is parsed
+and the settings are stored in the singleton class \c Config
+in \c src/config.h. The parser itself is written using \c flex and can be
+found in \c src/config.l. This parser is also used directly by \c doxywizard,
+so it is put in a separate library.
+
+Each configuration option has one of 5 possible types: \c String,
+\c List, \c Enum, \c Int, or \c Bool. The values of these options are
+available through the global functions \c Config_getXXX(), where \c XXX is the
+type of the option. The argument of these function is a string naming
+the option as it appears in the configuration file. For instance:
+\c Config_getBool("GENERATE_TESTLIST") returns a reference to a boolean
+value that is \c TRUE if the test list was enabled in the config file.
+
+The function \c readConfiguration() in \c src/doxygen.cpp
+reads the command line options and then calls the configuration parser.
+
+<h3>C Preprocessor</h3>
+
+The input files mentioned in the config file are (by default) fed to the
+C Preprocessor (after being piped through a user defined filter if available).
+
+The way the preprocessor works differs somewhat from a standard C Preprocessor.
+By default it does not do macro expansion, although it can be configured to
+expand all macros. Typical usage is to only expand a user specified set
+of macros. This is to allow macro names to appear in the type of
+function parameters for instance.
+
+Another difference is that the preprocessor parses, but not actually includes
+code when it encounters a #include (with the exception of #include
+found inside { ... } blocks). The reasons behind this deviation from
+the standard is to prevent feeding multiple definitions of the
+same functions/classes to doxygen's parser. If all source files would
+include a common header file for instance, the class and type
+definitions (and their documentation) would be present in each
+translation unit.
+
+The preprocessor is written using \c flex and can be found in
+\c src/pre.l. For condition blocks (#if) evaluation of constant expressions
+is needed. For this a \c yacc based parser is used, which can be found
+in \c src/constexp.y and \c src/constexp.l.
+
+The preprocessor is invoked for each file using the \c preprocessFile()
+function declared in \c src/pre.h, and will append the preprocessed result
+to a character buffer. The format of the character buffer is
+
+\verbatim
+0x06 file name 1
+0x06 preprocessed contents of file 1
+...
+0x06 file name n
+0x06 preprocessed contents of file n
+\endverbatim
+
+<h3>Language parser</h3>
+
+The preprocessed input buffer is fed to the language parser, which is
+implemented as a big state machine using \c flex. It can be found
+in the file \c src/scanner.l. There is one parser for all
+languages (C/C++/Java/IDL). The state variables \c insideIDL
+and \c insideJava are uses at some places for language specific choices.
+
+The task of the parser is to convert the input buffer into a tree of entries
+(basically an abstract syntax tree). An entry is defined in \c src/entry.h
+and is a blob of loosely structured information. The most important field
+is \c section which specifies the kind of information contained in the entry.
+
+Possible improvements for future versions:
+ - Use one scanner/parser per language instead of one big scanner.
+ - Move the first pass parsing of documentation blocks to a separate module.
+ - Parse defines (these are currently gathered by the preprocessor, and
+ ignored by the language parser).
+
+<h3>Data organizer</h3>
+
+This step consists of many smaller steps, that build
+dictionaries of the extracted classes, files, namespaces,
+variables, functions, packages, pages, and groups. Besides building
+dictionaries, during this step relations (such as inheritance relations),
+between the extracted entities are computed.
+
+Each step has a function defined in \c src/doxygen.cpp, which operates
+on the tree of entries, built during language parsing. Look at the
+"Gathering information" part of \c parseInput() for details.
+
+The result of this step is a number of dictionaries, which can be
+found in the Doxygen "namespace" defined in \c src/doxygen.h. Most
+elements of these dictionaries are derived from the class \c Definition;
+The class \c MemberDef, for instance, holds all information for a member.
+An instance of such a class can be part of a file ( class \c FileDef ),
+a class ( class \c ClassDef ), a namespace ( class \c NamespaceDef ),
+a group ( class \c GroupDef ), or a Java package ( class \c PackageDef ).
+
+<h3>Tag file parser</h3>
+
+If tag files are specified in the configuration file, these are parsed
+by a SAX based XML parser, which can be found in \c src/tagreader.cpp.
+The result of parsing a tag file is the insertion of \c Entry objects in the
+entry tree. The field \c Entry::tagInfo is used to mark the entry as
+external, and holds information about the tag file.
+
+<h3>Documentation parser</h3>
+
+Special comment blocks are stored as strings in the entities that they
+document. There is a string for the brief description and a string
+for the detailed description. The documentation parser reads these
+strings and executes the commands it finds in it (this is the second pass
+in parsing the documentation). It writes the result directly to the output
+generators.
+
+The parser is written using \c flex and can be found in \c src/doc.l
+Code fragments found in the comment blocks are passed on to the source parser.
+
+The main entry point for the documentation parser is \c parseDoc()
+declared in \c src/doc.h. For simple texts with special
+commands \c parseText() is used.
+
+<h3>Source parser</h3>
+
+If source browsing is enabled or if code fragments are encountered in the
+documentation, the source parser is invoked.
+
+The code parser tries to cross-reference to source code it parses with
+documented entities. It also does syntax highlighting of the sources. The
+output is directly written to the output generators.
+
+The main entry point for the code parser is \c parseCode()
+declared in \c src/code.h.
+
+<h3>Output generators</h3>
+
+After data is gathered and cross-referenced, doxygen generates
+output in various formats. For this it uses the methods provided by
+the abstract class \c OutputGenerator. In order to generate output
+for multiple formats at once, the methods of \c OutputList are called
+instead. This class maintains a list of concrete output generators,
+where each method called is delegated to all generators in the list.
+
+To allow small deviations in what is written to the output for each
+concrete output generator, it is possible to temporarily disable certain
+generators. The OutputList class contains various \c disable() and \c enable()
+methods for this. The methods \c OutputList::pushGeneratorState() and
+\c OutputList::popGeneratorState() are used to temporarily save the
+set of enabled/disabled output generators on a stack.
+
+The XML is generated directly from the gathered data structures. In the
+future XML will be used as an intermediate language (IL). The output
+generators will then use this IL as a starting point to generate the
+specific output formats. The advantage of having an IL is that various
+independently developed tools written in various languages,
+could extract information from the XML output. Possible tools could be:
+- an interactive source browser
+- a class diagram generator
+- computing code metrics.
+
+<h3>Debugging</h3>
+
+Since doxygen uses a lot of \c flex code it is important to understand
+how \c flex works (for this one should read the man page)
+and to understand what it is doing when \c flex is parsing some input.
+Fortunately, when flex is used with the -d option it outputs what rules
+matched. This makes it quite easy to follow what is going on for a
+particular input fragment.
+
+To make it easier to toggle debug information for a given flex file I
+wrote the following perl script, which automatically adds or removes -d
+from the correct line in the Makefile:
+
+\verbatim
+#!/usr/local/bin/perl
+
+$file = shift @ARGV;
+print "Toggle debugging mode for $file\n";
+
+# add or remove the -d flex flag in the makefile
+unless (rename "Makefile.libdoxygen","Makefile.libdoxygen.old") {
+ print STDERR "Error: cannot rename Makefile.libdoxygen!\n";
+ exit 1;
+}
+if (open(F,"<Makefile.libdoxygen.old")) {
+ unless (open(G,">Makefile.libdoxygen")) {
+ print STDERR "Error: opening file Makefile.libdoxygen for writing\n";
+ exit 1;
+ }
+ print "Processing Makefile.libdoxygen...\n";
+ while (<F>) {
+ if ( s/\(LEX\) -P([a-z]+)YY -t $file/(LEX) -d -P\1YY -t $file/g ) {
+ print "Enabling debug info for $file\n";
+ }
+ elsif ( s/\(LEX\) -d -P([a-z]+)YY -t $file/(LEX) -P\1YY -t $file/g ) {
+ print "Disabling debug info for $file\n";
+ }
+ print G "$_";
+ }
+ close F;
+ unlink "Makefile.libdoxygen.old";
+}
+else {
+ print STDERR "Warning file Makefile.libdoxygen.old does not exist!\n";
+}
+
+# touch the file
+$now = time;
+utime $now, $now, $file
+\endverbatim
+
+*/
+
+
diff --git a/doc/archoverview.eps b/doc/archoverview.eps
new file mode 100644
index 0000000..b41d36c
--- /dev/null
+++ b/doc/archoverview.eps
@@ -0,0 +1,380 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: archoverview.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 1
+%%CreationDate: Sat Sep 8 19:41:40 2001
+%%For: root@blizzard (root)
+%%Orientation: Portrait
+%%BoundingBox: 0 0 733 511
+%%Pages: 0
+%%BeginSetup
+%%EndSetup
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-31.0 537.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n -1000 9949 m -1000 -1000 l 13719 -1000 l 13719 9949 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Ellipse
+n 4425 1725 900 900 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 5100 4200 900 900 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 10500 4275 900 900 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 2402 4198 900 900 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 7863 8104 837 837 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 5113 6622 887 887 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 9375 6450 837 837 0 360 DrawEllipse gs col0 s gr
+
+% Ellipse
+n 7800 4200 900 900 0 360 DrawEllipse gs col0 s gr
+
+% Polyline
+gs clippath
+1380 4170 m 1500 4200 l 1380 4230 l 1515 4230 l 1515 4170 l cp
+clip
+n 600 4200 m 1500 4200 l gs col0 s gr gr
+
+% arrowhead
+n 1380 4170 m 1500 4200 l 1380 4230 l 1380 4200 l 1380 4170 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+4080 4170 m 4200 4200 l 4080 4230 l 4215 4230 l 4215 4170 l cp
+clip
+n 3300 4200 m 4200 4200 l gs col0 s gr gr
+
+% arrowhead
+n 4080 4170 m 4200 4200 l 4080 4230 l 4080 4200 l 4080 4170 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+9480 4170 m 9600 4200 l 9480 4230 l 9615 4230 l 9615 4170 l cp
+clip
+n 8700 4200 m 9600 4200 l gs col0 s gr gr
+
+% arrowhead
+n 9480 4170 m 9600 4200 l 9480 4230 l 9480 4200 l 9480 4170 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11881 3482 m 12000 3450 l 11910 3535 l 12028 3469 l 11999 3416 l cp
+clip
+n 11325 3825 m 12000 3450 l gs col0 s gr gr
+
+% arrowhead
+n 11881 3482 m 12000 3450 l 11910 3535 l 11895 3508 l 11881 3482 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11876 4050 m 12000 4050 l 11891 4108 l 12022 4075 l 12007 4017 l cp
+clip
+n 11400 4200 m 12000 4050 l gs col0 s gr gr
+
+% arrowhead
+n 11876 4050 m 12000 4050 l 11891 4108 l 11884 4079 l 11876 4050 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11900 5028 m 12000 5100 l 11877 5083 l 12003 5133 l 12025 5078 l cp
+clip
+n 11250 4800 m 12000 5100 l gs col0 s gr gr
+
+% arrowhead
+n 11900 5028 m 12000 5100 l 11877 5083 l 11889 5055 l 11900 5028 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11891 4517 m 12000 4575 l 11876 4575 l 12007 4608 l 12022 4550 l cp
+clip
+n 11400 4425 m 12000 4575 l gs col0 s gr gr
+
+% arrowhead
+n 11891 4517 m 12000 4575 l 11876 4575 l 11884 4546 l 11891 4517 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11880 2820 m 12000 2850 l 11880 2880 l 12015 2880 l 12015 2820 l cp
+clip
+n 7800 3300 m 7800 2850 l 12000 2850 l gs col0 s gr gr
+
+% arrowhead
+n 11880 2820 m 12000 2850 l 11880 2880 l 11880 2850 l 11880 2820 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+10470 5295 m 10500 5175 l 10530 5295 l 10530 5160 l 10470 5160 l cp
+clip
+n 8700 8100 m 10500 8100 l 10500 5175 l gs col0 s gr gr
+
+% arrowhead
+n 10470 5295 m 10500 5175 l 10530 5295 l 10500 5295 l 10470 5295 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+4455 705 m 4425 825 l 4395 705 l 4395 840 l 4455 840 l cp
+clip
+n 4425 450 m 4425 825 l gs col0 s gr gr
+
+% arrowhead
+n 4455 705 m 4425 825 l 4395 705 l 4425 705 l 4455 705 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+gs clippath
+3405 1695 m 3525 1725 l 3405 1755 l 3540 1755 l 3540 1695 l cp
+clip
+n 3525 1725 m 2400 1725 l 2400 3300 l gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 3405 1695 m 3525 1725 l 3405 1755 l 3405 1725 l 3405 1695 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+gs clippath
+5445 1680 m 5325 1650 l 5445 1620 l 5310 1620 l 5310 1680 l cp
+clip
+n 5325 1650 m 7575 1650 l 7575 3300 l gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 5445 1680 m 5325 1650 l 5445 1620 l 5445 1650 l 5445 1680 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+gs clippath
+4845 2670 m 4875 2550 l 4905 2670 l 4905 2535 l 4845 2535 l cp
+clip
+n 4875 2550 m 4875 3300 l gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 4845 2670 m 4875 2550 l 4905 2670 l 4875 2670 l 4845 2670 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+n 7575 1650 m 10500 1650 l 10500 3375 l gs col0 s gr [] 0 sd
+% Polyline
+gs clippath
+6930 8070 m 7050 8100 l 6930 8130 l 7065 8130 l 7065 8070 l cp
+clip
+n 2400 5100 m 2400 8100 l 7050 8100 l gs col0 s gr gr
+
+% arrowhead
+n 6930 8070 m 7050 8100 l 6930 8130 l 6930 8100 l 6930 8070 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+6780 4170 m 6900 4200 l 6780 4230 l 6915 4230 l 6915 4170 l cp
+clip
+n 6000 4200 m 6900 4200 l gs col0 s gr gr
+
+% arrowhead
+n 6780 4170 m 6900 4200 l 6780 4230 l 6780 4200 l 6780 4170 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+7090 4932 m 7200 4875 l 7130 4977 l 7231 4887 l 7191 4843 l cp
+clip
+n 5850 6075 m 7200 4875 l gs col0 s gr gr
+
+% arrowhead
+n 7090 4932 m 7200 4875 l 7130 4977 l 7110 4955 l 7090 4932 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+7830 7155 m 7800 7275 l 7770 7155 l 7770 7290 l 7830 7290 l cp
+clip
+n 7800 7275 m 7800 5100 l gs col0 s gr gr
+
+% arrowhead
+n 7830 7155 m 7800 7275 l 7770 7155 l 7800 7155 l 7830 7155 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+8886 5583 m 8925 5700 l 8835 5615 l 8908 5729 l 8958 5697 l cp
+clip
+n 8400 4875 m 8925 5700 l gs col0 s gr gr
+
+% arrowhead
+n 8886 5583 m 8925 5700 l 8835 5615 l 8861 5599 l 8886 5583 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+8575 7427 m 8475 7500 l 8529 7389 l 8442 7492 l 8488 7531 l cp
+clip
+n 8850 7050 m 8475 7500 l gs col0 s gr gr
+
+% arrowhead
+n 8575 7427 m 8475 7500 l 8529 7389 l 8552 7408 l 8575 7427 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+10106 5255 m 10200 5175 l 10155 5290 l 10233 5180 l 10184 5145 l cp
+clip
+n 9825 5700 m 10200 5175 l gs col0 s gr gr
+
+% arrowhead
+n 10106 5255 m 10200 5175 l 10155 5290 l 10130 5273 l 10106 5255 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+3900 1725 m
+gs 1 -1 sc (Config parser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+4425 4275 m
+gs 1 -1 sc (Language parser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1725 4275 m
+gs 1 -1 sc (C Preprocessor) col0 sh gr
+/Helvetica ff 180.00 scf sf
+12150 3525 m
+gs 1 -1 sc (HTML) col0 sh gr
+/Helvetica ff 180.00 scf sf
+12150 4125 m
+gs 1 -1 sc (LaTeX) col0 sh gr
+/Helvetica ff 180.00 scf sf
+12150 4650 m
+gs 1 -1 sc (RTF) col0 sh gr
+/Helvetica ff 180.00 scf sf
+12150 2925 m
+gs 1 -1 sc (XML) col0 sh gr
+/Helvetica ff 180.00 scf sf
+3450 4500 m
+gs 1 -1 sc (input) col0 sh gr
+/Helvetica ff 180.00 scf sf
+3450 4725 m
+gs 1 -1 sc (string) col0 sh gr
+/Helvetica ff 180.00 scf sf
+6150 4500 m
+gs 1 -1 sc (entry) col0 sh gr
+/Helvetica ff 180.00 scf sf
+6150 4725 m
+gs 1 -1 sc (tree) col0 sh gr
+/Helvetica ff 180.00 scf sf
+525 3975 m
+gs 1 -1 sc (input files) col0 sh gr
+/Helvetica ff 180.00 scf sf
+12150 5175 m
+gs 1 -1 sc (Man) col0 sh gr
+/Helvetica ff 180.00 scf sf
+4650 750 m
+gs 1 -1 sc (config file) col0 sh gr
+/Helvetica ff 180.00 scf sf
+7950 5475 m
+gs 1 -1 sc (drives) col0 sh gr
+/Helvetica ff 180.00 scf sf
+8850 4050 m
+gs 1 -1 sc (drives) col0 sh gr
+/Helvetica ff 180.00 scf sf
+2475 3150 m
+gs 1 -1 sc (get settings) col0 sh gr
+/Helvetica ff 180.00 scf sf
+6675 5550 m
+gs 1 -1 sc (entry) col0 sh gr
+/Helvetica ff 180.00 scf sf
+6675 5775 m
+gs 1 -1 sc (tree) col0 sh gr
+/Helvetica ff 180.00 scf sf
+9525 5325 m
+gs 1 -1 sc (drives) col0 sh gr
+/Helvetica ff 180.00 scf sf
+8700 7500 m
+gs 1 -1 sc (drives) col0 sh gr
+/Helvetica ff 180.00 scf sf
+4575 6675 m
+gs 1 -1 sc (tag file parser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+8925 6525 m
+gs 1 -1 sc (Doc Parser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+7275 8175 m
+gs 1 -1 sc (Source Parser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+7200 4275 m
+gs 1 -1 sc (Data organiser) col0 sh gr
+/Helvetica ff 180.00 scf sf
+9750 4275 m
+gs 1 -1 sc (Output generators) col0 sh gr
+/Helvetica ff 180.00 scf sf
+8775 8325 m
+gs 1 -1 sc (drives) col0 sh gr
+$F2psEnd
+rs
diff --git a/doc/archoverview.gif b/doc/archoverview.gif
new file mode 100644
index 0000000..f404076
--- /dev/null
+++ b/doc/archoverview.gif
Binary files differ
diff --git a/doc/config.doc b/doc/config.doc
index dbb0e53..b9f0e56 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -166,6 +166,7 @@ followed by the descriptions of the tags grouped by category.
<li> \refitem cfg_short_names SHORT_NAMES
<li> \refitem cfg_show_include_files SHOW_INCLUDE_FILES
<li> \refitem cfg_show_used_files SHOW_USED_FILES
+<li> \refitem cfg_skip_function_macros SKIP_FUNCTION_MACROS
<li> \refitem cfg_sort_member_docs SORT_MEMBER_DOCS
<li> \refitem cfg_source_browser SOURCE_BROWSER
<li> \refitem cfg_strip_code_comments STRIP_CODE_COMMENTS
@@ -1070,6 +1071,14 @@ EXTRA_PACKAGES = times
The macro definition that is found in the sources will be used.
Use the \c PREDEFINED tag if you want to use a different macro definition.
+\anchor cfg_skip_function_macros
+<dt>\c SKIP_FUNCTION_MACROS <dd>
+ \addindex SKIP_FUNCTION_MACROS
+ If the \c SKIP_FUNCTION_MACROS tag is set to \c YES (the default) then
+ doxygen's preprocessor will remove all function-like macros that are alone
+ on a line and do not end with a semicolon. Such function macros are typically
+ used for boiler-plate code, and will confuse the parser if not removed.
+
</dl>
\subsection config_extref External reference options
\anchor cfg_tagfiles
diff --git a/doc/doxygen_manual.tex b/doc/doxygen_manual.tex
index be93b99..bc1dfbb 100644
--- a/doc/doxygen_manual.tex
+++ b/doc/doxygen_manual.tex
@@ -16,6 +16,7 @@
\usepackage{a4wide}
\usepackage{makeidx}
\usepackage{fancyhdr}
+\usepackage{graphicx}
\usepackage{epsf}
\usepackage{doxygen}
\usepackage{multicol}
@@ -68,6 +69,8 @@ Written by Dimitri van Heesch\\[2ex]
\input{config}
\input{commands}
\input{htmlcmds}
+\part{Developers Manual}
+\input{arch}
\input{langhowto}
\printindex
\end{document}
diff --git a/doc/index.doc b/doc/index.doc
index 9c030cb..47248d1 100644
--- a/doc/index.doc
+++ b/doc/index.doc
@@ -73,7 +73,7 @@ but is set-up to be highly portable. As a result, it runs on most
other Unix flavors as well. Furthermore, an executable for
Windows 9x/NT is also available.
-This manual is divided into two parts, each of which is divided into several
+This manual is divided into three parts, each of which is divided into several
sections.
The first part forms a user manual:
@@ -117,11 +117,17 @@ The second part forms a reference manual:
used within the documentation.
<li>Section \ref htmlcmds shows an overview of the HTML commands that
can be used within the documentation.
+</ul>
+
+The third part provides information for developers:
+
+<ul>
+<li>Section \ref arch gives a global overview of how doxygen is internally
+ structured.
<li>Section \ref langhowto explains how to add support for new
output languages.
</ul>
-
<h2>Projects using doxygen</h2>
I have compiled a
diff --git a/doc/language.doc b/doc/language.doc
index 91046f2..101273f 100644
--- a/doc/language.doc
+++ b/doc/language.doc
@@ -25,7 +25,7 @@ Doxygen has built-in support for multiple languages. This means
that the text fragments that doxygen generates can be produced in
languages other than English (the default) at configuration time.
-Currently (version 1.2.9-20010819), 24 languages
+Currently (version 1.2.10), 24 languages
are supported (sorted alphabetically):
Brazilian Portuguese, Chinese, Croatian, Czech, Danish,
Dutch, English, Finnish, French, German,
diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec
index ec9287e..6b7d410 100644
--- a/packages/rpm/doxygen.spec
+++ b/packages/rpm/doxygen.spec
@@ -1,5 +1,5 @@
Name: doxygen
-Version: 1.2.10
+Version: 1.2.10_20010909
Summary: documentation system for C, C++ and IDL
Release: 4
Source: doxygen-%{version}.src.tar.gz
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 54f78e4..cb453ec 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -2264,7 +2264,7 @@ bool ClassDef::isReference() const
{
if (m_templateMaster)
{
- return m_templateMaster->getReference();
+ return m_templateMaster->isReference();
}
else
{
diff --git a/src/code.l b/src/code.l
index c07841b..39fc7d6 100644
--- a/src/code.l
+++ b/src/code.l
@@ -127,6 +127,7 @@ static int g_bodyCurlyCount;
static ClassDef * g_classVar;
static QCString g_saveName;
static QCString g_saveType;
+static int g_memCallContext;
/*! add class/namespace name s to the scope */
static void pushScope(const char *s)
@@ -196,6 +197,7 @@ static void startCodeLine()
lineAnchor.sprintf("l%05d",g_yyLineNr);
Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
+ g_code->startLineNumber();
if (!g_includeCodeFragment && d && d->isLinkableInProject())
{
g_currentDefinition = d;
@@ -211,13 +213,12 @@ static void startCodeLine()
g_code->writeCodeLink(d->getReference(),d->getOutputFileBase(),
anchor,lineNumber);
g_code->endCodeAnchor();
- g_code->codify(" ");
}
else
{
g_code->codify(lineNumber);
- g_code->codify(" ");
}
+ g_code->endLineNumber();
}
g_code->startCodeLine();
if (g_currentFontClass)
@@ -352,12 +353,14 @@ static void addParameter()
{
g_cvd.name=g_parmName.copy().simplifyWhiteSpace();
g_cvd.type=g_parmType.copy().simplifyWhiteSpace();
+ //printf("searching for parameter `%s' `%s'\n",g_cvd.type.data(),g_cvd.name.data());
if (g_cvd.type.isEmpty())
{
return;
}
else
{
+ if (g_cvd.type.left(7)=="struct ") g_cvd.type=g_cvd.type.right(g_cvd.type.length()-7);
int i;
if ((getResolvedClass(g_currentDefinition,g_cvd.type)) || (g_codeClassDict[g_cvd.type]))
{
@@ -375,6 +378,10 @@ static void addParameter()
g_codeParmList.append(new CodeVarDef(g_cvd));
}
}
+ else
+ {
+ //printf("parameter `%s' `%s' not found!\n",g_cvd.type.data(),g_cvd.name.data());
+ }
//printf("g_codeParmList.count()=%d\n",g_codeParmList.count());
}
}
@@ -440,6 +447,21 @@ static void generateClassLink(OutputDocInterface &ol,char *clName,int *clNameLen
}
else
{
+ MemberName *mn;
+ if (cd==0 && (mn=Doxygen::functionNameDict[clName]))
+ {
+ if (mn->count()==1)
+ {
+ MemberDef *md=mn->getFirst();
+ Definition *d=md->getNamespaceDef();
+ if (d==0) d=md->getFileDef();
+ if (d && md->isLinkable())
+ {
+ writeMultiLineCodeLink(ol,d->getReference(),d->getOutputFileBase(),md->anchor(),clName);
+ return;
+ }
+ }
+ }
codifyLines(clName);
if (clNameLen) *clNameLen=className.length()-1;
}
@@ -466,10 +488,12 @@ static ClassDef *stripClassName(const char *s)
}
if (cd)
{
+ //printf("stripClassName(%s)=%s\n",s,cd->name().data());
return cd;
}
p=i+l;
}
+ //printf("stripClassName(%s)=<null>\n",s);
return 0;
}
@@ -578,7 +602,10 @@ static void generateMemberLink(OutputDocInterface &ol,const char *varName,
//printf("generateMemberLink(object=%s,mem=%s) classScope=%s\n",
// varName,memName,g_classScope.data());
CodeVarDef *cvd=g_codeParmList.last();
- while (cvd && cvd->name!=varName) cvd=g_codeParmList.prev();
+ while (cvd && cvd->name!=varName)
+ {
+ cvd=g_codeParmList.prev();
+ }
if (!cvd)
{
cvd=g_codeVarList.last();
@@ -813,6 +840,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
%x MemberCall2
%x SkipInits
%x ClassName
+%x ClassVar
%x Bases
%x SkipSharp
%x ReadInclude
@@ -899,12 +927,12 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_insideBody=FALSE;
}
}
-<ClassName>";" {
+<ClassName,ClassVar>";" {
g_code->codify(yytext);
g_searchingForBody=FALSE;
BEGIN( Body );
}
-<ClassName>[*&]+ {
+<ClassName,ClassVar>[*&]+ {
addType();
g_code->codify(yytext);
}
@@ -912,12 +940,19 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_ccd.name=yytext;
addType();
generateClassLink(*g_code,yytext);
+ BEGIN( ClassVar );
}
-<ClassName>[ \t\n]*":"[ \t\n]* {
+<ClassVar>{ID} {
+ g_type = g_ccd.name.copy();
+ g_name = yytext;
+ addVariable();
+ g_code->codify(yytext);
+ }
+<ClassName,ClassVar>[ \t\n]*":"[ \t\n]* {
codifyLines(yytext);
BEGIN( Bases );
}
-<Bases,ClassName>[ \t]*"{"[ \t]* {
+<Bases,ClassName,ClassVar>[ \t]*"{"[ \t]* {
g_code->codify(yytext);
g_curlyCount++;
g_inClass=TRUE;
@@ -1038,7 +1073,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
addType();
g_name+=yytext;
}
-<Body>{SCOPENAME}{B}*"<"[^\n\/\{\"\>]*">"/{B}* { // A<T> *pt;
+<Body>{SCOPENAME}{B}*"<"[^\n\/\-\.\{\"\>]*">"/{B}* { // A<T> *pt;
generateClassLink(*g_code,yytext);
addType();
g_name+=yytext;
@@ -1048,19 +1083,18 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
addType();
g_name+=yytext;
}
-<Body>"("{B}*"*"{B}*{SCOPENAME}*{B}*")"/{B}* { // (*p)->func()
- QCString text=yytext;
- int s=0;
- while (s<yyleng && (text.at(s)=='(' || isspace(text.at(s)))) s++;
- int e=yyleng-1;
- while (e>=0 && (text.at(e)==')' || isspace(yytext[e]))) e--;
- QCString varname = text.mid(s+1,e-s);
- QCString tmp=varname.copy();
- g_code->codify(text.left(s+1));
- generateClassLink(*g_code,tmp.data());
- g_code->codify(text.right(yyleng-e-1));
+<Body>"("{B}*("*"{B}*)*{SCOPENAME}*{B}*")"/{B}* { // (*p)->func()
+ g_code->codify(yytext);
+ int s=0;while (!isId(yytext[s])) s++;
+ int e=yyleng-1;while (!isId(yytext[e])) e--;
+ QCString varname = ((QCString)yytext).mid(s,e-s+1);
+ //QCString text=yytext;
+ //QCString tmp=varname.copy();
+ //g_code->codify(text.left(s+1));
+ //generateClassLink(*g_code,tmp.data());
+ //g_code->codify(text.right(yyleng-e-1));
addType();
- g_name+=varname;
+ g_name=varname;
}
<Body>{SCOPETNAME}/{B}*"(" { // a() or c::a() or t<A,B>::a()
addType();
@@ -1119,12 +1153,14 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
<Body>"this->" { g_code->codify(yytext); }
<Body>"."|"->" {
g_code->codify(yytext);
+ g_memCallContext = YY_START;
BEGIN( MemberCall );
}
<MemberCall>{SCOPETNAME}/{B}*"(" {
if (!g_name.isEmpty())
{
generateMemberLink(*g_code,g_name,yytext);
+ g_name=yytext;
}
else if (g_classVar)
{
@@ -1133,20 +1169,52 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_code->codify(yytext);
}
g_classVar=0;
+ g_name.resize(0);
}
else
{
g_code->codify(yytext);
+ g_name.resize(0);
}
- g_name.resize(0);g_type.resize(0);
+ g_type.resize(0);
g_bracketCount=0;
- BEGIN(FuncCall);
+ if (g_memCallContext==Body)
+ {
+ BEGIN(FuncCall);
+ }
+ else
+ {
+ BEGIN(g_memCallContext);
+ }
+ }
+<MemberCall>{SCOPENAME}/{B}* {
+ if (!g_name.isEmpty())
+ {
+ generateMemberLink(*g_code,g_name,yytext);
+ g_name=yytext;
+ }
+ else if (g_classVar)
+ {
+ if (!generateClassMemberLink(*g_code,g_classVar,yytext))
+ {
+ g_code->codify(yytext);
+ }
+ g_classVar=0;
+ g_name.resize(0);
+ }
+ else
+ {
+ g_code->codify(yytext);
+ g_name.resize(0);
+ }
+ g_type.resize(0);
+ BEGIN(g_memCallContext);
}
<MemberCall>[^a-z_A-Z0-9(\n] {
g_code->codify(yytext);
g_type.resize(0);
g_name.resize(0);
- BEGIN(Body);
+ BEGIN(g_memCallContext);
}
<Body>[,=;\[] {
g_code->codify(yytext);
@@ -1211,9 +1279,11 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
<MemberCall2,FuncCall>")" {
g_code->codify(yytext);
if (--g_bracketCount<=0)
- g_name.resize(0);g_args.resize(0);
- g_parmType.resize(0);g_parmName.resize(0);
- BEGIN( Body );
+ {
+ g_name.resize(0);g_args.resize(0);
+ g_parmType.resize(0);g_parmName.resize(0);
+ BEGIN( Body );
+ }
}
<MemberCall2,FuncCall>")"[ \t\n]*[;:] {
codifyLines(yytext);
@@ -1295,7 +1365,14 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
}
<FuncCall>([a-z_A-Z][a-z_A-Z0-9]*)/("."|"->") {
g_code->codify(yytext);
- g_args=yytext;
+ g_name=yytext;
+ BEGIN( MemberCall2 );
+ }
+<FuncCall,MemberCall2>("("{B}*("*"{B}*)*[a-z_A-Z][a-z_A-Z0-9]*{B}*")"{B}*)/("."|"->") {
+ g_code->codify(yytext);
+ int s=0;while (!isId(yytext[s])) s++;
+ int e=yyleng-1;while (!isId(yytext[e])) e--;
+ g_name=((QCString)yytext).mid(s,e-s+1);
BEGIN( MemberCall2 );
}
<MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*"(") {
@@ -1308,8 +1385,14 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
}
<MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*("."|"->")) {
g_code->codify(yytext);
- g_args=yytext;
+ g_name=yytext;
+ BEGIN( MemberCall2 );
}
+<MemberCall2>"->"|"." {
+ g_code->codify(yytext);
+ g_memCallContext = YY_START;
+ BEGIN( MemberCall );
+ }
<SkipComment>"//" {
g_code->codify(yytext);
}
diff --git a/src/config.l b/src/config.l
index 6725e9d..006bd7e 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1979,6 +1979,15 @@ void Config::create()
"Use the PREDEFINED tag if you want to use a different macro definition. \n"
);
cl->addDependency("ENABLE_PREPROCESSING");
+ cb = addBool(
+ "SKIP_FUNCTION_MACROS",
+ "If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then \n"
+ "doxygen's preprocessor will remove all function-like macros that are alone \n"
+ "on a line and do not end with a semicolon. Such function macros are typically \n"
+ "used for boiler-plate code, and will confuse the parser if not removed. \n",
+ TRUE
+ );
+ cb->addDependency("ENABLE_PREPROCESSING");
//-----------------------------------------------------------------------------------------------
addInfo( "External","Configuration::addtions related to external references ");
//-----------------------------------------------------------------------------------------------
diff --git a/src/doc.l b/src/doc.l
index 59b714c..7868c9a 100644
--- a/src/doc.l
+++ b/src/doc.l
@@ -838,7 +838,7 @@ static void writeDotFile(const char *fileName, const char *captionText)
static int yyread(char *buf,int max_size)
{
int c=0;
- while( c < max_size && inputString[inputPosition] )
+ while ( c < max_size && inputString[inputPosition] )
{
*buf = inputString[inputPosition++] ;
//printf("%d (%c)\n",*buf,*buf);
diff --git a/src/dot.cpp b/src/dot.cpp
index e9b739b..4e43b2d 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -428,6 +428,68 @@ void DotNode::write(QTextStream &t,
}
}
+void DotNode::writeXML(QTextStream &t)
+{
+ t << " <node id=\"" << m_number << "\">" << endl;
+ t << " <label>" << m_label << "</label>" << endl;
+ if (!m_url.isEmpty())
+ {
+ QCString url(m_url);
+ char *refPtr = url.data();
+ char *urlPtr = strchr(url.data(),'$');
+ if (urlPtr)
+ {
+ *urlPtr++='\0';
+ t << " <link id=\"" << urlPtr << "\"";
+ if (*refPtr!='\0')
+ {
+ t << " external=\"" << refPtr << "\"";
+ }
+ t << "/>" << endl;
+ }
+ }
+ if (m_children)
+ {
+ QListIterator<DotNode> nli(*m_children);
+ QListIterator<EdgeInfo> eli(*m_edgeInfo);
+ DotNode *childNode;
+ EdgeInfo *edgeInfo;
+ for (;(childNode=nli.current());++nli,++eli)
+ {
+ edgeInfo=eli.current();
+ t << " <childnode id=\"" << childNode->m_number << "\" relation=\"";
+ switch(edgeInfo->m_color)
+ {
+ case EdgeInfo::Blue: t << "public-inheritance"; break;
+ case EdgeInfo::Green: t << "protected-inheritance"; break;
+ case EdgeInfo::Red: t << "private-inheritance"; break;
+ case EdgeInfo::Purple: t << "usage"; break;
+ case EdgeInfo::Orange: t << "template-instance"; break;
+ case EdgeInfo::Grey: ASSERT(0); break;
+ }
+ t << "\">" << endl;
+ if (!edgeInfo->m_label.isEmpty())
+ {
+ int p=0;
+ int ni;
+ while ((ni=edgeInfo->m_label.find("\\n",p))!=-1)
+ {
+ t << " <edgelabel>"
+ << edgeInfo->m_label.mid(p,ni-p)
+ << "</edgelabel>" << endl;
+ p=ni+2;
+ }
+ t << " <edgelabel>"
+ << edgeInfo->m_label.right(edgeInfo->m_label.length()-p)
+ << "</edgelabel>" << endl;
+ }
+ t << " </childnode>" << endl;
+ }
+ }
+ t << " </node>" << endl;
+}
+
+
void DotNode::clearWriteFlag()
{
m_written=FALSE;
@@ -555,18 +617,6 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path)
{
QCString baseName;
baseName.sprintf("inherit_graph_%d",count++);
- //="inherit_graph_";
- //QCString diskName=n->m_url.copy();
- //int i=diskName.find('$');
- //if (i!=-1)
- //{
- // diskName=diskName.right(diskName.length()-i-1);
- //}
- //else /* take the label name as the file name (and strip any template stuff) */
- //{
- // diskName=n->m_label;
- //}
- //baseName = convertNameToFile(baseName+diskName);
baseName = convertNameToFile(baseName);
QCString dotName=baseName+".dot";
QCString gifName=baseName+".gif";
@@ -604,9 +654,10 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path)
out << "</table>" << endl;
return;
}
+ QCString mapLabel = convertNameToFile(n->m_label);
out << "<tr><td><img src=\"" << gifName << "\" border=\"0\" usemap=\"#"
- << n->m_label << "_map\"></td></tr>" << endl;
- out << "<map name=\"" << n->m_label << "_map\">" << endl;
+ << mapLabel << "_map\"></td></tr>" << endl;
+ out << "<map name=\"" << mapLabel << "_map\">" << endl;
convertMapFile(out,mapName);
out << "</map>" << endl;
if (Config_getBool("DOT_CLEANUP")) thisDir.remove(dotName);
@@ -1181,8 +1232,9 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
QDir::setCurrent(oldDir);
return baseName;
}
+ QCString mapLabel = convertNameToFile(m_startNode->m_label+"_"+mapName);
out << "<p><center><img src=\"" << baseName << ".gif\" border=\"0\" usemap=\"#"
- << m_startNode->m_label << "_" << mapName << "\" alt=\"";
+ << mapLabel << "\" alt=\"";
switch (m_graphType)
{
case Implementation:
@@ -1196,7 +1248,7 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
break;
}
out << "\"></center>" << endl;
- out << "<map name=\"" << m_startNode->m_label << "_" << mapName << "\">" << endl;
+ out << "<map name=\"" << mapLabel << "\">" << endl;
convertMapFile(out,baseName+".map");
out << "</map>" << endl;
thisDir.remove(baseName+".map");
@@ -1249,6 +1301,18 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
//--------------------------------------------------------------------
+void DotClassGraph::writeXML(QTextStream &t)
+{
+ QDictIterator<DotNode> dni(*m_usedNodes);
+ DotNode *node;
+ for (;(node=dni.current());++dni)
+ {
+ node->writeXML(t);
+ }
+}
+
+//--------------------------------------------------------------------
+
int DotInclDepGraph::m_curNodeNumber;
void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd,int distance)
diff --git a/src/dot.h b/src/dot.h
index 7539dbe..99a51be 100644
--- a/src/dot.h
+++ b/src/dot.h
@@ -76,6 +76,7 @@ class DotNode
int maxDistance=1000,bool backArrows=TRUE);
int m_subgraphId;
void clearWriteFlag();
+ void writeXML(QTextStream &t);
private:
void colorConnectedNodes(int curColor);
@@ -86,7 +87,7 @@ class DotNode
const DotNode *findDocNode() const; // only works for acyclic graphs!
int m_number;
QCString m_label; //!< label text
- QCString m_url; //!< url of the node (format: remove$local)
+ QCString m_url; //!< url of the node (format: remote$local)
QList<DotNode> *m_parents; //!< list of parent nodes (incoming arrows)
QList<DotNode> *m_children; //!< list of child nodes (outgoing arrows)
QList<EdgeInfo> *m_edgeInfo; //!< edge info for each child
@@ -123,6 +124,8 @@ class DotClassGraph
bool isTrivial() const;
QCString writeGraph(QTextStream &t,GraphOutputFormat f,const char *path,
bool TBRank=TRUE,bool imageMap=TRUE);
+
+ void writeXML(QTextStream &t);
QCString diskName() const;
private:
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index f19f411..d6c5911 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -1689,13 +1689,26 @@ void buildVarList(Entry *root)
QCString type=root->type.stripWhiteSpace();
ClassDef *cd=0;
- if (root->name.findRev("::")!=-1) goto nextMember;
+ if (root->name.findRev("::")!=-1)
+ {
+ if (root->type=="friend class" || root->type=="friend struct" ||
+ root->type=="friend union")
+ {
+ cd=getClass(scope);
+ if (cd)
+ {
+ addVariableToClass(root,cd,MemberDef::Friend,scope,
+ root->name,FALSE,0,0,Public);
+ }
+ }
+ goto nextMember;
/* skip this member, because it is a
* static variable definition (always?), which will be
* found in a class scope as well, but then we know the
* correct protection level, so only then it will be
* inserted in the correct list!
*/
+ }
if (type=="@")
mtype=MemberDef::EnumValue;
@@ -1708,6 +1721,7 @@ void buildVarList(Entry *root)
else
mtype=MemberDef::Variable;
+
QCString classScope=stripAnonymousNamespaceScope(scope);
classScope=stripTemplateSpecifiersFromScope(classScope,FALSE);
QCString annScopePrefix=scope.left(scope.length()-classScope.length());
@@ -1780,7 +1794,7 @@ nextMember:
// Searches the Entry tree for Function sections.
// If found they are stored in their class or in the global list.
-static void buildMemberList(Entry *root)
+static void buildFunctionList(Entry *root)
{
if (root->section==Entry::FUNCTION_SEC)
{
@@ -2205,7 +2219,7 @@ static void buildMemberList(Entry *root)
Entry *e;
for (;(e=eli.current());++eli)
{
- buildMemberList(e);
+ buildFunctionList(e);
}
}
@@ -2467,7 +2481,6 @@ static void findUsedClassesForClass(Entry *root,
QDict<int> *templateNames=0
)
{
- //if (masterCd->visited) return;
masterCd->visited=TRUE;
ArgumentList *formalArgs = masterCd->templateArguments();
MemberNameInfoSDict::Iterator mnili(*masterCd->memberNameInfoSDict());
@@ -2490,7 +2503,7 @@ static void findUsedClassesForClass(Entry *root,
{
type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs);
}
- //printf("extractClassNameFromType(%s)\n",type.data());
+ //printf("findUsedClassesForClass(%s)=%s\n",masterCd->name().data(),type.data());
while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec))
{
QCString typeName = resolveTypeDef(masterCd,usedClassName);
@@ -2577,6 +2590,20 @@ static void findUsedClassesForClass(Entry *root,
templateNames=0;
}
}
+ if (!found && !type.isEmpty()) // used class is not documented in any scope
+ {
+ ClassDef *usedCd = Doxygen::hiddenClasses.find(type);
+ if (usedCd==0)
+ {
+ Debug::print(Debug::Classes,0," New undocumented used class `%s'\n", type.data());
+ usedCd = new ClassDef(
+ masterCd->getDefFileName(),masterCd->getDefLine(),
+ type,ClassDef::Class);
+ Doxygen::hiddenClasses.inSort(type,usedCd);
+ }
+ if (isArtificial) usedCd->setClassIsArtificial();
+ instanceCd->addUsedClass(usedCd,md->name());
+ }
}
}
}
@@ -2897,9 +2924,9 @@ static bool findClassRelation(
}
}
bool isATemplateArgument = templateNames!=0 && templateNames->find(bi->name)!=0;
- if (!isATemplateArgument && found)
+ if (/*!isATemplateArgument &&*/ found)
{
- Debug::print(Debug::Classes,0," Documented base class `%s' templSpec=%s\n",bi->name.data(),templSpec.data());
+ Debug::print(Debug::Classes,0," Documented class `%s' templSpec=%s\n",bi->name.data(),templSpec.data());
// add base class to this class
// if templSpec is not empty then we should "instantiate"
@@ -2956,19 +2983,6 @@ static bool findClassRelation(
baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
// the undocumented base was found in this file
baseClass->insertUsedFile(root->fileName);
- // is this an inherited template argument?
- //printf("%s->setIsTemplateBaseClass(%d)\n",baseClass->name().data(),isTemplBaseClass);
- //if (isATemplateArgument)
- //{
- // baseClass->setIsTemplateBaseClass(*templateNames->find(bi->name));
- //}
- // add class to the list
- //if (!isATemplateArgument)
- //{
- //}
- //else
- //{
- //}
return TRUE;
}
else
@@ -3370,8 +3384,6 @@ static void addTodoTestBugReferences()
addFileMemberTodoTestBugReferences(0);
}
-
-
//----------------------------------------------------------------------
// Copy the documentation in entry `root' to member definition `md' and
// set the function declaration of the member to `funcDecl'. If the boolean
@@ -3828,18 +3840,6 @@ static void findMember(Entry *root,
}
} while (!done);
- if (isFriend)
- {
- if (funcDecl.left(6)=="class ")
- {
- funcDecl=funcDecl.right(funcDecl.length()-6);
- }
- else if (funcDecl.left(7)=="struct ")
- {
- funcDecl=funcDecl.right(funcDecl.length()-7);
- }
- }
-
// delete any ; from the function declaration
int sep;
while ((sep=funcDecl.find(';'))!=-1)
@@ -3857,12 +3857,27 @@ static void findMember(Entry *root,
":: ","::"
),
" ::","::"
- );
+ ).stripWhiteSpace();
- // extract information from the declarations
- parseFuncDecl(funcDecl,scopeName,funcType,funcName,
+ //printf("funcDecl=`%s'\n",funcDecl.data());
+ if (isFriend && funcDecl.left(6)=="class ")
+ {
+ //printf("friend class\n");
+ funcDecl=funcDecl.right(funcDecl.length()-6);
+ funcName = funcDecl.copy();
+ }
+ else if (isFriend && funcDecl.left(7)=="struct ")
+ {
+ funcDecl=funcDecl.right(funcDecl.length()-7);
+ funcName = funcDecl.copy();
+ }
+ else
+ {
+ // extract information from the declarations
+ parseFuncDecl(funcDecl,scopeName,funcType,funcName,
funcArgs,funcTempList,exceptions
);
+ }
//printf("scopeName=`%s' funcType=`%s' funcName=`%s'\n",
// scopeName.data(),funcType.data(),funcName.data());
@@ -4473,8 +4488,17 @@ static void findMemberDocumentation(Entry *root)
// root->name.data(),root->args.data(),root->exception.data());
//if (root->relates.length()) printf(" Relates %s\n",root->relates.data());
//printf("Inside=%s\n Relates=%s\n",root->inside.data(),root->relates.data());
-
- if (!root->type.isEmpty())
+ if (root->type=="friend class" || root->type=="friend struct" ||
+ root->type=="friend union")
+ {
+ findMember(root,
+ root->type+" "+
+ root->name,
+ root->relates,
+ FALSE,FALSE);
+
+ }
+ else if (!root->type.isEmpty())
{
findMember(root,
root->type+" "+
@@ -6098,15 +6122,20 @@ static void copyAndFilterFile(const char *fileName,BufStr &dest)
pclose(f);
}
// filter unwanted bytes from the resulting data
- uchar *p=(uchar *)dest.data()+oldPos;
uchar conv[256];
int i;
for (i=0;i<256;i++) conv[i]=i;
conv[0x06]=0x20; // replace the offending characters with spaces
conv[0x00]=0x20;
// remove any special markers from the input
+ uchar *p=(uchar *)dest.data()+oldPos;
for (i=0;i<size;i++,p++) *p=conv[*p];
- // adjust pointer
+ // and translate CR's
+ int newSize=filterCRLF(dest.data()+oldPos,size);
+ if (newSize!=size) // we removed chars
+ {
+ dest.resize(newSize); // resize the array
+ }
}
//----------------------------------------------------------------------------
@@ -7054,7 +7083,7 @@ void parseInput()
buildVarList(root);
msg("Building member list...\n"); // using class info only !
- buildMemberList(root);
+ buildFunctionList(root);
transferFunctionDocumentation();
msg("Searching for friends...\n");
diff --git a/src/doxytag.l b/src/doxytag.l
index 95e7cbe..b8f1279 100644
--- a/src/doxytag.l
+++ b/src/doxytag.l
@@ -220,6 +220,7 @@ QCString unhtmlify(const char *str)
<Start>^"<li>" {
BEGIN( SearchClassFile );
}
+<Start>^"<td"[^\n]*"<h1 align=center>" | // Qt-3.x.x+
<Start>^"<h1 align=center>" { // Qt variant
BEGIN( ReadClassName );
}
diff --git a/src/entry.h b/src/entry.h
index 146ce57..3646d40 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -216,7 +216,7 @@ class Entry
MEMBERGRP_SEC = 0x01300000,
USINGDECL_SEC = 0x01400000,
PACKAGE_SEC = 0x01500000,
- PACKAGEDOC_SEC = 0x01600000,
+ PACKAGEDOC_SEC = 0x01600000
};
enum MemberSpecifier
{
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 31c24fc..2320473 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -831,7 +831,7 @@ void HtmlGenerator::endAlphabeticalIndexList()
void HtmlGenerator::writeIndexHeading(const char *s)
{
t << "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td><div class=\"ah\">&nbsp;&nbsp;" << s
- << "&nbsp;&nbsp;</td</tr></table>";
+ << "&nbsp;&nbsp;</td></tr></table>";
}
void HtmlGenerator::startImage(const char *name,const char *,bool hasCaption)
@@ -940,7 +940,7 @@ void HtmlGenerator::startParameterType(bool first)
if (first)
{
DBG_HTML(t << "<!-- startFirstParameterType -->" << endl;)
- t << " <td class=\"md\">";
+ t << " <td class=\"md\" nowrap>";
}
else
{
@@ -948,14 +948,14 @@ void HtmlGenerator::startParameterType(bool first)
t << " <tr>" << endl;
t << " <td></td>" << endl;
t << " <td></td>" << endl;
- t << " <td class=\"md\">";
+ t << " <td class=\"md\" nowrap>";
}
}
void HtmlGenerator::endParameterType()
{
DBG_HTML(t << "<!-- endParameterType -->" << endl;)
- t << "</td>" << endl;
+ t << "&nbsp;</td>" << endl;
}
void HtmlGenerator::startParameterName(bool oneArgOnly)
diff --git a/src/htmlgen.h b/src/htmlgen.h
index cbc40f1..caed87f 100644
--- a/src/htmlgen.h
+++ b/src/htmlgen.h
@@ -120,6 +120,8 @@ class HtmlGenerator : public OutputGenerator
void endCodeFragment() { t << "</pre></div>"; }
void startPreFragment() { t << "<pre>"; }
void endPreFragment() { t << "</pre>"; }
+ void startLineNumber() {}
+ void endLineNumber() { t << " "; }
void startCodeLine() { col=0; }
void endCodeLine() { codify("\n"); }
//void writeBoldString(const char *text)
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index 7e072ac..7bdfbdf 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -1529,9 +1529,14 @@ void LatexGenerator::endMemberList()
void LatexGenerator::startImage(const char *name,const char *size,bool hasCaption)
{
if (hasCaption)
- t << "\\begin{figure}[H]" << endl;
+ {
+ t << "\\begin{figure}[h]" << endl;
+ t << "\\begin{center}" << endl;
+ }
else
+ {
t << "\\mbox{";
+ }
QCString gfxName = name;
if (gfxName.right(4)==".eps") gfxName.left(gfxName.length()-4);
// "\\epsfig{file=" << name;
@@ -1539,9 +1544,13 @@ void LatexGenerator::startImage(const char *name,const char *size,bool hasCaptio
if (size) t << "[" << size << "]";
t << "{" << gfxName << "}";
if (hasCaption)
+ {
t << "\\caption{";
+ }
else
+ {
t << "}" << endl;
+ }
}
void LatexGenerator::endImage(bool hasCaption)
@@ -1549,6 +1558,7 @@ void LatexGenerator::endImage(bool hasCaption)
if (hasCaption)
{
t << "}" << endl;
+ t << "\\end{center}" << endl;
t << "\\end{figure}" << endl;
}
}
diff --git a/src/latexgen.h b/src/latexgen.h
index 3b09340..bf3e530 100644
--- a/src/latexgen.h
+++ b/src/latexgen.h
@@ -118,6 +118,8 @@ class LatexGenerator : public OutputGenerator
void endPreFragment() { t << "\\end{alltt}\\normalsize " << endl;
insidePre=FALSE;
}
+ void startLineNumber() {}
+ void endLineNumber() { t << " "; }
void startCodeLine() { col=0; }
void endCodeLine() { codify("\n"); }
//void writeBoldString(const char *text)
diff --git a/src/mangen.h b/src/mangen.h
index 5ce5a7c..e87cbc7 100644
--- a/src/mangen.h
+++ b/src/mangen.h
@@ -110,6 +110,8 @@ class ManGenerator : public OutputGenerator
void endCodeFragment();
void startPreFragment() { startCodeFragment(); }
void endPreFragment() { endCodeFragment(); }
+ void startLineNumber() {}
+ void endLineNumber() { t << " "; }
void startCodeLine() {}
void endCodeLine() { codify("\n"); col=0; }
//void writeBoldString(const char *text)
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index 8aaa7cc..afdcab6 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -558,7 +558,8 @@ bool MemberDef::isBriefSectionVisible() const
// only include members is the are documented or
// HIDE_UNDOC_MEMBERS is NO in the config file
bool visibleIfDocumented = (!Config_getBool("HIDE_UNDOC_MEMBERS") ||
- hasDocumentation()
+ hasDocumentation() ||
+ isDocumentedFriendClass()
);
// hide members with no detailed description and brief descriptions
@@ -767,7 +768,7 @@ void MemberDef::writeDeclaration(OutputList &ol,
if (!name().isEmpty() && name().at(0)!='@')
{
//printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable());
- if (/*d->isLinkable() &&*/ isLinkable())
+ if (isLinkable())
{
if (annMemb)
{
@@ -786,7 +787,14 @@ void MemberDef::writeDeclaration(OutputList &ol,
writeLink(ol,cd,nd,fd,gd);
}
}
- else // there is a brief member description and brief member
+ else if (isDocumentedFriendClass())
+ // if the member is an undocumented friend declaration for some class,
+ // then maybe we can link to the class
+ {
+ writeLink(ol,getClass(name()),0,0,0);
+ }
+ else
+ // there is a brief member description and brief member
// descriptions are enabled or there is no detailed description.
{
if (annMemb) annMemb->annUsed=annUsed=TRUE;
@@ -1479,7 +1487,8 @@ void MemberDef::warnIfUndocumented()
else
t="file", d=fd;
- if (d && d->isLinkable() && !isLinkable() && name().find('@')==-1)
+ if (d && d->isLinkable() && !isLinkable() && !isDocumentedFriendClass()
+ && name().find('@')==-1)
warn_undoc(m_defFileName,m_defLine,"Warning: Member %s of %s %s is not documented.",
name().data(),t,d->name().data());
}
@@ -1520,11 +1529,20 @@ void MemberDef::setEnumDecl(OutputList &ed)
*enumDeclList+=ed;
}
+bool MemberDef::isDocumentedFriendClass() const
+{
+ ClassDef *fcd=0;
+ return (isFriend() &&
+ (type=="friend class" || type=="friend struct" ||
+ type=="friend union") &&
+ (fcd=getClass(name())) && fcd->isLinkable());
+}
+
bool MemberDef::hasDocumentation() const
{
return Definition::hasDocumentation() ||
(mtype==Enumeration && docEnumValues) || // has enum values
- (argList!=0 && argList->hasDocumentation());
+ (argList!=0 && argList->hasDocumentation()); // has doc arguments
}
void MemberDef::setMemberGroup(MemberGroup *grp)
diff --git a/src/memberdef.h b/src/memberdef.h
index 9b9280e..4af6f66 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -129,6 +129,7 @@ class MemberDef : public Definition
bool isBriefSectionVisible() const;
bool isDetailedSectionVisible(bool inGroup=FALSE) const;
bool isDetailedSectionLinkable() const;
+ bool isDocumentedFriendClass() const;
// set functions
void setMemberType(MemberType t) { mtype=t; }
diff --git a/src/memberlist.cpp b/src/memberlist.cpp
index c591ffc..bc9195b 100644
--- a/src/memberlist.cpp
+++ b/src/memberlist.cpp
@@ -250,20 +250,20 @@ void MemberList::writePlainDeclarations(OutputList &ol,
bool fmdVisible = fmd->isBriefSectionVisible();
while (fmd)
{
- /* in html we start a new line after a number of items */
- if (numVisibleEnumValues>enumValuesPerLine
- && (enumMemCount%enumValuesPerLine)==0
- )
- {
- typeDecl.pushGeneratorState();
- typeDecl.disableAllBut(OutputGenerator::Html);
- typeDecl.lineBreak();
- typeDecl.writeString("&nbsp;&nbsp;");
- typeDecl.popGeneratorState();
- }
-
if (fmdVisible)
{
+ /* in html we start a new line after a number of items */
+ if (numVisibleEnumValues>enumValuesPerLine
+ && (enumMemCount%enumValuesPerLine)==0
+ )
+ {
+ typeDecl.pushGeneratorState();
+ typeDecl.disableAllBut(OutputGenerator::Html);
+ typeDecl.lineBreak();
+ typeDecl.writeString("&nbsp;&nbsp;");
+ typeDecl.popGeneratorState();
+ }
+
if (fmd->hasDocumentation()) // enum value has docs
{
if (!Config_getString("GENERATE_TAGFILE").isEmpty())
diff --git a/src/outputgen.h b/src/outputgen.h
index 4b60bbd..15cab68 100644
--- a/src/outputgen.h
+++ b/src/outputgen.h
@@ -248,6 +248,8 @@ class BaseOutputDocInterface
virtual void endPageRef(const char *,const char *) = 0;
+ virtual void startLineNumber() = 0;
+ virtual void endLineNumber() = 0;
virtual void startCodeLine() = 0;
virtual void endCodeLine() = 0;
virtual void startCodeAnchor(const char *label) = 0;
diff --git a/src/outputlist.h b/src/outputlist.h
index 3cc0b44..8583e56 100644
--- a/src/outputlist.h
+++ b/src/outputlist.h
@@ -206,8 +206,10 @@ class OutputList : public OutputDocInterface
{ forall(&OutputGenerator::startCodeLine); }
void endCodeLine()
{ forall(&OutputGenerator::endCodeLine); }
- //void writeBoldString(const char *text)
- //{ forall(&OutputGenerator::writeBoldString,text); }
+ void startLineNumber()
+ { forall(&OutputGenerator::startLineNumber); }
+ void endLineNumber()
+ { forall(&OutputGenerator::endLineNumber); }
void startEmphasis()
{ forall(&OutputGenerator::startEmphasis); }
void endEmphasis()
diff --git a/src/pre.l b/src/pre.l
index 3832f27..40bb394 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -977,6 +977,22 @@ static void readIncludeFile(const QCString &inc)
/* ----------------------------------------------------------------- */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int len = fread( buf, 1, max_size, yyin );
+ if (len==0 && ferror( yyin ))
+ {
+ yy_fatal_error( "input in flex scanner failed" );
+ return len;
+ }
+ return filterCRLF(buf,len);
+}
+
+/* ----------------------------------------------------------------- */
+
%}
ID [a-z_A-Z][a-z_A-Z0-9]*
@@ -1018,30 +1034,39 @@ BN [ \t\r\n]
<*>\x06
<*>\x00
<*>\r
- /*
-<Start>^{B}*([^ \t#\n\/][^\n]*)?"\n" {
- //printf("%s line %d: %s",g_yyFileName.data(),g_yyLineNr,yytext);
- if (g_includeStack.isEmpty())
- {
- //preprocessedFile+=yytext;
- //char *s=yytext,c;
- //if (s) while ((c=*s++)) *dataPtr++=c;
- g_outputBuf->addArray(yytext,yyleng);
- }
- g_yyLineNr++;
- }
- */
<Start>^{B}*"#" { BEGIN(Command); }
<Start>^{B}*/[^#] {
outputArray(yytext,yyleng);
BEGIN(CopyLine);
}
- /*
-<CopyLine>[^\n/]+ {
- outputArray(yytext,yyleng);
+<Start>^{B}*[_A-Z][_A-Z0-9]*"("[^\)\n]*")"{B}*\n { // function like macro
+ static bool skipFuncMacros = Config_getBool("SKIP_FUNCTION_MACROS");
+ QCString name(yytext);
+ name=name.left(name.find('(')).stripWhiteSpace();
+
+ Define *def=0;
+ if (skipFuncMacros &&
+ !(
+ (g_includeStack.isEmpty() || g_curlyCount>0) &&
+ g_macroExpansion &&
+ (def=g_fileDefineDict->find(name)) &&
+ (!g_expandOnlyPredef || def->isPredefined)
+ )
+ )
+ {
+ outputChar('\n');
+ g_yyLineNr++;
+ }
+ else // don't skip
+ {
+ int i;
+ for (i=yyleng-1;i>=0;i--)
+ {
+ unput(yytext[i]);
+ }
+ BEGIN(CopyLine);
+ }
}
- */
-
<CopyLine>"{" { // count brackets inside the main file
if (g_includeStack.isEmpty())
g_curlyCount++;
@@ -1843,9 +1868,7 @@ void cleanupPreprocessor()
void preprocessFile(const char *fileName,BufStr &output)
{
-//#if DUMP_OUTPUT
uint orgOffset=output.curPos();
-//#endif
g_macroExpansion = Config_getBool("MACRO_EXPANSION");
g_expandOnlyPredef = Config_getBool("EXPAND_ONLY_PREDEF");
diff --git a/src/rtfgen.h b/src/rtfgen.h
index ce1b71d..5569328 100644
--- a/src/rtfgen.h
+++ b/src/rtfgen.h
@@ -110,6 +110,8 @@ class RTFGenerator : public OutputGenerator
void endCodeFragment();
void startPreFragment() { startCodeFragment(); }
void endPreFragment() { endCodeFragment(); }
+ void startLineNumber() {}
+ void endLineNumber() { t << " "; }
void startCodeLine() { col=0; }
void endCodeLine() { lineBreak(); }
//void writeBoldString(const char *text)
diff --git a/src/scanner.l b/src/scanner.l
index 65e50b6..0088e9a 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -598,7 +598,6 @@ TITLE [tT][iI][tT][lL][eE]
}
BEGIN( FindMembers );
}
-<*>\x0d
<NextSemi>"{" {
curlyCount=0;
needsSemi = TRUE;
@@ -733,7 +732,7 @@ TITLE [tT][iI][tT][lL][eE]
current->argList->clear();
lineCount() ;
}
-<FindMembers>{BN}+ {
+<FindMembers>{BN}{1,80} {
lineCount();
}
<FindMembers>{B}*"package"{BN}+ { // Java package
@@ -1751,9 +1750,9 @@ TITLE [tT][iI][tT][lL][eE]
//if (!current->name.isEmpty() && current->name[0]!='@' &&
// current->parent->section & Entry::COMPOUND_MASK)
// varEntry->type+=current->parent->name+"::";
- //if (isTypedef)
- //{
- // varEntry->type.prepend("typedef ");
+ if (isTypedef)
+ {
+ varEntry->type.prepend("typedef ");
// //printf("current->name = %s %s\n",current->name.data(),msName.data());
// if (!current->name.isEmpty() && current->name.at(0)!='@')
// {
@@ -1762,7 +1761,7 @@ TITLE [tT][iI][tT][lL][eE]
// if (current_root->section & Entry::SCOPE_MASK) scope=current_root->name;
// Doxygen::typedefDict.insert(msName,new TypedefInfo(current->name,scope));
// }
- //}
+ }
varEntry->type+=current->name+msType;
varEntry->fileName = yyFileName;
varEntry->startLine = yyLineNr;
diff --git a/src/translator_en.h b/src/translator_en.h
index edffbb9..9e841e2 100644
--- a/src/translator_en.h
+++ b/src/translator_en.h
@@ -534,7 +534,7 @@ class TranslatorEnglish : public Translator
*/
virtual QCString trGeneratedAt(const char *date,const char *projName)
{
- QCString result=(QCString)"Generated at "+date;
+ QCString result=(QCString)"Generated on "+date;
if (projName) result+=(QCString)" for "+projName;
result+=(QCString)" by";
return result;
diff --git a/src/util.cpp b/src/util.cpp
index 95193f7..5f54a61 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -365,6 +365,7 @@ QCString resolveTypeDef(Definition *d,const QCString &name)
//printf("resolveTypeDef(%s,%s)\n",d ? d->name().data() : "<none>",name.data());
QCString result;
if (name.isEmpty()) return result;
+
Definition *mContext=d;
MemberDef *md=0;
while (mContext && md==0)
@@ -409,26 +410,6 @@ QCString resolveTypeDef(Definition *d,const QCString &name)
}
return result;
-#if 0
- QCString typeName;
- if (!name.isEmpty())
- {
- TypedefInfo *ti = Doxygen::typedefDict[name];
- if (ti)
- {
- int count=0;
- typeName=ti->value;
- TypedefInfo *newTi;
- while ((newTi=Doxygen::typedefDict[typeName]) && count<10)
- {
- if (typeName==newTi->value) break; // prevent lock-up
- typeName=newTi->value;
- count++;
- }
- }
- }
- return typeName;
-#endif
}
/*! Get a class definition given its name.
@@ -472,16 +453,11 @@ ClassDef *getResolvedClass(
QCString *pTemplSpec
)
{
- //printf("getResolvedClass(%s,%s)\n",scope ? scope->name().data() : "<none>",
- // n);
+ //printf("getResolvedClass(%s,%s)\n",scope ? scope->name().data() : "<none>", n);
QCString name = n;
if (name.isEmpty()) return 0;
if (scope==0) scope=Doxygen::globalScope;
int i = name.findRev("::");
- //QCString subst = 0;
- //if (i!=-1) subst = Doxygen::typedefDict[name.right(name.length()-i-2)];
- //if (subst==0) subst = Doxygen::typedefDict[name],i=-1;
- //if (subst) // there is a typedef with this name
QCString subst;
if (i!=-1)
{
@@ -491,11 +467,17 @@ ClassDef *getResolvedClass(
{
subst = resolveTypeDef(scope,name);
}
+ //printf(" typedef subst=`%s'\n",subst.data());
if (!subst.isEmpty())
{
+ // strip * and & from n
+ int ip=subst.length()-1;
+ while (subst.at(ip)=='*' || subst.at(ip)=='&' || subst.at(ip)==' ') ip--;
+ subst=subst.left(ip+1);
+
if (pIsTypeDef) *pIsTypeDef=TRUE;
- //printf("getResolvedClass `%s'->`%s'\n",name.data(),subst->data());
+ //printf(" getResolvedClass `%s'->`%s'\n",name.data(),subst.data());
if (subst==name) // avoid resolving typedef struct foo foo;
{
return Doxygen::classSDict.find(name);
@@ -503,15 +485,24 @@ ClassDef *getResolvedClass(
int count=0; // recursion detection guard
QCString newSubst;
QCString typeName = subst;
+
if (i!=-1) typeName.prepend(name.left(i)+"::");
while (!(newSubst=resolveTypeDef(scope,typeName)).isEmpty()
&& count<10)
{
if (typeName==newSubst)
{
- return Doxygen::classSDict.find(subst); // for breaking typedef struct A A;
+ ClassDef *cd = Doxygen::classSDict.find(subst); // for breaking typedef struct A A;
+ //printf(" getClass: exit `%s' %p\n",subst.data(),cd);
+ return cd;
}
subst=newSubst;
+ // strip * and & from n
+ int ip=subst.length()-1;
+ while (subst.at(ip)=='*' || subst.at(ip)=='&' || subst.at(ip)==' ') ip--;
+ subst=subst.left(ip+1);
+ //printf(" getResolvedClass `%s'->`%s'\n",name.data(),subst.data());
+
typeName=newSubst;
if (i!=-1) typeName.prepend(name.left(i)+"::");
count++;
@@ -523,9 +514,9 @@ ClassDef *getResolvedClass(
}
else
{
- //printf("getClass: subst %s->%s\n",name.data(),typeName.data());
int i;
ClassDef *cd = Doxygen::classSDict.find(typeName);
+ //printf(" getClass: subst %s->%s cd=%p\n",name.data(),typeName.data(),cd);
if (cd==0 && (i=typeName.find('<'))>0) // try unspecialized version as well
{
if (pTemplSpec) *pTemplSpec = typeName.right(typeName.length()-i);
@@ -899,8 +890,33 @@ void setAnchors(char id,MemberList *ml,int groupId)
}
//----------------------------------------------------------------------------
-// read a file with `name' to a string.
+int filterCRLF(char *buf,int len)
+{
+ char *ps=buf;
+ char *pd=buf;
+ char c;
+ int i;
+ for (i=0;i<len;i++)
+ {
+ c=*ps++;
+ if (c=='\r')
+ {
+ if (*ps=='\n') ps++; // DOS: CR+LF -> LF
+ *pd++='\n'; // MAC: CR -> LF
+ }
+ else
+ {
+ *pd++=c;
+ }
+ }
+ return len+pd-ps;
+}
+
+/*! reads a file with name \a name and returns it as a string. If \a filter
+ * is TRUE the file will be filtered by any user specified input filter.
+ * If \a name is "-" the string will be read from standard input.
+ */
QCString fileToString(const char *name,bool filter)
{
if (name==0 || name[0]==0) return 0;
@@ -921,7 +937,7 @@ QCString fileToString(const char *name,bool filter)
totalSize+=bSize;
contents.resize(totalSize+bSize);
}
- totalSize+=size+2;
+ totalSize = filterCRLF(contents.data(),totalSize+size)+2;
contents.resize(totalSize);
contents.at(totalSize-2)='\n'; // to help the scanner
contents.at(totalSize-1)='\0';
@@ -951,6 +967,11 @@ QCString fileToString(const char *name,bool filter)
contents[fsize]='\n'; // to help the scanner
contents[fsize+1]='\0';
f.close();
+ int newSize = filterCRLF(contents.data(),fsize+2);
+ if (newSize!=fsize+2)
+ {
+ contents.resize(newSize);
+ }
return contents;
}
}
@@ -972,7 +993,7 @@ QCString fileToString(const char *name,bool filter)
totalSize+=bSize;
contents.resize(totalSize+bSize);
}
- totalSize+=size+2;
+ totalSize = filterCRLF(contents.data(),totalSize+size)+2;
contents.resize(totalSize);
contents.at(totalSize-2)='\n'; // to help the scanner
contents.at(totalSize-1)='\0';
@@ -3212,7 +3233,7 @@ QCString substituteTemplateArgumentsInString(
}
else if (formArg->name==n && actArg==0 && !formArg->defval.isEmpty())
{
- result += formArg->defval;
+ result += substituteTemplateArgumentsInString(formArg->defval,formalArgs,actualArgs);
found=TRUE;
}
}
diff --git a/src/util.h b/src/util.h
index c61bd33..b9a4bf1 100644
--- a/src/util.h
+++ b/src/util.h
@@ -164,6 +164,7 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName,
QCString resolveTypeDef(Definition *d,const QCString &name);
QCString mergeScopes(const QCString &leftScope,const QCString &rightScope);
int getScopeFragment(const QCString &s,int p,int *l);
+int filterCRLF(char *buf,int len);
#endif
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index f18c2f3..dfe19b9 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -28,12 +28,14 @@
#include "defargs.h"
#include "outputgen.h"
#include "doc.h"
+#include "dot.h"
+#include "code.h"
#include <qdir.h>
#include <qfile.h>
#include <qtextstream.h>
-static QCString sectionTypeToString(BaseOutputDocInterface::SectionTypes t)
+QCString sectionTypeToString(BaseOutputDocInterface::SectionTypes t)
{
switch (t)
{
@@ -62,15 +64,19 @@ static QCString sectionTypeToString(BaseOutputDocInterface::SectionTypes t)
return "illegal";
}
-static inline void writeXMLString(QTextStream &t,const char *s)
+inline void writeXMLString(QTextStream &t,const char *s)
{
t << convertToXML(s);
}
-static void writeXMLLink(QTextStream &t,const char *compoundId,
+void writeXMLLink(QTextStream &t,const char *extRef,const char *compoundId,
const char *anchorId,const char *text)
{
t << "<ref idref=\"" << compoundId << "\"";
+ if (extRef)
+ {
+ t << " external=\"" << extRef << "\"";
+ }
if (anchorId)
{
t << " anchor=\"" << anchorId << "\"";
@@ -93,10 +99,7 @@ class TextGeneratorXMLImpl : public TextGeneratorIntf
const char *anchor,const char *text
) const
{
- if (extRef==0)
- { writeXMLLink(m_t,file,anchor,text); }
- else // external references are not supported for XML
- { writeXMLString(m_t,text); }
+ writeXMLLink(m_t,extRef,file,anchor,text);
}
private:
QTextStream &m_t;
@@ -418,26 +421,12 @@ class XMLGenerator : public OutputDocInterface
void writeObjectLink(const char *ref,const char *file,
const char *anchor, const char *text)
{
- if (ref) // TODO: add support for external references
- {
- docify(text);
- }
- else
- {
- writeXMLLink(m_t,file,anchor,text);
- }
+ writeXMLLink(m_t,ref,file,anchor,text);
}
void writeCodeLink(const char *ref,const char *file,
const char *anchor,const char *text)
{
- if (ref) // TODO: add support for external references
- {
- docify(text);
- }
- else
- {
- writeXMLLink(m_t,file,anchor,text);
- }
+ writeXMLLink(m_t,ref,file,anchor,text);
}
void startHtmlLink(const char *url)
{
@@ -628,14 +617,22 @@ class XMLGenerator : public OutputDocInterface
void endPageRef(const char *,const char *)
{
}
+ void startLineNumber()
+ {
+ m_t << "<linenumber>";
+ }
+ void endLineNumber()
+ {
+ m_t << "</linenumber>";
+ }
void startCodeLine()
{
startParMode();
- m_t << "<linenumber>"; // non DocBook
+ m_t << "<codeline>"; // non DocBook
}
void endCodeLine()
{
- m_t << "</linenumber>"; // non DocBook
+ m_t << "</codeline>" << endl; // non DocBook
}
void startCodeAnchor(const char *id)
{
@@ -740,6 +737,8 @@ class XMLGenerator : public OutputDocInterface
ValStack<bool> m_inParStack;
ValStack<bool> m_inListStack;
bool m_inParamList;
+
+ friend void writeXMLCodeBlock(QTextStream &t,FileDef *fd);
};
void writeXMLDocBlock(QTextStream &t,
@@ -762,6 +761,21 @@ void writeXMLDocBlock(QTextStream &t,
delete xmlGen;
}
+void writeXMLCodeBlock(QTextStream &t,FileDef *fd)
+{
+ initParseCodeContext();
+ XMLGenerator *xmlGen = new XMLGenerator;
+ xmlGen->m_inParStack.push(TRUE);
+ parseCode(*xmlGen,
+ 0,
+ fileToString(fd->absFilePath(),Config_getBool("FILTER_SOURCE_FILES")),
+ FALSE,
+ 0,
+ fd);
+ t << xmlGen->getContents();
+ delete xmlGen;
+}
+
void generateXMLForMember(MemberDef *md,QTextStream &t,Definition *def)
@@ -952,19 +966,18 @@ void generateXMLClassSection(ClassDef *cd,QTextStream &t,MemberList *ml,const ch
void generateXMLForClass(ClassDef *cd,QTextStream &t)
{
- // brief description
- // detailed description
- // template arguments
- // include files
- // inheritance diagram
- // list of direct super classes
- // list of direct sub classes
- // collaboration diagram
- // list of all members
- // user defined member sections
- // standard member sections
- // detailed documentation
- // detailed member documentation
+ // + brief description
+ // + detailed description
+ // - template arguments
+ // - include files
+ // + inheritance diagram
+ // + list of direct super classes
+ // + list of direct sub classes
+ // + collaboration diagram
+ // - list of all members
+ // + user defined member sections
+ // + standard member sections
+ // + detailed member documentation
if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
if (cd->templateMaster()!=0) return; // skip generated template instances.
@@ -1071,6 +1084,20 @@ void generateXMLForClass(ClassDef *cd,QTextStream &t)
t << " <detaileddescription>" << endl;
writeXMLDocBlock(t,cd->getDefFileName(),cd->getDefLine(),cd->name(),0,cd->documentation());
t << " </detaileddescription>" << endl;
+ DotClassGraph inheritanceGraph(cd,DotClassGraph::Inheritance);
+ if (!inheritanceGraph.isTrivial())
+ {
+ t << " <inheritancegraph>" << endl;
+ inheritanceGraph.writeXML(t);
+ t << " </inheritancegraph>" << endl;
+ }
+ DotClassGraph collaborationGraph(cd,DotClassGraph::Implementation);
+ if (!collaborationGraph.isTrivial())
+ {
+ t << " <collaborationgraph>" << endl;
+ collaborationGraph.writeXML(t);
+ t << " </collaborationgraph>" << endl;
+ }
t << " </compounddef>" << endl;
}
@@ -1118,6 +1145,9 @@ void generateXMLForFile(FileDef *fd,QTextStream &t)
t << " <detaileddescription>" << endl;
writeXMLDocBlock(t,fd->getDefFileName(),fd->getDefLine(),0,0,fd->documentation());
t << " </detaileddescription>" << endl;
+ t << " <sourcecode>" << endl;
+ writeXMLCodeBlock(t,fd);
+ t << " </sourcecode>" << endl;
t << " </compounddef>" << endl;
}
diff --git a/tmake/lib/hpux-g++/tmake.conf b/tmake/lib/hpux-g++/tmake.conf
index 872ab8d..cde6172 100755
--- a/tmake/lib/hpux-g++/tmake.conf
+++ b/tmake/lib/hpux-g++/tmake.conf
@@ -11,7 +11,7 @@ TMAKE_CC = gcc
TMAKE_CFLAGS =
TMAKE_CFLAGS_WARN_ON = -Wall -W
TMAKE_CFLAGS_WARN_OFF =
-TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_RELEASE = -O0
TMAKE_CFLAGS_DEBUG = -g
TMAKE_CFLAGS_SHLIB = -fPIC
TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
diff --git a/tmake/lib/irix-g++/tmake.conf b/tmake/lib/irix-g++/tmake.conf
index 32f1289..4b90f46 100755
--- a/tmake/lib/irix-g++/tmake.conf
+++ b/tmake/lib/irix-g++/tmake.conf
@@ -11,7 +11,7 @@ TMAKE_CC = gcc
TMAKE_CFLAGS =
TMAKE_CFLAGS_WARN_ON = -Wall -W
TMAKE_CFLAGS_WARN_OFF =
-TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_RELEASE = -O0
TMAKE_CFLAGS_DEBUG = -g
TMAKE_CFLAGS_SHLIB = -fPIC
TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses