diff options
author | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2001-08-05 12:03:04 (GMT) |
---|---|---|
committer | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2001-08-05 12:03:04 (GMT) |
commit | 0c6e5ac9eab4ff31bb5650ac2faf9f6c5fc46e68 (patch) | |
tree | ae6f91b471c21991428c9b75a29ff8df55d1889d | |
parent | 071e39254b00ad7ffed5de8cdeb44072278d4d57 (diff) | |
download | Doxygen-0c6e5ac9eab4ff31bb5650ac2faf9f6c5fc46e68.zip Doxygen-0c6e5ac9eab4ff31bb5650ac2faf9f6c5fc46e68.tar.gz Doxygen-0c6e5ac9eab4ff31bb5650ac2faf9f6c5fc46e68.tar.bz2 |
Release-1.2.9.1
41 files changed, 973 insertions, 277 deletions
@@ -110,7 +110,7 @@ COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = -PDF_HYPERLINKS = NO +PDF_HYPERLINKS = YES USE_PDFLATEX = NO LATEX_BATCHMODE = NO #--------------------------------------------------------------------------- @@ -1,6 +1,6 @@ -DOXYGEN Version 1.2.9 +DOXYGEN Version 1.2.9.1 Please read the installation section of the manual for instructions. -------- -Dimitri van Heesch (01 August 2001) +Dimitri van Heesch (05 August 2001) @@ -1,4 +1,4 @@ -DOXYGEN Version 1.2.9 +DOXYGEN Version 1.2.9.1 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) (01 August 2001) +Dimitri van Heesch (dimitri@stack.nl) (05 August 2001) @@ -1 +1 @@ -1.2.9 +1.2.9.1 diff --git a/addon/doxywizard/doxywizard.cpp b/addon/doxywizard/doxywizard.cpp index 3fcde0b..1a31b1a 100644 --- a/addon/doxywizard/doxywizard.cpp +++ b/addon/doxywizard/doxywizard.cpp @@ -62,7 +62,7 @@ static bool loadConfig( QString loadFile ) // parse the config file // this will initialize the various Config data members - if (Config::instance()->parse(loadFile)) + if (!Config::instance()->parse(loadFile)) { QMessageBox::warning(0, "Warning","Cannot open or read input "+loadFile+"!", @@ -89,7 +89,7 @@ static bool saveConfig( QString saveFile ) return FALSE; // failure } - Config::instance()->writeTemplate(&f,TRUE,TRUE); // write brief config file + Config::instance()->writeTemplate(&f,TRUE,FALSE); // write brief config file return TRUE; // success } diff --git a/addon/xmlparse/basehandler.h b/addon/xmlparse/basehandler.h index 2d037e0..0bf7c68 100644 --- a/addon/xmlparse/basehandler.h +++ b/addon/xmlparse/basehandler.h @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #ifndef _BASEHANDLER_H #define _BASEHANDLER_H diff --git a/addon/xmlparse/compoundhandler.cpp b/addon/xmlparse/compoundhandler.cpp index 4949f63..c299397 100644 --- a/addon/xmlparse/compoundhandler.cpp +++ b/addon/xmlparse/compoundhandler.cpp @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #include "mainhandler.h" #include "compoundhandler.h" #include "dochandler.h" diff --git a/addon/xmlparse/compoundhandler.h b/addon/xmlparse/compoundhandler.h index cd7da55..29556a0 100644 --- a/addon/xmlparse/compoundhandler.h +++ b/addon/xmlparse/compoundhandler.h @@ -1,3 +1,17 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ #ifndef _COMPOUNDHANDLER_H #define _COMPOUNDHANDLER_H diff --git a/addon/xmlparse/dochandler.cpp b/addon/xmlparse/dochandler.cpp index c9a96c4..4e91d8f 100644 --- a/addon/xmlparse/dochandler.cpp +++ b/addon/xmlparse/dochandler.cpp @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #include "dochandler.h" //---------------------------------------------------------------------- @@ -218,6 +233,37 @@ void ListHandler::startListItem(const QXmlAttributes& attrib) } //---------------------------------------------------------------------- +// ParameterHandler +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +// ParameterListHandler +//---------------------------------------------------------------------- + +ParameterListHandler::ParameterListHandler(IBaseHandler *parent) + : DocNode(ParameterList), m_parent(parent) +{ + addEndHandler("parameterlist",this,&ParameterListHandler::endParameterList); + m_parameters.setAutoDelete(TRUE); + m_curParam=0; +} + +ParameterListHandler::~ParameterListHandler() +{ +} + +void ParameterListHandler::startParameterList(const QXmlAttributes& /*attrib*/) +{ + m_parent->setDelegate(this); +} + +void ParameterListHandler::endParameterList() +{ + m_parent->setDelegate(0); +} + +//---------------------------------------------------------------------- // ParagraphHandler //---------------------------------------------------------------------- @@ -268,6 +314,14 @@ void ParagraphHandler::startOrderedList(const QXmlAttributes& attrib) m_children.append(listHandler); } +void ParagraphHandler::startParameterList(const QXmlAttributes& attrib) +{ + addTextNode(); + ParameterListHandler *parListHandler = new ParameterListHandler(this); + parListHandler->startParameterList(attrib); + m_children.append(parListHandler); +} + void ParagraphHandler::addTextNode() { if (!m_curString.isEmpty()) diff --git a/addon/xmlparse/dochandler.h b/addon/xmlparse/dochandler.h index 761842f..376d6f8 100644 --- a/addon/xmlparse/dochandler.h +++ b/addon/xmlparse/dochandler.h @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #ifndef _DOCHANDLER_H #define _DOCHANDLER_H @@ -7,6 +22,13 @@ #include "basehandler.h" +class ParagraphHandler; + +//----------------------------------------------------------------------------- + +/*! \brief Node of a structured documentation tree. + * + */ class DocNode { public: @@ -28,7 +50,8 @@ class DocNode MarkupModifier, ItemizedList, OrderedList, - ListItem + ListItem, + ParameterList }; DocNode(NodeKind k) : m_kind(k) {} virtual ~DocNode() {} @@ -37,6 +60,12 @@ class DocNode NodeKind m_kind; }; +//----------------------------------------------------------------------------- + + +/*! \brief Node representing a piece of text. + * + */ class TextNode : public DocNode { public: @@ -48,6 +77,11 @@ class TextNode : public DocNode int m_markup; }; +//----------------------------------------------------------------------------- + +/*! \brief Node representing a change in the markup style. + * + */ class MarkupModifierNode : public DocNode { public: @@ -59,6 +93,12 @@ class MarkupModifierNode : public DocNode bool m_enabled; }; + +//----------------------------------------------------------------------------- + +/*! \brief Handles markup commands in the XML input. + * + */ class MarkupHandler : public BaseFallBackHandler<MarkupHandler> { public: @@ -90,6 +130,12 @@ class MarkupHandler : public BaseFallBackHandler<MarkupHandler> int m_curMarkup; }; + +//----------------------------------------------------------------------------- + +/*! \brief Node representing a list item. + * + */ class ListItemHandler : public DocNode, public BaseHandler<ListItemHandler> { public: @@ -104,6 +150,12 @@ class ListItemHandler : public DocNode, public BaseHandler<ListItemHandler> QList<DocNode> m_children; }; + +//----------------------------------------------------------------------------- + +/*! \brief Node representing list of items. + * + */ class ListHandler : public DocNode, public BaseHandler<ListHandler> { public: @@ -118,6 +170,53 @@ class ListHandler : public DocNode, public BaseHandler<ListHandler> QList<DocNode> m_children; }; + +//----------------------------------------------------------------------------- + +/*! \brief Node representing a parameter. + * + */ +class ParameterHandler : public DocNode, + public BaseHandler<ParameterHandler> +{ + public: + ParameterHandler(IBaseHandler *parent); + virtual ~ParameterHandler(); + virtual void startParameterList(const QXmlAttributes& attrib); + virtual void endParameterList(); + + private: + IBaseHandler *m_parent; + QString m_name; + ParagraphHandler *m_description; +}; + + +//----------------------------------------------------------------------------- + +/* \brief Node representing a parameter list. + * + */ +class ParameterListHandler : public DocNode, + public BaseHandler<ParameterListHandler> +{ + public: + ParameterListHandler(IBaseHandler *parent); + virtual ~ParameterListHandler(); + virtual void startParameterList(const QXmlAttributes& attrib); + virtual void endParameterList(); + + private: + IBaseHandler *m_parent; + QList<ParameterHandler> m_parameters; + ParameterHandler *m_curParam; +}; + +//----------------------------------------------------------------------------- + +/*! \brief Node representing a paragraph of text and commands. + * + */ class ParagraphHandler : public DocNode, public BaseHandler<ParagraphHandler> { public: @@ -125,6 +224,7 @@ class ParagraphHandler : public DocNode, public BaseHandler<ParagraphHandler> virtual void endParagraph(); virtual void startItemizedList(const QXmlAttributes& attrib); virtual void startOrderedList(const QXmlAttributes& attrib); + virtual void startParameterList(const QXmlAttributes& attrib); ParagraphHandler(IBaseHandler *parent); virtual ~ParagraphHandler(); @@ -136,7 +236,11 @@ class ParagraphHandler : public DocNode, public BaseHandler<ParagraphHandler> MarkupHandler *m_markupHandler; }; +//----------------------------------------------------------------------------- +/*! \brief Node representing a documentation block. + * + */ class DocHandler : public BaseHandler<DocHandler> { public: diff --git a/addon/xmlparse/main.cpp b/addon/xmlparse/main.cpp index 82cc849..60f4142 100644 --- a/addon/xmlparse/main.cpp +++ b/addon/xmlparse/main.cpp @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #include "mainhandler.h" #include <qstring.h> diff --git a/addon/xmlparse/mainhandler.cpp b/addon/xmlparse/mainhandler.cpp index b062578..8a5d449 100644 --- a/addon/xmlparse/mainhandler.cpp +++ b/addon/xmlparse/mainhandler.cpp @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #include "mainhandler.h" void MainHandler::startCompound(const QXmlAttributes& attrib) diff --git a/addon/xmlparse/mainhandler.h b/addon/xmlparse/mainhandler.h index 20eedc3..75a3b98 100644 --- a/addon/xmlparse/mainhandler.h +++ b/addon/xmlparse/mainhandler.h @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #ifndef _MAINHANDLER_H #define _MAINHANDLER_H diff --git a/addon/xmlparse/memberhandler.cpp b/addon/xmlparse/memberhandler.cpp index 1130f8d..4cbe4a6 100644 --- a/addon/xmlparse/memberhandler.cpp +++ b/addon/xmlparse/memberhandler.cpp @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #include "memberhandler.h" #include "sectionhandler.h" #include "dochandler.h" diff --git a/addon/xmlparse/memberhandler.h b/addon/xmlparse/memberhandler.h index 5f19ee2..e18e59c 100644 --- a/addon/xmlparse/memberhandler.h +++ b/addon/xmlparse/memberhandler.h @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #ifndef _MEMBERHANDLER_H #define _MEMBERHANDLER_H diff --git a/addon/xmlparse/paramhandler.cpp b/addon/xmlparse/paramhandler.cpp index 3563ebd..a800195 100644 --- a/addon/xmlparse/paramhandler.cpp +++ b/addon/xmlparse/paramhandler.cpp @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #include "paramhandler.h" #include "memberhandler.h" diff --git a/addon/xmlparse/paramhandler.h b/addon/xmlparse/paramhandler.h index 062bab1..f93f83f 100644 --- a/addon/xmlparse/paramhandler.h +++ b/addon/xmlparse/paramhandler.h @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #ifndef _PARAMHANDLER_H #define _PARAMHANDLER_H diff --git a/addon/xmlparse/sectionhandler.cpp b/addon/xmlparse/sectionhandler.cpp index 0b63832..80db178 100644 --- a/addon/xmlparse/sectionhandler.cpp +++ b/addon/xmlparse/sectionhandler.cpp @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #include "compoundhandler.h" #include "sectionhandler.h" diff --git a/addon/xmlparse/sectionhandler.h b/addon/xmlparse/sectionhandler.h index b2d1ce1..5a4ab2a 100644 --- a/addon/xmlparse/sectionhandler.h +++ b/addon/xmlparse/sectionhandler.h @@ -1,3 +1,18 @@ +/****************************************************************************** + * + * $Id$ + * + * + * Copyright (C) 1997-2001 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + */ + #ifndef _SECTIONHANDLER_H #define _SECTIONHANDLER_H diff --git a/doc/commands.doc b/doc/commands.doc index bfee043..cd2a634 100644 --- a/doc/commands.doc +++ b/doc/commands.doc @@ -62,6 +62,8 @@ documentation: <li> \refitem cmddeprecated \deprecated <li> \refitem cmddontinclude \dontinclude <li> \refitem cmde \e +<li> \refitem cmdelse \else +<li> \refitem cmdelseif \elseif <li> \refitem cmdem \em <li> \refitem cmdendcode \endcode <li> \refitem cmdendhtmlonly \endhtmlonly @@ -81,6 +83,7 @@ documentation: <li> \refitem cmdhtmlinclude \htmlinclude <li> \refitem cmdhtmlonly \htmlonly <li> \refitem cmdif \if +<li> \refitem cmdifnot \\ifnot <li> \refitem cmdimage \image <li> \refitem cmdinclude \include <li> \refitem cmdingroup \ingroup @@ -663,15 +666,40 @@ Public/Protected/Private/... section. a deprecated entity. Can be used to describe alternatives, expected life span, etc. +<hr> +\subsection cmdelse \else + + \addindex \else + Starts a conditional section if the previous conditional section + was not enabled. The previous section should have been started with + a \c \\if, \c \\ifnot, or \c \\elseif command. + + \sa \ref cmdif "\\if", \ref cmdifnot "\\ifnot", \ref cmdelseif "\\elseif", + \ref cmdendif "\\endif." + +<hr> +\subsection cmdelseif \elseif <section-label> + + \addindex \elseif + Starts a conditional documentation section if the previous section + was not enabled. A conditional section is + disabled by default. To enable it you must put the + section-label after the \ref cfg_enabled_sections "ENABLED_SECTIONS" + tag in the configuration + file. Conditional blocks can be nested. A nested section is + only enabled if all enclosing sections are enabled as well. + + \sa sections \ref cmdendif "\\endif", \ref cmdifnot "\\ifnot", + \ref cmdelse "\\else", and \ref cmdelseif "\\elseif". <hr> \subsection cmdendif \endif - \addindex \endif - Ends a conditional section that was started with \c \if. - For each \c \if one and only one matching \c \endif must follow. + \addindex \\endif + Ends a conditional section that was started with \c \\if or \c \\ifnot + For each \c \\if or \c \\ifnot one and only one matching \c \\endif must follow. - \sa \ref cmdif "\\if" + \sa \ref cmdif "\\if", and \ref cmdifnot "\\ifnot". <hr> \subsection cmdexception \exception <exception-object> { exception description } @@ -694,9 +722,9 @@ Public/Protected/Private/... section. <hr> \subsection cmdif \if <section-label> - \addindex \if + \addindex \\if Starts a conditional documentation section. The section ends - with a matching \c \endif command. A conditional section is + with a matching \c \\endif command. A conditional section is disabled by default. To enable it you must put the section-label after the \ref cfg_enabled_sections "ENABLED_SECTIONS" tag in the configuration @@ -720,7 +748,22 @@ Public/Protected/Private/... section. */ \endverbatim - \sa section \ref cmdendif "\\endif". + \sa sections \ref cmdendif "\\endif", \ref cmdifnot "\\ifnot", + \ref cmdelse "\\else", and \ref cmdelseif "\\elseif". + +<hr> +\subsection cmdifnot \ifnot <section-label> + + \addindex \ifnot + Starts a conditional documentation section. The section ends + with a matching \c \\endif command. This conditional section is + enabled by default. To disable it you must put the + section-label after the \ref cfg_enabled_sections "ENABLED_SECTIONS" + tag in the configuration + file. + + \sa sections \ref cmdendif "\\endif", \ref cmdif "\\if", + \ref cmdelse "\\else", and \ref cmdelseif "\\elseif". <hr> \subsection cmdinvariant \invariant { description of invariant } diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec index e84f38d..c802b39 100644 --- a/packages/rpm/doxygen.spec +++ b/packages/rpm/doxygen.spec @@ -1,5 +1,5 @@ Name: doxygen -Version: 1.2.9 +Version: 1.2.9.1 Summary: documentation system for C, C++ and IDL Release: 4 Source: doxygen-%{version}.src.tar.gz @@ -41,7 +41,7 @@ Autor: %setup -n doxygen-%{version} %build -CFLAGS="$RPM_OPT_FLAGS" ./configure --with-doxywizard --with-xmlgen +CFLAGS="$RPM_OPT_FLAGS" ./configure --with-doxywizard # the next path is Suse specific QTDIR=/usr/lib/qt2 PATH=${QTDIR}/bin:$PATH diff --git a/src/classdef.cpp b/src/classdef.cpp index 0a600a2..c0feb10 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -88,15 +88,15 @@ ClassDef::ClassDef( m_memberGroupList->setAutoDelete(TRUE); m_memberGroupDict = new MemberGroupDict(17); m_innerClasses = new ClassSDict(17); - int i=name().findRev("::"); - if (i==-1) - { - m_scopelessName=name(); - } - else - { - m_scopelessName=name().right(name().length()-i-2); - } + //int i=name().findRev("::"); // TODO: broken if A<N::C> is the class name + //if (i==-1) + //{ + // m_scopelessName=name(); + //} + //else + //{ + // m_scopelessName=name().right(name().length()-i-2); + //} m_subGrouping=TRUE; m_isTemplBaseClass=-1; m_templateInstances = 0; @@ -415,7 +415,7 @@ void ClassDef::insertMember(MemberDef *md) enumValMembers.append(md); break; case MemberDef::Function: - if (md->name()==m_scopelessName || // constructor + if (md->name()==localName() || // constructor (md->name().find('~')!=-1 && // hack to detect destructor md->name().find("operator")==-1 ) @@ -2232,6 +2232,7 @@ void ClassDef::getTemplateParameterLists(QList<ArgumentList> &lists) const QCString ClassDef::qualifiedNameWithTemplateParameters( QList<ArgumentList> *actualParams) const { + //printf("qualifiedNameWithTemplateParameters() localName=%s\n",localName().data()); QCString scName; Definition *d=getOuterScope(); if (d) @@ -2268,7 +2269,7 @@ QCString ClassDef::qualifiedNameWithTemplateParameters( } } } - //printf("scope=%s qualifiedName=%s\n",name().data(),scName.data()); + //printf("qualifiedNameWithTemplateParameters: scope=%s qualifiedName=%s\n",name().data(),scName.data()); return scName; } diff --git a/src/classdef.h b/src/classdef.h index 924c56f..939cd90 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -325,7 +325,7 @@ class ClassDef : public Definition /*! Bare name of the class without any scoping prefixes * (like for nested classes and classes inside namespaces) */ - QCString m_scopelessName; + //QCString m_scopelessName; /*! List of base class (or super-classes) from which this class derives * directly. diff --git a/src/classlist.cpp b/src/classlist.cpp index ca05275..7c69d73 100644 --- a/src/classlist.cpp +++ b/src/classlist.cpp @@ -35,8 +35,8 @@ int ClassList::compareItems(GCI item1, GCI item2) { ClassDef *c1=(ClassDef *)item1; ClassDef *c2=(ClassDef *)item2; - return stricmp(c1->name().data()+getPrefixIndex(c1->name()), - c2->name().data()+getPrefixIndex(c2->name()) + return stricmp(c1->name().data()+getPrefixIndex(c1->localName()), + c2->name().data()+getPrefixIndex(c2->localName()) ); } @@ -44,8 +44,8 @@ int ClassSDict::compareItems(GCI item1, GCI item2) { ClassDef *c1=(ClassDef *)item1; ClassDef *c2=(ClassDef *)item2; - return stricmp(c1->name().data()+getPrefixIndex(c1->name()), - c2->name().data()+getPrefixIndex(c2->name()) + return stricmp(c1->name().data()+getPrefixIndex(c1->localName()), + c2->name().data()+getPrefixIndex(c2->localName()) ); } diff --git a/src/declinfo.h b/src/declinfo.h index b337aae..0b183d7 100644 --- a/src/declinfo.h +++ b/src/declinfo.h @@ -23,7 +23,6 @@ extern void parseFuncDecl(const QCString &decl, QCString &clName, - QCString &classTempList, QCString &type, QCString &name, QCString &args, diff --git a/src/declinfo.l b/src/declinfo.l index 5548b56..d06f824 100644 --- a/src/declinfo.l +++ b/src/declinfo.l @@ -206,7 +206,7 @@ ID ([a-z_A-Z][a-z_A-Z0-9]*)|(@[0-9]+) /*@ ---------------------------------------------------------------------------- */ -void parseFuncDecl(const QCString &decl,QCString &cl,QCString &ctl,QCString &t, +void parseFuncDecl(const QCString &decl,QCString &cl,QCString &t, QCString &n,QCString &a,QCString &ftl,QCString &exc) { inputString = decl; @@ -256,9 +256,11 @@ void parseFuncDecl(const QCString &decl,QCString &cl,QCString &ctl,QCString &t, cl+=c; } } -#endif cl=stripTemplateSpecifiersFromScope(removeRedundantWhiteSpace(scope),FALSE); ctl.resize(0); +#endif + + cl=scope; n=removeRedundantWhiteSpace(name); int il,ir; if ((il=n.find('<'))!=-1 && (ir=n.findRev('>'))!=-1) diff --git a/src/definition.cpp b/src/definition.cpp index e4ea9c3..fc764f7 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -34,12 +34,7 @@ Definition::Definition(const char *df,int dl, m_defFileName = df; m_defLine = dl; m_name=name; - m_localName=name; - int i=m_localName.findRev("::"); - if (i!=-1) - { - m_localName=m_localName.right(m_localName.length()-i-2); - } + m_localName=stripScope(name); m_brief=b; m_doc=d; m_sectionDict=0, @@ -451,7 +446,7 @@ void Definition::addInnerCompound(Definition *) QCString Definition::qualifiedName() const { - //printf("start Definition::qualifiedName()\n"); + //printf("start Definition::qualifiedName() localName=%s\n",m_localName.data()); if (m_outerScope==0) { if (m_localName=="<globalScope>") return ""; @@ -892,7 +892,6 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) %x DocEmphasis %x DocBold %x DocCode -%x DocIf %x DocCodeBlock %x DocInternal %x DocLink @@ -1506,9 +1505,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) inParamBlock=TRUE; currentListIndent.push("D"); outDoc->startParamList(); - outDoc->startBold(); scanString(theTranslator->trParameters()+": "); - outDoc->endBold(); outDoc->endDescTitle(); outDoc->writeDescItem(); outDoc->startDescTable(); @@ -1532,9 +1529,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) inRetValBlock=TRUE; currentListIndent.push("D"); outDoc->startParamList(); - outDoc->startBold(); scanString(theTranslator->trReturnValues()+": "); - outDoc->endBold(); outDoc->endDescTitle(); outDoc->writeDescItem(); outDoc->startDescTable(); @@ -1558,9 +1553,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) inExceptionBlock=TRUE; currentListIndent.push("D"); outDoc->startParamList(); - outDoc->startBold(); scanString(theTranslator->trExceptions()+": "); - outDoc->endBold(); outDoc->endDescTitle(); outDoc->writeDescItem(); outDoc->startDescTable(); @@ -1574,18 +1567,14 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) <DocScan>"\\capt".* <DocParam>({DOCPARAM}{BN}*","{BN}*)*{DOCPARAM}{BSEP}* { outDoc->startDescTableTitle(); - outDoc->startEmphasis(); outDoc->docify(substitute(yytext,"\"","").stripWhiteSpace()); - outDoc->endEmphasis(); outDoc->endDescTableTitle(); outDoc->startDescTableData(); BEGIN(DocScan); } <DocException>{SCOPENAME} { outDoc->startDescTableTitle(); - outDoc->startEmphasis(); outDoc->docify(yytext); - outDoc->endEmphasis(); outDoc->endDescTableTitle(); outDoc->startDescTableData(); BEGIN(DocScan); @@ -1646,6 +1635,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) <DocScan>{CMD}"refitem"/{BN} { BEGIN(DocRefItem); } + /* <DocScan>{CMD}"if"/{BN} { outDoc->pushGeneratorState(); depthIf++; @@ -1671,6 +1661,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) } BEGIN(DocScan); } + */ <DocRefName>{SCOPENAME}|{FILE} { QCString ref=yytext; SectionInfo *sec; diff --git a/src/doxygen.cpp b/src/doxygen.cpp index a0dd54c..70f7d98 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -353,6 +353,7 @@ static void addRefItem(int todoId,int testId,int bugId,const char *prefix, doc += "</dt>\n<dd>"; doc += item->text; doc += "</dd></dl>\n"; + //printf("Test page: %s\n",doc.data()); addRelatedPage("test",theTranslator->trTestList(),doc,0,"generated",1,0,0,0); item->written=TRUE; @@ -675,34 +676,29 @@ static Definition *findScope(Entry *root,int level=0) static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n) { //printf("findScopeFromQualifiedName(%s,%s)\n",startScope ? startScope->name().data() : 0, n.data()); - QCString name(n); - if (startScope==0) startScope=Doxygen::globalScope; - int i = name.find("::"); - if (i==-1) - { - return startScope; - } - - QCString scope=stripTemplateSpecifiersFromScope(name,FALSE); - //printf("name=%s -> scope=%s\n",name.data(),scope.data()); - while ((i = scope.find("::"))!=-1) - { - //int ti = name.find('<'); - //if (ti!=-1 && ti<i) i=ti; // strip template specifiers - QCString nestedNameSpecifier = scope.left(i); - //Definition *oldScope = startScope; - startScope = startScope->findInnerCompound(nestedNameSpecifier); - //printf("Trying %s result=%p\n",nestedNameSpecifier.data(),startScope); - if (startScope==0) + Definition *resultScope=startScope; + if (resultScope==0) resultScope=Doxygen::globalScope; + QCString scope=stripTemplateSpecifiersFromScope(n,FALSE); + int l1=0,i1; + i1=getScopeFragment(scope,0,&l1); + if (i1==-1) return resultScope; + int p=i1+l1,l2=0,i2; + while ((i2=getScopeFragment(scope,p,&l2))!=-1) + { + QCString nestedNameSpecifier = scope.mid(i1,l1); + //Definition *oldScope = resultScope; + resultScope = resultScope->findInnerCompound(nestedNameSpecifier); + if (resultScope==0) { //printf("name %s not found in scope %s\n",nestedNameSpecifier.data(),oldScope->name().data()); return 0; } - scope = scope.right(scope.length()-i-2); - //printf("scope=%s\n",scope.data()); + i1=i2; + l1=l2; + p=i2+l2; } - //printf("findScopeFromQualifiedName() result=%s\n",startScope ? startScope->name().data() : 0); - return startScope; + //printf("scope %s\n",resultScope->name().data()); + return resultScope; } ArgumentList *getTemplateArgumentsFromName( @@ -834,6 +830,15 @@ static void buildClassList(Entry *root) addClassToGroups(root,cd); cd->setRefItems(root->todoId,root->testId,root->bugId); if (!root->subGrouping) cd->setSubGrouping(FALSE); + + if (cd->templateArguments()==0) + { + // this happens if a template class declared with @class is found + // before the actual definition. + ArgumentList *tArgList = + getTemplateArgumentsFromName(fullName,root->tArgLists); + cd->setTemplateArguments(tArgList); + } } else // new class { @@ -1981,6 +1986,7 @@ static void buildMemberList(Entry *root) addMemberToGroups(root,md); root->section = Entry::EMPTY_SEC; + md->setRefItems(root->todoId,root->testId,root->bugId); } else if (root->parent && !(root->parent->section & Entry::COMPOUND_MASK) && @@ -2015,10 +2021,12 @@ static void buildMemberList(Entry *root) QCString nsName,rnsName; if (nd) nsName = nd->name().copy(); if (rnd) rnsName = rnd->name().copy(); + //printf("matching arguments for %s\n",md->name().data()); if ( matchArguments(md->argumentList(),root->argList,0,nsName) ) { + //printf("match!\n"); // see if we need to create a new member found=(nd && rnd && nsName==rnsName) || // members are in the same namespace ((fd!=0 && // no external reference and @@ -3206,8 +3214,96 @@ static void computeMemberReferences() //---------------------------------------------------------------------- +static void addClassMemberTodoTestBufReferences(Definition *compound) +{ + MemberNameListIterator mnli(Doxygen::memberNameList); + MemberName *mn=0; + for (mnli.toFirst();(mn=mnli.current());++mnli) + { + MemberNameIterator mni(*mn); + MemberDef *md=0; + for (mni.toFirst();(md=mni.current());++mni) + { + Definition *d=md->getClassDef(); + QCString scopeName; + if (d) scopeName=d->name(); + if (d==0) d=md->getGroupDef(); + if (d==0) d=md->getFileDef(); + if (compound==d || (compound==0 && d!=0 && !md->visited)) + { + QCString memLabel; + md->visited=TRUE; + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + memLabel=theTranslator->trField(TRUE,TRUE); + } + else + { + memLabel=theTranslator->trMember(TRUE,TRUE); + } + addRefItem(md->todoId(),md->testId(),md->bugId(),memLabel,d->getOutputFileBase()+":"+md->anchor(),scopeName+"::"+md->name(),md->argsString()); + } + } + } +} + +static void addFileMemberTodoTestBufReferences(Definition *compound) +{ + MemberNameListIterator fnli(Doxygen::functionNameList); + MemberName *mn=0; + for (fnli.toFirst();(mn=fnli.current());++fnli) + { + MemberNameIterator mni(*mn); + MemberDef *md=0; + for (mni.toFirst();(md=mni.current());++mni) + { + Definition *d=md->getNamespaceDef(); + QCString scopeName; + if (d) scopeName=d->name(); + if (d==0) d=md->getGroupDef(); + if (d==0) d=md->getFileDef(); + if (compound==d || (compound==0 && d!=0 && !md->visited)) + { + QCString memLabel; + md->visited=TRUE; + if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + memLabel=theTranslator->trGlobal(TRUE,TRUE); + } + else + { + memLabel=theTranslator->trMember(TRUE,TRUE); + } + addRefItem(md->todoId(),md->testId(),md->bugId(),memLabel,d->getOutputFileBase()+":"+md->anchor(),md->name(),md->argsString()); + } + } + } +} + static void addTodoTestBugReferences() { + MemberNameListIterator mnli(Doxygen::memberNameList); + MemberName *mn=0; + for (mnli.toFirst();(mn=mnli.current());++mnli) + { + MemberNameIterator mni(*mn); + MemberDef *md=0; + for (mni.toFirst();(md=mni.current());++mni) + { + md->visited=FALSE; + } + } + MemberNameListIterator fnli(Doxygen::functionNameList); + for (fnli.toFirst();(mn=fnli.current());++fnli) + { + MemberNameIterator mni(*mn); + MemberDef *md=0; + for (mni.toFirst();(md=mni.current());++mni) + { + md->visited=FALSE; + } + } + ClassSDict::Iterator cli(Doxygen::classSDict); ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) @@ -3216,6 +3312,7 @@ static void addTodoTestBugReferences() theTranslator->trClass(TRUE,TRUE), cd->getOutputFileBase(),cd->name() ); + addClassMemberTodoTestBufReferences(cd); } FileName *fn=Doxygen::inputNameList.first(); while (fn) @@ -3226,6 +3323,7 @@ static void addTodoTestBugReferences() addRefItem(fd->todoId(),fd->testId(),fd->bugId(), theTranslator->trFile(TRUE,TRUE), fd->getOutputFileBase(),fd->name()); + addFileMemberTodoTestBufReferences(fd); fd=fn->next(); } fn=Doxygen::inputNameList.next(); @@ -3236,6 +3334,7 @@ static void addTodoTestBugReferences() addRefItem(nd->todoId(),nd->testId(),nd->bugId(), theTranslator->trNamespace(TRUE,TRUE), nd->getOutputFileBase(),nd->name()); + addFileMemberTodoTestBufReferences(nd); nd=Doxygen::namespaceList.next(); } GroupDef *gd=Doxygen::groupList.first(); @@ -3244,6 +3343,7 @@ static void addTodoTestBugReferences() addRefItem(gd->todoId(),gd->testId(),gd->bugId(), theTranslator->trGroup(TRUE,TRUE), gd->getOutputFileBase(),gd->groupTitle()); + addFileMemberTodoTestBufReferences(gd); gd=Doxygen::groupList.next(); } PageSDictIterator pdi(*Doxygen::pageSDict); @@ -3254,62 +3354,8 @@ static void addTodoTestBugReferences() theTranslator->trPage(TRUE,TRUE), pi->name,pi->title); } - MemberNameListIterator mnli(Doxygen::memberNameList); - MemberName *mn=0; - for (mnli.toFirst();(mn=mnli.current());++mnli) - { - MemberNameIterator mni(*mn); - MemberDef *md=0; - for (mni.toFirst();(md=mni.current());++mni) - { - Definition *d=md->getClassDef(); - QCString scopeName; - if (d) scopeName=d->name(); - if (d==0) d=md->getGroupDef(); - if (d==0) d=md->getFileDef(); - // TODO: i18n this - QCString memLabel; - if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) - { - memLabel=theTranslator->trField(TRUE,TRUE); - } - else - { - memLabel=theTranslator->trMember(TRUE,TRUE); - } - if (d) - { - addRefItem(md->todoId(),md->testId(),md->bugId(),memLabel,d->getOutputFileBase()+":"+md->anchor(),scopeName+"::"+md->name(),md->argsString()); - } - } - } - MemberNameListIterator fnli(Doxygen::functionNameList); - for (fnli.toFirst();(mn=fnli.current());++fnli) - { - MemberNameIterator mni(*mn); - MemberDef *md=0; - for (mni.toFirst();(md=mni.current());++mni) - { - Definition *d=md->getNamespaceDef(); - QCString scopeName; - if (d) scopeName=d->name(); - if (d==0) d=md->getGroupDef(); - if (d==0) d=md->getFileDef(); - QCString memLabel; - if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) - { - memLabel=theTranslator->trGlobal(TRUE,TRUE); - } - else - { - memLabel=theTranslator->trMember(TRUE,TRUE); - } - if (d) - { - addRefItem(md->todoId(),md->testId(),md->bugId(),memLabel,d->getOutputFileBase()+":"+md->anchor(),md->name(),md->argsString()); - } - } - } + addClassMemberTodoTestBufReferences(0); + addFileMemberTodoTestBufReferences(0); } @@ -3458,29 +3504,10 @@ static void addMemberDocs(Entry *root, // find a class definition given the scope name and (optionally) a // template list specifier -static ClassDef *findSimpleClassDefinition(const char *scopeName,const char *classTempList) -{ - ClassDef *tcd=0; - if (classTempList) // try to find the correct specialization - { - tcd=getClass( - insertTemplateSpecifierInScope( - scopeName, - classTempList - ) - ); // try specialization - } - if (tcd==0) - { - tcd=getClass(scopeName); // try general class - } - return tcd; -} - static ClassDef *findClassDefinition(FileDef *fd,NamespaceDef *nd, - const char *scopeName,const char *classTempList) + const char *scopeName) { - ClassDef *tcd = findSimpleClassDefinition(scopeName,classTempList); + ClassDef *tcd = getClass(scopeName); if (tcd==0) // try using declaration { ClassList *cl = 0; @@ -3507,7 +3534,7 @@ static ClassDef *findClassDefinition(FileDef *fd,NamespaceDef *nd, if (rightScopeMatch(cd->name(),scope)) { //printf("Trying to find `%s'\n",(cd->name()+scName.right(scName.length()-scopeOffset)).data()); - tcd = findSimpleClassDefinition(cd->name()+scName.right(scName.length()-scopeOffset),classTempList); + tcd = getClass(cd->name()+scName.right(scName.length()-scopeOffset)); } scopeOffset=scName.findRev("::",scopeOffset-1); } while (scopeOffset>=0 && tcd==0); @@ -3532,7 +3559,7 @@ static ClassDef *findClassDefinition(FileDef *fd,NamespaceDef *nd, for (;(nd=nli.current()) && tcd==0;++nli) { //printf("Trying with scope=%s\n",nd->name().data()); - tcd = findSimpleClassDefinition(nd->name()+"::"+scopeName,classTempList); + tcd = getClass(nd->name()+"::"+scopeName); } } } @@ -3708,34 +3735,6 @@ static void substituteTemplatesInArgList( } -static QCString mergeScopes(const QCString &leftScope,const QCString &rightScope) -{ - // case leftScope=="A" rightScope=="A::B" => result = "A::B" - if (leftScopeMatch(rightScope,leftScope)) return rightScope; - QCString result; - int i=0,p=leftScope.length(); - - // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C" - // case leftScope=="A::B" rightScope=="B" => result = "A::B" - bool found=FALSE; - while ((i=leftScope.findRev("::",p))!=-1) - { - if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2))) - { - result = leftScope.left(i+2)+rightScope; - found=TRUE; - } - p=i-1; - } - if (found) return result; - - // case leftScope=="A" rightScope=="B" => result = "A::B" - result=leftScope.copy(); - if (!result.isEmpty() && !rightScope.isEmpty()) result+="::"; - result+=rightScope; - return result; -} - /*! This function tries to find a member (in a documented class/file/namespace) * that corresponds to the function/variable declaration given in \a funcDecl. @@ -3774,7 +3773,7 @@ static void findMember(Entry *root, QCString scopeName; QCString className; QCString namespaceName; - QCString classTempList; + //QCString classTempList; QCString funcType; QCString funcName; QCString funcArgs; @@ -3816,7 +3815,19 @@ static void findMember(Entry *root, done=FALSE; } } while (!done); - + + if (isFriend) + { + if (funcDecl.left(6)=="class ") + { + funcDecl=funcDecl.right(funcDecl.length()-6); + } + else if (funcDecl.left(7)=="struct ") + { + funcDecl=funcDecl.right(funcDecl.length()-7); + } + } + // delete any ; from the function declaration int sep; while ((sep=funcDecl.find(';'))!=-1) @@ -3837,12 +3848,12 @@ static void findMember(Entry *root, ); // extract information from the declarations - parseFuncDecl(funcDecl,scopeName,classTempList,funcType,funcName, + parseFuncDecl(funcDecl,scopeName,funcType,funcName, funcArgs,funcTempList,exceptions ); //printf("scopeName=`%s' funcType=`%s' funcName=`%s'\n", // scopeName.data(),funcType.data(),funcName.data()); - + // the class name can also be a namespace name, we decide this later. // if a related class name is specified and the class name could // not be derived from the function declaration, then use the @@ -3852,11 +3863,10 @@ static void findMember(Entry *root, if (!related.isEmpty() && !isRelated) { // related member, prefix user specified scope isRelated=TRUE; - //scopeName=resolveDefines(related); - if (!scopeName.isEmpty() && scopeName!=related) - scopeName+="::"+related; + if (getClass(related)==0 && !scopeName.isEmpty()) + scopeName= mergeScopes(scopeName,related); else - scopeName=related.copy(); + scopeName = related.copy(); } if (related.isEmpty() && root->parent && @@ -3864,8 +3874,9 @@ static void findMember(Entry *root, !root->parent->name.isEmpty()) { scopeName = mergeScopes(root->parent->name,scopeName); - scopeName = stripTemplateSpecifiersFromScope(scopeName); } + scopeName=stripTemplateSpecifiersFromScope( + removeRedundantWhiteSpace(scopeName),FALSE); // split scope into a namespace and a class part extractNamespaceName(scopeName,className,namespaceName); @@ -3966,7 +3977,6 @@ static void findMember(Entry *root, "findMember() Parse results:\n" " namespaceName=`%s'\n" " className=`%s`\n" - " classTempList=`%s'\n" " funcType=`%s'\n" " funcName=`%s'\n" " funcArgs=`%s'\n" @@ -3977,7 +3987,7 @@ static void findMember(Entry *root, " isRelated=%d\n" " isFriend=%d\n" " isFunc=%d\n\n", - namespaceName.data(),className.data(),classTempList.data(), + namespaceName.data(),className.data(), funcType.data(),funcName.data(),funcArgs.data(),funcTempList.data(), funcDecl.data(),related.data(),exceptions.data(),isRelated,isFriend, isFunc @@ -4019,7 +4029,7 @@ static void findMember(Entry *root, NamespaceDef *nd=0; if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName); - ClassDef *tcd=findClassDefinition(fd,nd,scopeName,classTempList); + ClassDef *tcd=findClassDefinition(fd,nd,scopeName); if (cd && tcd==cd) // member's classes match { @@ -4241,6 +4251,7 @@ static void findMember(Entry *root, { if (className.isEmpty()) className=related.copy(); ClassDef *cd; + //printf("scopeName=`%s'\n",scopeName.data()); if ((cd=getClass(scopeName))) { bool newMember=TRUE; // assume we have a new member diff --git a/src/htmlgen.h b/src/htmlgen.h index a471433..9bc9ffb 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -209,9 +209,9 @@ class HtmlGenerator : public OutputGenerator void endDescTable() { t << "</table>" << endl; } void startDescTableTitle() - { t << "<tr><td valign=top>"; } + { t << "<tr><td valign=top><em>"; } void endDescTableTitle() - { t << endl << " </td>"; } + { t << endl << "</em> </td>"; } void startDescTableData() { t << "<td>" << endl; } void endDescTableData() diff --git a/src/index.cpp b/src/index.cpp index 2f149dd..5e3e53f 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -1194,7 +1194,7 @@ void writeAlphabeticalClassList(OutputList &ol) { if (cd->isLinkableInProject() && cd->templateMaster()==0) { - int index = getPrefixIndex(cd->name()); + int index = getPrefixIndex(cd->localName()); if (toupper(cd->name().at(index))!=startLetter) // new begin letter => new header { startLetter=toupper(cd->name().at(index)); @@ -1227,7 +1227,7 @@ void writeAlphabeticalClassList(OutputList &ol) { if (cd->isLinkableInProject() && cd->templateMaster()==0) { - int index = getPrefixIndex(cd->name()); + int index = getPrefixIndex(cd->localName()); if (toupper(cd->name().at(index))!=startLetter) { // insert a new header using a dummy class pointer. @@ -1275,7 +1275,7 @@ void writeAlphabeticalClassList(OutputList &ol) if (cd) { //printf("head ClassDef=%p %s\n",cd,cd ? cd->name().data() : "<none>"); - int index = getPrefixIndex(cd->name()); + int index = getPrefixIndex(cd->localName()); startLetter=toupper(cd->name().at(index)); char s[2]; s[0]=startLetter; s[1]=0; ol.writeIndexHeading(s); diff --git a/src/latexgen.cpp b/src/latexgen.cpp index fb7777e..7ffa258 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -540,7 +540,7 @@ void LatexGenerator::startIndexSection(IndexSections is) bool found=FALSE; for (cli.toFirst();(cd=cli.current()) && !found;++cli) { - if (cd->isLinkableInProject()) + if (cd->isLinkableInProject() && cd->templateMaster()==0) { if (compactLatex) t << "\\section"; else t << "\\chapter"; t << "{"; //Compound Documentation}\n"; @@ -711,7 +711,7 @@ void LatexGenerator::endIndexSection(IndexSections is) bool found=FALSE; for (cli.toFirst();(cd=cli.current()) && !found;++cli) { - if (cd->isLinkableInProject()) + if (cd->isLinkableInProject() && cd->templateMaster()==0) { t << "}\n\\input{" << cd->getOutputFileBase() << "}\n"; found=TRUE; @@ -719,7 +719,7 @@ void LatexGenerator::endIndexSection(IndexSections is) } for (;(cd=cli.current());++cli) { - if (cd->isLinkableInProject()) + if (cd->isLinkableInProject() && cd->templateMaster()==0) { if (compactLatex) t << "\\input"; else t << "\\include"; t << "{" << cd->getOutputFileBase() << "}\n"; diff --git a/src/latexgen.h b/src/latexgen.h index 2e2c8e4..f2fca5a 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -217,9 +217,9 @@ class LatexGenerator : public OutputGenerator void endDescTable() { t << "\\end{description}" << endl; } void startDescTableTitle() - { t << "\\item[" << endl; } + { t << "\\item[{\\em " << endl; } void endDescTableTitle() - { t << "]"; } + { t << "}]"; } void startDescTableData() {} void endDescTableData() {} void lastIndexPage() {} diff --git a/src/mangen.h b/src/mangen.h index 4d0f774..92fcc3a 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -201,8 +201,8 @@ class ManGenerator : public OutputGenerator void startDescTable() {} void endDescTable() {} - void startDescTableTitle() { writeListItem(); startBold(); } - void endDescTableTitle() { endBold(); } + void startDescTableTitle() { writeListItem(); startBold(); startEmphasis(); } + void endDescTableTitle() { endEmphasis(); endBold(); } void startDescTableData() { t << endl; firstCol=TRUE; } void endDescTableData() {} diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 3b22fd7..9c04b94 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -553,7 +553,8 @@ bool MemberDef::isBriefSectionVisible() const // only include members that are non-private unless EXTRACT_PRIVATE is // set to YES or the member is part of a group bool visibleIfPrivate = (protection()!=Private || - Config_getBool("EXTRACT_PRIVATE") + Config_getBool("EXTRACT_PRIVATE") || + mtype==Friend ); bool visible = visibleIfStatic && visibleIfDocumented && @@ -666,7 +667,7 @@ void MemberDef::writeDeclaration(OutputList &ol, if (tArgList) { writeTemplatePrefix(ol,tArgList); - ol.lineBreak(); + //ol.lineBreak(); } QCString ltype(type); @@ -879,7 +880,8 @@ bool MemberDef::isDetailedSectionLinkable() const // only include members that are non-private unless EXTRACT_PRIVATE is // set to YES or the member is part of a group bool privateFilter = (protection()!=Private || - Config_getBool("EXTRACT_PRIVATE") + Config_getBool("EXTRACT_PRIVATE") || + mtype==Friend ); // member is part of an anonymous scope that is the type of @@ -1198,9 +1200,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, if (a->hasDocumentation()) { ol.startDescTableTitle(); - ol.startEmphasis(); ol.docify(a->name); - ol.endEmphasis(); ol.endDescTableTitle(); ol.startDescTableData(); parseDoc(ol,m_defFileName,m_defLine,scopeName,name(),a->docs+"\n"); @@ -1475,7 +1475,8 @@ bool MemberDef::isLinkableInProject() const return !name().isEmpty() && name().at(0)!='@' && ((hasDocumentation() && !isReference()) ) && - (prot!=Private || Config_getBool("EXTRACT_PRIVATE")) && // not a private class member + (prot!=Private || Config_getBool("EXTRACT_PRIVATE") || + mtype==Friend) && // not a hidden member due to protection (classDef!=0 || Config_getBool("EXTRACT_STATIC") || !isStatic()); // not a static file/namespace member } diff --git a/src/memberdef.h b/src/memberdef.h index 6fa3b37..9f28afc 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -231,6 +231,7 @@ class MemberDef : public Definition ArgumentList *actualArgs); void setTemplateMaster(MemberDef *mt) { m_templateMaster=mt; } + bool visited; private: ClassDef *classDef; // member of or related to diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index 4605ae6..e79646b 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -1005,7 +1005,7 @@ void RTFGenerator::startIndexSection(IndexSections is) bool found=FALSE; for (cli.toFirst();(cd=cli.current()) && !found;++cli) { - if (cd->isLinkableInProject()) + if (cd->isLinkableInProject() && cd->templateMaster()==0) { beginRTFChapter(); found=TRUE; @@ -1238,7 +1238,7 @@ void RTFGenerator::endIndexSection(IndexSections is) t << "{\\tc \\v " << theTranslator->trClassDocumentation() << "}"<< endl; for (cli.toFirst();(cd=cli.current()) && !found;++cli) { - if (cd->isLinkableInProject()) + if (cd->isLinkableInProject() && cd->templateMaster()==0) { t << "\\par " << Rtf_Style_Reset << endl; t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \""; @@ -1249,7 +1249,7 @@ void RTFGenerator::endIndexSection(IndexSections is) } for (;(cd=cli.current());++cli) { - if (cd->isLinkableInProject()) + if (cd->isLinkableInProject() && cd->templateMaster()==0) { t << "\\par " << Rtf_Style_Reset << endl; beginRTFSection(); @@ -2230,11 +2230,13 @@ void RTFGenerator::startDescTableTitle() //t << Rtf_BList_DepthStyle() << endl; DBG_RTF(t << "{\\comment (startDescTableTitle) }" << endl) startBold(); + startEmphasis(); } void RTFGenerator::endDescTableTitle() { DBG_RTF(t << "{\\comment (endDescTableTitle) }" << endl) + endEmphasis(); endBold(); t << " "; } diff --git a/src/scanner.l b/src/scanner.l index 239af2e..9f60f21 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -76,6 +76,7 @@ static int lastAnchorContext; static int lastInitializerContext; static int lastClassTemplSpecContext; static int lastSkipHtmlCommentContext; +static int lastIfContext; static int nextDefContext; static int overloadContext; static Protection protection; @@ -84,7 +85,6 @@ static int sharpCount = 0 ; static int roundCount = 0 ; static int curlyCount = 0 ; static int squareCount = 0 ; -static int ifCount = 0 ; static int padCount = 0 ; static int todoStartContext = 0; static QCString todoString; @@ -148,6 +148,8 @@ static Grouping lastDefGroup( "", Grouping::GROUPING_LOWEST ); static bool insideFormula; static bool insideTryBlock=FALSE; +static int depthIf; + //----------------------------------------------------------------------------- static void initParser() @@ -161,7 +163,6 @@ static void initParser() sharpCount = 0; roundCount = 0; curlyCount = 0; - ifCount = 0; memberGroupId = NOGROUP; mtype = Method; gstat = FALSE; @@ -171,6 +172,8 @@ static void initParser() autoGroupStack.clear(); insideTryBlock = FALSE; insideIDL = FALSE; + autoGroupStack.setAutoDelete(TRUE); + lastDefGroup.groupname.resize(0); } static void initEntry() @@ -481,6 +484,9 @@ TITLE [tT][iI][tT][lL][eE] %x SkipSharp %x SkipRound %x SkipSquare +%x SkipSection +%x IfGuard +%x IfNotGuard %x TypedefName %x TryFunctionBlock %x TryFunctionBlockEnd @@ -1297,7 +1303,7 @@ TITLE [tT][iI][tT][lL][eE] BEGIN(AfterDoc); } } -<FindMembers,FindFields>"//"([!/]?){B}*{CMD}"{"|"/*"([!*]?){B}*{CMD}"{" { +<FindMembers,FindFields>("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") { startGroup(); tmpDocType=-1; if (current_root->section & Entry::SCOPE_MASK) @@ -2624,7 +2630,9 @@ TITLE [tT][iI][tT][lL][eE] current->inside = current_root->name+"::"; BEGIN( LineDoc ); } -<FindMembers>"extern"{BN}+"\"C"("++")?"\""{BN}*("{")? +<FindMembers>"extern"{BN}+"\"C"("++")?"\""{BN}*("{")? { + lineCount(); + } <FindMembers>"{" { current->type.resize(0); current->name.resize(0); @@ -3411,6 +3419,102 @@ TITLE [tT][iI][tT][lL][eE] <PageDocTitle>\n { yyLineNr++; current->args+=" "; } <PageDocTitle>[^\n\<] { current->args+=yytext; } <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[1]; } +<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"ifnot"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; } +<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"elseif"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; } +<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"else"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; } +<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"endif"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; } +<LineDoc,JavaDoc>{CMD}{CMD}"if"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; } +<LineDoc,JavaDoc>{CMD}{CMD}"ifnot"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; } +<LineDoc,JavaDoc>{CMD}{CMD}"elseif"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; } +<LineDoc,JavaDoc>{CMD}{CMD}"else"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; } +<LineDoc,JavaDoc>{CMD}{CMD}"endif"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; } + + /* conditional commands */ +<ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"if"{B}+ { + lastIfContext = YY_START; + BEGIN(IfGuard); + } +<ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"ifnot"{B}+ { + lastIfContext = YY_START; + BEGIN(IfNotGuard); + } +<ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"if"(\r?)\n | +<IfGuard>\n { + warn(yyFileName,yyLineNr,"Missing guard for if statement!"); + yyLineNr++; + } +<IfGuard>[^\n\t ]+ { + if (Config_getList("ENABLED_SECTIONS").find(yytext)==-1) // not enabled + { + BEGIN(SkipSection); + depthIf=1; + } + else // section enabled + { + BEGIN(lastIfContext); + } + } +<IfNotGuard>\n { + warn(yyFileName,yyLineNr,"Missing guard for ifnot statement!"); + yyLineNr++; + } +<IfNotGuard>[^\n\t ]+ { + if (Config_getList("ENABLED_SECTIONS").find(yytext)==-1) // not enabled + { + BEGIN(lastIfContext); + } + else // section enabled + { + depthIf=1; + BEGIN(SkipSection); + } + } +<SkipSection>{CMD}"if"/[^a-z_A-Z0-9] { + depthIf++; + } +<SkipSection>{CMD}"endif"/[^a-z_A-Z0-9] { + if (--depthIf<=0) + { + BEGIN(lastIfContext); + } + } +<SkipSection>{CMD}"else"/[^a-z_A-Z0-9] { + if (depthIf==1) + { + depthIf=0; + BEGIN(lastIfContext); + } + } +<SkipSection>{CMD}"elseif"/[^a-z_A-Z0-9] { + if (depthIf==1) + { + BEGIN(IfGuard); + } + } +<SkipSection>"*/" { + unput('/');unput('*'); + BEGIN( lastIfContext ); + } +<SkipSection>\n { + yyLineNr++; + } +<SkipSection>"//"|"*/" +<ClassDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"elseif"/[^a-z_A-Z0-9] { + // previous section enabled => absorb else + } +<ClassDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"else"/[^a-z_A-Z0-9] { + // section was enable => skip now + depthIf=1; + BEGIN(SkipSection); + } +<ClassDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"endif"/[^a-z_A-Z0-9] { + // section enabled => absorb endif + } + + <ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc>{CMD}"ingroup"{B}+ { lastGroupContext = YY_START; lineCount(); @@ -3868,7 +3972,9 @@ static void parseCompounds(Entry *rt) // ce->name.data(),ce->program.data()); // init scanner state padCount=0; + depthIf = 0; inputString = ce->program; + lastDefGroup.groupname.resize(0); inputPosition = 0; scanYYrestart( scanYYin ) ; if (ce->section==Entry::ENUM_SEC) @@ -3900,6 +4006,11 @@ static void parseCompounds(Entry *rt) scanYYlex() ; delete current; current=0; ce->program.resize(0); + + if (depthIf>0) + { + warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!"); + } } parseCompounds(ce); } @@ -3911,6 +4022,7 @@ void parseMain(Entry *rt) { initParser(); anonCount = 0; + depthIf = 0; protection = Public; mtype = Method; gstat = FALSE; @@ -3920,10 +4032,13 @@ void parseMain(Entry *rt) current = new Entry; inputString = rt->program; inputPosition = 0; - ifCount=0; scanYYrestart( scanYYin ); BEGIN( FindMembers ); scanYYlex(); + if (depthIf>0) + { + warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!"); + } rt->program.resize(0); delete current; current=0; parseCompounds(rt); diff --git a/src/util.cpp b/src/util.cpp index 576e1c1..e766b3f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -557,7 +557,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) { result+=" >"; // insert extra space for layouting (nested) templates } - else if (i>0 && i<l-1 && c==',' && isId(s.at(i-1)) && isId(s.at(i+1))) + else if (i>0 && i<l-1 && c==',' && !isspace(s.at(i-1)) && isId(s.at(i+1))) { result+=", "; } @@ -1014,28 +1014,71 @@ int minClassDistance(ClassDef *cd,ClassDef *bcd,int level) //} // strip any template specifiers that follow className in string s -static QCString trimTemplateSpecifiers(const QCString &className,const QCString &s) +static QCString trimTemplateSpecifiers( + const QCString &namespaceName, + const QCString &className, + const QCString &s +) { - //printf("trimTemplateSpecifiers(%s,%s)\n",className.data(),s.data()); - ClassDef *cd=getClass(className); - if (cd==0) return s; + //printf("trimTemplateSpecifiers(%s,%s,%s)\n",namespaceName.data(),className.data(),s.data()); + QCString scopeName=mergeScopes(namespaceName,className); + ClassDef *cd=getClass(scopeName); + if (cd==0) return s; // should not happen, but guard anyway. + QCString result=s; + + int i=className.length()-1; + if (className.at(i)=='>') // template specialization + { + // replace unspecialized occurrences in s, with their specialized versions. + int count=1; + int cl=i+1; + while (i>=0) + { + char c=className.at(i); + if (c=='>') count++,i--; + else if (c=='<') { count--; if (count==0) break; } + else i--; + } + QCString unspecClassName=className.left(i); + int l=i; + int p=0; + while ((i=result.find(unspecClassName,p))!=-1) + { + if (result.at(i+l)!='<') // unspecialized version + { + result=result.left(i)+className+result.right(result.length()-i-l); + l=cl; + } + p=i+l; + } + } + + //printf("result after specialization: %s\n",result.data()); + QCString qualName=cd->qualifiedNameWithTemplateParameters(); //printf("QualifiedName = %s\n",qualName.data()); // We strip the template arguments following className (if any) - QCString result=s; if (!qualName.isEmpty()) // there is a class name { - int i,p=0; - // TODO: also try smaller parts of the qualName, since we - // could be inside a namespace or class. - while ((i=result.find(qualName,p))!=-1) // class name is in the argument type + int is,ps=0; + int p=0,l,i; + + while ((is=getScopeFragment(qualName,ps,&l))!=-1) { - int ql=qualName.length(); - result=result.left(i)+cd->name()+result.right(result.length()-i-ql); - p=i+cd->name().length(); + QCString qualNamePart = qualName.right(qualName.length()-is); + //printf("qualNamePart=%s\n",qualNamePart.data()); + while ((i=result.find(qualNamePart,p))!=-1) + { + int ql=qualNamePart.length(); + result=result.left(i)+cd->name()+result.right(result.length()-i-ql); + p=i+cd->name().length(); + } + ps=is+l; } } + //printf("result=%s\n",result.data()); + return result; } @@ -1203,9 +1246,9 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA, // before matching. This should use className and namespaceName // and usingNamespaces and usingClass to determine which typedefs // are in-scope, so it will not be very efficient :-( - - QCString srcAType=trimTemplateSpecifiers(className,srcA->type); - QCString dstAType=trimTemplateSpecifiers(className,dstA->type); + + QCString srcAType=trimTemplateSpecifiers(namespaceName,className,srcA->type); + QCString dstAType=trimTemplateSpecifiers(namespaceName,className,dstA->type); if (srcAType.left(6)=="class ") srcAType=srcAType.right(srcAType.length()-6); if (dstAType.left(6)=="class ") dstAType=dstAType.right(dstAType.length()-6); @@ -1235,6 +1278,9 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA, stripIrrelevantConstVolatile(srcAType); stripIrrelevantConstVolatile(dstAType); + srcAType = removeRedundantWhiteSpace(srcAType); + dstAType = removeRedundantWhiteSpace(dstAType); + //srcAType=stripTemplateSpecifiersFromScope(srcAType,FALSE); //dstAType=stripTemplateSpecifiersFromScope(dstAType,FALSE); @@ -1446,9 +1492,23 @@ static void mergeArgument(Argument *srcA,Argument *dstA, dstA->type+=dstA->name; dstA->name.resize(0); } + if (srcA->name=="const" || srcA->name=="volatile") + { + srcA->type+=" "; + srcA->type+=srcA->name; + srcA->type=removeRedundantWhiteSpace(srcA->type); + srcA->name.resize(0); + } + if (dstA->name=="const" || dstA->name=="volatile") + { + dstA->type+=" "; + dstA->type+=dstA->name; + dstA->type=removeRedundantWhiteSpace(dstA->type); + dstA->name.resize(0); + } - QCString srcAType=trimTemplateSpecifiers(className,srcA->type); - QCString dstAType=trimTemplateSpecifiers(className,dstA->type); + QCString srcAType=trimTemplateSpecifiers(namespaceName,className,srcA->type); + QCString dstAType=trimTemplateSpecifiers(namespaceName,className,dstA->type); if (srcAType.left(6)=="class ") srcAType=srcAType.right(srcAType.length()-6); if (dstAType.left(6)=="class ") dstAType=dstAType.right(dstAType.length()-6); @@ -1617,10 +1677,16 @@ static void mergeArgument(Argument *srcA,Argument *dstA, if (i>0 && i<(int)srcAType.length()-1 && srcAType.at(i)!=':') // there is (probably) a name { - srcA->name=srcAType.right(srcAType.length()-i-1); - srcA->type=srcAType.left(i+1).stripWhiteSpace(); - dstA->name=dstAType.right(dstAType.length()-i-1); - dstA->type=dstAType.left(i+1).stripWhiteSpace(); + QCString srcAName=srcAType.right(srcAType.length()-i-1); + QCString dstAName=dstAType.right(dstAType.length()-i-1); + if (srcAName!="const" && srcAName!="volatile" && + dstAName!="const" && dstAName!="volatile") + { + srcA->name=srcAName; + srcA->type=srcAType.left(i+1).stripWhiteSpace(); + dstA->name=dstAName; + dstA->type=dstAType.left(i+1).stripWhiteSpace(); + } } } else if (!dstA->name.isEmpty()) @@ -1655,11 +1721,11 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl, QCString namespaceName=ns; // strip template specialization from class name if present - int til=className.find('<'),tir=className.find('>'); - if (til!=-1 && tir!=-1 && tir>til) - { - className=className.left(til)+className.right(className.length()-tir-1); - } + //int til=className.find('<'),tir=className.find('>'); + //if (til!=-1 && tir!=-1 && tir>til) + //{ + // className=className.left(til)+className.right(className.length()-tir-1); + //} //printf("matchArguments(%s,%s) className=%s namespaceName=%s checkCV=%d usingNamespaces=%d usingClasses=%d\n", // srcAl ? argListToString(srcAl).data() : "", @@ -2670,24 +2736,22 @@ QCString substituteKeywords(const QCString &s,const char *title) */ int getPrefixIndex(const QCString &name) { - int ni = name.findRev("::"); - if (ni==-1) ni=0; else ni+=2; //printf("getPrefixIndex(%s) ni=%d\n",name.data(),ni); QStrList &sl = Config_getList("IGNORE_PREFIX"); char *s = sl.first(); while (s) { const char *ps=s; - const char *pd=name.data()+ni; + const char *pd=name.data(); int i=0; while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++; if (*ps==0 && *pd!=0) { - return ni+i; + return i; } s = sl.next(); } - return ni; + return 0; } //---------------------------------------------------------------------------- @@ -2868,17 +2932,52 @@ QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &te return result; } +/*! Strips the scope from a name. Examples: A::B will return A + * and A<T>::B<N::C<D> > will return A<T>. + * \todo deal with cases like A< s<<2 >::B + */ QCString stripScope(const char *name) { QCString result = name; - int ti=result.find('<'); // find start of template - if (ti==-1) ti=result.length(); - int i = ti>2 ? result.findRev("::",ti-2) : -1; // find scope just before template - if (i!=-1) // found scope + int l=result.length(); + int p=l-1; + bool done; + int count; + + while (p>=0) { - result=result.right(result.length()-i-2); + char c=result.at(p); + switch (c) + { + case ':': + //printf("stripScope(%s)=%s\n",name,result.right(l-p-1).data()); + return result.right(l-p-1); + case '>': + count=1; + done=FALSE; + //printf("pos < = %d\n",p); + p--; + while (p>=0 && !done) + { + c=result.at(p--); + switch (c) + { + case '>': count++; break; + case '<': count--; if (count<=0) done=TRUE; break; + default: + //printf("c=%c count=%d\n",c,count); + break; + } + } + //printf("pos > = %d\n",p+1); + break; + default: + p--; + } } - return result; + //printf("stripScope(%s)=%s\n",name,name); + return name; + } /*! Converts a string to an XML-encoded string */ @@ -3015,6 +3114,8 @@ bool extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCStr QCString substituteTemplateArgumentsInString( const QCString &name,ArgumentList *formalArgs,ArgumentList *actualArgs) { + //printf("substituteTemplateArgumentsInString(name=%s formal=%s actualArg=%s)\n", + // name.data(),argListToString(formalArgs).data(),argListToString(actualArgs).data()); if (formalArgs==0) return name; QCString result; static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*"); @@ -3036,16 +3137,19 @@ QCString substituteTemplateArgumentsInString( ++formAli,actArg=actualArgs->next() ) { - if (formArg->name==n && actArg && !actArg->type.isEmpty()) // base class is a template argument - { - // replace formal argument with the actual argument of the instance - result += actArg->type; - found=TRUE; - } - else if (formArg->name==n && actArg==0 && !formArg->defval.isEmpty()) + if (formArg->type=="class" || formArg->type=="typename") { - result += formArg->defval; - found=TRUE; + if (formArg->name==n && actArg && !actArg->type.isEmpty()) // base class is a template argument + { + // replace formal argument with the actual argument of the instance + result += actArg->type; + found=TRUE; + } + else if (formArg->name==n && actArg==0 && !formArg->defval.isEmpty()) + { + result += formArg->defval; + found=TRUE; + } } } if (!found) result += n; @@ -3109,10 +3213,8 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName, int p=0; int l=fullName.length(); int i=fullName.find('<'); - int si= i==-1 ? -1 : fullName.find("::",i); - while (i!=-1 && (!parentOnly || i<si)) + while (i!=-1) { - result+=fullName.mid(p,i-p); //printf("1:result+=%s\n",fullName.mid(p,i-p).data()); int e=i+1; bool done=FALSE; @@ -3130,18 +3232,112 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName, done = count==0; } } + int si= fullName.find("::",e); + + if (parentOnly && si==-1) break; + // we only do the parent scope, so we stop here if needed + + result+=fullName.mid(p,i-p); //printf(" trying %s\n",(result+fullName.mid(i,e-i)).data()); - if (getClass(result+fullName.mid(i,e-i))!=0) + if (getClass(result+fullName.mid(i,e-i))!=0) { result+=fullName.mid(i,e-i); //printf("2:result+=%s\n",fullName.mid(i,e-i-1).data()); } p=e; i=fullName.find('<',p); - si= i==-1 ? -1 : fullName.find("::",i); } result+=fullName.right(l-p); //printf("3:result+=%s\n",fullName.right(l-p).data()); return result; } +/*! Merges two scope parts together. The parts may (partially) overlap. + * Example1: \c A::B and \c B::C will result in \c A::B::C <br> + * Example2: \c A and \c B will be \c A::B <br> + * Example3: \c A::B and B will be \c A::B + * + * @param leftScope the left hand part of the scope. + * @param rightScope the right hand part of the scope. + * @returns the merged scope. + */ +QCString mergeScopes(const QCString &leftScope,const QCString &rightScope) +{ + // case leftScope=="A" rightScope=="A::B" => result = "A::B" + if (leftScopeMatch(rightScope,leftScope)) return rightScope; + QCString result; + int i=0,p=leftScope.length(); + + // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C" + // case leftScope=="A::B" rightScope=="B" => result = "A::B" + bool found=FALSE; + while ((i=leftScope.findRev("::",p))!=-1) + { + if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2))) + { + result = leftScope.left(i+2)+rightScope; + found=TRUE; + } + p=i-1; + } + if (found) return result; + + // case leftScope=="A" rightScope=="B" => result = "A::B" + result=leftScope.copy(); + if (!result.isEmpty() && !rightScope.isEmpty()) result+="::"; + result+=rightScope; + return result; +} + +/*! Returns a fragment from scope \a s, starting at position \a p. + * + * @param s the scope name as a string. + * @param p the start position (0 is the first). + * @param l the resulting length of the fragment. + * @returns the location of the fragment, or -1 if non is found. + */ +int getScopeFragment(const QCString &s,int p,int *l) +{ + int sl=s.length(); + int sp=p; + int count=0; + bool done; + if (sp>=sl) return -1; + while (sp<sl) + { + char c=s.at(sp); + if (c==':') sp++,p++; else break; + } + while (sp<sl) + { + char c=s.at(sp); + switch (c) + { + case ':': // found next part + goto found; + case '<': // skip template specifier + count=1;sp++; + done=FALSE; + while (sp<sl && !done) + { + // TODO: deal with << and >> operators! + char c=s.at(sp++); + switch(c) + { + case '<': count++; break; + case '>': count--; if (count==0) done=TRUE; break; + default: break; + } + } + break; + default: + sp++; + break; + } + } +found: + *l=sp-p; + //printf("getScopeFragment(%s,%d)=%s\n",s.data(),p,s.mid(p,*l).data()); + return p; +} + @@ -160,6 +160,8 @@ QList<ArgumentList> *copyArgumentLists(const QList<ArgumentList> *srcLists); QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly=TRUE); QCString resolveTypeDef(Definition *d,const QCString &name); +QCString mergeScopes(const QCString &leftScope,const QCString &rightScope); +int getScopeFragment(const QCString &s,int p,int *l); #endif diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index 8b9ed39..3b9d404 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -38,8 +38,8 @@ static inline void writeXMLString(QTextStream &t,const char *s) t << convertToXML(s); } -static void writeXMLLink(QTextStream &t,const char *compoundId,const char *memId, - const char *text) +static void writeXMLLink(QTextStream &t,const char *compoundId, + const char *memId,const char *text) { if (memId==0) { |