summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/config.doc39
-rw-r--r--doc/install.doc12
-rw-r--r--src/classdef.cpp19
-rw-r--r--src/classdef.h7
-rw-r--r--src/commentscan.l2
-rw-r--r--src/config.xml9
-rw-r--r--src/context.cpp767
-rw-r--r--src/context.h40
-rw-r--r--src/definition.cpp2
-rw-r--r--src/htmlgen.cpp2
-rw-r--r--src/memberdef.cpp117
-rw-r--r--src/memberdef.h4
-rw-r--r--src/template.cpp170
13 files changed, 1084 insertions, 106 deletions
diff --git a/doc/config.doc b/doc/config.doc
index 1637275..9b27733 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -88,8 +88,8 @@ followed by the descriptions of the tags grouped by category.
\refitem cfg_compact_rtf COMPACT_RTF
\refitem cfg_cpp_cli_support CPP_CLI_SUPPORT
\refitem cfg_create_subdirs CREATE_SUBDIRS
-\refitem cfg_dia_path DIA_PATH
\refitem cfg_diafile_dirs DIAFILE_DIRS
+\refitem cfg_dia_path DIA_PATH
\refitem cfg_directory_graph DIRECTORY_GRAPH
\refitem cfg_disable_index DISABLE_INDEX
\refitem cfg_distribute_group_doc DISTRIBUTE_GROUP_DOC
@@ -278,6 +278,7 @@ followed by the descriptions of the tags grouped by category.
\refitem cfg_server_based_search SERVER_BASED_SEARCH
\refitem cfg_short_names SHORT_NAMES
\refitem cfg_show_files SHOW_FILES
+\refitem cfg_show_grouped_memb_inc SHOW_GROUPED_MEMB_INC
\refitem cfg_show_include_files SHOW_INCLUDE_FILES
\refitem cfg_show_namespaces SHOW_NAMESPACES
\refitem cfg_show_used_files SHOW_USED_FILES
@@ -397,6 +398,7 @@ The default value is: <code>NO</code>.
Possible values are:
<code>Afrikaans</code>,
<code>Arabic</code>,
+<code>Armenian</code>,
<code>Brazilian</code>,
<code>Catalan</code>,
<code>Chinese</code>,
@@ -405,28 +407,31 @@ Possible values are:
<code>Czech</code>,
<code>Danish</code>,
<code>Dutch</code>,
-<code>English</code>,
+<code>English</code> (United States),
<code>Esperanto</code>,
-<code>Farsi</code>,
+<code>Farsi</code> (Persian),
<code>Finnish</code>,
<code>French</code>,
<code>German</code>,
<code>Greek</code>,
<code>Hungarian</code>,
+<code>Indonesian</code>,
<code>Italian</code>,
<code>Japanese</code>,
-<code>Japanese-en</code>,
+<code>Japanese-en</code> (Japanese with English messages),
<code>Korean</code>,
-<code>Korean-en</code>,
+<code>Korean-en</code> (Korean with English messages),
<code>Latvian</code>,
-<code>Norwegian</code>,
+<code>Lithuanian</code>,
<code>Macedonian</code>,
-<code>Persian</code>,
+<code>Norwegian</code>,
+<code>Persian</code> (Farsi),
<code>Polish</code>,
<code>Portuguese</code>,
<code>Romanian</code>,
<code>Russian</code>,
<code>Serbian</code>,
+<code>Serbian-Cyrillic</code>,
<code>Slovak</code>,
<code>Slovene</code>,
<code>Spanish</code>,
@@ -1022,6 +1027,16 @@ The default value is: <code>NO</code>.
The default value is: <code>YES</code>.
+ \anchor cfg_show_grouped_memb_inc
+<dt>\c SHOW_GROUPED_MEMB_INC <dd>
+ \addindex SHOW_GROUPED_MEMB_INC
+ If the SHOW_GROUPED_MEMB_INC tag is set to \c YES then Doxygen
+ will add for each grouped member an include statement to the documentation,
+ telling the reader which file to include in order to use the member.
+
+
+The default value is: <code>NO</code>.
+
\anchor cfg_force_local_includes
<dt>\c FORCE_LOCAL_INCLUDES <dd>
\addindex FORCE_LOCAL_INCLUDES
@@ -3311,10 +3326,10 @@ The default value is: <code>YES</code>.
\anchor cfg_dia_path
<dt>\c DIA_PATH <dd>
\addindex DIA_PATH
- You can include diagrams drawn in dia using the \ref cmddiafile "\\diafile" command.
- Doxygen will run dia to produce the appropriate image and insert it in the documentation.
- The <code>DIA_PATH</code> tag allows you to specify the directory where the \c dia
- binary resides. If left empty the tool is assumed to be found in the default search path.
+You can include diagrams made with dia in doxygen documentation. Doxygen will then run
+dia to produce the diagram and insert it in the documentation. The DIA_PATH tag allows
+you to specify the directory where the dia binary resides. If left empty dia is assumed
+to be found in the default search path.
\anchor cfg_hide_undoc_relations
<dt>\c HIDE_UNDOC_RELATIONS <dd>
@@ -3607,7 +3622,7 @@ This tag requires that the tag \ref cfg_have_dot "HAVE_DOT" is set to \c YES.
\addindex DIAFILE_DIRS
The \c DIAFILE_DIRS tag can be used to specify one or more directories that
contain dia files that are included in the documentation (see the
- \ref cmddiafile "\\diafile" command).
+ \ref cmdmscfile "\\diafile" command).
\anchor cfg_dot_graph_max_nodes
<dt>\c DOT_GRAPH_MAX_NODES <dd>
diff --git a/doc/install.doc b/doc/install.doc
index 2f4373d..94f1099 100644
--- a/doc/install.doc
+++ b/doc/install.doc
@@ -269,9 +269,11 @@ compile doxygen. Alternatively, you can compile doxygen
<a href="http://en.wikipedia.org/wiki/Cygwin">Cygwin</a>
or <a href="http://www.mingw.org/">MinGW</a>.
-The next step is to install \c bison, \c flex, \c tar
-(see http://gnuwin32.sourceforge.net/packages.html) and \c python (version 2, see http://www.python.org).
-This packages are needed during the
+The next step is to install modern versions of \c bison and \c flex
+(see http://sourceforge.net/projects/winflexbison. After installation and adding them to
+your `path` rename `win_flex.exe` to `flex.exe` and `win_bison.exe` to `bison.exe`)
+Furthermore you have to install \c python (version 2, see http://www.python.org).
+These packages are needed during the
compilation process if you use a GitHub snapshot of doxygen (the official source releases
come with pre-generated sources).
@@ -282,7 +284,9 @@ Now start a new command shell and type
cd c:\tools
tar zxvf doxygen-x.y.z.src.tar.gz
\endverbatim
-to unpack the sources.
+to unpack the sources (you can obtain \c tar from e.g. http://gnuwin32.sourceforge.net/packages.html).
+Alternatively you can use an unpack program, like 7-Zip (see http://www.7-zip.org)
+or use the build in unpack feature of modern Windows systems).
Now your environment is setup to build \c doxygen.
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 474be45..eba870f 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -2446,12 +2446,12 @@ bool ClassDef::addExample(const char *anchor,const char *nameStr,
}
// returns TRUE if this class is used in an example
-bool ClassDef::hasExamples()
+bool ClassDef::hasExamples() const
{
- if (m_impl->exampleSDict==0)
- return FALSE;
- else
- return m_impl->exampleSDict->count()>0;
+ bool result=FALSE;
+ if (m_impl->exampleSDict)
+ result = m_impl->exampleSDict->count()>0;
+ return result;
}
@@ -4758,3 +4758,12 @@ const FileList &ClassDef::usedFiles() const
return m_impl->files;
}
+const ArgumentList *ClassDef::typeConstraints() const
+{
+ return m_impl->typeConstraints;
+}
+
+const ExampleSDict *ClassDef::exampleList() const
+{
+ return m_impl->exampleSDict;
+}
diff --git a/src/classdef.h b/src/classdef.h
index c3ae9f5..eb36383 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -313,6 +313,11 @@ class ClassDef : public Definition
QCString includeStatement() const;
+ const ArgumentList *typeConstraints() const;
+ const ExampleSDict *exampleList() const;
+ bool hasExamples() const;
+ QCString getMemberListFileName() const;
+
//-----------------------------------------------------------------------------------
// --- setters ----
//-----------------------------------------------------------------------------------
@@ -384,7 +389,6 @@ class ClassDef : public Definition
protected:
void addUsedInterfaceClasses(MemberDef *md,const char *typeStr);
- bool hasExamples();
bool hasNonReferenceSuperClass();
void showUsedFiles(OutputList &ol);
@@ -392,7 +396,6 @@ class ClassDef : public Definition
void writeTagFileMarker();
void writeDocumentationContents(OutputList &ol,const QCString &pageTitle);
void internalInsertMember(MemberDef *md,Protection prot,bool addToAllList);
- QCString getMemberListFileName() const;
void addMemberToList(MemberListType lt,MemberDef *md,bool isBrief);
MemberList *createMemberList(MemberListType lt);
void writeInheritedMemberDeclarations(OutputList &ol,MemberListType lt,int lt2,const QCString &title,ClassDef *inheritedFrom,bool invert,bool showAlways,QPtrDict<void> *visitedClasses);
diff --git a/src/commentscan.l b/src/commentscan.l
index 229cc2b..0d08e5c 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -2403,7 +2403,7 @@ static bool handleParBlock(const QCString &)
warn(yyFileName,yyLineNr,
"found \\parblock command while already in a parblock!");
}
- addOutput("@parblock");
+ addOutput("@parblock ");
g_insideParBlock = TRUE;
return FALSE;
}
diff --git a/src/config.xml b/src/config.xml
index e9c9add..eff8cff 100644
--- a/src/config.xml
+++ b/src/config.xml
@@ -882,6 +882,15 @@ Go to the <a href="commands.html">next</a> section or return to the
]]>
</docs>
</option>
+ <option type='bool' id='SHOW_GROUPED_MEMB_INC' defval='0'>
+ <docs>
+<![CDATA[
+ If the SHOW_GROUPED_MEMB_INC tag is set to \c YES then Doxygen
+ will add for each grouped member an include statement to the documentation,
+ telling the reader which file to include in order to use the member.
+]]>
+ </docs>
+ </option>
<option type='bool' id='FORCE_LOCAL_INCLUDES' defval='0'>
<docs>
<![CDATA[
diff --git a/src/context.cpp b/src/context.cpp
index a810808..1881147 100644
--- a/src/context.cpp
+++ b/src/context.cpp
@@ -19,6 +19,8 @@
#include "htmldocvisitor.h"
#include "dot.h"
#include "diagram.h"
+#include "example.h"
+#include "membername.h"
struct ContextGlobals
{
@@ -178,7 +180,14 @@ class PropertyMapper
void addProperty(const char *name,const T* obj,
typename PropertyFunc<T>::Handler handle)
{
- m_map.insert(name,new PropertyFunc<T>(obj,handle));
+ if (m_map.find(name))
+ {
+ err("Error: adding property '%s' more than once",name);
+ }
+ else
+ {
+ m_map.insert(name,new PropertyFunc<T>(obj,handle));
+ }
}
/** Gets the value of a property.
@@ -339,6 +348,10 @@ class TranslateContext::Private : public PropertyMapper
{
return ((TranslateContext::Private*)obj)->collaborationDiagramFor(args);
}
+ static TemplateVariant writeListFunc(const void *obj,const QValueList<TemplateVariant> &args)
+ {
+ return ((TranslateContext::Private*)obj)->writeList(args);
+ }
TemplateVariant generatedAt(const QValueList<TemplateVariant> &args) const
{
if (args.count()==2)
@@ -399,6 +412,18 @@ class TranslateContext::Private : public PropertyMapper
}
return QCString();
}
+ QCString writeList(const QValueList<TemplateVariant> &args) const
+ {
+ if (args.count()==1)
+ {
+ return theTranslator->trWriteList(args[0].toInt());
+ }
+ else
+ {
+ err("tr.*List should take one integer parameter, got %d!\n",args.count());
+ }
+ return QCString();
+ }
@@ -535,6 +560,34 @@ class TranslateContext::Private : public PropertyMapper
{
return TemplateVariant(this,&Private::inheritedByListFunc);
}
+ TemplateVariant definedAtLineInSourceFile() const
+ {
+ return theTranslator->trDefinedAtLineInSourceFile();
+ }
+ TemplateVariant typeConstraints() const
+ {
+ return theTranslator->trTypeConstraints();
+ }
+ TemplateVariant exampleList() const
+ {
+ return TemplateVariant(this,&Private::writeListFunc);
+ }
+ TemplateVariant listOfAllMembers() const
+ {
+ return theTranslator->trListOfAllMembers();
+ }
+ TemplateVariant memberList() const
+ {
+ return theTranslator->trMemberList();
+ }
+ TemplateVariant theListOfAllMembers() const
+ {
+ return theTranslator->trThisIsTheListOfAllMembers();
+ }
+ TemplateVariant incInheritedMembers() const
+ {
+ return theTranslator->trIncludingInheritedMembers();
+ }
Private()
{
//%% string generatedBy
@@ -580,13 +633,27 @@ class TranslateContext::Private : public PropertyMapper
//%% string detailedDescription
addProperty("detailedDesc", this,&Private::detailedDesc);
//%% string inheritanceDiagramFor
- addProperty("inheritanceDiagramFor", this,&Private::inheritanceDiagramFor);
+ addProperty("inheritanceDiagramFor", this,&Private::inheritanceDiagramFor);
//%% string collaborationDiagramFor
- addProperty("collaborationDiagramFor", this,&Private::collaborationDiagramFor);
- //%% string inheritsList
+ addProperty("collaborationDiagramFor", this,&Private::collaborationDiagramFor);
+ //%% markerstring inheritsList
addProperty("inheritsList", this,&Private::inheritsList);
- //%% string inheritedByList
+ //%% markerstring inheritedByList
addProperty("inheritedByList", this,&Private::inheritedByList);
+ //%% markerstring definedAtLineInSourceFile
+ addProperty("definedAtLineInSourceFile", this,&Private::definedAtLineInSourceFile);
+ //%% string typeConstraints
+ addProperty("typeConstraints", this,&Private::typeConstraints);
+ //%% string exampleList
+ addProperty("exampleList", this,&Private::exampleList);
+ //%% string listOfAllMembers
+ addProperty("listOfAllMembers", this,&Private::listOfAllMembers);
+ //%% string memberList
+ addProperty("memberList", this,&Private::memberList);
+ //%% string theListOfAllMembers
+ addProperty("theListOfAllMembers",this,&Private::theListOfAllMembers);
+ //%% string incInheritedMembers
+ addProperty("incInheritedMembers",this,&Private::incInheritedMembers);
m_javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
@@ -670,6 +737,33 @@ class DefinitionContext : public PropertyMapper
addProperty("dynSectionId",this,&DefinitionContext::dynSectionId);
//%% string language: the programming language in which the symbol is written
addProperty("language",this,&DefinitionContext::language);
+ //%% string sourceDef: A link to the source definition
+ addProperty("sourceDef",this,&DefinitionContext::sourceDef);
+
+ if (m_def && !m_def->getSourceFileBase().isEmpty())
+ {
+ m_sourceDef.append(&m_lineLink);
+ m_sourceDef.append(&m_fileLink);
+ m_lineLink.set("text",m_def->getStartBodyLine());
+ m_lineLink.set("isLinkable",m_def->isLinkable());
+ m_lineLink.set("fileName",m_def->getSourceFileBase());
+ m_lineLink.set("anchor",m_def->getSourceAnchor());
+ if (m_def->definitionType()==Definition::TypeFile)
+ {
+ m_fileLink.set("text",m_def->name());
+ }
+ else if (m_def->getBodyDef())
+ {
+ m_fileLink.set("text",m_def->getBodyDef()->name());
+ }
+ else
+ {
+ m_fileLink.set("text",name());
+ }
+ m_fileLink.set("isLinkable",m_def->isLinkable());
+ m_fileLink.set("fileName",m_def->getSourceFileBase());
+ m_fileLink.set("anchor",QCString());
+ }
}
TemplateVariant fileName() const
{
@@ -710,28 +804,28 @@ class DefinitionContext : public PropertyMapper
}
TemplateVariant details() const
{
- if (!m_details)
+ if (!m_cache.details)
{
- m_details.reset(new TemplateVariant(parseDoc(m_def,m_def->docFile(),m_def->docLine(),
+ m_cache.details.reset(new TemplateVariant(parseDoc(m_def,m_def->docFile(),m_def->docLine(),
relPathAsString(),m_def->documentation(),FALSE)));
}
- return *m_details;
+ return *m_cache.details;
}
TemplateVariant brief() const
{
- if (!m_brief)
+ if (!m_cache.brief)
{
if (m_def->hasBriefDescription())
{
- m_brief.reset(new TemplateVariant(parseDoc(m_def,m_def->briefFile(),m_def->briefLine(),
+ m_cache.brief.reset(new TemplateVariant(parseDoc(m_def,m_def->briefFile(),m_def->briefLine(),
relPathAsString(),m_def->briefDescription(),TRUE)));
}
else
{
- m_brief.reset(new TemplateVariant(""));
+ m_cache.brief.reset(new TemplateVariant(""));
}
}
- return *m_brief;
+ return *m_cache.brief;
}
TemplateVariant dynSectionId() const
{
@@ -761,11 +855,29 @@ class DefinitionContext : public PropertyMapper
}
return result;
}
+ TemplateVariant sourceDef() const
+ {
+ if (m_sourceDef.count()==2)
+ {
+ return &m_sourceDef;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
private:
Definition *m_def;
- mutable ScopedPtr<TemplateVariant> m_details;
- mutable ScopedPtr<TemplateVariant> m_brief;
+ struct Cachable
+ {
+ ScopedPtr<TemplateVariant> details;
+ ScopedPtr<TemplateVariant> brief;
+ };
+ mutable Cachable m_cache;
+ TemplateList m_sourceDef;
+ TemplateStruct m_fileLink;
+ TemplateStruct m_lineLink;
};
//%% }
@@ -889,10 +1001,19 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
addProperty("properties", this,&Private::properties);
addProperty("events", this,&Private::events);
addProperty("friends", this,&Private::friends);
- addProperty("related", this,&Private::related);
+ addProperty("relatedDecls", this,&Private::relatedDecls);
+
+ addProperty("typedefs", this,&Private::typedefs);
+ addProperty("methods", this,&Private::methods);
+ addProperty("relatedDefs", this,&Private::relatedDefs);
+
addProperty("nestedClasses", this,&Private::nestedClasses);
addProperty("compoundType", this,&Private::compoundType);
addProperty("templateDecls", this,&Private::templateDecls);
+ addProperty("typeConstraints", this,&Private::typeConstraints);
+ addProperty("examples", this,&Private::examples);
+ addProperty("allMembersList", this,&Private::allMembersList);
+ addProperty("allMembersFileName", this,&Private::allMembersFileName);
}
TemplateVariant title() const
{
@@ -1185,11 +1306,23 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
}
TemplateVariant friends() const
{
- return getMemberList(m_cache.events,MemberListType_friends,theTranslator->trFriends());
+ return getMemberList(m_cache.friends,MemberListType_friends,theTranslator->trFriends());
}
- TemplateVariant related() const
+ TemplateVariant relatedDecls() const
{
- return getMemberList(m_cache.events,MemberListType_related,theTranslator->trRelatedFunctions());
+ return getMemberList(m_cache.relatedDecls,MemberListType_related,theTranslator->trRelatedFunctions());
+ }
+ TemplateVariant typedefs() const
+ {
+ return getMemberList(m_cache.typedefs,MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation());
+ }
+ TemplateVariant methods() const
+ {
+ return getMemberList(m_cache.methods,MemberListType_functionMembers,theTranslator->trMemberFunctionDocumentation());
+ }
+ TemplateVariant relatedDefs() const
+ {
+ return getMemberList(m_cache.relatedDefs,MemberListType_relatedMembers,theTranslator->trRelatedFunctionDocumentation());
}
TemplateVariant nestedClasses() const
{
@@ -1243,7 +1376,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
ClassDef *cd=(ClassDef *)d;
if (cd->templateArguments())
{
- ArgumentListContext *al = new ArgumentListContext(cd->templateArguments());
+ ArgumentListContext *al = new ArgumentListContext(cd->templateArguments(),cd,relPathAsString());
// since a TemplateVariant does take ownership of the object, we add it
// a separate list just to be able to delete it and avoid a memory leak
m_cache.templateArgList.append(al);
@@ -1251,6 +1384,24 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
}
}
}
+ void addExamples(TemplateList *list) const
+ {
+ if (m_classDef->hasExamples())
+ {
+ ExampleSDict::Iterator it(*m_classDef->exampleList());
+ Example *ex;
+ for (it.toFirst();(ex=it.current());++it)
+ {
+ TemplateStruct *s = new TemplateStruct;
+ m_cache.exampleList.append(s);
+ s->set("text",ex->name);
+ s->set("isLinkable",TRUE);
+ s->set("anchor",ex->anchor);
+ s->set("fileName",ex->file);
+ list->append(s);
+ }
+ }
+ }
TemplateVariant templateDecls() const
{
if (!m_cache.templateDecls)
@@ -1268,6 +1419,58 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
return TemplateVariant(FALSE);
}
}
+ TemplateVariant typeConstraints() const
+ {
+ if (!m_cache.typeConstraints && m_classDef->typeConstraints())
+ {
+ m_cache.typeConstraints.reset(new ArgumentListContext(m_classDef->typeConstraints(),m_classDef,relPathAsString()));
+ }
+ if (m_cache.typeConstraints)
+ {
+ return m_cache.typeConstraints.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant examples() const
+ {
+ if (!m_cache.examples)
+ {
+ TemplateList *exampleList = new TemplateList;
+ addExamples(exampleList);
+ m_cache.examples.reset(exampleList);
+ }
+ if (m_cache.examples)
+ {
+ return m_cache.examples.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant allMembersList() const
+ {
+ if (!m_cache.allMembersList && m_classDef->memberNameInfoSDict())
+ {
+ AllMembersListContext *ml = new AllMembersListContext(m_classDef->memberNameInfoSDict());
+ m_cache.allMembersList.reset(ml);
+ }
+ if (m_cache.allMembersList)
+ {
+ return m_cache.allMembersList.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant allMembersFileName() const
+ {
+ return m_classDef->getMemberListFileName();
+ }
private:
ClassDef *m_classDef;
@@ -1275,7 +1478,11 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
IncludeInfoContext m_includeInfo;
struct Cachable
{
- Cachable() : inheritanceNodes(-1) { templateArgList.setAutoDelete(TRUE); }
+ Cachable() : inheritanceNodes(-1)
+ {
+ templateArgList.setAutoDelete(TRUE);
+ exampleList.setAutoDelete(TRUE);
+ }
ScopedPtr<InheritanceListContext> inheritsList;
ScopedPtr<InheritanceListContext> inheritedByList;
ScopedPtr<DotClassGraph> classGraph;
@@ -1310,10 +1517,17 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
ScopedPtr<MemberListInfoContext> properties;
ScopedPtr<MemberListInfoContext> events;
ScopedPtr<MemberListInfoContext> friends;
- ScopedPtr<MemberListInfoContext> related;
- ScopedPtr<TemplateList> templateDecls;
- int inheritanceNodes;
+ ScopedPtr<MemberListInfoContext> relatedDecls;
+ ScopedPtr<MemberListInfoContext> typedefs;
+ ScopedPtr<MemberListInfoContext> methods;
+ ScopedPtr<MemberListInfoContext> relatedDefs;
+ ScopedPtr<AllMembersListContext> allMembersList;
+ ScopedPtr<ArgumentListContext> typeConstraints;
+ ScopedPtr<TemplateList> examples;
+ ScopedPtr<TemplateList> templateDecls;
QList<ArgumentListContext> templateArgList;
+ int inheritanceNodes;
+ QList<TemplateStruct> exampleList;
};
mutable Cachable m_cache;
};
@@ -1645,23 +1859,39 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
public:
Private(MemberDef *md) : DefinitionContext(md) , m_memberDef(md)
{
- addProperty("declType", this,&Private::declType);
- addProperty("declArgs", this,&Private::declArgs);
- addProperty("isStatic", this,&Private::isStatic);
- addProperty("isObjCMethod", this,&Private::isObjCMethod);
- addProperty("isObjCProperty", this,&Private::isObjCProperty);
- addProperty("isImplementation", this,&Private::isImplementation);
- addProperty("isEvent", this,&Private::isEvent);
- addProperty("isProperty", this,&Private::isProperty);
- addProperty("hasDetails", this,&Private::hasDetails);
- addProperty("exception", this,&Private::exception);
- addProperty("bitfields", this,&Private::bitfields);
- addProperty("initializer", this,&Private::initializer);
- addProperty("oneLineInitializer",this,&Private::oneLineInitializer);
- addProperty("templateArgs", this,&Private::templateArgs);
- addProperty("templateAlias", this,&Private::templateAlias);
- addProperty("propertyAttrs", this,&Private::propertyAttrs);
- addProperty("eventAttrs", this,&Private::eventAttrs);
+ addProperty("declType", this,&Private::declType);
+ addProperty("declArgs", this,&Private::declArgs);
+ addProperty("isStatic", this,&Private::isStatic);
+ addProperty("isObjCMethod", this,&Private::isObjCMethod);
+ addProperty("isObjCProperty", this,&Private::isObjCProperty);
+ addProperty("isDefine", this,&Private::isDefine);
+ addProperty("isImplementation", this,&Private::isImplementation);
+ addProperty("isEvent", this,&Private::isEvent);
+ addProperty("isProperty", this,&Private::isProperty);
+ addProperty("isEnumeration", this,&Private::isEnumeration);
+ addProperty("isEnumValue", this,&Private::isEnumValue);
+ addProperty("isAnonymous", this,&Private::isAnonymous);
+ addProperty("hasDetails", this,&Private::hasDetails);
+ addProperty("exception", this,&Private::exception);
+ addProperty("bitfields", this,&Private::bitfields);
+ addProperty("initializer", this,&Private::initializer);
+ addProperty("oneLineInitializer", this,&Private::oneLineInitializer);
+ addProperty("templateArgs", this,&Private::templateArgs);
+ addProperty("templateAlias", this,&Private::templateAlias);
+ addProperty("propertyAttrs", this,&Private::propertyAttrs);
+ addProperty("eventAttrs", this,&Private::eventAttrs);
+ addProperty("class", this,&Private::getClass);
+ addProperty("definition", this,&Private::definition);
+ addProperty("parameters", this,&Private::parameters);
+ addProperty("hasParameterList", this,&Private::hasParameterList);
+ addProperty("hasConstQualifier", this,&Private::hasConstQualifier);
+ addProperty("hasVolatileQualifier",this,&Private::hasVolatileQualifier);
+ addProperty("trailingReturnType", this,&Private::trailingReturnType);
+ addProperty("extraTypeChars", this,&Private::extraTypeChars);
+ addProperty("templateDecls", this,&Private::templateDecls);
+ addProperty("labels", this,&Private::labels);
+ addProperty("enumBaseType", this,&Private::enumBaseType);
+ addProperty("enumValues", this,&Private::enumValues);
if (md && md->isProperty())
{
@@ -1715,25 +1945,65 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
{
return m_memberDef->isProperty();
}
+ TemplateVariant isEnumValue() const
+ {
+ return m_memberDef->isEnumValue();
+ }
+ TemplateVariant isEnumeration() const
+ {
+ return m_memberDef->isEnumerate();
+ }
TemplateVariant hasDetails() const
{
return m_memberDef->isDetailedSectionLinkable();
}
TemplateVariant initializer() const
{
- return m_memberDef->initializer();
+ return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->initializer());
+ }
+ TemplateVariant isDefine() const
+ {
+ return m_memberDef->isDefine();
+ }
+ TemplateVariant isAnonymous() const
+ {
+ QCString name = m_memberDef->name();
+ return !name.isEmpty() && name.at(0)=='@';
+ }
+ TemplateVariant enumBaseType() const
+ {
+ return m_memberDef->enumBaseType();
}
TemplateVariant oneLineInitializer() const
{
return m_memberDef->hasOneLineInitializer();
}
+ TemplateVariant enumValues() const
+ {
+ if (!m_cache.enumValues)
+ {
+ MemberList *ml = m_memberDef->enumFieldList();
+ if (ml)
+ {
+ m_cache.enumValues.reset(new MemberListContext(ml));
+ }
+ }
+ if (m_cache.enumValues)
+ {
+ return m_cache.enumValues.get();
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
TemplateVariant templateArgs() const
{
- if (!m_templateArgs)
+ if (!m_cache.templateArgs)
{
- m_templateArgs.reset(new ArgumentListContext(m_memberDef->templateArguments()));
+ m_cache.templateArgs.reset(new ArgumentListContext(m_memberDef->templateArguments(),m_memberDef,relPathAsString()));
}
- return m_templateArgs.get();
+ return m_cache.templateArgs.get();
}
TemplateVariant templateAlias() const
{
@@ -1752,9 +2022,188 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
{
return &m_eventAttrs;
}
+ TemplateVariant getClass() const
+ {
+ if (!m_cache.classDef && m_memberDef->getClassDef())
+ {
+ m_cache.classDef.reset(new ClassContext(m_memberDef->getClassDef()));
+ }
+ if (m_cache.classDef)
+ {
+ return m_cache.classDef.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant definition() const
+ {
+ return createLinkedText(m_memberDef,relPathAsString(),
+ m_memberDef->displayDefinition());
+ }
+ ArgumentList *getDefArgList() const
+ {
+ return (m_memberDef->isDocsForDefinition()) ?
+ m_memberDef->argumentList() : m_memberDef->declArgumentList();
+ }
+ TemplateVariant parameters() const
+ {
+ if (!m_cache.arguments)
+ {
+ ArgumentList *defArgList = getDefArgList();
+ if (defArgList && !m_memberDef->isProperty())
+ {
+ m_cache.arguments.reset(new ArgumentListContext(defArgList,m_memberDef,relPathAsString()));
+ }
+ }
+ if (m_cache.arguments)
+ {
+ return m_cache.arguments.get();
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ TemplateVariant hasParameterList() const
+ {
+ return getDefArgList()!=0;
+ }
+ TemplateVariant hasConstQualifier() const
+ {
+ ArgumentList *al = getDefArgList();
+ return al ? al->constSpecifier : FALSE;
+ }
+ TemplateVariant hasVolatileQualifier() const
+ {
+ ArgumentList *al = getDefArgList();
+ return al ? al->volatileSpecifier : FALSE;
+ }
+ TemplateVariant trailingReturnType() const
+ {
+ ArgumentList *al = getDefArgList();
+ if (al && !al->trailingReturnType.isEmpty())
+ {
+ return createLinkedText(m_memberDef,relPathAsString(),
+ al->trailingReturnType);
+ }
+ else
+ {
+ return "";
+ }
+ }
+ TemplateVariant extraTypeChars() const
+ {
+ return m_memberDef->extraTypeChars();
+ }
+ void addTemplateDecls(TemplateList *tl) const
+ {
+ ClassDef *cd=m_memberDef->getClassDef();
+ if (m_memberDef->definitionTemplateParameterLists())
+ {
+ QListIterator<ArgumentList> ali(*m_memberDef->definitionTemplateParameterLists());
+ ArgumentList *tal;
+ for (ali.toFirst();(tal=ali.current());++ali)
+ {
+ if (tal->count()>0)
+ {
+ ArgumentListContext *al = new ArgumentListContext(tal,m_memberDef,relPathAsString());
+ // since a TemplateVariant does take ownership of the object, we add it
+ // a separate list just to be able to delete it and avoid a memory leak
+ m_cache.templateArgList.append(al);
+ tl->append(al);
+ }
+ }
+ }
+ else
+ {
+ if (cd && !m_memberDef->isTemplateSpecialization())
+ {
+ QList<ArgumentList> tempParamLists;
+ cd->getTemplateParameterLists(tempParamLists);
+ //printf("#tempParamLists=%d\n",tempParamLists.count());
+ QListIterator<ArgumentList> ali(tempParamLists);
+ ArgumentList *tal;
+ for (ali.toFirst();(tal=ali.current());++ali)
+ {
+ if (tal->count()>0)
+ {
+ ArgumentListContext *al = new ArgumentListContext(tal,m_memberDef,relPathAsString());
+ // since a TemplateVariant does take ownership of the object, we add it
+ // a separate list just to be able to delete it and avoid a memory leak
+ m_cache.templateArgList.append(al);
+ tl->append(al);
+ }
+ }
+ }
+ if (m_memberDef->templateArguments()) // function template prefix
+ {
+ ArgumentListContext *al = new ArgumentListContext(
+ m_memberDef->templateArguments(),m_memberDef,relPathAsString());
+ // since a TemplateVariant does take ownership of the object, we add it
+ // a separate list just to be able to delete it and avoid a memory leak
+ m_cache.templateArgList.append(al);
+ tl->append(al);
+ }
+ }
+ }
+ TemplateVariant templateDecls() const
+ {
+ if (!m_cache.templateDecls)
+ {
+ TemplateList *tl = new TemplateList;
+ addTemplateDecls(tl);
+ m_cache.templateDecls.reset(tl);
+ }
+ if (m_cache.templateDecls)
+ {
+ return m_cache.templateDecls.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ TemplateVariant labels() const
+ {
+ if (!m_cache.labels)
+ {
+ QStrList sl;
+ m_memberDef->getLabels(sl,m_memberDef->getOuterScope());
+ if (sl.count()>0)
+ {
+ TemplateList *tl = new TemplateList;
+ QStrListIterator it(sl);
+ for (;it.current();++it)
+ {
+ tl->append(*it);
+ }
+ m_cache.labels.reset(tl);
+ }
+ }
+ if (m_cache.labels)
+ {
+ return m_cache.labels.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
private:
MemberDef *m_memberDef;
- mutable ScopedPtr<ArgumentListContext> m_templateArgs;
+ struct Cachable
+ {
+ ScopedPtr<ArgumentListContext> templateArgs;
+ ScopedPtr<ArgumentListContext> arguments;
+ ScopedPtr<MemberListContext> enumValues;
+ ScopedPtr<ClassContext> classDef;
+ ScopedPtr<TemplateList> templateDecls;
+ QList<ArgumentListContext> templateArgList;
+ ScopedPtr<TemplateList> labels;
+ };
+ mutable Cachable m_cache;
TemplateList m_propertyAttrs;
TemplateList m_eventAttrs;
};
@@ -3543,7 +3992,6 @@ TemplateListIntf::ConstIterator *InheritanceListContext::createIterator() const
return p->createIterator();
}
-
//------------------------------------------------------------------------
//%% list MemberList[Member] : list of inherited classes
@@ -3596,6 +4044,148 @@ TemplateListIntf::ConstIterator *MemberListContext::createIterator() const
//------------------------------------------------------------------------
+//%% struct MemberInfo: member information
+//%% {
+class MemberInfoContext::Private : public PropertyMapper
+{
+ public:
+ Private(const MemberInfo *mi) : m_memberInfo(mi)
+ {
+ //%% string protection
+ addProperty("protection",this,&Private::protection);
+ //%% string virtualness
+ addProperty("virtualness",this,&Private::virtualness);
+ //%% string ambiguityScope
+ addProperty("ambiguityScope",this,&Private::ambiguityScope);
+ //%% Member member
+ addProperty("member",this,&Private::member);
+ }
+ TemplateVariant protection() const
+ {
+ switch (m_memberInfo->prot)
+ {
+ case ::Public: return "public";
+ case ::Protected: return "protected";
+ case ::Private: return "private";
+ case ::Package: return "package";
+ }
+ }
+ TemplateVariant virtualness() const
+ {
+ switch (m_memberInfo->virt)
+ {
+ case ::Normal: return "normal";
+ case ::Virtual: return "virtual";
+ case ::Pure: return "pure";
+ }
+ }
+ TemplateVariant ambiguityScope() const
+ {
+ return m_memberInfo->ambiguityResolutionScope;
+ }
+ TemplateVariant member() const
+ {
+ if (!m_member && m_memberInfo->memberDef)
+ {
+ m_member.reset(new MemberContext(m_memberInfo->memberDef));
+ }
+ if (m_member)
+ {
+ return m_member.get();
+ }
+ else
+ {
+ return TemplateVariant(FALSE);
+ }
+ }
+ private:
+ const MemberInfo *m_memberInfo;
+ mutable ScopedPtr<MemberContext> m_member;
+};
+//%% }
+
+MemberInfoContext::MemberInfoContext(const MemberInfo *mi)
+{
+ p = new Private(mi);
+}
+
+MemberInfoContext::~MemberInfoContext()
+{
+ delete p;
+}
+
+TemplateVariant MemberInfoContext::get(const char *name) const
+{
+ return p->get(name);
+}
+
+
+//------------------------------------------------------------------------
+
+//%% list AllMembersList[MemberList] : list of inherited classes
+class AllMembersListContext::Private : public GenericNodeListContext<MemberInfoContext>
+{
+ public:
+ Private(const MemberNameInfoSDict *ml)
+ {
+ if (ml)
+ {
+ static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
+ MemberNameInfoSDict::Iterator mnii(*ml);
+ MemberNameInfo *mni;
+ for (mnii.toFirst();(mni=mnii.current());++mnii)
+ {
+ MemberNameInfoIterator mnii2(*mni);
+ MemberInfo *mi;
+ for (mnii2.toFirst();(mi=mnii2.current());++mnii2)
+ {
+ MemberDef *md=mi->memberDef;
+ ClassDef *cd=md->getClassDef();
+ if (cd && !md->name().isEmpty() && md->name()[0]!='@')
+ {
+ if ((cd->isLinkable() && md->isLinkable()) ||
+ (!cd->isArtificial() && !hideUndocMembers &&
+ (protectionLevelVisible(md->protection()) || md->isFriend())
+ )
+ )
+ {
+ append(new MemberInfoContext(mi));
+ }
+ }
+ }
+ }
+ }
+ }
+};
+
+AllMembersListContext::AllMembersListContext(const MemberNameInfoSDict *ml)
+{
+ p = new Private(ml);
+}
+
+AllMembersListContext::~AllMembersListContext()
+{
+ delete p;
+}
+
+// TemplateListIntf
+int AllMembersListContext::count() const
+{
+ return p->count();
+}
+
+TemplateVariant AllMembersListContext::at(int index) const
+{
+ return p->at(index);
+}
+
+TemplateListIntf::ConstIterator *AllMembersListContext::createIterator() const
+{
+ return p->createIterator();
+}
+
+//------------------------------------------------------------------------
+
//%% struct MemberListInfo: member list information
//%% {
class MemberListInfoContext::Private : public PropertyMapper
@@ -3652,21 +4242,29 @@ TemplateVariant MemberListInfoContext::get(const char *name) const
//------------------------------------------------------------------------
-//%% struct Argument: member list information
+//%% struct Argument: parameter information
//%% {
class ArgumentContext::Private : public PropertyMapper
{
public:
- Private(const Argument *arg) :
- m_argument(arg)
+ Private(const Argument *arg,Definition *def,const QCString &relPath) :
+ m_argument(arg), m_def(def), m_relPath(relPath)
{
- addProperty("type", this,&Private::type);
- addProperty("name", this,&Private::name);
- addProperty("defVal",this,&Private::defVal);
+ addProperty("type", this,&Private::type);
+ addProperty("name", this,&Private::name);
+ addProperty("defVal", this,&Private::defVal);
+ addProperty("docs", this,&Private::docs);
+ addProperty("attrib", this,&Private::attrib);
+ addProperty("array", this,&Private::array);
+ addProperty("namePart", this,&Private::namePart);
}
TemplateVariant type() const
{
- return m_argument->type;
+ return createLinkedText(m_def,m_relPath,m_argument->type);
+ }
+ TemplateVariant attrib() const
+ {
+ return m_argument->attrib;
}
TemplateVariant name() const
{
@@ -3674,16 +4272,55 @@ class ArgumentContext::Private : public PropertyMapper
}
TemplateVariant defVal() const
{
- return m_argument->defval;
+ return createLinkedText(m_def,m_relPath,m_argument->defval);
+ }
+ TemplateVariant array() const
+ {
+ return m_argument->array;
+ }
+ TemplateVariant docs() const
+ {
+ if (!m_cache.docs && m_def)
+ {
+ if (!m_argument->docs.isEmpty())
+ {
+ m_cache.docs.reset(new TemplateVariant(
+ parseDoc(m_def,m_def->docFile(),m_def->docLine(),
+ m_relPath,m_argument->docs,TRUE)));
+ }
+ else
+ {
+ m_cache.docs.reset(new TemplateVariant(""));
+ }
+ }
+ return *m_cache.docs;
+ }
+ TemplateVariant namePart() const
+ {
+ QCString result = m_argument->attrib;
+ int l = result.length();
+ if (l>2 && result.at(0)=='[' && result.at(l-1)==']')
+ {
+ result = result.mid(1,l-2);
+ if (result!=",") result+=":"; // for normal keywords add colon
+ }
+ return result;
}
private:
const Argument *m_argument;
+ Definition *m_def;
+ QCString m_relPath;
+ struct Cachable
+ {
+ ScopedPtr<TemplateVariant> docs;
+ };
+ mutable Cachable m_cache;
};
//%% }
-ArgumentContext::ArgumentContext(const Argument *al)
+ArgumentContext::ArgumentContext(const Argument *al,Definition *def,const QCString &relPath)
{
- p = new Private(al);
+ p = new Private(al,def,relPath);
}
ArgumentContext::~ArgumentContext()
@@ -3702,13 +4339,14 @@ TemplateVariant ArgumentContext::get(const char *name) const
class ArgumentListContext::Private : public GenericNodeListContext<ArgumentContext>
{
public:
- void addArgument(const Argument *arg)
+ void addArgument(const Argument *arg,Definition *def,const QCString &relPath)
{
- append(new ArgumentContext(arg));
+ append(new ArgumentContext(arg,def,relPath));
}
};
-ArgumentListContext::ArgumentListContext(const ArgumentList *list)
+ArgumentListContext::ArgumentListContext(const ArgumentList *list,
+ Definition *def,const QCString &relPath)
{
p = new Private;
if (list)
@@ -3717,7 +4355,7 @@ ArgumentListContext::ArgumentListContext(const ArgumentList *list)
const Argument *arg;
for (ali.toFirst();(arg=ali.current());++ali)
{
- p->addArgument(arg);
+ p->addArgument(arg,def,relPath);
}
}
}
@@ -3796,16 +4434,17 @@ class HtmlSpaceless : public TemplateSpacelessIntf
result+=c;
break;
case ' ': case '\t': case '\n': // whitespace
- if (!m_removeSpaces)
- {
- result+=' ';
- }
if (!m_insideTag) // outside tags strip consecutive whitespace
{
m_removeSpaces=TRUE;
}
+ else
+ {
+ result+=' ';
+ }
break;
default:
+ //if (m_removeSpaces) result+=' ';
result+=c;
m_removeSpaces=FALSE;
break;
diff --git a/src/context.h b/src/context.h
index d99eeac..75f1579 100644
--- a/src/context.h
+++ b/src/context.h
@@ -28,6 +28,8 @@ class MemberList;
class MemberDef;
struct Argument;
class ArgumentList;
+class MemberNameInfoSDict;
+struct MemberInfo;
//----------------------------------------------------
@@ -679,10 +681,44 @@ class MemberListInfoContext : public TemplateStructIntf
//----------------------------------------------------
+class MemberInfoContext : public TemplateStructIntf
+{
+ public:
+ MemberInfoContext(const MemberInfo *mi);
+ ~MemberInfoContext();
+
+ // TemplateStructIntf methods
+ virtual TemplateVariant get(const char *name) const;
+
+ private:
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
+class AllMembersListContext : public TemplateListIntf
+{
+ public:
+ AllMembersListContext(const MemberNameInfoSDict *ml);
+ ~AllMembersListContext();
+
+ // TemplateListIntf
+ virtual int count() const;
+ virtual TemplateVariant at(int index) const;
+ virtual TemplateListIntf::ConstIterator *createIterator() const;
+
+ private:
+ class Private;
+ Private *p;
+};
+
+//----------------------------------------------------
+
class ArgumentContext : public TemplateStructIntf
{
public:
- ArgumentContext(const Argument *arg);
+ ArgumentContext(const Argument *arg,Definition *def,const QCString &relPath);
~ArgumentContext();
// TemplateStructIntf methods
@@ -698,7 +734,7 @@ class ArgumentContext : public TemplateStructIntf
class ArgumentListContext : public TemplateListIntf
{
public:
- ArgumentListContext(const ArgumentList *al);
+ ArgumentListContext(const ArgumentList *al,Definition *def,const QCString &relPath);
~ArgumentListContext();
// TemplateListIntf
diff --git a/src/definition.cpp b/src/definition.cpp
index 93b55ab..2c05f29 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -959,7 +959,7 @@ void Definition::writeSourceDef(OutputList &ol,const char *)
{
ol.disable(OutputGenerator::Latex);
}
- // write line link (HTML, LaTeX optionally)
+ // write file link (HTML, LaTeX optionally)
ol.writeObjectLink(0,fn,0,m_impl->body->fileDef->name());
ol.enableAll();
ol.disable(OutputGenerator::Html);
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 8aa89be..920c199 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -3279,7 +3279,7 @@ void HtmlGenerator::writeExternalSearchPage()
void HtmlGenerator::startConstraintList(const char *header)
{
t << "<div class=\"typeconstraint\">" << endl;
- t << "<dl><dt><b>" << header << "</b><dt><dd>" << endl;
+ t << "<dl><dt><b>" << header << "</b></dt><dd>" << endl;
t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">" << endl;
}
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index 10c5b29..2059341 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -128,7 +128,6 @@ static bool writeDefArgumentList(OutputList &ol,ClassDef *cd,
{
return FALSE; // member has no function like argument list
}
- if (!md->isDefine()) ol.docify(" ");
// simple argument list for tcl
if (md->getLanguage()==SrcLangExt_Tcl)
@@ -156,6 +155,8 @@ static bool writeDefArgumentList(OutputList &ol,ClassDef *cd,
return TRUE;
}
+ if (!md->isDefine()) ol.docify(" ");
+
//printf("writeDefArgList(%d)\n",defArgList->count());
ol.pushGeneratorState();
//ol.disableAllBut(OutputGenerator::Html);
@@ -262,7 +263,7 @@ static bool writeDefArgumentList(OutputList &ol,ClassDef *cd,
{
ol.docify(a->type.mid(wp,vp-wp));
}
- if (!a->name.isEmpty() || (a->name.isEmpty() && a->type=="...")) // argument has a name
+ if (!a->name.isEmpty() || a->type=="...") // argument has a name
{
//if (!hasFuncPtrType)
//{
@@ -809,7 +810,7 @@ MemberDef *MemberDef::deepCopy() const
}
if (m_impl->enumFields)
{
- MemberListIterator mli(*m_impl->redefinedBy);
+ MemberListIterator mli(*m_impl->enumFields);
MemberDef *md;
for (mli.toFirst();(md=mli.current());++mli)
{
@@ -1925,7 +1926,7 @@ bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const
return result;
}
-void MemberDef::_getLabels(QStrList &sl,Definition *container) const
+void MemberDef::getLabels(QStrList &sl,Definition *container) const
{
static bool inlineInfo = Config_getBool("INLINE_INFO");
@@ -2382,6 +2383,110 @@ void MemberDef::_writeEnumValues(OutputList &ol,Definition *container,
}
}
+QCString MemberDef::displayDefinition() const
+{
+ QCString ldef = definition();
+ QCString title = name();
+ if (isEnumerate())
+ {
+ if (title.at(0)=='@')
+ {
+ ldef = title = "anonymous enum";
+ if (!m_impl->enumBaseType.isEmpty())
+ {
+ ldef+=" : "+m_impl->enumBaseType;
+ }
+ }
+ else
+ {
+ ldef.prepend("enum ");
+ }
+ }
+ else if (isEnumValue())
+ {
+ if (ldef.at(0)=='@')
+ {
+ ldef=ldef.mid(2);
+ }
+ }
+ ClassDef *cd=getClassDef();
+ if (cd && cd->isObjectiveC())
+ {
+ // strip scope name
+ int ep = ldef.find("::");
+ if (ep!=-1)
+ {
+ int sp=ldef.findRev(' ',ep);
+ if (sp!=-1)
+ {
+ ldef=ldef.left(sp+1)+ldef.mid(ep+2);
+ }
+ }
+ // strip keywords
+ int dp = ldef.find(':');
+ if (dp!=-1)
+ {
+ ldef=ldef.left(dp+1);
+ }
+ int l=ldef.length();
+ //printf("start >%s<\n",ldef.data());
+ int i=l-1;
+ while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
+ while (i>=0 && isspace((uchar)ldef.at(i))) i--;
+ if (i>0)
+ {
+ // insert braches around the type
+ QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
+ ldef=tmp;
+ }
+ //printf("end >%s< i=%d\n",ldef.data(),i);
+ if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
+ }
+ SrcLangExt lang = getLanguage();
+ QCString sep = getLanguageSpecificSeparator(lang,TRUE);
+ return substitute(ldef,"::",sep);
+}
+
+void MemberDef::_writeGroupInclude(OutputList &ol,bool inGroup)
+{
+ // only write out the include file if this is not part of a class or file
+ // definition
+ static bool showGroupedMembInc = Config_getBool("SHOW_GROUPED_MEMB_INC");
+ FileDef *fd = getFileDef();
+ QCString nm;
+ if (fd) nm = getFileDef()->docName();
+ if (inGroup && fd && showGroupedMembInc && !nm.isEmpty())
+ {
+ ol.startParagraph();
+ ol.startTypewriter();
+ SrcLangExt lang = getLanguage();
+ bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
+ if (isIDLorJava)
+ {
+ ol.docify("import ");
+ }
+ else
+ {
+ ol.docify("#include ");
+ }
+
+ if (isIDLorJava) ol.docify("\""); else ol.docify("<");
+
+ if (fd && fd->isLinkable())
+ {
+ ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),fd->anchor(),nm);
+ }
+ else
+ {
+ ol.docify(nm);
+ }
+
+ if (isIDLorJava) ol.docify("\""); else ol.docify(">");
+
+ ol.endTypewriter();
+ ol.endParagraph();
+ }
+}
/*! Writes the "detailed documentation" section of this member to
* all active output formats.
@@ -2473,7 +2578,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
bool htmlEndLabelTable=FALSE;
QStrList sl;
- _getLabels(sl,container);
+ getLabels(sl,container);
if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
{
@@ -2711,6 +2816,8 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
ol.endDoxyAnchor(cfname,memAnchor);
ol.startIndent();
+ _writeGroupInclude(ol,inGroup);
+
/* write multi-line initializer (if any) */
if (hasMultiLineInitializer()
//initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
diff --git a/src/memberdef.h b/src/memberdef.h
index bb6fb0e..aa17798 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -75,6 +75,7 @@ class MemberDef : public Definition
int initializerLines() const;
uint64 getMemberSpecifiers() const;
MemberList *getSectionList(Definition *d) const;
+ QCString displayDefinition() const;
// scope query members
ClassDef *getClassDef() const;
@@ -242,6 +243,7 @@ class MemberDef : public Definition
QCString displayName(bool=TRUE) const;
QCString getDeclType() const;
+ void getLabels(QStrList &sl,Definition *container) const;
//-----------------------------------------------------------------------------------
// ---- setters -----
@@ -384,7 +386,7 @@ class MemberDef : public Definition
void _computeLinkableInProject();
void _computeIsConstructor();
void _computeIsDestructor();
- void _getLabels(QStrList &sl,Definition *container) const;
+ void _writeGroupInclude(OutputList &ol,bool inGroup);
void _writeCallGraph(OutputList &ol);
void _writeCallerGraph(OutputList &ol);
void _writeReimplements(OutputList &ol);
diff --git a/src/template.cpp b/src/template.cpp
index bc564cc..e3eecf9 100644
--- a/src/template.cpp
+++ b/src/template.cpp
@@ -250,7 +250,7 @@ bool TemplateVariant::toBool() const
result = p->intVal!=0;
break;
case String:
- result = !p->strVal.isEmpty() && p->strVal!="false" && p->strVal!="0";
+ result = !p->strVal.isEmpty(); // && p->strVal!="false" && p->strVal!="0";
break;
case Struct:
result = TRUE;
@@ -758,6 +758,31 @@ class FilterNoWrap
}
};
+//--------------------------------------------------------------------
+
+/** @brief The implementation of the "divisibleby" filter */
+class FilterDivisibleBy
+{
+ public:
+ static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &n)
+ {
+ printf("FilterDivisibleBy::apply()\n");
+ if (!v.isValid() || !n.isValid())
+ {
+ return TemplateVariant();
+ }
+ if (v.type()==TemplateVariant::Integer && n.type()==TemplateVariant::Integer)
+ {
+ printf("FilterDivisibleBy(%d,%d)=%d",v.toInt(),n.toInt(),(v.toInt()%n.toInt())==0);
+ return TemplateVariant((v.toInt()%n.toInt())==0);
+ }
+ else
+ {
+ return TemplateVariant();
+ }
+ }
+};
+
//--------------------------------------------------------------------
@@ -809,12 +834,14 @@ class TemplateFilterFactory
};
// register a handlers for each filter we support
-static TemplateFilterFactory::AutoRegister<FilterAdd> fAdd("add");
-static TemplateFilterFactory::AutoRegister<FilterPrepend> fPrepend("prepend");
-static TemplateFilterFactory::AutoRegister<FilterLength> fLength("length");
-static TemplateFilterFactory::AutoRegister<FilterDefault> fDefault("default");
-static TemplateFilterFactory::AutoRegister<FilterStripPath> fStripPath("stripPath");
-static TemplateFilterFactory::AutoRegister<FilterNoWrap> fNoWrap("nowrap");
+static TemplateFilterFactory::AutoRegister<FilterAdd> fAdd("add");
+static TemplateFilterFactory::AutoRegister<FilterAdd> fAppend("append");
+static TemplateFilterFactory::AutoRegister<FilterLength> fLength("length");
+static TemplateFilterFactory::AutoRegister<FilterNoWrap> fNoWrap("nowrap");
+static TemplateFilterFactory::AutoRegister<FilterDefault> fDefault("default");
+static TemplateFilterFactory::AutoRegister<FilterPrepend> fPrepend("prepend");
+static TemplateFilterFactory::AutoRegister<FilterStripPath> fStripPath("stripPath");
+static TemplateFilterFactory::AutoRegister<FilterDivisibleBy> fDivisibleBy("divisibleby");
//--------------------------------------------------------------------
@@ -1404,6 +1431,16 @@ class ExpressionParser
m_curToken.id+=s;
p++;
}
+ if (m_curToken.id=="True") // treat true literal as numerical 1
+ {
+ m_curToken.type = ExprToken::Number;
+ m_curToken.num = 1;
+ }
+ else if (m_curToken.id=="False") // treat false literal as numerical 0
+ {
+ m_curToken.type = ExprToken::Number;
+ m_curToken.num = 0;
+ }
}
else if (c=='"' || c=='\'')
{
@@ -2066,7 +2103,7 @@ class TemplateNodeBlock : public TemplateNodeCreator<TemplateNodeBlock>
}
// add 'block.super' variable to allow access to parent block content
TemplateStruct superBlock;
- superBlock.set("super",super.data());
+ superBlock.set("super",TemplateVariant(super.data(),TRUE));
ci->set("block",&superBlock);
// render the overruled block contents
nb->m_nodes.render(ts,c);
@@ -2495,6 +2532,121 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
//----------------------------------------------------------
+/** @brief Class representing an 'set' tag in a template */
+class TemplateNodeCycle : public TemplateNodeCreator<TemplateNodeCycle>
+{
+ public:
+ TemplateNodeCycle(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeCycle>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeCycle(%s)\n",data.data()));
+ m_args.setAutoDelete(TRUE);
+ m_index=0;
+ ExpressionParser expParser(parser->templateName(),line);
+ QValueList<QCString> args = split(data," ");
+ QValueListIterator<QCString> it = args.begin();
+ while (it!=args.end())
+ {
+ ExprAst *expr = expParser.parsePrimary(*it);
+ if (expr)
+ {
+ m_args.append(expr);
+ }
+ ++it;
+ }
+ if (m_args.count()<2)
+ {
+ warn(parser->templateName(),line,"expected at least two arguments for cycle command, got %d",m_args.count());
+ }
+ TRACE(("}TemplateNodeCycle(%s)\n",data.data()));
+ }
+ void render(FTextStream &ts, TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ if (m_index<m_args.count())
+ {
+ TemplateVariant v = m_args.at(m_index)->resolve(c);
+ if (v.type()==TemplateVariant::Function)
+ {
+ v = v.call(QValueList<TemplateVariant>());
+ }
+ if (ci->escapeIntf() && !v.raw())
+ {
+ ts << ci->escapeIntf()->escape(v.toString());
+ }
+ else
+ {
+ ts << v.toString();
+ }
+ }
+ if (++m_index==m_args.count()) // wrap around
+ {
+ m_index=0;
+ }
+ }
+ private:
+ uint m_index;
+ QList<ExprAst> m_args;
+};
+
+//----------------------------------------------------------
+
+/** @brief Class representing an 'set' tag in a template */
+class TemplateNodeSet : public TemplateNodeCreator<TemplateNodeSet>
+{
+ struct Mapping
+ {
+ Mapping(const QCString &n,ExprAst *e) : name(n), value(e) {}
+ ~Mapping() { delete value; }
+ QCString name;
+ ExprAst *value;
+ };
+ public:
+ TemplateNodeSet(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
+ : TemplateNodeCreator<TemplateNodeSet>(parser,parent,line)
+ {
+ TRACE(("{TemplateNodeSet(%s)\n",data.data()));
+ m_args.setAutoDelete(TRUE);
+ ExpressionParser expParser(parser->templateName(),line);
+ QValueList<QCString> args = split(data," ");
+ QValueListIterator<QCString> it = args.begin();
+ while (it!=args.end())
+ {
+ QCString arg = *it;
+ int j=arg.find('=');
+ if (j>0)
+ {
+ ExprAst *expr = expParser.parsePrimary(arg.mid(j+1));
+ if (expr)
+ {
+ m_args.append(new Mapping(arg.left(j),expr));
+ }
+ }
+ else
+ {
+ warn(parser->templateName(),line,"invalid argument '%s' for with tag",arg.data());
+ }
+ ++it;
+ }
+ TRACE(("}TemplateNodeSet(%s)\n",data.data()));
+ }
+ void render(FTextStream &, TemplateContext *c)
+ {
+ TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
+ QListIterator<Mapping> it(m_args);
+ Mapping *mapping;
+ for (it.toFirst();(mapping=it.current());++it)
+ {
+ TemplateVariant value = mapping->value->resolve(c);
+ ci->set(mapping->name,value);
+ }
+ }
+ private:
+ QList<Mapping> m_args;
+};
+
+//----------------------------------------------------------
+
/** @brief Class representing an 'spaceless' tag in a template */
class TemplateNodeSpaceless : public TemplateNodeCreator<TemplateNodeSpaceless>
{
@@ -2667,9 +2819,11 @@ class TemplateNodeFactory
static TemplateNodeFactory::AutoRegister<TemplateNodeIf> autoRefIf("if");
static TemplateNodeFactory::AutoRegister<TemplateNodeFor> autoRefFor("for");
static TemplateNodeFactory::AutoRegister<TemplateNodeMsg> autoRefMsg("msg");
+static TemplateNodeFactory::AutoRegister<TemplateNodeSet> autoRefSet("set");
static TemplateNodeFactory::AutoRegister<TemplateNodeTree> autoRefTree("recursetree");
static TemplateNodeFactory::AutoRegister<TemplateNodeWith> autoRefWith("with");
static TemplateNodeFactory::AutoRegister<TemplateNodeBlock> autoRefBlock("block");
+static TemplateNodeFactory::AutoRegister<TemplateNodeCycle> autoRefCycle("cycle");
static TemplateNodeFactory::AutoRegister<TemplateNodeExtend> autoRefExtend("extend");
static TemplateNodeFactory::AutoRegister<TemplateNodeCreate> autoRefCreate("create");
static TemplateNodeFactory::AutoRegister<TemplateNodeInclude> autoRefInclude("include");