From 02b5f51ef09a211e16e0158e5115ddf5b33d194d Mon Sep 17 00:00:00 2001
From: dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>
Date: Wed, 24 Mar 2004 21:24:19 +0000
Subject: Release-1.3.6-20040324

---
 INSTALL                   |    4 +-
 README                    |    4 +-
 VERSION                   |    2 +-
 doc/commands.doc          |   10 +
 doc/config.doc            |   11 +
 packages/rpm/doxygen.spec |    2 +-
 src/classdef.cpp          |    4 +-
 src/config.l              |   33 +-
 src/declinfo.l            |    6 +-
 src/defargs.l             |    2 +-
 src/definition.h          |    2 +-
 src/docparser.cpp         |   20 +-
 src/docparser.h           |    8 +
 src/doctokenizer.l        |    3 +-
 src/dot.cpp               |   19 +-
 src/dot.h                 |    5 +-
 src/doxygen.cpp           |    2 +
 src/doxygen.h             |    1 +
 src/htmldocvisitor.cpp    |   20 +-
 src/htmldocvisitor.h      |    2 +-
 src/htmlgen.cpp           |  105 +++--
 src/htmlgen.h             |    3 +-
 src/latexdocvisitor.cpp   |    4 +-
 src/latexgen.cpp          |   24 +-
 src/latexgen.h            |    3 +-
 src/mangen.cpp            |    8 +-
 src/mangen.h              |    2 +-
 src/memberdef.cpp         | 1048 +++++++++++++++++++++++----------------------
 src/memberdef.h           |    1 +
 src/outputgen.h           |    2 +-
 src/outputlist.h          |    4 +-
 src/rtfgen.cpp            |   13 +-
 src/rtfgen.h              |    3 +-
 src/scanner.l             |  113 ++---
 src/util.cpp              |  101 ++++-
 src/util.h                |    6 +
 36 files changed, 902 insertions(+), 698 deletions(-)

diff --git a/INSTALL b/INSTALL
index 4963bfe..78d83e1 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,7 +1,7 @@
-DOXYGEN Version 1.3.6-20040307
+DOXYGEN Version 1.3.6-20040324
 
 Please read the installation section of the manual 
 (http://www.doxygen.org/install.html) for instructions.
 
 --------
-Dimitri van Heesch (07 March 2004)
+Dimitri van Heesch (24 March 2004)
diff --git a/README b/README
index 7ef83dd..8f59530 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-DOXYGEN Version 1.3.6_20040307
+DOXYGEN Version 1.3.6_20040324
 
 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) (07 March 2004)
+Dimitri van Heesch (dimitri@stack.nl) (24 March 2004)
diff --git a/VERSION b/VERSION
index a1e7d6c..2836576 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.3.6-20040307
+1.3.6-20040324
diff --git a/doc/commands.doc b/doc/commands.doc
index 4d3d804..39a6aa6 100644
--- a/doc/commands.doc
+++ b/doc/commands.doc
@@ -147,6 +147,7 @@ documentation:
 \refitem cmdlt \\\<
 \refitem cmdgt \\\>
 \refitem cmdhash \\\#
+\refitem cmdperc \\\%
 \endsecreflist
 
 The following subsections provide a list of all commands that are recognized by
@@ -1956,6 +1957,15 @@ class C {};
   \f$\mbox{\LaTeX}\f$ output. This 
   character has to be escaped because it has a special meaning in HTML.
 
+\section cmdperc \%
+
+  \addindex \\\%
+  This command writes the \% character to the HTML and 
+  \f$\mbox{\LaTeX}\f$ output. This 
+  character has to be escaped in some cases, because it is used to 
+  prevent auto-linking to word that is also a documented class or struct. 
+
+<hr>
 <hr>
 <h2>\htmlonly <center> --- \endhtmlonly 
     Commands included for Qt compatibility
diff --git a/doc/config.doc b/doc/config.doc
index fb671b8..35aa62b 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -71,6 +71,7 @@ followed by the descriptions of the tags grouped by category.
 \refitem cfg_cols_in_alpha_index COLS_IN_ALPHA_INDEX
 \refitem cfg_compact_latex COMPACT_LATEX 
 \refitem cfg_compact_rtf COMPACT_RTF
+\refitem cfg_create_subdirs CREATE_SUBDIRS
 \refitem cfg_details_at_top DETAILS_AT_TOP 
 \refitem cfg_disable_index DISABLE_INDEX 
 \refitem cfg_distribute_group_doc DISTRIBUTE_GROUP_DOC
@@ -233,6 +234,16 @@ followed by the descriptions of the tags grouped by category.
  If a relative path is entered, it will be relative to the location 
  where doxygen was started. If left blank the current directory will be used.
 
+\anchor cfg_create_subdirs
+<dt>\c CREATE_SUBDIRS <dd> 
+ \addindex CREATE_SUBDIRS
+ If the \c CREATE_SUBDIRS tag is set to \c YES, then doxygen will create
+ 2 levels of 10 sub-directories under the output directory of each output 
+ format and will distribute the generated files over these directories. 
+ Enabling this option can be useful when feeding doxygen a huge amount of source
+ files, where putting all generated files in the same directory would otherwise
+ causes performance problems for the file system. 
+
 \anchor cfg_output_language
 <dt>\c OUTPUT_LANGUAGE <dd>
  \addindex OUTPUT_LANGUAGE
diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec
index 96436aa..f6465d0 100644
--- a/packages/rpm/doxygen.spec
+++ b/packages/rpm/doxygen.spec
@@ -1,6 +1,6 @@
 Summary: A documentation system for C/C++.
 Name: doxygen
-Version: 1.3.6_20040307
+Version: 1.3.6_20040324
 Release: 1
 Epoch: 1
 Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 7721925..802b9cd 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -1186,7 +1186,7 @@ void ClassDef::writeDocumentation(OutputList &ol)
         ol.pushGeneratorState();
         ol.disableAllBut(OutputGenerator::Html);
         ol.writeString("<center><font size=\"2\">[");
-        ol.startHtmlLink("graph_legend"+Doxygen::htmlFileExtension);
+        ol.startHtmlLink(relativePathToRoot(0)+"graph_legend"+Doxygen::htmlFileExtension);
         ol.docify(theTranslator->trLegend());
         ol.endHtmlLink();
         ol.writeString("]</font></center>");
@@ -1220,7 +1220,7 @@ void ClassDef::writeDocumentation(OutputList &ol)
       {
         ol.disableAllBut(OutputGenerator::Html);
         ol.writeString("<center><font size=\"2\">[");
-        ol.startHtmlLink("graph_legend"+Doxygen::htmlFileExtension);
+        ol.startHtmlLink(relativePathToRoot(0)+"graph_legend"+Doxygen::htmlFileExtension);
         ol.docify(theTranslator->trLegend());
         ol.endHtmlLink();
         ol.writeString("]</font></center>");
diff --git a/src/config.l b/src/config.l
index faee601..e63d0bb 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1319,18 +1319,29 @@ void Config::create()
                  "where doxygen was started. If left blank the current directory will be used.\n"
 		);
   cs->setWidgetType(ConfigString::Dir);
+  cb = addBool(
+                 "CREATE_SUBDIRS",
+                 "If the CREATE_SUBDIRS tag is set to YES, then doxygen will create \n"
+                 "2 levels of 10 sub-directories under the output directory of each output \n"
+		 "format and will distribute the generated files over these directories. \n"
+		 "Enabling this option can be useful when feeding doxygen a huge amount of source \n"
+		 "files, where putting all generated files in the same directory would otherwise \n"
+		 "cause performance problems for the file system. \n",
+		 FALSE
+                );
+  cb->addDependency("GENERATE_HTML");
   ce = addEnum(
-                    "OUTPUT_LANGUAGE",
-                    "The OUTPUT_LANGUAGE tag is used to specify the language in which all \n"
-                    "documentation generated by doxygen is written. Doxygen will use this \n"
-                    "information to generate all constant output in the proper language. \n"
-                    "The default language is English, other supported languages are: \n"
-		    "Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, \n"
-		    "Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en \n"
-		    "(Japanese with English messages), Korean, Korean-en, Norwegian, Polish, Portuguese, \n"
-		    "Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.\n",
-		    "English"
-                   );
+                 "OUTPUT_LANGUAGE",
+                 "The OUTPUT_LANGUAGE tag is used to specify the language in which all \n"
+                 "documentation generated by doxygen is written. Doxygen will use this \n"
+                 "information to generate all constant output in the proper language. \n"
+                 "The default language is English, other supported languages are: \n"
+		 "Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, \n"
+		 "Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en \n"
+		 "(Japanese with English messages), Korean, Korean-en, Norwegian, Polish, Portuguese, \n"
+		 "Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.\n",
+		 "English"
+                );
 #ifdef LANG_BR
   ce->addValue("Brazilian");
 #endif
diff --git a/src/declinfo.l b/src/declinfo.l
index 7058e43..0be2a08 100644
--- a/src/declinfo.l
+++ b/src/declinfo.l
@@ -65,7 +65,11 @@ static void addTypeName()
 {
   //printf("addTypeName() type=`%s' scope=`%s' name=`%s'\n",
   //       type.data(),scope.data(),name.data());
-  if (name.isEmpty()) return;
+  if (name.isEmpty() || 
+      name.at(name.length()-1)==':')  // end of Objective-C keyword => append to name not type
+  {
+    return;
+  }
   if (!type.isEmpty()) type+=' ';
   type+=name;
   name.resize(0);
diff --git a/src/defargs.l b/src/defargs.l
index ebeba4e..db8f000 100644
--- a/src/defargs.l
+++ b/src/defargs.l
@@ -266,7 +266,7 @@ ID	[a-z_A-Z][a-z_A-Z0-9]*
 					    if (l>0)
 					    {
 					      int i=l-1;
-					      while (i>=0 && (isspace(g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='.')) i--;
+					      while (i>=0 && (isspace((uchar)g_curArgTypeName.at(i)) || g_curArgTypeName.at(i)=='.')) i--;
 					      while (i>=0 && isId(g_curArgTypeName.at(i))) i--;
 					      //printf("g_curArgTypeName=`%s' i=%d\n",g_curArgTypeName.data(),i);
 					      Argument *a = new Argument; 
diff --git a/src/definition.h b/src/definition.h
index 6ddce6c..88d0479 100644
--- a/src/definition.h
+++ b/src/definition.h
@@ -58,7 +58,7 @@ class Definition
     /*! Returns the base name of the output file that contains this 
      *  definition. 
      */
-    QCString qualifiedName() const;
+    virtual QCString qualifiedName() const;
     QCString localName() const;
     virtual QCString getOutputFileBase() const = 0;
     /*! Returns the name of the source listing of this file. */
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 645a8f9..ee0d83a 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -84,6 +84,7 @@ static QStack<DocStyleChange> g_styleStack;
 static QStack<DocStyleChange> g_initialStyleStack;
 static QList<Definition>      g_copyStack;
 static QString                g_fileName;
+static QString                g_relPath;
 
 struct DocParserContext
 {
@@ -96,6 +97,7 @@ struct DocParserContext
   QList<Definition> copyStack;
   MemberDef *memberDef;
   QString fileName;
+  QString relPath;
 };
 
 static QStack<DocParserContext> g_parserStack;
@@ -114,6 +116,7 @@ static void docParserPushContext()
   ctx->initialStyleStack  = g_initialStyleStack;
   ctx->copyStack          = g_copyStack;
   ctx->fileName           = g_fileName;
+  ctx->relPath            = g_relPath;
   g_parserStack.push(ctx);
 }
 
@@ -128,6 +131,7 @@ static void docParserPopContext()
   g_initialStyleStack   = ctx->initialStyleStack;
   g_copyStack           = ctx->copyStack;
   g_fileName            = ctx->fileName;
+  g_relPath             = ctx->relPath;
   delete ctx;
   doctokenizerYYpopContext();
 }
@@ -1191,7 +1195,7 @@ DocLinkedWord::DocLinkedWord(DocNode *parent,const QString &word,
                   const QString &ref,const QString &file,
                   const QString &anchor) : 
       m_parent(parent), m_word(word), m_ref(ref), 
-      m_file(file), m_anchor(anchor) 
+      m_file(file), m_relPath(g_relPath), m_anchor(anchor) 
 {
   //printf("new word %s url=%s\n",word.data(),g_searchUrl.data());
   if (!g_searchUrl.isEmpty())
@@ -1281,7 +1285,7 @@ void DocIncOperator::parse()
           if (nonEmpty) break; // we have a pattern to match
           so=o+1; // no pattern, skip empty line
         }
-        else if (!isspace(c)) // no white space char
+        else if (!isspace((uchar)c)) // no white space char
         {
           nonEmpty=TRUE;
         }
@@ -1306,7 +1310,7 @@ void DocIncOperator::parse()
             if (nonEmpty) break; // we have a pattern to match
             so=o+1; // no pattern, skip empty line
           }
-          else if (!isspace(c)) // no white space char
+          else if (!isspace((uchar)c)) // no white space char
           {
             nonEmpty=TRUE;
           }
@@ -1334,7 +1338,7 @@ void DocIncOperator::parse()
             if (nonEmpty) break; // we have a pattern to match
             so=o+1; // no pattern, skip empty line
           }
-          else if (!isspace(c)) // no white space char
+          else if (!isspace((uchar)c)) // no white space char
           {
             nonEmpty=TRUE;
           }
@@ -1361,7 +1365,7 @@ void DocIncOperator::parse()
             if (nonEmpty) break; // we have a pattern to match
             so=o+1; // no pattern, skip empty line
           }
-          else if (!isspace(c)) // no white space char
+          else if (!isspace((uchar)c)) // no white space char
           {
             nonEmpty=TRUE;
           }
@@ -1635,7 +1639,7 @@ endsecreflist:
 //---------------------------------------------------------------------------
 
 DocInternalRef::DocInternalRef(DocNode *parent,const QString &ref) 
-  : m_parent(parent)
+  : m_parent(parent), m_relPath(g_relPath)
 {
   int i=ref.find('#');
   if (i!=-1)
@@ -1691,6 +1695,7 @@ DocRef::DocRef(DocNode *parent,const QString &target) :
   Definition  *compound = 0;
   QCString     anchor;
   ASSERT(!target.isEmpty());
+  m_relPath = g_relPath;
   SectionInfo *sec = Doxygen::sectionDict[target];
   if (sec) // ref to section or anchor
   {
@@ -1779,6 +1784,7 @@ DocLink::DocLink(DocNode *parent,const QString &target) :
   //PageInfo *page;
   QCString anchor;
   m_refText = target;
+  m_relPath = g_relPath;
   if (!m_refText.isEmpty() && m_refText.at(0)=='#')
   {
     m_refText = m_refText.right(m_refText.length()-1);
@@ -4889,6 +4895,7 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
   }
 
   g_fileName = fileName;
+  g_relPath = ctx ? relativePathToRoot(ctx->getOutputFileBase()) : QString("");
   g_memberDef = md;
   g_nodeStack.clear();
   g_styleStack.clear();
@@ -4940,6 +4947,7 @@ DocNode *validatingParseText(const char *input)
   g_token = new TokenInfo;
   g_context = "";
   g_fileName = "<parseText>";
+  g_relPath = "";
   g_memberDef = 0;
   g_nodeStack.clear();
   g_styleStack.clear();
diff --git a/src/docparser.h b/src/docparser.h
index 0aba864..6ccb05c 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -203,6 +203,7 @@ class DocLinkedWord : public DocNode
     Kind kind() const          { return Kind_Word; }
     DocNode *parent() const    { return m_parent; }
     QString file() const       { return m_file; }
+    QString relPath() const    { return m_relPath; }
     QString ref() const        { return m_ref; }
     QString anchor() const     { return m_anchor; }
     void accept(DocVisitor *v) { v->visit(this); }
@@ -212,6 +213,7 @@ class DocLinkedWord : public DocNode
     QString  m_word;
     QString  m_ref;
     QString  m_file;
+    QString  m_relPath;
     QString  m_anchor;
 };
 
@@ -614,6 +616,7 @@ class DocLink : public CompAccept<DocLink>, public DocNode
     QString parse(bool);
     Kind kind() const          { return Kind_Link; }
     QString file() const       { return m_file; }
+    QString relPath() const    { return m_relPath; }
     QString ref() const        { return m_ref; }
     QString anchor() const     { return m_anchor; }
     DocNode *parent() const    { return m_parent; }
@@ -622,6 +625,7 @@ class DocLink : public CompAccept<DocLink>, public DocNode
   private:
     DocNode *m_parent;
     QString  m_file;
+    QString  m_relPath;
     QString  m_ref;
     QString  m_anchor;
     QString  m_refText;
@@ -635,6 +639,7 @@ class DocRef : public CompAccept<DocRef>, public DocNode
     void parse();
     Kind kind() const            { return Kind_Ref; }
     QString file() const         { return m_file; }
+    QString relPath() const      { return m_relPath; }
     QString ref() const          { return m_ref; }
     QString anchor() const       { return m_anchor; }
     QString targetTitle() const  { return m_text; }
@@ -649,6 +654,7 @@ class DocRef : public CompAccept<DocRef>, public DocNode
     bool      m_refToSection;
     bool      m_refToAnchor;
     QString   m_file;
+    QString   m_relPath;
     QString   m_ref;
     QString   m_anchor;
     QString   m_text;
@@ -662,6 +668,7 @@ class DocInternalRef : public CompAccept<DocInternalRef>, public DocNode
     void parse();
     Kind kind() const            { return Kind_Ref; }
     QString file() const         { return m_file; }
+    QString relPath() const      { return m_relPath; }
     QString anchor() const       { return m_anchor; }
     DocNode *parent() const      { return m_parent; }
     void accept(DocVisitor *v)   { CompAccept<DocInternalRef>::accept(this,v); }
@@ -669,6 +676,7 @@ class DocInternalRef : public CompAccept<DocInternalRef>, public DocNode
   private:
     DocNode * m_parent;
     QString   m_file;
+    QString   m_relPath;
     QString   m_anchor;
 };
 
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 3c3dcaf..5c9b6ea 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -292,7 +292,8 @@ TEMPCHAR  [a-z_A-Z0-9,: \t\*\&]
 FUNCCHAR  [a-z_A-Z0-9,:\<\> \t\*\&]
 SCOPESEP  "::"|"#"|"."
 SCOPEPRE  {ID}("<"{TEMPCHAR}*">")?{SCOPESEP}
-SCOPEMASK {SCOPEPRE}*(~)?{ID}("<"{TEMPCHAR}*">")?
+SCOPEKEYS ":"({ID}":")*
+SCOPEMASK {SCOPEPRE}*(~)?{ID}{SCOPEKEYS}?("<"{TEMPCHAR}*">")?
 FUNCARG   "("{FUNCCHAR}*")"
 OPNEW     {BLANK}+"new"({BLANK}*"[]")?
 OPDEL     {BLANK}+"delete"({BLANK}*"[]")?
diff --git a/src/dot.cpp b/src/dot.cpp
index 86ef71e..16c5d07 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -1610,6 +1610,7 @@ QCString DotClassGraph::diskName() const
 QCString DotClassGraph::writeGraph(QTextStream &out,
                                GraphOutputFormat format,
                                const char *path,
+                               const char *relPath,
                                bool isTBRank,
                                bool generateImageMap)
 {
@@ -1643,7 +1644,6 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
   }
   baseName = convertNameToFile(diskName());
 
-
   QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
   QCString md5 = computeMd5Signature(m_startNode,        // root
                                      m_graphType,        // gt
@@ -1722,7 +1722,7 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
   if (format==BITMAP && generateImageMap) // run dot to create a image map
   {
     QCString mapLabel = convertNameToFile(m_startNode->m_label+"_"+mapName);
-    out << "<p><center><img src=\"" << baseName << "." 
+    out << "<p><center><img src=\"" << relPath << baseName << "." 
       << imgExt << "\" border=\"0\" usemap=\"#"
       << mapLabel << "\" alt=\"";
     switch (m_graphType)
@@ -1816,7 +1816,7 @@ void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd,int distance)
       doc = bfd->isLinkable();
       src = bfd->generateSourceFile();
     }
-    if (doc || src)
+    if (doc || src || !Config_getBool("HIDE_UNDOC_RELATIONS"))
     {
       QCString url="";
       if (bfd) url=bfd->getOutputFileBase().copy();
@@ -1833,8 +1833,8 @@ void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd,int distance)
       }
       else
       {
-        QCString tmp_url="";
-        if (bfd) tmp_url=bfd->getReference()+"$"+url;
+        QCString tmp_url;
+        if (bfd) tmp_url=doc || src ? bfd->getReference()+"$"+url : QCString();
         bn = new DotNode(
                           m_curNodeNumber++,
                           ii->includeName,
@@ -1890,6 +1890,7 @@ QCString DotInclDepGraph::diskName() const
 QCString DotInclDepGraph::writeGraph(QTextStream &out,
                                  GraphOutputFormat format,
                                  const char *path,
+                                 const char *relPath,
                                  bool generateImageMap
                                 )
 {
@@ -1900,7 +1901,7 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
     err("Error: Output dir %s does not exist!\n",path); exit(1);
   }
   QCString oldDir = convertToQCString(QDir::currentDirPath());
-  // go to the html output directory (i.e. path)
+  // go to the output directory (i.e. path)
   QDir::setCurrent(d.absPath());
   QDir thisDir;
 
@@ -1995,7 +1996,7 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
 
   if (format==BITMAP && generateImageMap)
   {
-    out << "<p><center><img src=\"" << baseName << "." 
+    out << "<p><center><img src=\"" << relPath << baseName << "." 
       << imgExt << "\" border=\"0\" usemap=\"#"
       << mapName << "_map\" alt=\"";
     if (m_inverse) out << "Included by dependency graph"; else out << "Include dependency graph";
@@ -2081,7 +2082,7 @@ DotCallGraph::~DotCallGraph()
 }
 
 QCString DotCallGraph::writeGraph(QTextStream &out, GraphOutputFormat format,
-                        const char *path,bool generateImageMap)
+                        const char *path,const char *relPath,bool generateImageMap)
 {
   QDir d(path);
   // store the original directory
@@ -2177,7 +2178,7 @@ QCString DotCallGraph::writeGraph(QTextStream &out, GraphOutputFormat format,
 
   if (format==BITMAP && generateImageMap)
   {
-    out << "<p><center><img src=\"" << baseName << "." 
+    out << "<p><center><img src=\"" << relPath << baseName << "." 
         << imgExt << "\" border=\"0\" usemap=\"#"
         << mapName << "_map\" alt=\"";
     out << "\">";
diff --git a/src/dot.h b/src/dot.h
index e51a463..4571a68 100644
--- a/src/dot.h
+++ b/src/dot.h
@@ -137,7 +137,7 @@ class DotClassGraph
    ~DotClassGraph();
     bool isTrivial() const;
     QCString writeGraph(QTextStream &t,GraphOutputFormat f,const char *path,
-                    bool TBRank=TRUE,bool imageMap=TRUE);
+                    const char *relPath, bool TBRank=TRUE,bool imageMap=TRUE);
 
     void writeXML(QTextStream &t);
     void writeDEF(QTextStream &t);
@@ -163,6 +163,7 @@ class DotInclDepGraph
     DotInclDepGraph(FileDef *fd,int maxRecusionDepth,bool inverse);
    ~DotInclDepGraph();
     QCString writeGraph(QTextStream &t, GraphOutputFormat f,const char *path,
+                    const char *relPath,
                     bool writeImageMap=TRUE);
     bool isTrivial() const;
     QCString diskName() const;
@@ -185,7 +186,7 @@ class DotCallGraph
     DotCallGraph(MemberDef *md,int maxRecursionDepth);
    ~DotCallGraph();
     QCString writeGraph(QTextStream &t, GraphOutputFormat f,
-                        const char *path,bool writeImageMap=TRUE);
+                        const char *path,const char *relPath,bool writeImageMap=TRUE);
     void buildGraph(DotNode *n,MemberDef *md,int distance);
     bool isTrivial() const;
     
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index fbfc687..8a1dcec 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -118,12 +118,14 @@ QTime          Doxygen::runningTime;
 SearchIndex *  Doxygen::searchIndex=0;
 SDict<DefinitionList> *Doxygen::symbolMap;
 bool           Doxygen::outputToWizard=FALSE;
+QDict<int> *   Doxygen::htmlDirMap = 0;
 
 static StringList     inputFiles;         
 static StringDict     excludeNameDict(1009);   // sections
 static QDict<void>    compoundKeywordDict(7);  // keywords recognised as compounds
 static OutputList     *outputList = 0;         // list of output generating objects
 
+
 void clearAll()
 {
   inputFiles.clear();      
diff --git a/src/doxygen.h b/src/doxygen.h
index f593470..f16efed 100644
--- a/src/doxygen.h
+++ b/src/doxygen.h
@@ -101,6 +101,7 @@ class Doxygen
     static SearchIndex              *searchIndex;
     static SDict<DefinitionList>    *symbolMap;
     static bool                      outputToWizard;
+    static QDict<int>               *htmlDirMap;
 };
 
 void initDoxygen();
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index 1496366..6d46942 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -61,7 +61,7 @@ void HtmlDocVisitor::visit(DocWord *w)
 void HtmlDocVisitor::visit(DocLinkedWord *w)
 {
   if (m_hide) return;
-  startLink(w->ref(),w->file(),w->anchor());
+  startLink(w->ref(),w->file(),w->relPath(),w->anchor());
   filter(w->word());
   endLink();
 }
@@ -750,7 +750,7 @@ void HtmlDocVisitor::visitPost(DocDotFile *df)
 void HtmlDocVisitor::visitPre(DocLink *lnk)
 {
   if (m_hide) return;
-  startLink(lnk->ref(),lnk->file(),lnk->anchor());
+  startLink(lnk->ref(),lnk->file(),lnk->relPath(),lnk->anchor());
 }
 
 void HtmlDocVisitor::visitPost(DocLink *) 
@@ -762,7 +762,10 @@ void HtmlDocVisitor::visitPost(DocLink *)
 void HtmlDocVisitor::visitPre(DocRef *ref)
 {
   if (m_hide) return;
-  if (!ref->file().isEmpty()) startLink(ref->ref(),ref->file(),ref->anchor());
+  if (!ref->file().isEmpty()) 
+  {
+    startLink(ref->ref(),ref->file(),ref->relPath(),ref->anchor());
+  }
   if (!ref->hasLinkText()) filter(ref->targetTitle());
 }
 
@@ -891,7 +894,7 @@ void HtmlDocVisitor::visitPost(DocXRefItem *)
 void HtmlDocVisitor::visitPre(DocInternalRef *ref)
 {
   if (m_hide) return;
-  startLink(0,ref->file(),ref->anchor());
+  startLink(0,ref->file(),ref->relPath(),ref->anchor());
 }
 
 void HtmlDocVisitor::visitPost(DocInternalRef *) 
@@ -972,7 +975,8 @@ void HtmlDocVisitor::filterQuotedCdataAttr(const char* str)
   }
 }
 
-void HtmlDocVisitor::startLink(const QString &ref,const QString &file,const QString &anchor)
+void HtmlDocVisitor::startLink(const QString &ref,const QString &file,
+                               const QString &relPath,const QString &anchor)
 {
   QCString *dest;
   if (!ref.isEmpty()) // link to entity imported via tag file
@@ -989,7 +993,11 @@ void HtmlDocVisitor::startLink(const QString &ref,const QString &file,const QStr
   m_t << "href=\"";
   if (!ref.isEmpty())
   {
-    if ((dest=Doxygen::tagDestinationDict[ref])) m_t << *dest << "/";
+    if ((dest=Doxygen::tagDestinationDict[ref])) m_t << relPath << *dest << "/";
+  }
+  else
+  {
+    m_t << relPath;
   }
   if (!file.isEmpty()) m_t << file << Doxygen::htmlFileExtension;
   if (!anchor.isEmpty()) m_t << "#" << anchor;
diff --git a/src/htmldocvisitor.h b/src/htmldocvisitor.h
index 5f29339..0650478 100644
--- a/src/htmldocvisitor.h
+++ b/src/htmldocvisitor.h
@@ -135,7 +135,7 @@ class HtmlDocVisitor : public DocVisitor
     void filter(const char *str);
     void filterQuotedCdataAttr(const char* str);
     void startLink(const QString &ref,const QString &file,
-                   const QString &anchor);
+                   const QString &relPath,const QString &anchor);
     void endLink();
     void writeDotFile(const QString &fileName);
 
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 66ecb52..46a797e 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -298,6 +298,7 @@ void HtmlGenerator::init()
     g_footer=fileToString(Config_getString("HTML_FOOTER"));
     //printf("g_footer='%s'\n",g_footer.data());
   }
+  createSubDirs(d);
 }
 
 void HtmlGenerator::writeStyleSheetFile(QFile &file)
@@ -306,7 +307,8 @@ void HtmlGenerator::writeStyleSheetFile(QFile &file)
   t << defaultStyleSheet;
 }
 
-static void writeDefaultHeaderFile(QTextStream &t, const char *title)
+static void writeDefaultHeaderFile(QTextStream &t, const char *title,
+                                   const char *relPath)
 {
   t << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
     "<html><head>" 
@@ -319,7 +321,7 @@ static void writeDefaultHeaderFile(QTextStream &t, const char *title)
   t << "href=\"";
   if (Config_getString("HTML_STYLESHEET").isEmpty())
   {
-    t << "doxygen.css";
+    t << relPath << "doxygen.css";
   }
   else
   {
@@ -342,7 +344,7 @@ void HtmlGenerator::writeHeaderFile(QFile &file)
 #if QT_VERSION >= 200
   t.setEncoding(QTextStream::Latin1);
 #endif
-  writeDefaultHeaderFile(t,"$title");
+  writeDefaultHeaderFile(t,"$title",relativePathToRoot(0));
 }
 
 void HtmlGenerator::writeFooterFile(QFile &file)
@@ -366,6 +368,8 @@ void HtmlGenerator::startFile(const char *name,const char *,
   //printf("HtmlGenerator::startFile(%s)\n",name);
   QCString fileName=name;
   lastTitle=title;
+  relPath = relativePathToRoot(fileName);
+
   if (fileName.right(Doxygen::htmlFileExtension.length())!=Doxygen::htmlFileExtension) 
   {
     fileName+=Doxygen::htmlFileExtension;
@@ -386,7 +390,7 @@ void HtmlGenerator::startFile(const char *name,const char *,
   lastFile = fileName;
   if (g_header.isEmpty()) 
   {
-    writeDefaultHeaderFile(t,dispTitle);
+    writeDefaultHeaderFile(t,dispTitle,relPath);
   }
   else
   {
@@ -425,7 +429,8 @@ void HtmlGenerator::startFile(const char *name,const char *,
 //  t << "</a> &nbsp; ";
 //}
 
-static void writePageFooter(QTextStream &t,const QCString lastTitle)
+static void writePageFooter(QTextStream &t,const QCString &lastTitle,
+                            const QCString relPath)
 {
   if (g_footer.isEmpty())
   {
@@ -435,8 +440,8 @@ static void writePageFooter(QTextStream &t,const QCString lastTitle)
         Config_getString("PROJECT_NAME")
         );
     t << endl << "<a href=\"http://www.doxygen.org/index.html\">";
-    t << endl << "<img src=\"doxygen.png\" alt=\"doxygen\" " 
-      << "align=\"middle\" border=0 > " << "</a>" << versionString << " ";
+    t << endl << "<img src=\"" << relPath << "doxygen.png\" alt=\"doxygen\" " 
+      << "align=\"middle\" border=0 >" << "</a> " << versionString << " ";
     t << "</small></address>\n</body>\n</html>\n";
   }
   else
@@ -447,7 +452,7 @@ static void writePageFooter(QTextStream &t,const QCString lastTitle)
 
 void HtmlGenerator::writeFooter()
 {
-  writePageFooter(t,lastTitle);
+  writePageFooter(t,lastTitle,relPath);
 }
 
 void HtmlGenerator::endFile()
@@ -562,10 +567,6 @@ void HtmlGenerator::writeIndexItem(const char *ref,const char *f,
   {
     t << "</b>";
   }
-  //if (Config_getBool("GENERATE_HTMLHELP") && f)
-  //{
-  //  htmlHelp->addItem(name,((QCString)f)+htmlFileExtension);
-  //}
 }
 
 void HtmlGenerator::writeStartAnnoItem(const char *,const char *f,
@@ -576,10 +577,6 @@ void HtmlGenerator::writeStartAnnoItem(const char *,const char *f,
   t << "<a class=\"el\" href=\"" << f << Doxygen::htmlFileExtension << "\">";
   docify(name);
   t << "</a> ";
-  //if (Config_getBool("GENERATE_HTMLHELP") && f)
-  //{
-  //  htmlHelp->addItem(name, ((QCString)f)+htmlFileExtension);
-  //}
 }
 
 void HtmlGenerator::writeObjectLink(const char *ref,const char *f,
@@ -600,7 +597,11 @@ void HtmlGenerator::writeObjectLink(const char *ref,const char *f,
   t << "href=\"";
   if (ref)
   {
-    if ((dest=Doxygen::tagDestinationDict[ref])) t << *dest << "/";
+    if ((dest=Doxygen::tagDestinationDict[ref])) t << relPath << *dest << "/";
+  }
+  else
+  {
+    t << relPath;
   }
   if (f) t << f << Doxygen::htmlFileExtension;
   if (anchor) t << "#" << anchor;
@@ -627,7 +628,11 @@ void HtmlGenerator::writeCodeLink(const char *ref,const char *f,
   t << "href=\"";
   if (ref)
   {
-    if ((dest=Doxygen::tagDestinationDict[ref])) t << *dest << "/";
+    if ((dest=Doxygen::tagDestinationDict[ref])) t << relPath << *dest << "/";
+  }
+  else
+  {
+    t << relPath;
   }
   if (f) t << f << Doxygen::htmlFileExtension;
   if (anchor) t << "#" << anchor;
@@ -640,7 +645,7 @@ void HtmlGenerator::writeCodeLink(const char *ref,const char *f,
 void HtmlGenerator::startTextLink(const char *f,const char *anchor)
 {
   t << "<a href=\"";
-  if (f)   t << f << Doxygen::htmlFileExtension;
+  if (f)   t << relPath << f << Doxygen::htmlFileExtension;
   if (anchor) t << "#" << anchor;
   t << "\">"; 
 }
@@ -1019,7 +1024,7 @@ void HtmlGenerator::startMemberDocName(bool align)
 void HtmlGenerator::endMemberDocName()
 {
   DBG_HTML(t << "<!-- endMemberDocName -->" << endl;)
-  t << "</td>" << endl;
+  t << "          </td>" << endl;
 }
 
 void HtmlGenerator::startParameterList(bool openBracket)
@@ -1108,10 +1113,13 @@ void HtmlGenerator::endParameterList()
   t << "        </tr>" << endl;
 }
 
-void HtmlGenerator::endMemberDoc()     
+void HtmlGenerator::endMemberDoc(bool hasArgs)     
 { 
   DBG_HTML(t << "<!-- endMemberDoc -->" << endl;)
-  t << endl;
+  if (!hasArgs)
+  {
+    t << "        </tr>" << endl;
+  }
   t << "      </table>" << endl;
   t << "    </td>" << endl;
   t << "  </tr>" << endl;
@@ -1124,7 +1132,7 @@ void HtmlGenerator::startDotGraph()
 
 void HtmlGenerator::endDotGraph(DotClassGraph &g)
 {
-  g.writeGraph(t,BITMAP,Config_getString("HTML_OUTPUT"));
+  g.writeGraph(t,BITMAP,dir,relPath);
 }
 
 void HtmlGenerator::startInclDepGraph()
@@ -1133,7 +1141,7 @@ void HtmlGenerator::startInclDepGraph()
 
 void HtmlGenerator::endInclDepGraph(DotInclDepGraph &g)
 {
-  g.writeGraph(t,BITMAP,Config_getString("HTML_OUTPUT"));
+  g.writeGraph(t,BITMAP,dir,relPath);
 }
 
 void HtmlGenerator::startCallGraph()
@@ -1142,12 +1150,12 @@ void HtmlGenerator::startCallGraph()
 
 void HtmlGenerator::endCallGraph(DotCallGraph &g)
 {
-  g.writeGraph(t,BITMAP,Config_getString("HTML_OUTPUT"));
+  g.writeGraph(t,BITMAP,dir,relPath);
 }
 
 void HtmlGenerator::writeGraphicalHierarchy(DotGfxHierarchyTable &g)
 {
-  g.writeGraph(t,Config_getString("HTML_OUTPUT"));
+  g.writeGraph(t,dir);
 }
 
 void HtmlGenerator::startMemberGroupHeader(bool)
@@ -1278,7 +1286,8 @@ void HtmlGenerator::printDoc(DocNode *n)
 }
 
 static void startQuickIndexItem(QTextStream &t,const char *l,
-                                bool hl,bool compact,bool &first)
+                                bool hl,bool compact,bool &first,
+                                const QCString &relPath)
 {
   if (!first && compact) t << " | ";
   first=FALSE;
@@ -1291,7 +1300,7 @@ static void startQuickIndexItem(QTextStream &t,const char *l,
   {
     t << "<a class=\"qindex\" ";
   }
-  t << "href=\"" << l << "\">";
+  t << "href=\"" << relPath << l << "\">";
 }
 
 static void endQuickIndexItem(QTextStream &t)
@@ -1304,7 +1313,8 @@ static QCString fixSpaces(const QCString &s)
   return substitute(s," ","&nbsp;");
 }
 
-static void writeDefaultQuickLinks(QTextStream &t,bool compact,HighlightedItem hli)
+static void writeDefaultQuickLinks(QTextStream &t,bool compact,
+                                   HighlightedItem hli,const QCString &relPath)
 {
   bool first=TRUE;
   if (compact) 
@@ -1318,18 +1328,19 @@ static void writeDefaultQuickLinks(QTextStream &t,bool compact,HighlightedItem h
 
   if (Config_getBool("SEARCHENGINE"))
   {
-    t << "  <form class=\"search\" action=\"search.php\" method=\"get\">\n";
+    t << "  <form class=\"search\" action=\"" << relPath 
+      << "search.php\" method=\"get\">\n";
   }
 
   if (Config_getBool("GENERATE_TREEVIEW"))
   {
     startQuickIndexItem(t,"main"+Doxygen::htmlFileExtension,
-                        hli==HLI_Main,compact,first);
+                        hli==HLI_Main,compact,first,relPath);
   }
   else
   {
     startQuickIndexItem(t,"index"+Doxygen::htmlFileExtension,
-                        hli==HLI_Main,compact,first);
+                        hli==HLI_Main,compact,first,relPath);
   }
   t << fixSpaces(theTranslator->trMainPage());
   endQuickIndexItem(t);
@@ -1337,14 +1348,14 @@ static void writeDefaultQuickLinks(QTextStream &t,bool compact,HighlightedItem h
   if (documentedGroups>0)
   {
     startQuickIndexItem(t,"modules"+Doxygen::htmlFileExtension,
-                        hli==HLI_Modules,compact,first);
+                        hli==HLI_Modules,compact,first,relPath);
     t << fixSpaces(theTranslator->trModules());
     endQuickIndexItem(t);
   } 
   if (documentedNamespaces>0)
   {
     startQuickIndexItem(t,"namespaces"+Doxygen::htmlFileExtension,
-                        hli==HLI_Namespaces,compact,first);
+                        hli==HLI_Namespaces,compact,first,relPath);
     if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
     {
       t << fixSpaces(theTranslator->trPackages());
@@ -1358,7 +1369,7 @@ static void writeDefaultQuickLinks(QTextStream &t,bool compact,HighlightedItem h
   if (hierarchyClasses>0)
   {
     startQuickIndexItem(t,"hierarchy"+Doxygen::htmlFileExtension,
-                           hli==HLI_Hierarchy,compact,first);
+                           hli==HLI_Hierarchy,compact,first,relPath);
     t << fixSpaces(theTranslator->trClassHierarchy());
     endQuickIndexItem(t);
   } 
@@ -1367,54 +1378,54 @@ static void writeDefaultQuickLinks(QTextStream &t,bool compact,HighlightedItem h
     if (Config_getBool("ALPHABETICAL_INDEX"))
     {
       startQuickIndexItem(t,"classes"+Doxygen::htmlFileExtension,
-                          hli==HLI_Classes,compact,first);
+                          hli==HLI_Classes,compact,first,relPath);
       t << fixSpaces(theTranslator->trAlphabeticalList());
       endQuickIndexItem(t);
     }
     startQuickIndexItem(t,"annotated"+Doxygen::htmlFileExtension,
-                        hli==HLI_Annotated,compact,first);
+                        hli==HLI_Annotated,compact,first,relPath);
     t << fixSpaces(theTranslator->trCompoundList());
     endQuickIndexItem(t);
   } 
   if (documentedHtmlFiles>0)
   {
     startQuickIndexItem(t,"files"+Doxygen::htmlFileExtension,
-                        hli==HLI_Files,compact,first);
+                        hli==HLI_Files,compact,first,relPath);
     t << fixSpaces(theTranslator->trFileList());
     endQuickIndexItem(t);
   } 
   if (documentedNamespaceMembers[NMHL_All]>0)
   {
     startQuickIndexItem(t,"namespacemembers"+Doxygen::htmlFileExtension,
-                        hli==HLI_NamespaceMembers,compact,first);
+                        hli==HLI_NamespaceMembers,compact,first,relPath);
     t << fixSpaces(theTranslator->trNamespaceMembers());
     endQuickIndexItem(t);
   }
   if (documentedClassMembers[CMHL_All]>0)
   {
     startQuickIndexItem(t,"functions"+Doxygen::htmlFileExtension,
-                        hli==HLI_Functions,compact,first);
+                        hli==HLI_Functions,compact,first,relPath);
     t << fixSpaces(theTranslator->trCompoundMembers());
     endQuickIndexItem(t);
   } 
   if (documentedFileMembers[FMHL_All]>0)
   {
     startQuickIndexItem(t,"globals"+Doxygen::htmlFileExtension,
-                        hli==HLI_Globals,compact,first);
+                        hli==HLI_Globals,compact,first,relPath);
     t << fixSpaces(theTranslator->trFileMembers());
     endQuickIndexItem(t);
   } 
   if (indexedPages>0)
   {
     startQuickIndexItem(t,"pages"+Doxygen::htmlFileExtension,
-                        hli==HLI_Pages,compact,first);
+                        hli==HLI_Pages,compact,first,relPath);
     t << fixSpaces(theTranslator->trRelatedPages());
     endQuickIndexItem(t);
   } 
   if (Doxygen::exampleSDict->count()>0)
   {
     startQuickIndexItem(t,"examples"+Doxygen::htmlFileExtension,
-                        hli==HLI_Examples,compact,first);
+                        hli==HLI_Examples,compact,first,relPath);
     t << fixSpaces(theTranslator->trExamples());
     endQuickIndexItem(t);
   } 
@@ -1454,7 +1465,7 @@ static void writeDefaultQuickLinks(QTextStream &t,bool compact,HighlightedItem h
 
 void HtmlGenerator::writeQuickLinks(bool compact,HighlightedItem hli)
 {
-  writeDefaultQuickLinks(t,compact,hli);
+  writeDefaultQuickLinks(t,compact,hli,relPath);
 }
 
 void HtmlGenerator::writeSearchPage()
@@ -1471,7 +1482,7 @@ void HtmlGenerator::writeSearchPage()
 #endif
       if (g_header.isEmpty()) 
       {
-        writeDefaultHeaderFile(t,"Search");
+        writeDefaultHeaderFile(t,"Search",0);
       }
       else
       {
@@ -1481,7 +1492,7 @@ void HtmlGenerator::writeSearchPage()
         << versionString << " -->" << endl;
       if (!Config_getBool("DISABLE_INDEX")) 
       { 
-        writeDefaultQuickLinks(t,TRUE,HLI_Search);
+        writeDefaultQuickLinks(t,TRUE,HLI_Search,"");
       }
 
       t << "\n<?php\n\n";
@@ -1514,7 +1525,7 @@ void HtmlGenerator::writeSearchPage()
       t << search_script;
       t << "\n";
       t << "?>\n";
-      writePageFooter(t,"Search");
+      writePageFooter(t,"Search","");
     }
   }
 }
diff --git a/src/htmlgen.h b/src/htmlgen.h
index b832b35..f06318f 100644
--- a/src/htmlgen.h
+++ b/src/htmlgen.h
@@ -128,7 +128,7 @@ class HtmlGenerator : public OutputGenerator
     void lineBreak() { t << "<br>" << endl; }
     void writeChar(char c);
     void startMemberDoc(const char *,const char *,const char *,const char *);
-    void endMemberDoc(); 
+    void endMemberDoc(bool); 
     void startDoxyAnchor(const char *fName,const char *manName,
                          const char *anchor,const char *name);
     void endDoxyAnchor(const char *fName,const char *anchor);
@@ -214,6 +214,7 @@ class HtmlGenerator : public OutputGenerator
   private:
     QCString lastTitle;
     QCString lastFile;
+    QCString relPath;
 
     HtmlGenerator &operator=(const HtmlGenerator &g);
     HtmlGenerator(const HtmlGenerator &g);
diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp
index 30305db..0cb1bae 100644
--- a/src/latexdocvisitor.cpp
+++ b/src/latexdocvisitor.cpp
@@ -904,7 +904,7 @@ void LatexDocVisitor::visitPre(DocXRefItem *x)
   m_t << "\\item[";
   if (Config_getBool("PDF_HYPERLINKS"))
   {
-    m_t << "\\hyperlink{" << x->file() << "_" << x->anchor() << "}{";
+    m_t << "\\hyperlink{" << stripPath(x->file()) << "_" << x->anchor() << "}{";
   }
   else
   {
@@ -960,7 +960,7 @@ void LatexDocVisitor::startLink(const QString &ref,const QString &file,const QSt
   if (ref.isEmpty() && Config_getBool("PDF_HYPERLINKS"))
   {
     m_t << "\\hyperlink{";
-    if (!file.isEmpty()) m_t << file;
+    if (!file.isEmpty()) m_t << stripPath(file);
     if (!file.isEmpty() && !anchor.isEmpty()) m_t << "_";
     if (!anchor.isEmpty()) m_t << anchor;
     m_t << "}{";
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index 2bcb3fc..761a209 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -51,6 +51,7 @@
 //  return result;  
 //}
 
+
 static QCString escapeLabelName(const char *s)
 {
   QCString result;
@@ -222,6 +223,8 @@ void LatexGenerator::init()
   t << endl
     << "clean:" << endl
     << "\trm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out refman.pdf" << endl;
+
+  createSubDirs(d);
 }
 
 static void writeDefaultHeaderPart1(QTextStream &t)
@@ -441,6 +444,7 @@ void LatexGenerator::writeStyleSheetFile(QFile &f)
 void LatexGenerator::startFile(const char *name,const char *,const char *)
 {
   QCString fileName=name;
+  relPath = relativePathToRoot(fileName);
   if (fileName.right(4)!=".tex" && fileName.right(4)!=".sty") fileName+=".tex";
   startPlainFile(fileName);
 }
@@ -926,7 +930,7 @@ void LatexGenerator::startTextLink(const char *f,const char *anchor)
   if (Config_getBool("PDF_HYPERLINKS"))
   {
     t << "\\hyperlink{";
-    if (f) t << f;
+    if (f) t << stripPath(f);
     if (anchor) t << "_" << anchor; 
     t << "}{";
   }
@@ -947,7 +951,7 @@ void LatexGenerator::writeObjectLink(const char *ref, const char *f,
   if (!ref && Config_getBool("PDF_HYPERLINKS"))
   {
     t << "\\hyperlink{";
-    if (f) t << f;
+    if (f) t << stripPath(f);
     if (f && anchor) t << "_"; 
     if (anchor) t << anchor; 
     t << "}{";
@@ -986,7 +990,7 @@ void LatexGenerator::startTitleHead(const char *fileName)
 {
   if (Config_getBool("PDF_HYPERLINKS") && fileName)
   {
-    t << "\\hypertarget{" << fileName << "}{" << endl;
+    t << "\\hypertarget{" << stripPath(fileName) << "}{" << endl;
   }
   if (Config_getBool("COMPACT_LATEX")) 
   {
@@ -1100,7 +1104,7 @@ void LatexGenerator::startMemberDoc(const char *clname,
   t << "{\\setlength{\\rightskip}{0pt plus 5cm}";
 }
 
-void LatexGenerator::endMemberDoc() 
+void LatexGenerator::endMemberDoc(bool) 
 { 
   t << "}";
   if (Config_getBool("COMPACT_LATEX")) t << "\\hfill";
@@ -1112,7 +1116,7 @@ void LatexGenerator::startDoxyAnchor(const char *fName,const char *,
   if (Config_getBool("PDF_HYPERLINKS"))
   {
     t << "\\hypertarget{";
-    if (fName) t << fName;
+    if (fName) t << stripPath(fName);
     if (anchor) t << "_" << anchor;
     t << "}{" << endl;
   }
@@ -1136,7 +1140,7 @@ void LatexGenerator::writeAnchor(const char *fName,const char *name)
   t << "\\label{" << name << "}" << endl; 
   if (fName && Config_getBool("PDF_HYPERLINKS"))
   {
-    t << "\\hypertarget{" << fName << "_" << name << "}{}" << endl;
+    t << "\\hypertarget{" << stripPath(fName) << "_" << name << "}{}" << endl;
   }
 }
 
@@ -1168,7 +1172,7 @@ void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::Sect
 {
   if (Config_getBool("PDF_HYPERLINKS"))
   {
-    t << "\\hypertarget{" << lab << "}{}";
+    t << "\\hypertarget{" << stripPath(lab) << "}{}";
   }
   t << "\\";
   if (Config_getBool("COMPACT_LATEX"))
@@ -1380,7 +1384,7 @@ void LatexGenerator::startDotGraph()
 
 void LatexGenerator::endDotGraph(DotClassGraph &g) 
 {
-  g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"));
+  g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),relPath);
 }
 
 void LatexGenerator::startInclDepGraph() 
@@ -1389,7 +1393,7 @@ void LatexGenerator::startInclDepGraph()
 
 void LatexGenerator::endInclDepGraph(DotInclDepGraph &g) 
 {
-  g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"));
+  g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),relPath);
 }
 
 void LatexGenerator::startCallGraph() 
@@ -1398,7 +1402,7 @@ void LatexGenerator::startCallGraph()
 
 void LatexGenerator::endCallGraph(DotCallGraph &g) 
 {
-  g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"));
+  g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),relPath);
 }
 
 void LatexGenerator::startDescription() 
diff --git a/src/latexgen.h b/src/latexgen.h
index 9272290..49705d2 100644
--- a/src/latexgen.h
+++ b/src/latexgen.h
@@ -142,7 +142,7 @@ class LatexGenerator : public OutputGenerator
     void endDescItem();
     void lineBreak() { t << "\\par\n"; }
     void startMemberDoc(const char *,const char *,const char *,const char *);
-    void endMemberDoc();
+    void endMemberDoc(bool);
     void startDoxyAnchor(const char *,const char *,const char *,const char *);
     void endDoxyAnchor(const char *,const char *);
     void startCodeAnchor(const char *) {}
@@ -299,6 +299,7 @@ class LatexGenerator : public OutputGenerator
     bool insideTabbing;
     bool firstDescItem;
     bool insidePre;
+    QCString relPath;
 };
 
 #endif
diff --git a/src/mangen.cpp b/src/mangen.cpp
index 6981372..6f11f82 100644
--- a/src/mangen.cpp
+++ b/src/mangen.cpp
@@ -35,10 +35,9 @@ static QCString getExtension()
 {
   QCString ext = Config_getString("MAN_EXTENSION");
   if( ext.length() >= 2 &&
-      ext.data()[0] == '.' &&
-      isdigit( ext.data()[1] ) )
+      ext.data()[0] == '.')
   {
-    ext = ext.mid(1, 1);
+    ext = ext.mid(1, ext.length()-1);
   }
   else
   {
@@ -95,6 +94,7 @@ void ManGenerator::init()
     err("Could not create output directory %s/man%s\n",manOutput.data(),ext.data());
     exit(1);
   }
+  createSubDirs(d);
 }
 
 static QCString buildFileName(const char *name)
@@ -405,7 +405,7 @@ void ManGenerator::startDoxyAnchor(const char *,const char *manName,
     linkfile.close();
 }
 
-void ManGenerator::endMemberDoc()
+void ManGenerator::endMemberDoc(bool)
 {
     t << "\"";
 }
diff --git a/src/mangen.h b/src/mangen.h
index c9abef4..b7d43bb 100644
--- a/src/mangen.h
+++ b/src/mangen.h
@@ -135,7 +135,7 @@ class ManGenerator : public OutputGenerator
     void lineBreak() { t << "\n.br" << endl; }
     void writeChar(char c);
     void startMemberDoc(const char *,const char *,const char *,const char *);
-    void endMemberDoc();
+    void endMemberDoc(bool);
     void startDoxyAnchor(const char *,const char *,const char *,const char *);
     void endDoxyAnchor(const char *,const char *) {}
     void startCodeAnchor(const char *) {}
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index dfc0685..4e44a98 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -74,24 +74,33 @@ static QCString addTemplateNames(const QCString &s,const QCString &n,const QCStr
   return result;
 }
 
-static void writeDefArgumentList(OutputList &ol,ClassDef *cd,
+static bool writeDefArgumentList(OutputList &ol,ClassDef *cd,
                                  const QCString & /*scopeName*/,MemberDef *md)
 {
   ArgumentList *defArgList=md->isDocsForDefinition() ? 
                              md->argumentList() : md->declArgumentList();
   //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition());
-  if (defArgList==0) return; // member has no function like argument list
+  if (defArgList==0) 
+  {
+    return FALSE; // member has no function like argument list
+  }
   if (!md->isDefine()) ol.docify(" ");
 
   //printf("writeDefArgList(%d)\n",defArgList->count());
   ol.pushGeneratorState();
   ol.disableAllBut(OutputGenerator::Html);
-  ol.endMemberDocName();
-  ol.startParameterList(!md->isObjCMethod()); 
+  {
+    // html
+    ol.endMemberDocName();
+    ol.startParameterList(!md->isObjCMethod()); 
+  }
   ol.enableAll();
   ol.disable(OutputGenerator::Html);
-  if (!md->isObjCMethod()) ol.docify("("); // start argument list
-  ol.endMemberDocName();
+  {
+    // other formats
+    if (!md->isObjCMethod()) ol.docify("("); // start argument list
+    ol.endMemberDocName();
+  }
   ol.popGeneratorState();
   //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine());
 
@@ -227,6 +236,7 @@ static void writeDefArgumentList(OutputList &ol,ClassDef *cd,
   {
     ol.docify(" volatile");
   }
+  return TRUE;
 }
 
 static void writeTemplatePrefix(OutputList &ol,ArgumentList *al)
@@ -1168,124 +1178,145 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
                                   )
 {
   // if this member is in a group find the real scope name.
+  bool hasParameterList = FALSE;
   bool hasDocs = isDetailedSectionVisible(inGroup);
   //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d\n",
   //    name().data(),hasDocs,container->definitionType(),inGroup);
-  if ( hasDocs )
+  if ( !hasDocs ) return;
+  QCString scopeName = scName;
+  if (container->definitionType()==TypeGroup)
   {
-    QCString scopeName = scName;
-    if (container->definitionType()==TypeGroup)
-    {
-      if (getClassDef())          scopeName=getClassDef()->name();
-      else if (getNamespaceDef()) scopeName=getNamespaceDef()->name();
-      else if (getFileDef())      scopeName=getFileDef()->name();
-    }
-  
-    QCString cname  = container->name();
-    QCString cfname = getOutputFileBase();  
+    if (getClassDef())          scopeName=getClassDef()->name();
+    else if (getNamespaceDef()) scopeName=getNamespaceDef()->name();
+    else if (getFileDef())      scopeName=getFileDef()->name();
+  }
 
-    //ol.addIndexItem(name(),cname);
-    //ol.addIndexItem(cname,name());
+  QCString cname  = container->name();
+  QCString cfname = getOutputFileBase();  
 
-    if (Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP"))
-    {
-      HtmlHelp *htmlHelp = HtmlHelp::getInstance();
-      htmlHelp->addIndexItem(cname,name(),cfname,anchor());
-    }
+  //ol.addIndexItem(name(),cname);
+  //ol.addIndexItem(cname,name());
 
-    // get member name
-    QCString doxyName=name().copy();
-    // prepend scope if there is any. TODO: make this optional for C only docs
-    if (scopeName) doxyName.prepend((QCString)scopeName+"::");
+  if (Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP"))
+  {
+    HtmlHelp *htmlHelp = HtmlHelp::getInstance();
+    htmlHelp->addIndexItem(cname,name(),cfname,anchor());
+  }
+
+  // get member name
+  QCString doxyName=name().copy();
+  // prepend scope if there is any. TODO: make this optional for C only docs
+  if (scopeName) doxyName.prepend((QCString)scopeName+"::");
 
-    QCString ldef = definition();
-    //printf("member `%s' def=`%s'\n",name().data(),ldef.data());
-    if (isEnumerate()) 
+  QCString ldef = definition();
+  //printf("member `%s' def=`%s'\n",name().data(),ldef.data());
+  if (isEnumerate()) 
+  {
+    if (name().at(0)=='@')
     {
-      if (name().at(0)=='@')
-      {
-        ldef = "anonymous enum";
-      }
-      else
-      {
-        ldef.prepend("enum ");
-      }
+      ldef = "anonymous enum";
     }
-    int i=0,l;
-    static QRegExp r("@[0-9]+");
+    else
+    {
+      ldef.prepend("enum ");
+    }
+  }
+  int i=0,l;
+  static QRegExp r("@[0-9]+");
 
-    if (isEnumValue()) return;
+  if (isEnumValue()) return;
 
-    ol.pushGeneratorState();
+  ol.pushGeneratorState();
 
-    bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
-    HtmlHelp *htmlHelp = 0;
-    if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
+  bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
+  HtmlHelp *htmlHelp = 0;
+  if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
 
-    if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
+  if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
+  {
+    // find enum type and insert it in the definition
+    MemberListIterator vmli(*ml);
+    MemberDef *vmd;
+    bool found=FALSE;
+    for ( ; (vmd=vmli.current()) && !found ; ++vmli)
     {
-      // find enum type and insert it in the definition
-      MemberListIterator vmli(*ml);
-      MemberDef *vmd;
-      bool found=FALSE;
-      for ( ; (vmd=vmli.current()) && !found ; ++vmli)
+      if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
       {
-        if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
-        {
-          ol.startDoxyAnchor(cfname,cname,anchor(),doxyName);
-          ol.startMemberDoc(cname,name(),anchor(),name());
-          if (hasHtmlHelp)
-          {
-            htmlHelp->addIndexItem(cname,name(),cfname,anchor());
-          }
-          linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.left(i));
-          //ol+=*vmd->enumDecl();
-          vmd->writeEnumDeclaration(ol,getClassDef(),getNamespaceDef(),getFileDef(),getGroupDef());
-          linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.right(ldef.length()-i-l));
-
-          found=TRUE;
-        }
-      }
-      if (!found) // anonymous compound
-      {
-        //printf("Anonymous compound `%s'\n",cname.data());
         ol.startDoxyAnchor(cfname,cname,anchor(),doxyName);
         ol.startMemberDoc(cname,name(),anchor(),name());
         if (hasHtmlHelp)
         {
           htmlHelp->addIndexItem(cname,name(),cfname,anchor());
         }
-        // strip anonymous compound names from definition
-        int si=ldef.find(' '),pi,ei=i+l;
-        if (si==-1) si=0;
-        while ((pi=r.match(ldef,i+l,&l))!=-1) ei=i=pi+l;
-        // first si characters of ldef contain compound type name
-        ol.startMemberDocName(isObjCMethod());
-        ol.docify(ldef.left(si));
-        ol.docify(" { ... } ");
-        // last ei characters of ldef contain pointer/reference specifiers
-        int ni=ldef.find("::",si);
-        if (ni>=ei) ei=ni+2;
-        linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.right(ldef.length()-ei));
+        linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.left(i));
+        //ol+=*vmd->enumDecl();
+        vmd->writeEnumDeclaration(ol,getClassDef(),getNamespaceDef(),getFileDef(),getGroupDef());
+        linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.right(ldef.length()-i-l));
+
+        found=TRUE;
       }
     }
-    else // not an enum value
+    if (!found) // anonymous compound
     {
+      //printf("Anonymous compound `%s'\n",cname.data());
       ol.startDoxyAnchor(cfname,cname,anchor(),doxyName);
       ol.startMemberDoc(cname,name(),anchor(),name());
       if (hasHtmlHelp)
       {
         htmlHelp->addIndexItem(cname,name(),cfname,anchor());
       }
+      // strip anonymous compound names from definition
+      int si=ldef.find(' '),pi,ei=i+l;
+      if (si==-1) si=0;
+      while ((pi=r.match(ldef,i+l,&l))!=-1) ei=i=pi+l;
+      // first si characters of ldef contain compound type name
+      ol.startMemberDocName(isObjCMethod());
+      ol.docify(ldef.left(si));
+      ol.docify(" { ... } ");
+      // last ei characters of ldef contain pointer/reference specifiers
+      int ni=ldef.find("::",si);
+      if (ni>=ei) ei=ni+2;
+      linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.right(ldef.length()-ei));
+    }
+  }
+  else // not an enum value
+  {
+    ol.startDoxyAnchor(cfname,cname,anchor(),doxyName);
+    ol.startMemberDoc(cname,name(),anchor(),name());
+    if (hasHtmlHelp)
+    {
+      htmlHelp->addIndexItem(cname,name(),cfname,anchor());
+    }
 
-      ClassDef *cd=getClassDef();
-      if (!Config_getBool("HIDE_SCOPE_NAMES"))
+    ClassDef *cd=getClassDef();
+    if (!Config_getBool("HIDE_SCOPE_NAMES"))
+    {
+      bool first=TRUE;
+      if (m_defTmpArgLists) 
+        // definition has explicit template parameter declarations
+      {
+        QListIterator<ArgumentList> ali(*m_defTmpArgLists);
+        ArgumentList *tal;
+        for (ali.toFirst();(tal=ali.current());++ali)
+        {
+          if (tal->count()>0)
+          {
+            if (!first) ol.docify(" ");
+            ol.startMemberDocPrefixItem();
+            writeTemplatePrefix(ol,tal);
+            ol.endMemberDocPrefixItem();
+          }
+        }
+      }
+      else // definition gets it template parameters from its class
+        // (since no definition was found)
       {
-        bool first=TRUE;
-        if (m_defTmpArgLists) 
-          // definition has explicit template parameter declarations
+        if (cd)
         {
-          QListIterator<ArgumentList> ali(*m_defTmpArgLists);
+          QList<ArgumentList> tempParamLists;
+          cd->getTemplateParameterLists(tempParamLists);
+          //printf("#tempParamLists=%d\n",tempParamLists.count());
+          QListIterator<ArgumentList> ali(tempParamLists);
           ArgumentList *tal;
           for (ali.toFirst();(tal=ali.current());++ali)
           {
@@ -1298,499 +1329,485 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
             }
           }
         }
-        else // definition gets it template parameters from its class
-             // (since no definition was found)
+        if (tArgList) // function template prefix
         {
-          if (cd)
-          {
-            QList<ArgumentList> tempParamLists;
-            cd->getTemplateParameterLists(tempParamLists);
-            //printf("#tempParamLists=%d\n",tempParamLists.count());
-            QListIterator<ArgumentList> ali(tempParamLists);
-            ArgumentList *tal;
-            for (ali.toFirst();(tal=ali.current());++ali)
-            {
-              if (tal->count()>0)
-              {
-                if (!first) ol.docify(" ");
-                ol.startMemberDocPrefixItem();
-                writeTemplatePrefix(ol,tal);
-                ol.endMemberDocPrefixItem();
-              }
-            }
-          }
-          if (tArgList) // function template prefix
-          {
-            ol.startMemberDocPrefixItem();
-            writeTemplatePrefix(ol,tArgList);
-            ol.endMemberDocPrefixItem();
-          }
+          ol.startMemberDocPrefixItem();
+          writeTemplatePrefix(ol,tArgList);
+          ol.endMemberDocPrefixItem();
         }
       }
-      ol.startMemberDocName(isObjCMethod());
-      if (isObjCMethod())
+    }
+    ol.startMemberDocName(isObjCMethod());
+    if (cd && cd->isObjectiveC())
+    {
+      // strip scope name
+      int ep = ldef.find("::");
+      if (ep!=-1) 
       {
-        // strip scope name
-        int ep = ldef.find("::");
-        if (ep!=-1) 
-        {
-          int sp=ldef.findRev(' ',ep);
-          if (sp!=-1)
-          {
-            ldef=ldef.left(sp+1)+ldef.mid(ep+2);
-          }
-        }
-        // strip keywords
-        int dp = ldef.find(':');
-        if (dp!=-1)
-        {
-          ldef=ldef.left(dp+1);
-        }
-        int l=ldef.length();
-        //printf("start >%s<\n",ldef.data());
-        int i=l-1;
-        while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
-        while (i>=0 && isspace(ldef.at(i))) i--;
-        if (i>0)
+        int sp=ldef.findRev(' ',ep);
+        if (sp!=-1)
         {
-          // insert braches around the type
-          QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
-          ldef=tmp;
+          ldef=ldef.left(sp+1)+ldef.mid(ep+2);
         }
-        //printf("end   >%s< i=%d\n",ldef.data(),i);
-        if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
       }
-      linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef);
-      writeDefArgumentList(ol,cd,scopeName,this);
-      if (hasOneLineInitializer()) // add initializer
+      // strip keywords
+      int dp = ldef.find(':');
+      if (dp!=-1)
       {
-        if (!isDefine()) 
-        {
-          ol.docify(" = "); 
-          linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),init.simplifyWhiteSpace());
-        }
-        else 
-        {
-          ol.writeNonBreakableSpace(3);
-          linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),init);
-        }
+        ldef=ldef.left(dp+1);
       }
-      if (excpString()) // add exception list
+      int l=ldef.length();
+      //printf("start >%s<\n",ldef.data());
+      int i=l-1;
+      while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
+      while (i>=0 && isspace((uchar)ldef.at(i))) i--;
+      if (i>0)
       {
-        ol.docify(" ");
-        linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),excpString());
+        // insert braches around the type
+        QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
+        ldef=tmp;
       }
+      //printf("end   >%s< i=%d\n",ldef.data(),i);
+      if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
     }
-
-    Specifier lvirt=virtualness();
-
-    if (!isObjCMethod() &&
-        (protection()!=Public || lvirt!=Normal ||
-         isFriend() || isRelated() || isExplicit() ||
-         isMutable() || (isInline() && Config_getBool("INLINE_INFO")) ||
-         isSignal() || isSlot() ||
-         isStatic() || (classDef && classDef!=container) ||
-         isSettable() || isGettable() || isReadable() || isWritable()
-        )
-       )
+    linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef);
+    hasParameterList=writeDefArgumentList(ol,cd,scopeName,this);
+    if (hasOneLineInitializer()) // add initializer
     {
-      // write the member specifier list
-      ol.writeLatexSpacing();
-      ol.startTypewriter();
-      ol.docify(" [");
-      QStrList sl;
-      if (isFriend()) sl.append("friend");
-      else if (isRelated()) sl.append("related");
-      else
+      if (!isDefine()) 
       {
-        if      (Config_getBool("INLINE_INFO") && isInline())              
-                                          sl.append("inline");
-        if      (isExplicit())            sl.append("explicit");
-        if      (isMutable())             sl.append("mutable");
-        if      (isStatic())              sl.append("static");
-        if      (isGettable())            sl.append("get");
-        if      (isSettable())            sl.append("set");
-        if      (isReadable())            sl.append("read");
-        if      (isWritable())            sl.append("write");
-        if      (protection()==Protected) sl.append("protected");
-        else if (protection()==Private)   sl.append("private");
-        else if (protection()==Package)   sl.append("package");
-        if      (lvirt==Virtual)          sl.append("virtual");
-        else if (lvirt==Pure)             sl.append("pure virtual");
-        if      (isSignal())              sl.append("signal");
-        if      (isSlot())                sl.append("slot");
+        ol.docify(" = "); 
+        linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),init.simplifyWhiteSpace());
       }
-      if (classDef && classDef!=container) sl.append("inherited");
-      const char *s=sl.first();
-      while (s)
+      else 
       {
-        ol.docify(s);
-        s=sl.next();
-        if (s) ol.docify(", ");
+        ol.writeNonBreakableSpace(3);
+        linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),init);
       }
-      ol.docify("]");
-      ol.endTypewriter();
     }
-    else if (isObjCMethod() && isImplementation())
+    if (excpString()) // add exception list
     {
-      ol.writeLatexSpacing();
-      ol.startTypewriter();
-      ol.docify(" [implementation]");
-      ol.endTypewriter();
+      ol.docify(" ");
+      linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),excpString());
     }
-    if (!isDefine() && defArgList) ol.endParameterList();
-    ol.endMemberDoc();
-    ol.endDoxyAnchor(cfname,anchor());
-    ol.startIndent();
-    
-    ol.pushGeneratorState();
-    ol.disable(OutputGenerator::RTF);
-    ol.newParagraph();
-    ol.popGeneratorState();
+  }
 
-    /* write multi-line initializer (if any) */
-    if (hasMultiLineInitializer()
-        //initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
-        //                || initLines<userInitLines // explicitly enabled
-        //               )
-       )
+  Specifier lvirt=virtualness();
+
+  if (!isObjCMethod() &&
+      (protection()!=Public || lvirt!=Normal ||
+       isFriend() || isRelated() || isExplicit() ||
+       isMutable() || (isInline() && Config_getBool("INLINE_INFO")) ||
+       isSignal() || isSlot() ||
+       isStatic() || (classDef && classDef!=container) ||
+       isSettable() || isGettable() || isReadable() || isWritable()
+      )
+     )
+  {
+    // write the member specifier list
+    ol.writeLatexSpacing();
+    ol.startTypewriter();
+    ol.docify(" [");
+    QStrList sl;
+    if (isFriend()) sl.append("friend");
+    else if (isRelated()) sl.append("related");
+    else
     {
-      //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data());
-      ol.startBold();
-      if (mtype==Define)
-        ol.parseText(theTranslator->trDefineValue());
-      else
-        ol.parseText(theTranslator->trInitialValue());
-      ol.endBold();
-      initParseCodeContext();
-      ol.startCodeFragment();
-      parseCode(ol,scopeName,init,FALSE,0);
-      ol.endCodeFragment();
+      if      (Config_getBool("INLINE_INFO") && isInline())              
+        sl.append("inline");
+      if      (isExplicit())            sl.append("explicit");
+      if      (isMutable())             sl.append("mutable");
+      if      (isStatic())              sl.append("static");
+      if      (isGettable())            sl.append("get");
+      if      (isSettable())            sl.append("set");
+      if      (isReadable())            sl.append("read");
+      if      (isWritable())            sl.append("write");
+      if      (protection()==Protected) sl.append("protected");
+      else if (protection()==Private)   sl.append("private");
+      else if (protection()==Package)   sl.append("package");
+      if      (lvirt==Virtual)          sl.append("virtual");
+      else if (lvirt==Pure)             sl.append("pure virtual");
+      if      (isSignal())              sl.append("signal");
+      if      (isSlot())                sl.append("slot");
     }
-
-    QCString brief    = m_templateMaster ? 
-                        m_templateMaster->briefDescription() : briefDescription();
-    QCString detailed = m_templateMaster ?
-                        m_templateMaster->documentation() : documentation();
-    ArgumentList *docArgList = m_templateMaster ? 
-                        m_templateMaster->defArgList : defArgList;
-    
-    /* write brief description */
-    if (!brief.isEmpty() && 
-        (Config_getBool("REPEAT_BRIEF") || 
-         !Config_getBool("BRIEF_MEMBER_DESC")
-        ) 
-       )  
-    { 
-      ol.parseDoc(briefFile(),briefLine(),getOuterScope()?getOuterScope():container,this,brief,FALSE,FALSE);
-      ol.newParagraph();
+    if (classDef && classDef!=container) sl.append("inherited");
+    const char *s=sl.first();
+    while (s)
+    {
+      ol.docify(s);
+      s=sl.next();
+      if (s) ol.docify(", ");
     }
+    ol.docify("]");
+    ol.endTypewriter();
+  }
+  else if (isObjCMethod() && isImplementation())
+  {
+    ol.writeLatexSpacing();
+    ol.startTypewriter();
+    ol.docify(" [implementation]");
+    ol.endTypewriter();
+  }
+  if (hasParameterList) 
+  {
+    ol.endParameterList();
+    ol.endMemberDoc(TRUE);
+  }
+  else
+  {
+    ol.endMemberDocName();
+    ol.endMemberDoc(FALSE);
+  }
+  ol.endDoxyAnchor(cfname,anchor());
+  ol.startIndent();
 
-    /* write detailed description */
-    if (!detailed.isEmpty())
-    { 
-      ol.parseDoc(docFile(),docLine(),getOuterScope()?getOuterScope():container,this,detailed+"\n",TRUE,FALSE);
-      ol.pushGeneratorState();
-      if (!m_inbodyDocs.isEmpty())
-      {
-        ol.newParagraph();
-        ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,m_inbodyDocs+"\n",TRUE,FALSE);
-      }
-      ol.disableAllBut(OutputGenerator::RTF);
+  ol.pushGeneratorState();
+  ol.disable(OutputGenerator::RTF);
+  ol.newParagraph();
+  ol.popGeneratorState();
+
+  /* write multi-line initializer (if any) */
+  if (hasMultiLineInitializer()
+      //initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
+      //                || initLines<userInitLines // explicitly enabled
+      //               )
+     )
+  {
+    //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data());
+    ol.startBold();
+    if (mtype==Define)
+      ol.parseText(theTranslator->trDefineValue());
+    else
+      ol.parseText(theTranslator->trInitialValue());
+    ol.endBold();
+    initParseCodeContext();
+    ol.startCodeFragment();
+    parseCode(ol,scopeName,init,FALSE,0);
+    ol.endCodeFragment();
+  }
+
+  QCString brief    = m_templateMaster ? 
+    m_templateMaster->briefDescription() : briefDescription();
+  QCString detailed = m_templateMaster ?
+    m_templateMaster->documentation() : documentation();
+  ArgumentList *docArgList = m_templateMaster ? 
+    m_templateMaster->defArgList : defArgList;
+
+  /* write brief description */
+  if (!brief.isEmpty() && 
+      (Config_getBool("REPEAT_BRIEF") || 
+       !Config_getBool("BRIEF_MEMBER_DESC")
+      ) 
+     )  
+  { 
+    ol.parseDoc(briefFile(),briefLine(),getOuterScope()?getOuterScope():container,this,brief,FALSE,FALSE);
+    ol.newParagraph();
+  }
+
+  /* write detailed description */
+  if (!detailed.isEmpty())
+  { 
+    ol.parseDoc(docFile(),docLine(),getOuterScope()?getOuterScope():container,this,detailed+"\n",TRUE,FALSE);
+    ol.pushGeneratorState();
+    if (!m_inbodyDocs.isEmpty())
+    {
       ol.newParagraph();
-      ol.popGeneratorState();
+      ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,m_inbodyDocs+"\n",TRUE,FALSE);
     }
-    else if(!brief.isEmpty() && (Config_getBool("REPEAT_BRIEF") ||
-            !Config_getBool("BRIEF_MEMBER_DESC")))
+    ol.disableAllBut(OutputGenerator::RTF);
+    ol.newParagraph();
+    ol.popGeneratorState();
+  }
+  else if(!brief.isEmpty() && (Config_getBool("REPEAT_BRIEF") ||
+        !Config_getBool("BRIEF_MEMBER_DESC")))
+  {
+    if (!m_inbodyDocs.isEmpty())
     {
-      if (!m_inbodyDocs.isEmpty())
-      {
-        ol.newParagraph();
-        ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,m_inbodyDocs+"\n",TRUE,FALSE);
-      }
-      ol.pushGeneratorState();
-      ol.disableAllBut(OutputGenerator::RTF);
       ol.newParagraph();
-      ol.popGeneratorState();
+      ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,m_inbodyDocs+"\n",TRUE,FALSE);
     }
+    ol.pushGeneratorState();
+    ol.disableAllBut(OutputGenerator::RTF);
+    ol.newParagraph();
+    ol.popGeneratorState();
+  }
 
 
-    //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n",
-    //     defArgList, 
-    //     defArgList?defArgList->hasDocumentation():-1);
-    if (docArgList && docArgList->hasDocumentation())
+  //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n",
+  //     defArgList, 
+  //     defArgList?defArgList->hasDocumentation():-1);
+  if (docArgList && docArgList->hasDocumentation())
+  {
+    //printf("***** argumentList is documented\n");
+    ol.startParamList(BaseOutputDocInterface::Param,theTranslator->trParameters()+": ");
+    ol.writeDescItem();
+    ol.startDescTable();
+    ArgumentListIterator ali(*docArgList);
+    Argument *a;
+    for (ali.toFirst();(a=ali.current());++ali)
     {
-      //printf("***** argumentList is documented\n");
-      ol.startParamList(BaseOutputDocInterface::Param,theTranslator->trParameters()+": ");
-      ol.writeDescItem();
-      ol.startDescTable();
-      ArgumentListIterator ali(*docArgList);
-      Argument *a;
-      for (ali.toFirst();(a=ali.current());++ali)
+      if (a->hasDocumentation())
       {
-        if (a->hasDocumentation())
-        {
-          ol.startDescTableTitle();
-          ol.docify(a->name);
-          ol.endDescTableTitle();
-          ol.startDescTableData();
-          ol.parseDoc(docFile(),docLine(),getOuterScope()?getOuterScope():container,this,a->docs+"\n",TRUE,FALSE);
-          ol.endDescTableData();
-        }
+        ol.startDescTableTitle();
+        ol.docify(a->name);
+        ol.endDescTableTitle();
+        ol.startDescTableData();
+        ol.parseDoc(docFile(),docLine(),getOuterScope()?getOuterScope():container,this,a->docs+"\n",TRUE,FALSE);
+        ol.endDescTableData();
       }
-      ol.endDescTable();
-      ol.endParamList();
     }
-    
-    if (isEnumerate())
+    ol.endDescTable();
+    ol.endParamList();
+  }
+
+  if (isEnumerate())
+  {
+    bool first=TRUE;
+    MemberList *fmdl=enumFieldList();
+    if (fmdl)
     {
-      bool first=TRUE;
-      MemberList *fmdl=enumFieldList();
-      if (fmdl)
+      MemberDef *fmd=fmdl->first();
+      while (fmd)
       {
-        MemberDef *fmd=fmdl->first();
-        while (fmd)
+        if (fmd->isLinkable())
         {
-          if (fmd->isLinkable())
+          if (first)
           {
-            if (first)
-            {
-              //ol.newParagraph();
-              ol.startSimpleSect(BaseOutputDocInterface::EnumValues,0,0,theTranslator->trEnumerationValues()+": ");
-              ol.writeDescItem();
-              ol.startDescTable();
-            }
-
-            ol.addIndexItem(fmd->name(),cname);
-            ol.addIndexItem(cname,fmd->name());
-
-            if (Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP"))
-            {
-              HtmlHelp::getInstance()->addIndexItem(cname,fmd->name(),cfname,fmd->anchor());
-            }
-            //ol.writeListItem();
-            ol.startDescTableTitle(); // this enables emphasis!
-            ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name());
-            first=FALSE;
-            //ol.startEmphasis();
-            ol.docify(fmd->name());
-            //ol.endEmphasis();
-            ol.disableAllBut(OutputGenerator::Man);
-            ol.writeString(" ");
-            ol.enableAll();
-            ol.endDoxyAnchor(cfname,fmd->anchor());
-            ol.endDescTableTitle();
             //ol.newParagraph();
-            ol.startDescTableData();
-
-            if (!fmd->briefDescription().isEmpty())
-            { 
-              ol.parseDoc(fmd->briefFile(),fmd->briefLine(),getOuterScope()?getOuterScope():container,fmd,fmd->briefDescription(),TRUE,FALSE);
-              //ol.newParagraph();
-            }
-            if (!fmd->briefDescription().isEmpty() && 
-                !fmd->documentation().isEmpty())
-            {
-              ol.newParagraph();
-            }
-            if (!fmd->documentation().isEmpty())
-            { 
-              ol.parseDoc(fmd->docFile(),fmd->docLine(),getOuterScope()?getOuterScope():container,fmd,fmd->documentation()+"\n",TRUE,FALSE);
-            }
-            ol.endDescTableData();
+            ol.startSimpleSect(BaseOutputDocInterface::EnumValues,0,0,theTranslator->trEnumerationValues()+": ");
+            ol.writeDescItem();
+            ol.startDescTable();
           }
-          fmd=fmdl->next();
-        }
-      }
-      if (!first) 
-      { 
-        //ol.endItemList(); 
-        ol.endDescTable();
-        ol.endSimpleSect();
-        ol.writeChar('\n'); 
-      }
-    }
 
-    MemberDef *bmd=reimplements();
-    ClassDef *bcd=0;
-    if (bmd && (bcd=bmd->getClassDef()))
-    {
-      // write class that contains a member that is reimplemented by this one
-      if (bcd->isLinkable())
-      {
-        ol.disable(OutputGenerator::RTF);
-        ol.newParagraph();
-        ol.enableAll();
+          ol.addIndexItem(fmd->name(),cname);
+          ol.addIndexItem(cname,fmd->name());
 
-        QCString reimplFromLine; 
-        if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
-        {
-          reimplFromLine = theTranslator->trReimplementedFromList(1);
-        }
-        else
-        {
-          reimplFromLine = theTranslator->trImplementedFromList(1);
-        }
-        int markerPos = reimplFromLine.find("@0");
-        if (markerPos!=-1) // should always pass this.
-        {
-          ol.parseText(reimplFromLine.left(markerPos)); //text left from marker
-          if (bmd->isLinkable()) // replace marker with link
+          if (Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP"))
           {
-            //Definition *bd=bmd->group;
-            //if (bd==0) bd=bcd;
-            ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
-                bmd->anchor(),bcd->displayName());
-
-            //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
-            //    bmd->anchor(),bcd->name());
-            if ( bmd->isLinkableInProject() ) 
-            {
-              writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
-            }
+            HtmlHelp::getInstance()->addIndexItem(cname,fmd->name(),cfname,fmd->anchor());
           }
-          else
+          //ol.writeListItem();
+          ol.startDescTableTitle(); // this enables emphasis!
+          ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name());
+          first=FALSE;
+          //ol.startEmphasis();
+          ol.docify(fmd->name());
+          //ol.endEmphasis();
+          ol.disableAllBut(OutputGenerator::Man);
+          ol.writeString(" ");
+          ol.enableAll();
+          ol.endDoxyAnchor(cfname,fmd->anchor());
+          ol.endDescTableTitle();
+          //ol.newParagraph();
+          ol.startDescTableData();
+
+          if (!fmd->briefDescription().isEmpty())
+          { 
+            ol.parseDoc(fmd->briefFile(),fmd->briefLine(),getOuterScope()?getOuterScope():container,fmd,fmd->briefDescription(),TRUE,FALSE);
+            //ol.newParagraph();
+          }
+          if (!fmd->briefDescription().isEmpty() && 
+              !fmd->documentation().isEmpty())
           {
-            ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
-                0,bcd->displayName());
-            if (bcd->isLinkableInProject()/* && !Config_getBool("PDF_HYPERLINKS")*/ )
-            {
-              writePageRef(ol,bcd->getOutputFileBase(),0);
-            }
+            ol.newParagraph();
           }
-          ol.parseText(reimplFromLine.right(
-                reimplFromLine.length()-markerPos-2)); // text right from marker
-
-          ol.disableAllBut(OutputGenerator::RTF);
-          ol.newParagraph();
-          ol.enableAll();
-        }
-        else
-        {
-          err("Error: translation error: no marker in trReimplementsFromList()\n");
+          if (!fmd->documentation().isEmpty())
+          { 
+            ol.parseDoc(fmd->docFile(),fmd->docLine(),getOuterScope()?getOuterScope():container,fmd,fmd->documentation()+"\n",TRUE,FALSE);
+          }
+          ol.endDescTableData();
         }
+        fmd=fmdl->next();
       }
-
-      //ol.writeString(".");
     }
+    if (!first) 
+    { 
+      //ol.endItemList(); 
+      ol.endDescTable();
+      ol.endSimpleSect();
+      ol.writeChar('\n'); 
+    }
+  }
 
-    MemberList *bml=reimplementedBy();
-    if (bml)
+  MemberDef *bmd=reimplements();
+  ClassDef *bcd=0;
+  if (bmd && (bcd=bmd->getClassDef()))
+  {
+    // write class that contains a member that is reimplemented by this one
+    if (bcd->isLinkable())
     {
-      MemberListIterator mli(*bml);
-      MemberDef *bmd=0;
-      uint count=0;
-      ClassDef *bcd=0;
-      for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
+      ol.disable(OutputGenerator::RTF);
+      ol.newParagraph();
+      ol.enableAll();
+
+      QCString reimplFromLine; 
+      if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
       {
-        // count the members that directly inherit from md and for
-        // which the member and class are visible in the docs.
-        if ( bmd->isLinkable() && bcd->isLinkable() ) 
-        {
-          count++;
-        }
+        reimplFromLine = theTranslator->trReimplementedFromList(1);
       }
-      if (count>0)
+      else
       {
-        mli.toFirst();
-        // write the list of classes that overwrite this member
-        ol.disable(OutputGenerator::RTF);
-        ol.newParagraph();
-        ol.enableAll();
-
-        QCString reimplInLine;
-        if (virt==Pure || (classDef && classDef->compoundType()==ClassDef::Interface))
+        reimplFromLine = theTranslator->trImplementedFromList(1);
+      }
+      int markerPos = reimplFromLine.find("@0");
+      if (markerPos!=-1) // should always pass this.
+      {
+        ol.parseText(reimplFromLine.left(markerPos)); //text left from marker
+        if (bmd->isLinkable()) // replace marker with link
         {
-          reimplInLine = theTranslator->trImplementedInList(count);
+          //Definition *bd=bmd->group;
+          //if (bd==0) bd=bcd;
+          ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
+              bmd->anchor(),bcd->displayName());
+
+          //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+          //    bmd->anchor(),bcd->name());
+          if ( bmd->isLinkableInProject() ) 
+          {
+            writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
+          }
         }
         else
         {
-          reimplInLine = theTranslator->trReimplementedInList(count);
-        }
-        static QRegExp marker("@[0-9]+");
-        int index=0,newIndex,matchLen;
-        // now replace all markers in reimplInLine with links to the classes
-        while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
-        {
-          ol.parseText(reimplInLine.mid(index,newIndex-index));
-          bool ok;
-          uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
-          //bmd=bml->at(entryIndex);
-
-          count=0;
-          // find the entryIndex-th documented entry in the inheritance list.
-          for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
+          ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+              0,bcd->displayName());
+          if (bcd->isLinkableInProject()/* && !Config_getBool("PDF_HYPERLINKS")*/ )
           {
-            if ( bmd->isLinkable() && bcd->isLinkable()) 
-            {
-              if (count==entryIndex) break;
-              count++;
-            }
+            writePageRef(ol,bcd->getOutputFileBase(),0);
           }
+        }
+        ol.parseText(reimplFromLine.right(
+              reimplFromLine.length()-markerPos-2)); // text right from marker
 
-          if (ok && bcd && bmd) // write link for marker
-          {
-            //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
-            //    bmd->anchor(),bcd->name());
-            ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
-                bmd->anchor(),bcd->displayName());
-                
-            if (bmd->isLinkableInProject() ) 
-            {
-              writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
-            }
-          }
-          ++mli;
-          index=newIndex+matchLen;
-        } 
-        ol.parseText(reimplInLine.right(reimplInLine.length()-index));
         ol.disableAllBut(OutputGenerator::RTF);
         ol.newParagraph();
         ol.enableAll();
       }
+      else
+      {
+        err("Error: translation error: no marker in trReimplementsFromList()\n");
+      }
     }
-    // write the list of examples that use this member
-    if (hasExamples())
+
+    //ol.writeString(".");
+  }
+
+  MemberList *bml=reimplementedBy();
+  if (bml)
+  {
+    MemberListIterator mli(*bml);
+    MemberDef *bmd=0;
+    uint count=0;
+    ClassDef *bcd=0;
+    for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
     {
-      ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
-      ol.writeDescItem();
-      writeExample(ol,getExamples());
-      //ol.endDescItem();
-      ol.endSimpleSect();
+      // count the members that directly inherit from md and for
+      // which the member and class are visible in the docs.
+      if ( bmd->isLinkable() && bcd->isLinkable() ) 
+      {
+        count++;
+      }
     }
-    // write reference to the source
-    writeSourceDef(ol,cname);
-    writeSourceRefs(ol,cname);
-    writeSourceReffedBy(ol,cname);
-    writeInlineCode(ol,cname);
+    if (count>0)
+    {
+      mli.toFirst();
+      // write the list of classes that overwrite this member
+      ol.disable(OutputGenerator::RTF);
+      ol.newParagraph();
+      ol.enableAll();
 
-    ol.disableAllBut(OutputGenerator::RTF);
-    ol.newParagraph();
-    ol.enableAll();
+      QCString reimplInLine;
+      if (virt==Pure || (classDef && classDef->compoundType()==ClassDef::Interface))
+      {
+        reimplInLine = theTranslator->trImplementedInList(count);
+      }
+      else
+      {
+        reimplInLine = theTranslator->trReimplementedInList(count);
+      }
+      static QRegExp marker("@[0-9]+");
+      int index=0,newIndex,matchLen;
+      // now replace all markers in reimplInLine with links to the classes
+      while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
+      {
+        ol.parseText(reimplInLine.mid(index,newIndex-index));
+        bool ok;
+        uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
+        //bmd=bml->at(entryIndex);
+
+        count=0;
+        // find the entryIndex-th documented entry in the inheritance list.
+        for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
+        {
+          if ( bmd->isLinkable() && bcd->isLinkable()) 
+          {
+            if (count==entryIndex) break;
+            count++;
+          }
+        }
 
-    ol.endIndent();
-    // enable LaTeX again
-    //if (Config_getBool("EXTRACT_ALL") && !hasDocs) ol.enable(OutputGenerator::Latex); 
-    ol.popGeneratorState();
+        if (ok && bcd && bmd) // write link for marker
+        {
+          //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+          //    bmd->anchor(),bcd->name());
+          ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
+              bmd->anchor(),bcd->displayName());
+
+          if (bmd->isLinkableInProject() ) 
+          {
+            writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
+          }
+        }
+        ++mli;
+        index=newIndex+matchLen;
+      } 
+      ol.parseText(reimplInLine.right(reimplInLine.length()-index));
+      ol.disableAllBut(OutputGenerator::RTF);
+      ol.newParagraph();
+      ol.enableAll();
+    }
+  }
+  // write the list of examples that use this member
+  if (hasExamples())
+  {
+    ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
+    ol.writeDescItem();
+    writeExample(ol,getExamples());
+    //ol.endDescItem();
+    ol.endSimpleSect();
+  }
+  // write reference to the source
+  writeSourceDef(ol,cname);
+  writeSourceRefs(ol,cname);
+  writeSourceReffedBy(ol,cname);
+  writeInlineCode(ol,cname);
 
-    if ((m_hasCallGraph || Config_getBool("CALL_GRAPH")) 
-        && isFunction() && Config_getBool("HAVE_DOT")
-       )
+  ol.disableAllBut(OutputGenerator::RTF);
+  ol.newParagraph();
+  ol.enableAll();
+
+  if ((m_hasCallGraph || Config_getBool("CALL_GRAPH")) 
+      && isFunction() && Config_getBool("HAVE_DOT")
+     )
+  {
+    DotCallGraph callGraph(this,Config_getInt("MAX_DOT_GRAPH_DEPTH"));
+    if (!callGraph.isTrivial())
     {
-      DotCallGraph callGraph(this,Config_getInt("MAX_DOT_GRAPH_DEPTH"));
-      if (!callGraph.isTrivial())
-      {
-        msg("Generating call graph for function %s\n",qualifiedName().data());
-        ol.disable(OutputGenerator::Man);
-        ol.newParagraph();
-        ol.startCallGraph();
-        ol.parseText(theTranslator->trCallGraph());
-        ol.endCallGraph(callGraph);
-        ol.enableAll();
-      }
+      msg("Generating call graph for function %s\n",qualifiedName().data());
+      ol.disable(OutputGenerator::Man);
+      ol.newParagraph();
+      ol.startCallGraph();
+      ol.parseText(theTranslator->trCallGraph());
+      ol.endCallGraph(callGraph);
+      ol.enableAll();
     }
   }
 
+  ol.endIndent();
+  // enable LaTeX again
+  //if (Config_getBool("EXTRACT_ALL") && !hasDocs) ol.enable(OutputGenerator::Latex); 
+  ol.popGeneratorState();
+
 }
 
 void MemberDef::warnIfUndocumented()
@@ -1969,7 +1986,7 @@ void MemberDef::setInitializer(const char *initializer)
 { 
   init=initializer; 
   int p=init.length()-1;
-  while (p>=0 && isspace(init.at(p))) p--;
+  while (p>=0 && isspace((uchar)init.at(p))) p--;
   init=init.left(p+1);
   initLines=init.contains('\n');
 }
@@ -2209,4 +2226,21 @@ bool MemberDef::isObjCMethod() const
   return FALSE; 
 }
 
+QCString MemberDef::qualifiedName() const
+{
+  if (isObjCMethod())
+  {
+    QCString qm;
+    if (isStatic()) qm="+"; else qm="-";
+    qm+="[";
+    qm+=classDef->name()+" ";
+    qm+=name();
+    qm+="]";
+    return qm;
+  }
+  else
+  {
+    return Definition::qualifiedName();
+  }  
+}
 
diff --git a/src/memberdef.h b/src/memberdef.h
index e880a12..c19133e 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -99,6 +99,7 @@ class MemberDef : public Definition
     const char *getGroupFileName() const     { return groupFileName; }
     int getGroupStartLine() const            { return groupStartLine; }
     bool getGroupHasDocs() const             { return groupHasDocs; }
+    QCString qualifiedName() const;
 
     // direct kind info 
     Protection protection() const         { return prot; }
diff --git a/src/outputgen.h b/src/outputgen.h
index 980dfdf..6a86831 100644
--- a/src/outputgen.h
+++ b/src/outputgen.h
@@ -316,7 +316,7 @@ class OutputGenerator : public BaseOutputDocInterface
     virtual void insertMemberAlign() = 0;
     virtual void startMemberDoc(const char *,const char *,
                                 const char *,const char *) = 0;
-    virtual void endMemberDoc() = 0;
+    virtual void endMemberDoc(bool) = 0;
     virtual void startDoxyAnchor(const char *fName,const char *manName,
                                  const char *anchor,const char *name) = 0;
     virtual void endDoxyAnchor(const char *fileName,const char *anchor) = 0;
diff --git a/src/outputlist.h b/src/outputlist.h
index 52fc346..c24950f 100644
--- a/src/outputlist.h
+++ b/src/outputlist.h
@@ -207,8 +207,8 @@ class OutputList : public OutputDocInterface
     void startMemberDoc(const char *clName,const char *memName,
                         const char *anchor,const char *title)
     { forall(&OutputGenerator::startMemberDoc,clName,memName,anchor,title); }
-    void endMemberDoc() 
-    { forall(&OutputGenerator::endMemberDoc); }
+    void endMemberDoc(bool hasArgs) 
+    { forall(&OutputGenerator::endMemberDoc,hasArgs); }
     void startDoxyAnchor(const char *fName,const char *manName,
                          const char *anchor, const char *name)
     { forall(&OutputGenerator::startDoxyAnchor,fName,manName,anchor,name); }
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index faf8dd1..4f024d8 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -190,6 +190,8 @@ void RTFGenerator::init()
   {
     loadExtensions(rtfExtensionsFile);
   }
+
+  createSubDirs(d);
 }
 
 static QCString makeIndexName(const char *s,int i)
@@ -322,6 +324,7 @@ void RTFGenerator::beginRTFSection()
 void RTFGenerator::startFile(const char *name,const char *,const char *)
 {
   QCString fileName=name;
+  relPath = relativePathToRoot(fileName);
 
   if (fileName.right(4)!=".rtf" ) fileName+=".rtf";
   startPlainFile(fileName);
@@ -1357,7 +1360,7 @@ void RTFGenerator::startMemberDoc(const char *clname,
   t << endl;
 }
 
-void RTFGenerator::endMemberDoc()
+void RTFGenerator::endMemberDoc(bool)
 {
   DBG_RTF(t << "{\\comment endMemberDoc}" << endl)
   t << "}" << endl;
@@ -2188,7 +2191,7 @@ void RTFGenerator::endDotGraph(DotClassGraph &g)
   newParagraph();
 
   QCString fileName =
-    g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),TRUE,FALSE);
+    g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),relPath,TRUE,FALSE);
 
   // display the file
   t << "{" << endl;
@@ -2210,7 +2213,8 @@ void RTFGenerator::endInclDepGraph(DotInclDepGraph &g)
 {
   newParagraph();
 
-  QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),FALSE);
+  QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
+                         relPath,FALSE);
 
   // display the file
   t << "{" << endl;
@@ -2231,7 +2235,8 @@ void RTFGenerator::endCallGraph(DotCallGraph &g)
 {
   newParagraph();
 
-  QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),FALSE);
+  QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
+                        relPath,FALSE);
 
   // display the file
   t << "{" << endl;
diff --git a/src/rtfgen.h b/src/rtfgen.h
index bd611cf..ee4d767 100644
--- a/src/rtfgen.h
+++ b/src/rtfgen.h
@@ -134,7 +134,7 @@ class RTFGenerator : public OutputGenerator
     void endDescItem();
     void lineBreak();
     void startMemberDoc(const char *,const char *,const char *,const char *);
-    void endMemberDoc();
+    void endMemberDoc(bool);
     void startDoxyAnchor(const char *,const char *,const char *,const char *);
     void endDoxyAnchor(const char *,const char *);
     void startCodeAnchor(const char *) {};
@@ -282,6 +282,7 @@ class RTFGenerator : public OutputGenerator
     int  m_listLevel; // // RTF does not really have a addative indent...manually set list level.
     bool m_omitParagraph; // should a the next paragraph command be ignored?
     int  m_numCols; // number of columns in a table
+    QCString relPath;
 
     void beginRTFDocument();
     void beginRTFChapter();
diff --git a/src/scanner.l b/src/scanner.l
index 2db9d21..349f156 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -516,7 +516,7 @@ static void splitKnRArg(QCString &oldStyleArgPtr,QCString &oldStyleArgName)
       int s=bi2+1;
       oldStyleArgType = current->args.left(s);
       int i=s;
-      while (i<si && ((c=current->args.at(i))=='*' || isspace(c))) i++;
+      while (i<si && ((c=current->args.at(i))=='*' || isspace((uchar)c))) i++;
       oldStyleArgType += current->args.mid(s,i-s);
       s=i;
       while (i<si && isId(current->args.at(i))) i++;
@@ -529,7 +529,7 @@ static void splitKnRArg(QCString &oldStyleArgPtr,QCString &oldStyleArgName)
       oldStyleArgType = current->args.left(s);
       s++;
       int i=s+1;
-      while (i<si && ((c=current->args.at(i))=='*' || isspace(c))) i++;
+      while (i<si && ((c=current->args.at(i))=='*' || isspace((uchar)c))) i++;
       oldStyleArgType += current->args.mid(s,i-s);
       s=i;
       while (i<si && isId(current->args.at(i))) i++;
@@ -543,7 +543,7 @@ static void splitKnRArg(QCString &oldStyleArgPtr,QCString &oldStyleArgName)
       while (i>=0 && isId(current->args.at(i))) i--;
       j=i+1;
       // look for start of *'s
-      while (i>=0 && ((c=current->args.at(i))=='*' || isspace(c))) i--;
+      while (i>=0 && ((c=current->args.at(i))=='*' || isspace((uchar)c))) i--;
       i++;
       if (i!=l)
       {
@@ -561,7 +561,7 @@ static void splitKnRArg(QCString &oldStyleArgPtr,QCString &oldStyleArgName)
   {
     int l=si,j=0;
     char c;
-    while (j<l && ((c=current->args.at(j))=='*' || isspace(c))) j++;
+    while (j<l && ((c=current->args.at(j))=='*' || isspace((uchar)c))) j++;
     if (j>0)
     {
       oldStyleArgPtr=current->args.left(j);
@@ -750,7 +750,6 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 %x      PageDocArg2
 %x      FileDocArg1
 %x      FileDocArg2
-%x      ExampleDoc
 %x	ExampleDocArg1
 %x	EnumDocArg1
 %x	FuncPtr
@@ -1067,9 +1066,17 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 <ObjCReturnType>")"			{
   					  BEGIN( ObjCMethod );
   					}
-<ObjCParams>{ID}/":"			{ // Keyword of parameter
-  					  current->argList->getLast()->attrib=(QCString)"["+yytext+"]";
-					  current->name += yytext;
+<ObjCParams>{ID}{BN}*/":"		{ // Keyword of parameter
+  					  lineCount();
+					  QCString keyw = QCString(yytext).stripWhiteSpace();
+					  current->name += keyw;
+					  if (current->argList->getLast()->type.isEmpty())
+					  {
+					    current->argList->getLast()->type="id";
+					  }
+  					  Argument *a = new Argument;
+  					  a->attrib=(QCString)"["+keyw+"]";
+					  current->argList->append(a);
   					}
 <ObjCParams>{ID}{BN}*			{ // name of parameter
   					  lineCount();
@@ -1085,17 +1092,8 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 <ObjCParams>"("				{
   					  BEGIN( ObjCParamType );
   					}
-<ObjCParams>{BN}*			{
-  					  lineCount();
-					  if (current->argList->getLast()->type.isEmpty())
-					  {
-					    current->argList->getLast()->type="id";
-					  }
-  					  Argument *a = new Argument;
-					  current->argList->append(a);
-  					}
 <ObjCParamType>[^)]*			{
-  					  current->argList->last()->type=yytext;
+  					  current->argList->getLast()->type=yytext;
   					}
 <ObjCParamType>")"{B}*			{
   					  BEGIN( ObjCParams );
@@ -1107,6 +1105,9 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					  BEGIN( Function );
   					}
 <ObjCMethod,ObjCParams>"{"		{ // start of a method body
+                                          //printf("Type=%s Name=%s args=%s\n",
+					  //    current->type.data(),current->name.data(),argListToString(current->argList).data()
+					  //    );
                                           unput('{');
   					  BEGIN( Function );
   					}
@@ -3940,14 +3941,14 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					  current->groupDocType = Entry::GROUPDOC_NORMAL;
 					  BEGIN( GroupDocArg1 );
   					}
-<Doc,PageDoc,ExampleDoc,JavaDoc>{B}*{CMD}"addtogroup"{B}+ {
+<Doc,PageDoc,JavaDoc>{B}*{CMD}"addtogroup"{B}+ {
   					  current->section = Entry::GROUPDOC_SEC;
 					  current->fileName = yyFileName;
 					  current->startLine = yyLineNr;
 					  current->groupDocType = Entry::GROUPDOC_ADD;
 					  BEGIN( GroupDocArg1 );
   					}
-<Doc,PageDoc,ExampleDoc,JavaDoc>{B}*{CMD}"weakgroup"{B}+ {
+<Doc,PageDoc,JavaDoc>{B}*{CMD}"weakgroup"{B}+ {
   					  current->section = Entry::GROUPDOC_SEC;
 					  current->fileName = yyFileName;
 					  current->startLine = yyLineNr;
@@ -4163,7 +4164,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					}
 <ExampleDocArg1>{FILE}			{
 				          current->name = stripQuotes(yytext);	
-					  BEGIN( ExampleDoc );
+					  BEGIN( PageDoc );
 					}
 <ClassDoc,Doc,JavaDoc>{B}*{CMD}"relate"[sd]{B}*    { 
   					  lastDocRelContext = YY_START;
@@ -4362,22 +4363,22 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 <PageDoc>{CMD}"refitem".*"\n"		{
   					  current->doc+=yytext;
   					}
-<ExampleDoc,ClassDoc,PageDoc,Doc,JavaDoc>{CMD}"section"{B}+		{
+<ClassDoc,PageDoc,Doc,JavaDoc>{CMD}"section"{B}+		{
   					  //sectionType=SectionInfo::Section;
 					  current->doc+=yytext;
   					  BEGIN(SectionLabel);
   					}
-<ExampleDoc,ClassDoc,PageDoc,Doc,JavaDoc>{CMD}"subsection"{B}+		{
+<ClassDoc,PageDoc,Doc,JavaDoc>{CMD}"subsection"{B}+		{
   					  //sectionType=SectionInfo::Subsection;
 					  current->doc+=yytext;
   					  BEGIN(SectionLabel);
   					}
-<ExampleDoc,ClassDoc,PageDoc,Doc,JavaDoc>{CMD}"subsubsection"{B}+	{
+<ClassDoc,PageDoc,Doc,JavaDoc>{CMD}"subsubsection"{B}+	{
   					  //sectionType=SectionInfo::Subsubsection;
 					  current->doc+=yytext;
   					  BEGIN(SectionLabel);
   					}
-<ExampleDoc,ClassDoc,PageDoc,Doc,JavaDoc>{CMD}"paragraph"{B}+		{
+<ClassDoc,PageDoc,Doc,JavaDoc>{CMD}"paragraph"{B}+		{
   					  //sectionType=SectionInfo::Paragraph;
 					  current->doc+=yytext;
   					  BEGIN(SectionLabel);
@@ -4418,7 +4419,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					  current->brief.resize(0);
 					  BEGIN(lastDocContext);
   					}
-<ExampleDoc,Doc,PageDoc,JavaDoc,ClassDoc>{CMD}"anchor"{B}+ {
+<Doc,PageDoc,JavaDoc,ClassDoc>{CMD}"anchor"{B}+ {
   					  lastAnchorContext = YY_START;
   					  //sectionType=SectionInfo::Anchor;
 					  current->doc+=yytext;
@@ -4640,9 +4641,9 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					  sectionTitle+=yytext;
                                           current->doc+=yytext;
   					}
-<ExampleDoc,PageDoc,ClassDoc>"\n"			{ yyLineNr++ ; current->doc+=yytext; }
-<ExampleDoc,PageDoc,ClassDoc>[a-z_A-Z0-9 \t]+		{ current->doc += yytext; }
-<ExampleDoc,PageDoc>{CMD}"ingroup"{B}+			{
+<PageDoc,ClassDoc>"\n"			{ yyLineNr++ ; current->doc+=yytext; }
+<PageDoc,ClassDoc>[a-z_A-Z0-9 \t]+		{ current->doc += yytext; }
+<PageDoc>{CMD}"ingroup"{B}+			{
   							  lastGroupContext = YY_START;
 							  lineCount();
 							  BEGIN( GroupName );
@@ -4663,20 +4664,20 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   							  endGroup();
                                                           memberGroupHeader.resize(0);
   							}
-<ExampleDoc,PageDoc,ClassDoc>.    	 	        { current->doc += yytext; }
-<Doc,JavaDoc,LineDoc,ExampleDoc,PageDoc,ClassDoc>^{B}*"//" 
-<Doc,ExampleDoc,PageDoc,ClassDoc>"//"  			{ current->doc += yytext; }
+<PageDoc,ClassDoc>.    	 	        { current->doc += yytext; }
+<Doc,JavaDoc,LineDoc,PageDoc,ClassDoc>^{B}*"//" 
+<Doc,PageDoc,ClassDoc>"//"  			{ current->doc += yytext; }
 <LineDoc,JavaDoc,ClassDocBrief>"//"			{ current->brief += yytext; }
-<Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief>("\\\\"|"@@")"f"[$\[\]] {
+<Doc,JavaDoc,LineDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief>("\\\\"|"@@")"f"[$\[\]] {
 							  current->doc += yytext; 
 							}
-<Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief,CopyArgComment,CopyArgCommentLine>{CMD}"f$"	{ 
+<Doc,JavaDoc,LineDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief,CopyArgComment,CopyArgCommentLine>{CMD}"f$"	{ 
   							  lastFormulaContext = YY_START;
   							  formulaText="$"; 
 							  insideFormula=TRUE;
 							  BEGIN(ReadFormulaShort); 
 							}
-<Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief,CopyArgComment,CopyArgCommentLine>{CMD}"f["	{ 
+<Doc,JavaDoc,LineDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief,CopyArgComment,CopyArgCommentLine>{CMD}"f["	{ 
   							  lastFormulaContext = YY_START;
   							  formulaText="\\["; 
 							  insideFormula=TRUE;
@@ -4742,7 +4743,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   							}
 <ReadFormulaLong>\n					{ formulaText+=*yytext; yyLineNr++; }
 <ReadFormulaLong,ReadFormulaShort>.                     { formulaText+=*yytext; }
-<ExampleDoc,PageDoc,ClassDocBrief,ClassDoc,ReadFormulaShort,ReadFormulaLong>{B}*"*/"  	{
+<PageDoc,ClassDocBrief,ClassDoc,ReadFormulaShort,ReadFormulaLong>{B}*"*/"  	{
   					  checkDocs();
 					  //printf("current->section=%x\n",current->section);
 					  if (YY_START==SkipCode) // premature end of code block
@@ -4814,11 +4815,11 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 <PageDocTitle>"</"{TITLE}">"		{ BEGIN( PageDoc ); }
 
   /* escaped versions of the conditional commands (for putting them in the docs) */
-<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"if"/[^a-z_A-Z0-9]     { current->doc+=yytext; }
-<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"ifnot"/[^a-z_A-Z0-9]  { current->doc+=yytext; }
-<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"elseif"/[^a-z_A-Z0-9] { current->doc+=yytext; }
-<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"else"/[^a-z_A-Z0-9]   { current->doc+=yytext; }
-<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"endif"/[^a-z_A-Z0-9]  { current->doc+=yytext; }
+<ClassDoc,Doc,AfterDoc,PageDoc>{CMD}{CMD}"if"/[^a-z_A-Z0-9]     { current->doc+=yytext; }
+<ClassDoc,Doc,AfterDoc,PageDoc>{CMD}{CMD}"ifnot"/[^a-z_A-Z0-9]  { current->doc+=yytext; }
+<ClassDoc,Doc,AfterDoc,PageDoc>{CMD}{CMD}"elseif"/[^a-z_A-Z0-9] { current->doc+=yytext; }
+<ClassDoc,Doc,AfterDoc,PageDoc>{CMD}{CMD}"else"/[^a-z_A-Z0-9]   { current->doc+=yytext; }
+<ClassDoc,Doc,AfterDoc,PageDoc>{CMD}{CMD}"endif"/[^a-z_A-Z0-9]  { current->doc+=yytext; }
 <LineDoc,JavaDoc>{CMD}{CMD}"if"/[^a-z_A-Z0-9]     { current->brief+=yytext; }
 <LineDoc,JavaDoc>{CMD}{CMD}"ifnot"/[^a-z_A-Z0-9]  { current->brief+=yytext; }
 <LineDoc,JavaDoc>{CMD}{CMD}"elseif"/[^a-z_A-Z0-9] { current->brief+=yytext; }
@@ -4826,15 +4827,15 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 <LineDoc,JavaDoc>{CMD}{CMD}"endif"/[^a-z_A-Z0-9]  { current->brief+=yytext; }
 
   /* conditional commands */
-<ClassDoc,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"if"{B}+ {
+<ClassDoc,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc>{CMD}"if"{B}+ {
                                           lastIfContext = YY_START;
 					  BEGIN(IfGuard);
   					}
-<ClassDoc,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"ifnot"{B}+ {
+<ClassDoc,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc>{CMD}"ifnot"{B}+ {
                                           lastIfContext = YY_START;
 					  BEGIN(IfNotGuard);
   					}
-<ClassDoc,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"if"(\r?)\n |
+<ClassDoc,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc>{CMD}"if"(\r?)\n |
 <IfGuard>\n				{
   					  warn(yyFileName,yyLineNr,"Missing guard for if statement!");
 					  yyLineNr++;
@@ -4897,17 +4898,17 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					  yyLineNr++;
   					}
 <SkipSection>"//"|"*/"
-<ClassDoc,ClassDocBrief,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"elseif"/[^a-z_A-Z0-9] {
+<ClassDoc,ClassDocBrief,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc>{CMD}"elseif"/[^a-z_A-Z0-9] {
                                           // previous section enabled => skip now
   					  depthIf=1;
   					  BEGIN(SkipSection);
   					}
-<ClassDoc,ClassDocBrief,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"else"/[^a-z_A-Z0-9] {
+<ClassDoc,ClassDocBrief,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc>{CMD}"else"/[^a-z_A-Z0-9] {
                                           // section was enabled => skip now
   					  depthIf=1;
   					  BEGIN(SkipSection);
   					}
-<ClassDoc,ClassDocBrief,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"endif"/[^a-z_A-Z0-9] {
+<ClassDoc,ClassDocBrief,LineDoc,AfterDocLine,AfterDocBrief,Doc,JavaDoc,AfterDoc,PageDoc>{CMD}"endif"/[^a-z_A-Z0-9] {
                                           // section enabled => absorb endif
   					}
 
@@ -5222,7 +5223,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
                                             current->doc+="\\internal"; 
 					  }
 					}
-<Doc,JavaDoc,ExampleDoc,PageDoc,ClassDoc,AfterDoc>{CMD}"internal"		{ 
+<Doc,JavaDoc,PageDoc,ClassDoc,AfterDoc>{CMD}"internal"		{ 
                                           if (!Config_getBool("INTERNAL_DOCS"))
                                           {
 					    lastInternalDocContext = YY_START;
@@ -5294,10 +5295,10 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					  unput('/');unput('*');
 					  BEGIN( tmpDocType );
 					}
-<Doc,JavaDoc,ClassDoc,PageDoc,ExampleDoc,ReadFormulaShort,ReadFormulaLong,AfterDoc>^{B}*(("//"{B}*)?)"*"+[ \t]*"-"("#")?{B}+ { 
+<Doc,JavaDoc,ClassDoc,PageDoc,ReadFormulaShort,ReadFormulaLong,AfterDoc>^{B}*(("//"{B}*)?)"*"+[ \t]*"-"("#")?{B}+ { 
   				         current->doc += yytext; 
 					}
-<Doc,JavaDoc,ClassDoc,PageDoc,ExampleDoc,ReadFormulaShort,ReadFormulaLong,AfterDoc>^{B}*(("//"{B}*)?)"*"+[ \t]*"."{B}*\n { 
+<Doc,JavaDoc,ClassDoc,PageDoc,ReadFormulaShort,ReadFormulaLong,AfterDoc>^{B}*(("//"{B}*)?)"*"+[ \t]*"."{B}*\n { 
   				         current->doc += yytext; 
 					 yyLineNr++;
 					}
@@ -5307,12 +5308,12 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 <ClassDocBrief,AfterDocBrief>^{B}*(("//"{B}*)?)"*"+[ \t]*"."{B}*\n { 
   				         current->brief += "."; yyLineNr++; 
 					}
-<Doc,JavaDoc,ClassDoc,PageDoc,ExampleDoc,ReadFormulaShort,ReadFormulaLong,ClassDocBrief,AfterDoc,AfterDocBrief>^{B}*(("//"{B}*)?)"*"+/[^/]
-<Doc,JavaDoc,ClassDoc,PageDoc,ExampleDoc,ReadFormulaShort,ReadFormulaLong,ClassDocBrief,AfterDoc,AfterDocBrief>^{B}*(("//"{B}*)?)"*"+{B}+ { 
+<Doc,JavaDoc,ClassDoc,PageDoc,ReadFormulaShort,ReadFormulaLong,ClassDocBrief,AfterDoc,AfterDocBrief>^{B}*(("//"{B}*)?)"*"+/[^/]
+<Doc,JavaDoc,ClassDoc,PageDoc,ReadFormulaShort,ReadFormulaLong,ClassDocBrief,AfterDoc,AfterDocBrief>^{B}*(("//"{B}*)?)"*"+{B}+ { 
 					  current->doc+=' '; 
 					}
 
-<Doc,ClassDoc,PageDoc,ExampleDoc,AfterDoc>"\\"[a-z_A-Z][a-z_A-Z0-9]*[\\] { // directory type of text
+<Doc,ClassDoc,PageDoc,AfterDoc>"\\"[a-z_A-Z][a-z_A-Z0-9]*[\\] { // directory type of text
   					  current->doc+=yytext;
   					}
   /*
@@ -5328,13 +5329,13 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					    }
                                           }
   */
-<Doc,ClassDoc,PageDoc,ExampleDoc,AfterDoc,CopyArgComment>{CMD}{CMD}[a-z_A-Z][a-z_A-Z0-9]* 	{ /* escaped command */
+<Doc,ClassDoc,PageDoc,AfterDoc,CopyArgComment>{CMD}{CMD}[a-z_A-Z][a-z_A-Z0-9]* 	{ /* escaped command */
 					    if (YY_START==CopyArgComment)
 					      fullArgString+=yytext;
 					    else
   					      current->doc+=yytext;
                                           }
-<Doc,ClassDoc,PageDoc,ExampleDoc,AfterDoc,CopyArgComment>{CMD}[a-z_A-Z][a-z_A-Z0-9]* 	{
+<Doc,ClassDoc,PageDoc,AfterDoc,CopyArgComment>{CMD}[a-z_A-Z][a-z_A-Z0-9]* 	{
                                           bool handled=FALSE;
                                           if ( useOverrideCommands)
                                           {
@@ -5422,7 +5423,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					      current->brief+=yytext;
 					  //}
   					}
-<DefLineDoc,LineDoc,ClassDoc,PageDoc,ExampleDoc,Doc>"/*"|"//"   { current->doc += yytext; }
+<DefLineDoc,LineDoc,ClassDoc,PageDoc,Doc>"/*"|"//"   { current->doc += yytext; }
 <SkipCxxComment>.*/\n			{ 
 					  BEGIN( lastCContext ) ;
 					}
diff --git a/src/util.cpp b/src/util.cpp
index 5a1099a..5cc3ca8 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -1127,7 +1127,7 @@ static bool findOperator(const QCString &s,int i)
   while (b<i) // check if there are only spaces inbetween 
               // the operator and the >
   {
-    if (!isspace(s.at(b))) return FALSE;
+    if (!isspace((uchar)s.at(b))) return FALSE;
     b++;
   }
   return TRUE;
@@ -1147,20 +1147,20 @@ QCString removeRedundantWhiteSpace(const QCString &s)
     char c=s.at(i);
     if (csp<6 && c==constScope[csp]) csp++; else csp=0;
     if (i<l-2 && c=='<' &&  // current char is a <
-        (isId(s.at(i+1)) || isspace(s.at(i+1))) && // next char is an id char or space
+        (isId(s.at(i+1)) || isspace((uchar)s.at(i+1))) && // next char is an id char or space
         (i<8 || !findOperator(s,i)) // string in front is not "operator"
        )
     {
       result+="< "; // insert extra space for layouting (nested) templates
     }
     else if (i>0 && c=='>' && // current char is a >
-             (isId(s.at(i-1)) || isspace(s.at(i-1)) || s.at(i-1)=='*' || s.at(i-1)=='&') && // prev char is an id char or space
+             (isId(s.at(i-1)) || isspace((uchar)s.at(i-1)) || s.at(i-1)=='*' || s.at(i-1)=='&') && // prev char is an id char or space
              (i<8 || !findOperator(s,i)) // string in front is not "operator"
             )
     {
       result+=" >"; // insert extra space for layouting (nested) templates
     }
-    else if (i>0 && c==',' && !isspace(s.at(i-1))
+    else if (i>0 && c==',' && !isspace((uchar)s.at(i-1))
              && ((i<l-1 && isId(s.at(i+1)))
                  || (i<l-2 && s.at(i+1)=='$' && isId(s.at(i+2)))  // for PHP
                  || (i<l-3 && s.at(i+1)=='&' && s.at(i+2)=='$' && isId(s.at(i+3)))))  // for PHP
@@ -1186,7 +1186,7 @@ QCString removeRedundantWhiteSpace(const QCString &s)
       result+=" :";
       csp=0;
     }
-    else if (!isspace(c) ||
+    else if (!isspace((uchar)c) ||
 	      ( i>0 && i<l-1 && 
                 (isId(s.at(i-1)) || s.at(i-1)==')' || s.at(i-1)==',' || s.at(i-1)=='>' || s.at(i-1)==']')
                  && (isId(s.at(i+1)) || (i<l-2 && s.at(i+1)=='$' && isId(s.at(i+2)))
@@ -2247,7 +2247,7 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA,
     }
     else if (dstPos<dstAType.length())
     {
-      if (!isspace(dstAType.at(dstPos))) // maybe the names differ
+      if (!isspace((uchar)dstAType.at(dstPos))) // maybe the names differ
       {
         if (!dstA->name.isEmpty()) // dst has its name separated from its type
         {
@@ -2274,7 +2274,7 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA,
     }
     else if (srcPos<srcAType.length())
     {
-      if (!isspace(srcAType.at(srcPos))) // maybe the names differ
+      if (!isspace((uchar)srcAType.at(srcPos))) // maybe the names differ
       {
         if (!srcA->name.isEmpty()) // src has its name separated from its type
         {
@@ -2646,7 +2646,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
         {
           delete argList; argList=0;
         }
-        if (mdist==maxInheritanceDepth && !strcmp(args,"()"))
+        if (mdist==maxInheritanceDepth && args && strcmp(args,"()")!=0)
           // no exact match found, but if args="()" an arbitrary member will do
         {
           //printf("  >Searching for arbitrary member\n");
@@ -2746,7 +2746,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
             }
           }
         }
-        if (!found && !strcmp(args,"()")) 
+        if (!found && args && !strcmp(args,"()")) 
           // no exact match found, but if args="()" an arbitrary 
           // member will do
         {
@@ -2812,7 +2812,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
             }
           }
         }
-        if (members.count()!=1 && !strcmp(args,"()"))
+        if (members.count()!=1 && args && !strcmp(args,"()"))
         {
           // no exact match found, but if args="()" an arbitrary 
           // member will do
@@ -3548,11 +3548,12 @@ QCString escapeCharsInString(const char *name,bool allowDots)
 }
 
 /*! This function determines the file name on disk of an item
- *  given its name, which could be a class name with templete 
+ *  given its name, which could be a class name with template 
  *  arguments, so special characters need to be escaped.
  */
 QCString convertNameToFile(const char *name,bool allowDots)
 {
+  QCString result;
   if (Config_getBool("SHORT_NAMES"))
   {
     static QDict<void> usedNames(10007);
@@ -3569,13 +3570,75 @@ QCString convertNameToFile(const char *name,bool allowDots)
     {
       num = *(int*)&value;
     }
-    QCString result;
     result.sprintf("a%05d",num); 
-    return result;
   }
   else // long names
   {
-    return escapeCharsInString(name,allowDots);
+    result=escapeCharsInString(name,allowDots);
+  }
+  if (Config_getBool("CREATE_SUBDIRS"))
+  {
+    if (Doxygen::htmlDirMap==0) 
+    {
+      Doxygen::htmlDirMap=new QDict<int>(100003);
+      Doxygen::htmlDirMap->setAutoDelete(TRUE);
+    }
+    static int curDirNum=0;
+    int *dirNum = Doxygen::htmlDirMap->find(result);
+    int l1Dir=0,l2Dir=0;
+    if (dirNum==0) // new name
+    {
+      Doxygen::htmlDirMap->insert(result,new int(curDirNum)); 
+      l1Dir = (curDirNum)%10;
+      l2Dir = ((curDirNum)/10)%10;
+      curDirNum++;
+    }
+    else // existing name
+    {
+      l1Dir = (*dirNum)%10;
+      l2Dir = ((*dirNum)/10)%10;
+    }
+    result.prepend(QCString().sprintf("d%d/d%d/",l1Dir,l2Dir));
+  }
+  return result;
+}
+
+QCString relativePathToRoot(const char *name)
+{
+  QCString result;
+  if (Config_getBool("CREATE_SUBDIRS"))
+  {
+    if (name==0)
+    {
+      return REL_PATH_TO_ROOT;
+    }
+    else
+    {
+      QCString n = name;
+      int i = n.findRev('/');
+      if (i!=-1)
+      {
+        result=REL_PATH_TO_ROOT;
+      }
+    }
+  }
+  return result;
+}
+
+void createSubDirs(QDir &d)
+{
+  if (Config_getBool("CREATE_SUBDIRS"))
+  {
+    // create 100 subdirectories
+    int l1,l2;
+    for (l1=0;l1<10;l1++)
+    {
+      d.mkdir(QString().sprintf("d%d",l1));
+      for (l2=0;l2<10;l2++)
+      {
+        d.mkdir(QString().sprintf("d%d/d%d",l1,l2));
+      }
+    }
   }
 }
 
@@ -4714,3 +4777,13 @@ void replaceNamespaceAliases(QCString &scope,int i)
   //printf("replaceNamespaceAliases() result=%s\n",scope.data());
 }
 
+QCString stripPath(const char *s)
+{
+  QCString result=s;
+  int i=result.findRev('/');
+  if (i!=-1)
+  {
+    result=result.mid(i+1);
+  }
+  return result;
+}
diff --git a/src/util.h b/src/util.h
index dacb25e..e27b75e 100644
--- a/src/util.h
+++ b/src/util.h
@@ -49,6 +49,7 @@ class MemberNameInfoSDict;
 struct ListItemInfo;
 class PageDef;
 struct SectionInfo;
+class QDir;
 
 //--------------------------------------------------------------------
 
@@ -213,6 +214,11 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item);
 int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item,
                      const QCString &explicitScopePart);
 int computeQualifiedIndex(const QString &name);
+void addDirPrefix(QCString &fileName);
+QCString relativePathToRoot(const char *name);
+#define REL_PATH_TO_ROOT "../../"
+void createSubDirs(QDir &d);
+QCString stripPath(const char *s);
 
 #endif
 
-- 
cgit v0.12

