From 4ce0e4344711a79781e2f6d64f2553ab4b45c4a5 Mon Sep 17 00:00:00 2001
From: dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>
Date: Sun, 9 Sep 2001 13:43:55 +0000
Subject: Release-1.2.10-20010909

---
 INSTALL                       |   4 +-
 README                        |   4 +-
 VERSION                       |   2 +-
 doc/Doxyfile                  |   2 +-
 doc/arch.doc                  | 240 ++++++++++++++++++++++++++
 doc/archoverview.eps          | 380 ++++++++++++++++++++++++++++++++++++++++++
 doc/archoverview.gif          | Bin 0 -> 7822 bytes
 doc/config.doc                |   9 +
 doc/doxygen_manual.tex        |   3 +
 doc/index.doc                 |  10 +-
 doc/language.doc              |   2 +-
 packages/rpm/doxygen.spec     |   2 +-
 src/classdef.cpp              |   2 +-
 src/code.l                    | 139 +++++++++++----
 src/config.l                  |   9 +
 src/doc.l                     |   2 +-
 src/dot.cpp                   |  96 +++++++++--
 src/dot.h                     |   5 +-
 src/doxygen.cpp               | 113 ++++++++-----
 src/doxytag.l                 |   1 +
 src/entry.h                   |   2 +-
 src/htmlgen.cpp               |   8 +-
 src/htmlgen.h                 |   2 +
 src/latexgen.cpp              |  12 +-
 src/latexgen.h                |   2 +
 src/mangen.h                  |   2 +
 src/memberdef.cpp             |  28 +++-
 src/memberdef.h               |   1 +
 src/memberlist.cpp            |  24 +--
 src/outputgen.h               |   2 +
 src/outputlist.h              |   6 +-
 src/pre.l                     |  63 ++++---
 src/rtfgen.h                  |   2 +
 src/scanner.l                 |  11 +-
 src/translator_en.h           |   2 +-
 src/util.cpp                  |  87 ++++++----
 src/util.h                    |   1 +
 src/xmlgen.cpp                | 106 +++++++-----
 tmake/lib/hpux-g++/tmake.conf |   2 +-
 tmake/lib/irix-g++/tmake.conf |   2 +-
 40 files changed, 1166 insertions(+), 224 deletions(-)
 create mode 100644 doc/arch.doc
 create mode 100644 doc/archoverview.eps
 create mode 100644 doc/archoverview.gif

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
Binary files /dev/null and b/doc/archoverview.gif 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
-- 
cgit v0.12

