From 62039dd46dfca33a45f5461a3732b3a707e4ce8b Mon Sep 17 00:00:00 2001
From: Dimitri van Heesch <dimitri@stack.nl>
Date: Wed, 26 May 2004 19:08:11 +0000
Subject: Release-1.3.7-20040526

---
 INSTALL                   |   4 +-
 README                    |   4 +-
 VERSION                   |   2 +-
 doc/commands.doc          |  24 ++++-
 packages/rpm/doxygen.spec |   2 +-
 src/code.l                |  16 ++--
 src/diagram.cpp           |  19 ++--
 src/diagram.h             |   3 +-
 src/docparser.cpp         |  42 ++++++---
 src/docparser.h           |   8 +-
 src/doctokenizer.l        |  17 ++--
 src/doxygen.cpp           |  17 ++--
 src/htmldocvisitor.cpp    |   2 +-
 src/htmlgen.cpp           |   4 +-
 src/htmlhelp.cpp          |   1 +
 src/index.cpp             |  61 ++++++++++---
 src/index.h               |  13 +++
 src/mandocvisitor.cpp     |   8 ++
 src/mangen.cpp            |   1 +
 src/pre.l                 |   1 +
 src/rtfgen.cpp            |   2 +-
 src/scanner.l             | 221 +++++++++++++++++++++++++++++++++++++++-------
 src/util.cpp              |  16 ++--
 23 files changed, 375 insertions(+), 113 deletions(-)

diff --git a/INSTALL b/INSTALL
index 655417b..0138680 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,7 +1,7 @@
-DOXYGEN Version 1.3.7-20040517
+DOXYGEN Version 1.3.7-20040526
 
 Please read the installation section of the manual 
 (http://www.doxygen.org/install.html) for instructions.
 
 --------
-Dimitri van Heesch (17 May 2004)
+Dimitri van Heesch (26 May 2004)
diff --git a/README b/README
index d797fa3..55d9776 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-DOXYGEN Version 1.3.7_20040517
+DOXYGEN Version 1.3.7_20040526
 
 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) (17 May 2004)
+Dimitri van Heesch (dimitri@stack.nl) (26 May 2004)
diff --git a/VERSION b/VERSION
index e045738..658b5e1 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.3.7-20040517
+1.3.7-20040526
diff --git a/doc/commands.doc b/doc/commands.doc
index 309a852..932f83f 100644
--- a/doc/commands.doc
+++ b/doc/commands.doc
@@ -48,6 +48,7 @@ documentation:
 \refitem cmdbug \\bug
 \refitem cmdc \\c
 \refitem cmdcallgraph \\callgraph
+\refitem cmdcategory \\category
 \refitem cmdclass \\class
 \refitem cmdcode \\code
 \refitem cmdcopydoc \\copydoc
@@ -111,6 +112,7 @@ documentation:
 \refitem cmdpost \\post
 \refitem cmdpre \\pre
 \refitem cmdproperty \\property
+\refitem cmdprotocol \\protocol
 \refitem cmdref \\ref
 \refitem cmdrelates \\relates
 \refitem cmdrelatesalso \\relatesalso
@@ -203,6 +205,16 @@ doxygen. Unrecognized commands are treated as normal text.
   \note The completeness (and correctness) of the call graph depends on the 
   doxygen code parser which is not perfect.
 
+<hr>
+\section cmdcategory \category <name> [<header-file>] [<header-name>]
+
+  \addindex \\category
+  For Objective-C only: Indicates that a comment block contains documentation 
+  for a class category with name \<name\>. The arguments are 
+  equal to the \\class command.
+
+  \sa section \ref cmdclass "\\class".
+
 \section cmdclass \class <name> [<header-file>] [<header-name>]
 
   \addindex \\class
@@ -385,7 +397,7 @@ doxygen. Unrecognized commands are treated as normal text.
   \ref cmdaddtogroup "\\addtogroup" and \ref cmdweakgroup "\\weakgroup"
 
 <hr>
-\section cmdinterface \interface 
+\section cmdinterface \interface <name> [<header-file>] [<header-name>]
 
   \addindex \\interface
   Indicates that a comment block contains documentation for an
@@ -553,6 +565,16 @@ See section \ref memgroup for an example.
   \sa section \ref cmdfn "\\fn" and \ref cmdvar "\\var".
 
 <hr>
+\section cmdprotocol \protocol <name> [<header-file>] [<header-name>]
+
+  \addindex \\protocol
+  Indicates that a comment block contains documentation for a
+  protocol in Objective-C with name \<name\>. The arguments are equal 
+  to the \\class command.
+
+  \sa section \ref cmdclass "\\class".
+
+<hr>
 \section cmdrelates \relates <name>
 
   \addindex \\relates
diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec
index 15c4fc8..625b268 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.7_20040517
+Version: 1.3.7_20040526
 Release: 1
 Epoch: 1
 Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz
diff --git a/src/code.l b/src/code.l
index 1943589..7e4d281 100644
--- a/src/code.l
+++ b/src/code.l
@@ -711,7 +711,6 @@ static void generateClassOrGlobalLink(BaseCodeDocInterface &ol,char *clName,
                                       bool typeOnly=FALSE)
 {
   int i=0;
-  //fprintf(stderr,"generateClassOrGlobalLink(clName=%s)\n",clName);
   if (*clName=='~') // correct for matching negated values i.s.o. destructors.
   {
     g_code->codify("~");
@@ -726,14 +725,21 @@ static void generateClassOrGlobalLink(BaseCodeDocInterface &ol,char *clName,
   ClassDef *cd=0;
   MemberDef *md=0;
 
+  //printf("generateClassOrGlobalLink(className=%s)\n",className.data());
   if (!g_theVarContext.findVariable(className)) // not a local variable
   {
     Definition *d = g_currentDefinition;
+    //printf("d=%p g_sourceFileDef=%p\n",d,g_currentDefinition);
     cd = getResolvedClass(d,g_sourceFileDef,className,&md);
     if (cd==0 && md==0 && (i=className.find('<'))!=-1)
     {
       cd=getResolvedClass(d,g_sourceFileDef,className.left(i),&md);
     }
+    //printf("is not found as a variable %s\n",cd?cd->name().data():"<null>");
+  }
+  else
+  {
+    //printf("is a local variable!\n");
   }
   if (cd && cd->isLinkable()) // is it a linkable class
   {
@@ -1212,7 +1218,7 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx)
 	  }
 	  else
 	  {
-	    printf("Invalid name: id=%d\n",refId);
+	    //printf("Invalid name: id=%d\n",refId);
 	  }
 	}
 	else if (nc=='o') // reference to potential object name
@@ -1321,7 +1327,7 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx)
 	  }
 	  else
 	  {
-	    printf("Invalid object: id=%d\n",refId);
+	    //printf("Invalid object: id=%d\n",refId);
 	  }
 	}
 	else if (nc=='c') // reference to nested call
@@ -1364,7 +1370,7 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx)
 	  }
 	  else
 	  {
-	    printf("Invalid context: id=%d\n",refId);
+	    //printf("Invalid context: id=%d\n",refId);
 	  }
 	}
 	else // illegal marker
@@ -1981,7 +1987,7 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
 <Body>{SCOPETNAME}/{B}*"("		{ // a() or c::a() or t<A,B>::a()
   					  addType();
 					  generateFunctionLink(*g_code,yytext);
-					  g_theVarContext.addVariable(g_type,yytext);
+					  //g_theVarContext.addVariable(g_type,yytext);
   					  g_bracketCount=0;
 					  g_args.resize(0);
   					  g_name+=yytext; 
diff --git a/src/diagram.cpp b/src/diagram.cpp
index 1c7a7a5..c483e04 100644
--- a/src/diagram.cpp
+++ b/src/diagram.cpp
@@ -151,7 +151,8 @@ static void writeVectorBox(QTextStream &t,DiagramItem *di,
   if (di->virtualness()==Virtual) t << "solid\n";
 }
 
-static void writeMapArea(QTextStream &t,ClassDef *cd,int x,int y,int w,int h)
+static void writeMapArea(QTextStream &t,ClassDef *cd,QCString relPath,
+                         int x,int y,int w,int h)
 {
   if (cd->isLinkable())
   {
@@ -169,6 +170,10 @@ static void writeMapArea(QTextStream &t,ClassDef *cd,int x,int y,int w,int h)
     {
       if ((dest=Doxygen::tagDestinationDict[ref])) t << *dest << "/";
     }
+    else
+    {
+      t << relPath;
+    }
     t << cd->getOutputFileBase() << Doxygen::htmlFileExtension << "\" ";
     t << "alt=\"" << cd->displayName(); 
     t << "\" shape=\"rect\" coords=\"" << x << "," << y << ",";
@@ -479,6 +484,7 @@ void TreeDiagram::drawBoxes(QTextStream &t,Image *image,
                             bool doBase,bool bitmap,
                             uint baseRows,uint superRows,
                             uint cellWidth,uint cellHeight,
+                            QCString relPath,
                             bool generateMap)
 {
   DiagramRow *dr=first();
@@ -548,7 +554,7 @@ void TreeDiagram::drawBoxes(QTextStream &t,Image *image,
           writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,
               hasDocs,di->getChildren()->count()>0); 
           if (!firstRow && generateMap) 
-            writeMapArea(t,di->getClassDef(),x,y,cellWidth,cellHeight);
+            writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
         }
         else
         {
@@ -581,7 +587,7 @@ void TreeDiagram::drawBoxes(QTextStream &t,Image *image,
           bool hasDocs=di->getClassDef()->isLinkable();
           writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,hasDocs); 
           if (!firstRow && generateMap) 
-            writeMapArea(t,di->getClassDef(),x,y,cellWidth,cellHeight);
+            writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
         }
         else
         {
@@ -1252,7 +1258,8 @@ void ClassDiagram::writeFigure(QTextStream &output,const char *path,
 
 
 void ClassDiagram::writeImage(QTextStream &t,const char *path,
-                              const char *fileName, bool generateMap)
+                              const char *relPath,const char *fileName, 
+                              bool generateMap)
 {
   uint baseRows=base->computeRows();
   uint superRows=super->computeRows();
@@ -1272,8 +1279,8 @@ void ClassDiagram::writeImage(QTextStream &t,const char *path,
 
   Image image(imageWidth,imageHeight);
 
-  base->drawBoxes(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight,generateMap);
-  super->drawBoxes(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight,generateMap);
+  base->drawBoxes(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
+  super->drawBoxes(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
   base->drawConnectors(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight);
   super->drawConnectors(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight);
 
diff --git a/src/diagram.h b/src/diagram.h
index 91c85c9..df9759a 100644
--- a/src/diagram.h
+++ b/src/diagram.h
@@ -105,6 +105,7 @@ class TreeDiagram : public QList<DiagramRow>
                    bool doBase,bool bitmap,
                    uint baseRows,uint superRows,
                    uint cellWidth,uint cellHeight,
+                   QCString relPath="",
                    bool generateMap=TRUE);
     void drawConnectors(QTextStream &t,Image *image,
                    bool doBase,bool bitmap,
@@ -123,7 +124,7 @@ class ClassDiagram
    ~ClassDiagram();
     void writeFigure(QTextStream &t,const char *path,
                      const char *file);
-    void writeImage(QTextStream &t,const char *path,
+    void writeImage(QTextStream &t,const char *path,const char *relPath,
                      const char *file,bool generateMap=TRUE);
   private:
     TreeDiagram *base;
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 16bbb58..f810ce3 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -239,7 +239,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type)
 /*! Collects the parameters found with \@param or \@retval commands
  *  in a global list g_paramsFound. If \a isParam is set to TRUE
  *  and the parameter is not an actual parameter of the current
- *  member g_memberDef, than a warning is raised (unless warnings
+ *  member g_memberDef, then a warning is raised (unless warnings
  *  are disabled altogether).
  */
 static void checkArgumentName(const QString &name,bool isParam)
@@ -340,7 +340,7 @@ static void checkUndocumentedParams()
 
 //---------------------------------------------------------------------------
 
-/*! Strips know html and tex extensions from \a text. */
+/*! Strips known html and tex extensions from \a text. */
 static QString stripKnownExtensions(const char *text)
 {
   QString result=text;
@@ -1429,16 +1429,14 @@ void DocCopy::parse()
 
 //---------------------------------------------------------------------------
 
-void DocXRefItem::parse()
+DocXRefItem::DocXRefItem(DocNode *parent,int id,const char *key) : 
+   m_parent(parent), m_id(id), m_key(key), m_relPath(g_relPath)
+{
+}
+
+bool DocXRefItem::parse()
 {
   QString listName;
-  //switch(m_type)
-  //{
-  //  case Bug:        listName="bug"; break; 
-  //  case Test:       listName="test"; break; 
-  //  case Todo:       listName="todo"; break; 
-  //  case Deprecated: listName="deprecated"; break; 
-  //}
   RefList *refList = Doxygen::xrefLists->find(m_key); 
   if (refList && 
       (
@@ -1465,7 +1463,9 @@ void DocXRefItem::parse()
         docParserPopContext();
       }
     }
+    return TRUE;
   }
+  return FALSE;
 }
 
 //---------------------------------------------------------------------------
@@ -1699,6 +1699,7 @@ DocRef::DocRef(DocNode *parent,const QString &target) :
   ASSERT(!target.isEmpty());
   m_relPath = g_relPath;
   SectionInfo *sec = Doxygen::sectionDict[target];
+  //printf("DocRef::DocRef(target=%s) sec=%p\n",target.data(),sec);
   if (sec) // ref to section or anchor
   {
     m_text         = sec->title;
@@ -1709,6 +1710,8 @@ DocRef::DocRef(DocNode *parent,const QString &target) :
     if (sec->type!=SectionInfo::Page) m_anchor = sec->label;
     m_refToAnchor  = sec->type==SectionInfo::Anchor;
     m_refToSection = sec->type!=SectionInfo::Anchor;
+    //printf("m_text=%s,m_ref=%s,m_file=%s,m_refToAnchor=%d\n",
+    //    m_text.data(),m_ref.data(),m_file.data(),m_refToAnchor);
   }
   else if (resolveLink(g_context,target,TRUE,&compound,/*&pageInfo,*/anchor))
   {
@@ -3234,8 +3237,14 @@ int DocPara::handleXRefItem()
   if (retval==RetVal_OK)
   {
     DocXRefItem *ref = new DocXRefItem(this,g_token->id,g_token->name);
-    m_children.append(ref);
-    ref->parse();
+    if (ref->parse())
+    {
+      m_children.append(ref);
+    }
+    else
+    {
+      delete ref;
+    }
   }
   doctokenizerYYsetStatePara();
   return retval;
@@ -3329,13 +3338,13 @@ void DocPara::handleImage(const QString &cmdName)
   } 
   doctokenizerYYsetStateFile();
   tok=doctokenizerYYlex();
+  doctokenizerYYsetStatePara();
   if (tok!=TK_WORD)
   {
     warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: unexpected token %s as the argument of %s",
         tokToString(tok),cmdName.data());
     return;
   }
-  doctokenizerYYsetStatePara();
   HtmlAttribList attrList;
   DocImage *img = new DocImage(this,attrList,findAndCopyImage(g_token->name,t),t);
   m_children.append(img);
@@ -3353,13 +3362,13 @@ void DocPara::handleDotFile(const QString &cmdName)
   }
   doctokenizerYYsetStateFile();
   tok=doctokenizerYYlex();
+  doctokenizerYYsetStatePara();
   if (tok!=TK_WORD)
   {
     warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: unexpected token %s as the argument of %s",
         tokToString(tok),cmdName.data());
     return;
   }
-  doctokenizerYYsetStatePara();
   QString name = g_token->name;
   DocDotFile *df = new DocDotFile(this,name);
   m_children.append(df);
@@ -4825,6 +4834,10 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
   {
     g_context = ctx->name();
   }
+  else if (ctx && ctx->definitionType()==Definition::TypePage)
+  {
+    g_context = ctx->getOuterScope()->name();
+  }
   else
   {
     g_context = "";
@@ -4904,6 +4917,7 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
 
   g_fileName = fileName;
   g_relPath = ctx ? relativePathToRoot(ctx->getOutputFileBase()) : QString("");
+  //printf("ctx->name=%s relPath=%s\n",ctx->name().data(),g_relPath.data());
   g_memberDef = md;
   g_nodeStack.clear();
   g_styleStack.clear();
diff --git a/src/docparser.h b/src/docparser.h
index da57809..1b75451 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -541,16 +541,15 @@ class DocXRefItem : public CompAccept<DocXRefItem>, public DocNode
 {
   public:
     //enum Type { Bug, Test, Todo, Deprecated };
-    DocXRefItem(DocNode *parent,int id,const char *key) : 
-      m_parent(parent), m_id(id), m_key(key) /*, m_type(t)*/ {}
+    DocXRefItem(DocNode *parent,int id,const char *key);
     Kind kind() const          { return Kind_XRefItem; }
-    //Type type() const          { return m_type; }
     QString file() const       { return m_file; }
     QString anchor() const     { return m_anchor; }
     QString title() const      { return m_title; }
     DocNode *parent() const    { return m_parent; }
+    QString relPath() const    { return m_relPath; }
     void accept(DocVisitor *v) { CompAccept<DocXRefItem>::accept(this,v); }
-    void parse();
+    bool parse();
 
   private:
     DocNode *m_parent;
@@ -559,6 +558,7 @@ class DocXRefItem : public CompAccept<DocXRefItem>, public DocNode
     QString  m_file;
     QString  m_anchor;
     QString  m_title;
+    QString  m_relPath;
 };
 
 /*! @brief Node representing an image */
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 31a315d..e445f55 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -585,6 +585,7 @@ LABELID   [a-z_A-Z][a-z_A-Z0-9\-]*
 			 BEGIN(St_TitleN);
                        }
 <St_Title>\n	       {
+                         unput(*yytext);
   			 return 0;
   		       }
 <St_TitleN>"&"{ID}";"  { /* symbol */
@@ -680,7 +681,7 @@ LABELID   [a-z_A-Z][a-z_A-Z0-9\-]*
                          unput(*yytext);
   			 return 0;
   		       }
-<St_IntRef>[A-Z_a-z0-9.:#\-\+]+ {
+<St_IntRef>[A-Z_a-z0-9.:/#\-\+]+ {
                          g_token->name = yytext;
 			 return TK_WORD;
   		       }
@@ -710,7 +711,7 @@ LABELID   [a-z_A-Z][a-z_A-Z0-9\-]*
 <St_Ref2>"\""|\n       { /* " or \n => end of title */
   			 return 0;
                        }
-<St_XRefItem>{ID}      {
+<St_XRefItem>{ID}   {
                          g_token->name=yytext;
                        }
 <St_XRefItem>" "       {
@@ -793,27 +794,27 @@ LABELID   [a-z_A-Z][a-z_A-Z0-9\-]*
                                       g_secType = SectionInfo::Paragraph; 
                                       BEGIN(St_SecLabel2); 
                                     }
-<St_Sections>{CMD}"verbatim"	    {
+<St_Sections>{CMD}"verbatim"{BLANK}+  {
                                       g_endMarker="endverbatim";
 				      BEGIN(St_SecSkip);
   				    }
-<St_Sections>{CMD}"dot"	    {
+<St_Sections>{CMD}"dot"/[^a-z_A-Z0-9] {
                                       g_endMarker="enddot";
 				      BEGIN(St_SecSkip);
   				    }
-<St_Sections>{CMD}"htmlonly"	    {
+<St_Sections>{CMD}"htmlonly"/[^a-z_A-Z0-9] {
                                       g_endMarker="endhtmlonly";
 				      BEGIN(St_SecSkip);
                                     }
-<St_Sections>{CMD}"latexonly"	    {
+<St_Sections>{CMD}"latexonly"/[^a-z_A-Z0-9] {
                                       g_endMarker="endlatexonly";
 				      BEGIN(St_SecSkip);
                                     }
-<St_Sections>{CMD}"xmlonly"	    {
+<St_Sections>{CMD}"xmlonly"/[^a-z_A-Z0-9] {
                                       g_endMarker="endxmlonly";
 				      BEGIN(St_SecSkip);
                                     }
-<St_Sections>{CMD}"code"	    {
+<St_Sections>{CMD}"code"/[^a-z_A-Z0-9] {
                                       g_endMarker="endcode";
 				      BEGIN(St_SecSkip);
   				    }
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index a91a64e..78040ca 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -6497,13 +6497,14 @@ static void generatePageDocs()
         outputList->endSection(si->label,si->type);
       }
       outputList->startTextBlock();
-      outputList->parseDoc(pd->docFile(),
-                           pd->docLine(),
-                           pd->getOuterScope(),0,
-                           pd->documentation(),
-                           TRUE,    // index words
-                           FALSE    // not an example
-                           /*,pd->sectionDict*/);
+      outputList->parseDoc(pd->docFile(),       // fileName
+                           pd->docLine(),       // startLine
+                           pd,                  // context
+                           0,                   // memberdef
+                           pd->documentation(), // docStr
+                           TRUE,                // index words
+                           FALSE                // not an example
+                          );
       outputList->endTextBlock();
       endFile(*outputList);
       //outputList->enable(OutputGenerator::Man);
@@ -6591,7 +6592,7 @@ static void generateExampleDocs()
     endTitle(*outputList,n,0);
     outputList->parseDoc(pd->docFile(),                            // file
                          pd->docLine(),                            // startLine
-                         pd->getOuterScope(),                      // context
+                         pd,                                       // context
                          0,                                        // memberDef
                          pd->documentation()+"\n\\include "+pd->name(),          // docs
                          TRUE,                                     // index words
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index bfb0958..189c102 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -908,7 +908,7 @@ void HtmlDocVisitor::visitPre(DocXRefItem *x)
 {
   if (m_hide) return;
   m_t << "<dl compact><dt><b><a class=\"el\" href=\"" 
-    << x->file() << Doxygen::htmlFileExtension << "#" << x->anchor() << "\">";
+      << x->relPath() << x->file() << Doxygen::htmlFileExtension << "#" << x->anchor() << "\">";
   filter(x->title());
   m_t << ":</a></b></dt><dd>";
 }
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 1e5666a..ebe994c 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -813,11 +813,11 @@ void HtmlGenerator::endClassDiagram(ClassDiagram &d,
                                 const char *fileName,const char *name)
 {
   t << "\n<p><center><img src=\""
-    << fileName << ".png\" usemap=\"#" << name << "_map\""
+    << relPath << fileName << ".png\" usemap=\"#" << name << "_map\""
     << " border=\"0\" alt=\"\"></center>" << endl
     << "<map name=\"" << name << "_map\">" << endl;
 
-  d.writeImage(t,dir,fileName);
+  d.writeImage(t,dir,relPath,fileName);
 }
 
 
diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp
index 341f825..a90a919 100644
--- a/src/htmlhelp.cpp
+++ b/src/htmlhelp.cpp
@@ -353,6 +353,7 @@ void HtmlHelp::initialize()
   s_languageDict.insert("japanese-en", new QCString("0x411 Japanese"));
   s_languageDict.insert("korean",      new QCString("0x412 Korean"));
   s_languageDict.insert("chinese",     new QCString("0x804 Chinese (PRC)"));
+  s_languageDict.insert("chinese-traditional", new QCString("0x404 Chinese (Taiwan)"));
 }
 
 
diff --git a/src/index.cpp b/src/index.cpp
index 6473f9a..2a12120 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -116,6 +116,7 @@ static void endIndexHierarchy(OutputList &ol,int level)
 static bool g_memberIndexLetterUsed[CMHL_Total][256];
 static bool g_fileIndexLetterUsed[FMHL_Total][256];
 static bool g_namespaceIndexLetterUsed[NMHL_Total][256];
+static bool g_classIndexLetterUsed[CHL_Total][256];
 
 const int maxItemsBeforeQuickIndex = 30;
 
@@ -886,9 +887,7 @@ void writeFileIndex(OutputList &ol)
     ftvHelp->addContentsItem(TRUE,0,"files",0,ftvHelpTitle); 
     ftvHelp->incContentsDepth();
   }
-  //ol.newParagraph();
   ol.parseText(theTranslator->trFileListDescription(Config_getBool("EXTRACT_ALL")));
-  //ol.newParagraph();
   ol.endTextBlock();
 
   OutputNameDict outputNameDict(1009);
@@ -1196,16 +1195,58 @@ void writeAnnotatedClassList(OutputList &ol)
   bool hasHtmlHelp = generateHtml && Config_getBool("GENERATE_HTMLHELP");
   bool hasFtvHelp =  generateHtml && Config_getBool("GENERATE_TREEVIEW");
   ol.startIndexList(); 
-  //ClassDef *cd=Doxygen::classList.first();
-  //while (cd)
   ClassSDict::Iterator cli(Doxygen::classSDict);
   ClassDef *cd;
-  for (;(cd=cli.current());++cli)
+  
+  // clear index
+  for (int y=0;y<CHL_Total;y++)
+  {
+    for (int x=0;x<256;x++)
+    {
+      g_classIndexLetterUsed[y][x]=FALSE;
+    }
+  }
+  
+  // see which elements are in use
+  for (cli.toFirst();(cd=cli.current());++cli)
+  {
+    if (cd->isLinkableInProject() && cd->templateMaster()==0)
+    {
+      int c = cd->displayName().at(0);
+      g_classIndexLetterUsed[CHL_All][c]=TRUE;
+      switch(cd->compoundType())
+      {
+        case ClassDef::Class:
+          g_classIndexLetterUsed[CHL_Classes][c]=TRUE;
+          break;
+        case ClassDef::Struct:
+          g_classIndexLetterUsed[CHL_Structs][c]=TRUE;
+          break;
+        case ClassDef::Union:
+          g_classIndexLetterUsed[CHL_Unions][c]=TRUE;
+          break;
+        case ClassDef::Interface:
+          g_classIndexLetterUsed[CHL_Interfaces][c]=TRUE;
+          break;
+        case ClassDef::Protocol:
+          g_classIndexLetterUsed[CHL_Protocols][c]=TRUE;
+          break;
+        case ClassDef::Category:
+          g_classIndexLetterUsed[CHL_Categories][c]=TRUE;
+          break;
+        case ClassDef::Exception:
+          g_classIndexLetterUsed[CHL_Exceptions][c]=TRUE;
+          break;
+
+      }
+    }
+  }
+  
+  for (cli.toFirst();(cd=cli.current());++cli)
   {
     if (cd->isLinkableInProject() && cd->templateMaster()==0)
     {
       QCString type=cd->compoundTypeString();
-      //ol.writeStartAnnoItem(type,cd->getOutputFileBase(),0,cd->displayName());
       ol.startIndexKey();
       ol.writeObjectLink(0,cd->getOutputFileBase(),0,cd->displayName());
       ol.endIndexKey();
@@ -1216,7 +1257,7 @@ void writeAnnotatedClassList(OutputList &ol)
         ol.parseDoc(
                  cd->briefFile(),cd->briefLine(),
                  cd,0,
-                 abbreviate(cd->briefDescription(),cd->name()),
+                 abbreviate(cd->briefDescription(),cd->displayName()),
                  FALSE,  // indexWords
                  FALSE   // isExample
                 );
@@ -1709,7 +1750,7 @@ int countClassMembers(int filter)
           (cd=md->getClassDef()) && 
           cd->isLinkableInProject() &&
           ( filter==CMHL_All        && !(md->isFriend() && isFriendToHide) ||
-           (filter==CMHL_Functions  && (md->isFunction() || md->isSlot() || md->isSignal()))  ||
+           (filter==CMHL_Functions  && (md->isFunction()  || md->isSlot() || md->isSignal()))  ||
            (filter==CMHL_Variables  && md->isVariable())  ||
            (filter==CMHL_Typedefs   && md->isTypedef())   ||
            (filter==CMHL_Enums      && md->isEnumerate()) ||
@@ -1769,10 +1810,6 @@ static void writeMemberIndexFiltered(OutputList &ol,
   QCString title = theTranslator->trCompoundMembers();
   QCString htmlHelpTitle = title;
   QCString ftvHelpTitle =  title;
-  //if (!Config_getString("PROJECT_NAME").isEmpty()) title.prepend(Config_getString("PROJECT_NAME")+" ");
-  //startTitle(ol,0);
-  //ol.parseText(title);
-  //endTitle(ol,0,0);
   
   ol.writeString("<div class=\"qindex\">"); 
 
diff --git a/src/index.h b/src/index.h
index dee48a4..469d75a 100644
--- a/src/index.h
+++ b/src/index.h
@@ -124,6 +124,19 @@ enum NamespaceMemberHighlight
   NMHL_Total = FMHL_EnumValues+1
 };
 
+enum ClassHighlight
+{
+  CHL_All = 0,
+  CHL_Classes,
+  CHL_Structs,
+  CHL_Unions,
+  CHL_Interfaces,
+  CHL_Protocols,
+  CHL_Categories,
+  CHL_Exceptions,
+  CHL_Total = CHL_Exceptions+1
+};
+
 extern int annotatedClasses;
 extern int hierarchyClasses;
 extern int documentedFiles;
diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp
index b560a27..6bb1288 100644
--- a/src/mandocvisitor.cpp
+++ b/src/mandocvisitor.cpp
@@ -167,6 +167,7 @@ void ManDocVisitor::visit(DocStyleChange *s)
       {
         m_insidePre=FALSE;
         if (!m_firstCol) m_t << endl;
+        m_t << ".fi" << endl;
         m_t << ".PP" << endl;
         m_firstCol=TRUE;
       }
@@ -187,6 +188,7 @@ void ManDocVisitor::visit(DocVerbatim *s)
       m_t << ".nf" << endl;
       parseCode(m_ci,s->context(),s->text().latin1(),s->isExample(),s->exampleFile());
       if (!m_firstCol) m_t << endl;
+      m_t << ".fi" << endl;
       m_t << ".PP" << endl;
       m_firstCol=TRUE;
       break;
@@ -196,6 +198,7 @@ void ManDocVisitor::visit(DocVerbatim *s)
       m_t << ".nf" << endl;
       m_t << s->text();
       if (!m_firstCol) m_t << endl;
+      m_t << ".fi" << endl;
       m_t << ".PP" << endl;
       m_firstCol=TRUE;
       break;
@@ -230,6 +233,7 @@ void ManDocVisitor::visit(DocInclude *inc)
          FileDef fd( cfi.dirPath(), cfi.fileName() );
          parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd);
          if (!m_firstCol) m_t << endl;
+         m_t << ".fi" << endl;
          m_t << ".PP" << endl;
          m_firstCol=TRUE;
       }
@@ -240,6 +244,7 @@ void ManDocVisitor::visit(DocInclude *inc)
       m_t << ".nf" << endl;
       parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile());
       if (!m_firstCol) m_t << endl;
+      m_t << ".fi" << endl;
       m_t << ".PP" << endl;
       m_firstCol=TRUE;
       break;
@@ -253,6 +258,7 @@ void ManDocVisitor::visit(DocInclude *inc)
       m_t << ".nf" << endl;
       m_t << inc->text();
       if (!m_firstCol) m_t << endl;
+      m_t << ".fi" << endl;
       m_t << ".PP" << endl;
       m_firstCol=TRUE;
       break;
@@ -287,6 +293,7 @@ void ManDocVisitor::visit(DocIncOperator *op)
     if (!m_hide)
     {
       if (!m_firstCol) m_t << endl;
+      m_t << ".fi" << endl;
       m_t << ".PP" << endl;
       m_firstCol=TRUE;
     }
@@ -548,6 +555,7 @@ void ManDocVisitor::visitPost(DocHtmlListItem *)
 //{
 //  m_insidePre=FALSE;
 //  if (!m_firstCol) m_t << endl;
+//  m_t << ".fi" << endl;
 //  m_t << ".PP" << endl;
 //  m_firstCol=TRUE;
 //}
diff --git a/src/mangen.cpp b/src/mangen.cpp
index 6f11f82..13f11c1 100644
--- a/src/mangen.cpp
+++ b/src/mangen.cpp
@@ -632,5 +632,6 @@ void ManGenerator::printDoc(DocNode *n)
   n->accept(visitor);
   delete visitor; 
   firstCol=FALSE;
+  paragraph = FALSE;
 }
 
diff --git a/src/pre.l b/src/pre.l
index c57f35b..847d8db 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -1871,6 +1871,7 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
 					  if (!comment.isEmpty())
 					  {
 					    outputArray(comment,comment.length());
+					    g_defLitText=g_defLitText.left(g_defLitText.length()-comment.length()-1);
 					  }
   					  outputChar('\n');
   					  Define *def=0;
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index 17958b9..d2d6ec9 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -1700,7 +1700,7 @@ void RTFGenerator::endClassDiagram(ClassDiagram &d,
   newParagraph();
 
   // create a png file
-  d.writeImage(t,dir,fileName,FALSE);
+  d.writeImage(t,dir,relPath,fileName,FALSE);
 
   // display the file
   t << "{" << endl;
diff --git a/src/scanner.l b/src/scanner.l
index 3470a18..43b355a 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -154,6 +154,7 @@ static Grouping  lastDefGroup( "", Grouping::GROUPING_LOWEST );
 
 static bool             insideFormula;
 static bool  	        insideTryBlock=FALSE;
+static bool             insideCode;
 static bool             needsSemi;
 
 static int              depthIf;
@@ -293,6 +294,28 @@ static QCString stripQuotes(const char *s)
   return name;
 }
 
+//static QCString stripCComments(const QCString &s)
+//{
+//  int p=0,i;
+//  QCString result;
+//  while ((i=s.find("/*",p))!=-1)
+//  {
+//    result+=s.mid(p,i-p);
+//    int ei = s.find("*/",i+1);
+//    if (ei!=-1)
+//    {
+//      p=ei+2;
+//    }
+//    else
+//    {
+//      return result;
+//    }
+//  }
+//  result+=s.right(s.length()-p);
+//  printf("stripCComments: input=%s output=%s\n",s.data(),result.data());
+//  return result;
+//}
+
 static void newDocState();
 
 //-----------------------------------------------------------------
@@ -695,6 +718,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 %x	SkipCurlyCpp
 %x	SkipCurlyEndDoc
 %x      SkipString
+%x      SkipPHPString
 %x	SkipInits
 %x	SkipCPP
 %x	SkipCPPBlock
@@ -720,6 +744,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 %x      LineDoc
 %x      DefLineDoc
 %x      ClassDocArg1
+%x      CategoryDocArg1
 %x      ClassDocArg2
 %x      ClassDocArg3
 %x      ClassDocFunc
@@ -790,6 +815,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 %x	AnchorLabel
 %x	ReadInitializer
 %x	CopyString
+%x	CopyPHPString
 %x	CopyRound
 %x	CopyCurly
 %x	IDLUnionCase
@@ -883,7 +909,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					    BEGIN( FindMembers );
 					  }
 					}
-<NextSemi>{CHARLIT}			
+<NextSemi>{CHARLIT}			{ if (insidePHP) REJECT; }
 <NextSemi>\"				{
   					  lastStringContext=NextSemi;
 					  BEGIN(SkipString);
@@ -899,6 +925,11 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 <FindMembersPHP>"<?"("php"?)            { // PHP code start
                                            BEGIN( FindMembers );
 					}
+<FindMembersPHP>[^\n<]+                 { // Non-PHP code text, ignore
+  					}
+<FindMembersPHP>\n                      { // Non-PHP code text, ignore
+  					  yyLineNr++;
+  					}
 <FindMembersPHP>.                       { // Non-PHP code text, ignore
 				        }
 <FindMembers>"?>"                       { // PHP code end
@@ -2028,7 +2059,16 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					  current->initializer+=*yytext; 
   					}
   */
-<ReadInitializer>{CHARLIT}              { current->initializer+=yytext; } 
+<ReadInitializer>{CHARLIT}              { 
+                                          if (insidePHP) 
+					  {
+					    REJECT;
+					  }
+					  else
+					  {  
+					    current->initializer+=yytext; 
+					  }
+                                        } 
 <ReadInitializer>\n			{
   					  current->initializer+=*yytext;
 					  yyLineNr++;
@@ -2063,21 +2103,25 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					}
 
   /* generic quoted string copy rules */
-<CopyString>\\.				{
+<CopyString,CopyPHPString>\\.		{
   					  *pCopyQuotedString+=yytext;
   					}
 <CopyString>\"				{ 
   					  *pCopyQuotedString+=*yytext;
   					  BEGIN( lastStringContext ); 
 					}
-<CopyString>"/*"|"*/"|"//"		{
+<CopyPHPString>\'			{ 
+  					  *pCopyQuotedString+=*yytext;
+  					  BEGIN( lastStringContext ); 
+					}
+<CopyString,CopyPHPString>"/*"|"*/"|"//" {
   					  *pCopyQuotedString+=yytext;
   					}
-<CopyString>\n				{
+<CopyString,CopyPHPString>\n		{
   					  *pCopyQuotedString+=*yytext;
   					  yyLineNr++;
   					}
-<CopyString>.				{
+<CopyString,CopyPHPString>.		{
   					  *pCopyQuotedString+=*yytext;
   					}
 
@@ -2101,10 +2145,22 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					  yyLineNr++;
   					  *pCopyRoundString+=*yytext;
   					}
-<CopyRound>{CHARLIT}		        { *pCopyRoundString+=yytext; }
+<CopyRound>{CHARLIT}		        { 
+                                          if (insidePHP)
+					  {
+					    REJECT;
+					  }
+					  else
+					  {
+                                            *pCopyRoundString+=yytext; 
+					  }
+                                        }
 <CopyRound>[^"'()\n]+			{
   					  *pCopyRoundString+=yytext;
   					}
+<CopyRound>.				{
+  					  *pCopyRoundString+=*yytext;
+  					}
 
   /* generic curly bracket list copy rules */
 <CopyCurly>\"				{
@@ -2122,7 +2178,15 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					  if (--curlyCount<0)
 					    BEGIN(lastCurlyContext); 
   					}
-<CopyCurly>{CHARLIT}                    { *pCopyCurlyString+=yytext; }
+<CopyCurly>{CHARLIT}                    { if (insidePHP) 
+                                          { 
+					    REJECT; 
+					  } 
+					  else 
+					  {
+					    *pCopyCurlyString+=yytext; 
+					  }
+                                        }
 <CopyCurly>[^"'{}\/\n]+			{
   					  *pCopyCurlyString+=yytext;
   					}
@@ -2131,6 +2195,9 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					  yyLineNr++;
 					  *pCopyCurlyString+=*yytext;
   					}
+<CopyCurly>.				{
+					  *pCopyCurlyString+=*yytext;
+  					}
 <FindMembers>":"			{
   					  if (current->type.isEmpty()) // bit pad field
 					  {
@@ -2306,8 +2373,18 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					  lastContext = YY_START ;
 					  BEGIN( Comment ) ;
 					}
-<ReadBody,ReadNSBody,ReadBodyIntf>{CHARLIT}          { current->program += yytext; }
-<ReadBody,ReadNSBody,ReadBodyIntf>"{"                { current->program += yytext ;
+<ReadBody,ReadNSBody,ReadBodyIntf>{CHARLIT} { 
+                                              if (insidePHP) 
+					      {
+						REJECT; // for PHP code single quotes 
+					                // are used for strings of arbitrary length
+					      }
+					      else
+					      {
+                                                current->program += yytext; 
+					      }
+                                            }
+<ReadBody,ReadNSBody,ReadBodyIntf>"{"       { current->program += yytext ;
 					  ++curlyCount ;
 					}
 <ReadBody,ReadNSBody>"}"		{ //err("ReadBody count=%d\n",curlyCount);
@@ -2544,6 +2621,19 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					  insideObjC=FALSE;
 					  BEGIN( FindMembers ); 
   					}
+<ReadBody,ReadNSBody,ReadBodyIntf>"'"	{
+  					  if (!insidePHP)
+					  {
+					    current->program += yytext;
+					  }
+					  else
+					  { // begin of single quoted string
+					    current->program += yytext;
+                                            pCopyQuotedString = &current->program;
+                                            lastStringContext=YY_START;
+					    BEGIN(CopyPHPString);
+					  }
+  					}
 <ReadBody,ReadNSBody,ReadBodyIntf>.	{ current->program += yytext ; }
 <ReadBody,ReadNSBody,ReadBodyIntf>"'#"	{ current->program += yytext ; }
 
@@ -2881,8 +2971,15 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					  BEGIN( lastCopyArgStringContext );
   					}
 <ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSharp>{CHARLIT}     { 
-  					  *copyArgString+=yytext; 
-  					  fullArgString+=yytext; 
+                                          if (insidePHP)
+					  {
+					    REJECT;
+					  }
+					  else
+					  {
+  					    *copyArgString+=yytext; 
+  					    fullArgString+=yytext; 
+					  }
 					}
 <ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgRound,CopyArgSharp>\n  { 
   					  yyLineNr++; 
@@ -2973,7 +3070,14 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					  BEGIN(CopyString);
 					}
 <FuncPtrInit>{CHARLIT}			{
-                                          current->args += yytext; 
+                                          if (insidePHP)
+					  {
+					    REJECT;
+					  }
+					  else
+					  {
+                                            current->args += yytext; 
+					  }
   					}
 <FuncPtrInit>{ID}			{
                                           current->args += yytext; 
@@ -3258,6 +3362,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					}
 <SkipCurly>{CHARLIT}                    {
   				          //addToBody(yytext);
+                                          if (insidePHP) REJECT;
   					}
 <SkipCurly>\"			        { 
   				          //addToBody(yytext);
@@ -3323,27 +3428,21 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					  BEGIN(SkipVerbString);
   					}
 <SkipInits,SkipCurly,SkipCurlyCpp>{CHARLIT}	{
+                                          if (insidePHP) REJECT;
                                         }
-<SkipInits,SkipCurly,SkipCurlyCpp>.	{
-  				          //addToBody(yytext);
-  					}
-<SkipString>\\.				{
-  				          //addToBodyCond(yytext);
-  					}
+<SkipInits,SkipCurly,SkipCurlyCpp>.	{ }
+<SkipString,SkipPHPString>\\.		{ }
 <SkipString>\"				{ 
-  				          //addToBodyCond(yytext);
   					  BEGIN( lastStringContext ); 
 					}
-<SkipString>"/*"|"*/"|"//"		{
-  				          //addToBodyCond(yytext);
-  					}
-<SkipString>\n				{
+<SkipPHPString>\'			{ 
+  					  BEGIN( lastStringContext ); 
+					}
+<SkipString,SkipPHPString>"/*"|"*/"|"//" { }
+<SkipString,SkipPHPString>\n		{
   					  yyLineNr++;
-  				          //addToBodyCond(yytext);
-  					}
-<SkipString>.				{
-  				          //addToBodyCond(yytext);
   					}
+<SkipString,SkipPHPString>.		{ }
 <Bases,CompoundName>";"			{ 
 					  current->section = Entry::EMPTY_SEC ;
 					  current->type.resize(0) ;
@@ -3526,8 +3625,10 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					    current->name.sprintf("@%d",anonCount++);
 					  }
 					  curlyCount=0;
-					  if (current->section==Entry::PROTOCOL_SEC ||
-					      current->section==Entry::OBJCIMPL_SEC)
+					  if (/*current->section==Entry::PROTOCOL_SEC ||
+					      current->section==Entry::OBJCIMPL_SEC*/
+					      insideObjC
+					     )
 					  { // ObjC body that ends with @end
 					    BEGIN( ReadBodyIntf );
 					  }
@@ -3697,9 +3798,17 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					}
 <Comment>"/*"				{ current->program += yytext ; } 
 <Comment>"//"				{ current->program += yytext ; }
-<Comment>[^\n\/\*]+			{ current->program += yytext ; }
+<Comment>{CMD}("code"|"verbatim")	{
+                                          insideCode=TRUE;
+  					  current->program += yytext ;
+  					}
+<Comment>{CMD}("endcode"|"endverbatim")	{
+                                          insideCode=FALSE;
+  					  current->program += yytext ;
+  					}
+<Comment>[^ \.\n\/\*]+			{ current->program += yytext ; }
 <Comment>"*/"				{ current->program += yytext ;
-					  BEGIN( lastContext ) ;
+					  if (!insideCode) BEGIN( lastContext ) ;
 					}
 <Comment>.				{ current->program += *yytext ; }
 
@@ -4014,6 +4123,18 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					  current->startLine = yyLineNr;
 					  BEGIN( ClassDocArg1 ); 
 					}
+<Doc,JavaDoc>{B}*{CMD}"protocol"{B}+  	{ // ObjC protocol
+  					  current->section = Entry::PROTOCOLDOC_SEC;
+					  current->fileName = yyFileName;
+					  current->startLine = yyLineNr;
+					  BEGIN( ClassDocArg1 ); 
+					}
+<Doc,JavaDoc>{B}*{CMD}"category"{B}+  	{ // ObjC category
+  					  current->section = Entry::CATEGORYDOC_SEC;
+					  current->fileName = yyFileName;
+					  current->startLine = yyLineNr;
+					  BEGIN( CategoryDocArg1 ); 
+					}
 <Doc,JavaDoc>{B}*{CMD}"union"{B}+  	{
   					  current->section = Entry::UNIONDOC_SEC;
 					  current->fileName = yyFileName;
@@ -4260,6 +4381,11 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
                                               );
   					  yyLineNr++;
   					}
+<CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" {
+					  current->name = yytext;
+					  prependScope();
+					  BEGIN( ClassDocArg2 );
+   					}
 <ClassDocArg1>{SCOPENAME}/"<"		{
 					  current->name = yytext;
 					  // prepend outer scope name 
@@ -4269,11 +4395,15 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					}
 <ClassDocArg1>{SCOPENAME}		{
 					  current->name = yytext;
+					  if (current->section==Entry::PROTOCOLDOC_SEC)
+					  {
+					    current->name+="-p";
+					  }
 					  // prepend outer scope name 
 					  prependScope();
 					  BEGIN( ClassDocArg2 );
 					}
-<ClassDocArg1>"\\"{B}*"\n"		{ 
+<ClassDocArg1,CategoryDocArg1>"\\"{B}*"\n"		{ 
                                           yyLineNr++; 
                                         }
 <ClassDocArg1>"\n"			{
@@ -4284,6 +4414,14 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					  yyLineNr++;
 					  
   					}
+<CategoryDocArg1>"\n"			{
+  					  warn(yyFileName,yyLineNr,
+                                               "Warning: missing argument after "
+					       "\\category."
+                                              );
+  					  yyLineNr++;
+					  
+  					}
 <GroupDocArg1>{ID}(".html"?)		{ 
   					  current->name = yytext;
 					  lastDefGroup.groupname = yytext;
@@ -4668,6 +4806,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 <SectionTitle>[^\n*]*/"\n"		{
 					  sectionTitle+=yytext;
 					  sectionTitle=sectionTitle.stripWhiteSpace();
+					  //printf("Adding new section file=%s label=%s title=%s\n",yyFileName,sectionLabel.data(),sectionTitle.data()); 
   					  SectionInfo *si = new SectionInfo(yyFileName,sectionLabel,sectionTitle,SectionInfo::Anchor);
   					  current->anchors->append(si);
                                           Doxygen::sectionDict.insert(yytext,si);
@@ -5299,7 +5438,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					    unput(afterDocTerminator);
 					  BEGIN(lastAfterDocContext);
   					}
-<ClassDocRelates,ClassDocFunc,ClassDocDefine,GroupDocArg1,ClassDocArg1,SectionTitle,EnumDocArg1,PageDocArg1,ExampleDocArg1,ClassDefineArgs>"*/" {
+<ClassDocRelates,ClassDocFunc,ClassDocDefine,GroupDocArg1,CategoryDocArg1,ClassDocArg1,SectionTitle,EnumDocArg1,PageDocArg1,ExampleDocArg1,ClassDefineArgs>"*/" {
                                           // defer "*/" to a later time
   					  unput('/');
   					  unput('*');
@@ -5482,6 +5621,20 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					  lastCContext = YY_START ;
 					  BEGIN( SkipCxxComment ) ;
 					}
+<*>\'					{
+  					  if (insidePHP)
+					  {
+  					    lastStringContext=YY_START;
+					    BEGIN(SkipPHPString);
+					  }
+  					}
+<*>\"					{
+  					  if (insidePHP)
+					  {
+  					    lastStringContext=YY_START;
+					    BEGIN(SkipString);
+					  }
+  					}
 <*>.
 <SkipComment>"//"|"/*"
 <*>"/*"					{ lastCContext = YY_START ;
diff --git a/src/util.cpp b/src/util.cpp
index e223da2..1f7bef8 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -2616,7 +2616,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
   fd=0, md=0, cd=0, nd=0, gd=0;
   if (memberName.isEmpty()) return FALSE; /* empty name => nothing to link */
 
-  QCString scopeName=scName.copy();
+  QCString scopeName=scName;
   //printf("Search for name=%s args=%s in scope=%s\n",
   //          memberName.data(),args,scopeName.data());
   
@@ -2707,7 +2707,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
         {
           delete argList; argList=0;
         }
-        if (mdist==maxInheritanceDepth && args && strcmp(args,"()")!=0)
+        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");
@@ -3023,8 +3023,9 @@ bool resolveRef(/* in */  const char *scName,
   QCString fullName = substitute(tsName,"#","::");
   fullName = removeRedundantWhiteSpace(substitute(fullName,".","::"));
   
-  int scopePos=fullName.findRev("::");
   int bracePos=fullName.findRev('('); // reverse is needed for operator()(...)
+  int endNamePos=bracePos!=-1 ? bracePos : fullName.length();
+  int scopePos=fullName.findRev("::",endNamePos);
 
   // default result values
   *resContext=0;
@@ -3063,22 +3064,15 @@ bool resolveRef(/* in */  const char *scName,
     // continue search...
   }
   
-  // extract scope
-  QCString scopeStr=scName;
-
   //printf("scopeContext=%s scopeUser=%s\n",scopeContext.data(),scopeUser.data());
 
   // extract userscope+name
-  int endNamePos=bracePos!=-1 ? bracePos : fullName.length();
   QCString nameStr=fullName.left(endNamePos);
 
   // extract arguments
   QCString argsStr;
   if (bracePos!=-1) argsStr=fullName.right(fullName.length()-bracePos);
   
-  //printf("scope=`%s' name=`%s' arg=`%s'\n",
-  //       scopeStr.data(),nameStr.data(),argsStr.data());
-  
   // strip template specifier
   // TODO: match against the correct partial template instantiation 
   int templPos=nameStr.find('<');
@@ -3088,6 +3082,8 @@ bool resolveRef(/* in */  const char *scName,
     nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1);
   }
 
+  QCString scopeStr=scName;
+
   MemberDef    *md = 0;
   ClassDef     *cd = 0;
   FileDef      *fd = 0;
-- 
cgit v0.12