summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authordimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2001-07-15 17:11:26 (GMT)
committerdimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2001-07-15 17:11:26 (GMT)
commit5346e18047c0e047db2f1b13dc2c767a73c5c305 (patch)
treebc5400211360251f121d60efdd50b09f10db11d2 /src
parentd723d351b1ec59ad9db456f820d59a6e270f21a4 (diff)
downloadDoxygen-5346e18047c0e047db2f1b13dc2c767a73c5c305.zip
Doxygen-5346e18047c0e047db2f1b13dc2c767a73c5c305.tar.gz
Doxygen-5346e18047c0e047db2f1b13dc2c767a73c5c305.tar.bz2
Release-1.2.8-20010715
Diffstat (limited to 'src')
-rw-r--r--src/classdef.cpp281
-rw-r--r--src/classdef.h58
-rw-r--r--src/code.l2
-rw-r--r--src/config.h2
-rw-r--r--src/config.l2
-rw-r--r--src/constexp.h8
-rw-r--r--src/constexp.l36
-rw-r--r--src/constexp.y6
-rw-r--r--src/cppvalue.cpp16
-rw-r--r--src/cppvalue.h14
-rw-r--r--src/declinfo.l2
-rw-r--r--src/defargs.l2
-rw-r--r--src/definition.cpp6
-rw-r--r--src/definition.h6
-rw-r--r--src/doc.l4
-rw-r--r--src/dot.cpp158
-rw-r--r--src/dot.h2
-rw-r--r--src/doxygen.cpp707
-rw-r--r--src/doxygen.h2
-rw-r--r--src/filedef.h4
-rw-r--r--src/ftvhelp.cpp5
-rw-r--r--src/groupdef.h4
-rw-r--r--src/htmlgen.cpp29
-rw-r--r--src/index.cpp66
-rw-r--r--src/libdoxygen.pro.in1
-rw-r--r--src/memberdef.cpp70
-rw-r--r--src/memberdef.h12
-rw-r--r--src/namespacedef.h4
-rw-r--r--src/packagedef.h4
-rw-r--r--src/pre.l4
-rw-r--r--src/rtfgen.cpp4
-rw-r--r--src/scanner.l14
-rw-r--r--src/tagreader.cpp62
-rw-r--r--src/translator.cpp84
-rw-r--r--src/translator.h81
-rw-r--r--src/translator_en.h33
-rw-r--r--src/translator_fr.h287
-rw-r--r--src/util.cpp70
-rw-r--r--src/util.h2
39 files changed, 1712 insertions, 442 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp
index f2c733b..f7c0550 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -33,7 +33,8 @@
#include "example.h"
#include "outputlist.h"
#include "dot.h"
-//#include "xml.h"
+#include "defargs.h"
+#include "debug.h"
static QCString stripExtension(const char *fName)
{
@@ -98,8 +99,10 @@ ClassDef::ClassDef(
}
m_subGrouping=TRUE;
m_isTemplBaseClass=-1;
- m_templateMapping = new StringDict;
- m_templateMapping->setAutoDelete(TRUE);
+ m_templateInstances = 0;
+ m_templateMaster =0;
+ m_templBaseClassNames = 0;
+ m_artificial = FALSE;
}
// destroy the class definition
@@ -115,19 +118,26 @@ ClassDef::~ClassDef()
delete m_memberGroupList;
delete m_memberGroupDict;
delete m_innerClasses;
- delete m_templateMapping;
+ delete m_templateInstances;
+ delete m_templBaseClassNames;
}
QCString ClassDef::displayName() const
{
+ QCString n;
if (Config_getBool("HIDE_SCOPE_NAMES"))
{
- return stripScope(name());
+ n=stripScope(name());
}
else
{
- return name();
+ n=name();
}
+ if (m_tempArgs)
+ {
+ n+=tempArgListToString(m_tempArgs);
+ }
+ return n;
}
// inserts a base class in the inheritance list
@@ -527,6 +537,15 @@ void ClassDef::distributeMemberGroupDocumentation()
void ClassDef::insertUsedFile(const char *f)
{
if (m_files.find(f)==-1) m_files.append(f);
+ if (m_templateInstances)
+ {
+ QDictIterator<ClassDef> qdi(*m_templateInstances);
+ ClassDef *cd;
+ for (qdi.toFirst();(cd=qdi.current());++qdi)
+ {
+ cd->insertUsedFile(f);
+ }
+ }
}
static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd)
@@ -566,6 +585,7 @@ void ClassDef::setIncludeFile(FileDef *fd,const char *includeName,bool local)
}
}
+// TODO: fix this: a nested template class can have multiple outer templates
ArgumentList *ClassDef::outerTemplateArguments() const
{
int ti;
@@ -700,6 +720,15 @@ void ClassDef::writeDocumentation(OutputList &ol)
Doxygen::tagFile << "\">" << endl;
Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << ".html</filename>" << endl;
+ if (m_tempArgs)
+ {
+ ArgumentListIterator ali(*m_tempArgs);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ Doxygen::tagFile << " <templarg>" << convertToXML(a->name) << "</templarg>" << endl;
+ }
+ }
}
@@ -1145,15 +1174,16 @@ void ClassDef::writeMemberList(OutputList &ol)
ClassDef *cd=md->getClassDef();
// compute the protection level for this member
- Protection prot=md->protection();
- if (mi->prot==Protected) // inherited protection: Protected
- {
- if (prot==Public) prot=Protected;
- }
- else if (mi->prot==Private) // inherited protection: Private
- {
- prot=Private;
- }
+ //Protection prot=md->protection();
+ //if (mi->prot==Protected) // inherited protection: Protected
+ //{
+ // if (prot==Public) prot=Protected;
+ //}
+ //else if (mi->prot==Private) // inherited protection: Private
+ //{
+ // prot=Private;
+ //}
+ Protection prot = mi->prot;
//printf("%s: Member %s of class %s md->protection()=%d mi->prot=%d prot=%d inherited=%d\n",
// name().data(),md->name().data(),cd->name().data(),md->protection(),mi->prot,prot,mi->inherited);
@@ -1166,13 +1196,15 @@ void ClassDef::writeMemberList(OutputList &ol)
rmd = rmd->reimplements();
}
- if (cd && !md->name().isEmpty() && md->name()[0]!='@' &&
- (
- md->isFriend() ||
- (/*mi->prot!=Private &&*/
- (prot!=Private || Config_getBool("EXTRACT_PRIVATE"))
- )
- )
+ if (cd && !md->name().isEmpty() && md->name()[0]!='@'
+ // &&
+ //(
+ // md->isFriend()
+ // ||
+ //(/*mi->prot!=Private &&*/
+ // (prot!=Private || Config_getBool("EXTRACT_PRIVATE"))
+ //)
+ //)
)
{
bool memberWritten=FALSE;
@@ -1416,7 +1448,7 @@ void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup)
}
/*! a link to this class is possible within this project */
-bool ClassDef::isLinkableInProject()
+bool ClassDef::isLinkableInProject() const
{
return !name().isEmpty() && /* no name */
m_isTemplBaseClass==-1 && /* template base class */
@@ -1432,8 +1464,10 @@ bool ClassDef::isVisibleInHierarchy()
(Config_getBool("ALLEXTERNALS") || hasNonReferenceSuperClass()) &&
// and not an annonymous compound
name().find('@')==-1 &&
+ // not an artifically introduced class
+ !m_artificial &&
// and not an inherited template argument
- m_isTemplBaseClass==-1 &&
+ //m_isTemplBaseClass==-1 &&
// and not privately inherited
(m_prot!=Private || Config_getBool("EXTRACT_PRIVATE")) &&
// documented or show anyway or documentation is external
@@ -1642,6 +1676,7 @@ void ClassDef::mergeMembers()
Specifier virt=mi->virt;
if (mi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
+ //printf("Adding!\n");
MemberInfo *newMi=new MemberInfo(mi->memberDef,prot,virt,TRUE);
newMi->scopePath=bClass->name()+"::"+mi->scopePath;
newMi->ambigClass=mi->ambigClass;
@@ -1660,6 +1695,22 @@ void ClassDef::mergeMembers()
//----------------------------------------------------------------------------
+void ClassDef::addUsedClass(ClassDef *cd,const char *accessName)
+{
+ if (m_usesImplClassDict==0) m_usesImplClassDict = new UsesClassDict(17);
+ UsesClassDef *ucd=m_usesImplClassDict->find(cd->name());
+ if (ucd==0 /*|| ucd->templSpecifiers!=templSpec*/)
+ {
+ ucd = new UsesClassDef(cd);
+ m_usesImplClassDict->insert(cd->name(),ucd);
+ //ucd->templSpecifiers = templSpec;
+ //printf("Adding used class %s to class %s\n",
+ // cd->name().data(),name().data());
+ }
+ ucd->addAccessor(accessName);
+}
+
+#if 0
/*! Builds up a dictionary of all classes that are used by the state of this
* class (the "implementation").
* Must be called before mergeMembers() is called!
@@ -1772,7 +1823,6 @@ void ClassDef::determineImplUsageRelation()
//----------------------------------------------------------------------------
-#if 0
// I have disabled this code because the graphs it renders quickly become
// too large to be of practical use.
@@ -1873,6 +1923,22 @@ QCString ClassDef::compoundTypeString() const
QCString ClassDef::getOutputFileBase() const
{
+ if (m_templateMaster)
+ {
+ return m_templateMaster->getOutputFileBase();
+ }
+ else if (isReference())
+ {
+ return m_fileName;
+ }
+ else
+ {
+ return convertNameToFile(m_fileName);
+ }
+}
+
+QCString ClassDef::getInstanceOutputFileBase() const
+{
if (isReference())
{
return m_fileName;
@@ -1885,12 +1951,26 @@ QCString ClassDef::getOutputFileBase() const
QCString ClassDef::getFileBase() const
{
- return m_fileName;
+ if (m_templateMaster)
+ {
+ return m_templateMaster->getFileBase();
+ }
+ else
+ {
+ return m_fileName;
+ }
}
QCString ClassDef::getSourceFileBase() const
{
- return convertNameToFile(m_fileName+"-source");
+ if (m_templateMaster)
+ {
+ return m_templateMaster->getSourceFileBase();
+ }
+ else
+ {
+ return convertNameToFile(m_fileName+"-source");
+ }
}
void ClassDef::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs)
@@ -1925,44 +2005,147 @@ Definition *ClassDef::findInnerCompound(const char *name)
return m_innerClasses->find(name);
}
-void ClassDef::initTemplateMapping()
+//void ClassDef::initTemplateMapping()
+//{
+// m_templateMapping->clear();
+// ArgumentList *al = templateArguments();
+// if (al)
+// {
+// ArgumentListIterator ali(*al);
+// Argument *arg;
+// for (ali.toFirst();(arg=ali.current());++ali)
+// {
+// setTemplateArgumentMapping(arg->name,arg->defval);
+// }
+// }
+//}
+//void ClassDef::setTemplateArgumentMapping(const char *formal,const char *actual)
+//{
+// //printf("ClassDef::setTemplateArgumentMapping(%s,%s)\n",formal,actual);
+// if (m_templateMapping && formal)
+// {
+// if (m_templateMapping->find(formal))
+// {
+// m_templateMapping->remove(formal);
+// }
+// m_templateMapping->insert(formal,new QCString(actual));
+// }
+//}
+//
+//QCString ClassDef::getTemplateArgumentMapping(const char *formal) const
+//{
+// if (m_templateMapping && formal)
+// {
+// QCString *s = m_templateMapping->find(formal);
+// if (s)
+// {
+// return *s;
+// }
+// }
+// return "";
+//}
+
+ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName,
+ int startLine, const QCString &templSpec,bool &freshInstance)
+{
+ freshInstance = FALSE;
+ if (m_templateInstances==0)
+ {
+ m_templateInstances = new QDict<ClassDef>(17);
+ }
+ ClassDef *templateClass=m_templateInstances->find(templSpec);
+ if (templateClass==0)
+ {
+ Debug::print(Debug::Classes,0," New template instance class %s%s\n",name().data(),templSpec.data());
+ templateClass = new ClassDef(
+ fileName,startLine,name()+templSpec,ClassDef::Class);
+ //templateClass->setBriefDescription(briefDescription());
+ //templateClass->setDocumentation(documentation());
+ templateClass->setTemplateMaster(this);
+ m_templateInstances->insert(templSpec,templateClass);
+ freshInstance=TRUE;
+ }
+ return templateClass;
+}
+
+void ClassDef::setTemplateBaseClassNames(QDict<int> *templateNames)
{
- m_templateMapping->clear();
- ArgumentList *al = templateArguments();
- if (al)
+ if (templateNames==0) return;
+ if (m_templBaseClassNames==0)
+ {
+ m_templBaseClassNames = new QDict<int>(17);
+ m_templBaseClassNames->setAutoDelete(TRUE);
+ }
+ // make a deep copy of the dictionary.
+ QDictIterator<int> qdi(*templateNames);
+ for (;qdi.current();++qdi)
{
- ArgumentListIterator ali(*al);
- Argument *arg;
- for (ali.toFirst();(arg=ali.current());++ali)
+ if (m_templBaseClassNames->find(qdi.currentKey())==0)
{
- setTemplateArgumentMapping(arg->name,arg->defval);
+ m_templBaseClassNames->insert(qdi.currentKey(),new int(*qdi.current()));
}
}
}
-void ClassDef::setTemplateArgumentMapping(const char *formal,const char *actual)
+QDict<int> *ClassDef::getTemplateBaseClassNames() const
+{
+ return m_templBaseClassNames;
+}
+
+void ClassDef::addMembersToTemplateInstance(ClassDef *cd,const char *templSpec)
{
- //printf("ClassDef::setTemplateArgumentMapping(%s,%s)\n",formal,actual);
- if (m_templateMapping && formal)
+ //printf("%s::addMembersToTemplateInstance(%s,%s)\n",name().data(),cd->name().data(),templSpec);
+ MemberNameInfoSDict::Iterator mnili(*cd->m_allMemberNameInfoSDict);
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
{
- if (m_templateMapping->find(formal))
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
{
- m_templateMapping->remove(formal);
+ ArgumentList *actualArguments = new ArgumentList;
+ stringToArgumentList(templSpec,actualArguments);
+ MemberDef *md = mi->memberDef;
+ MemberDef *imd = md->createTemplateInstanceMember(
+ cd->templateArguments(),actualArguments);
+ delete actualArguments;
+ //printf("%s->setMemberClass(%p)\n",imd->name().data(),this);
+ imd->setMemberClass(this);
+ imd->setTemplateMaster(md);
+ //imd->setDocumentation(md->documentation());
+ //imd->setBriefDescription(md->briefDescription());
+ imd->setMemberSpecifiers(md->getMemberSpecifiers());
+ insertMember(imd);
+ //printf("Adding member=%s%s to class %s\n",imd->name().data(),imd->argsString(),imd->getClassDef()->name().data());
+ // insert imd in the list of all members
+ //printf("Adding member=%s class=%s\n",imd->name().data(),name().data());
+#if 0
+ MemberName *mn;
+ if ((mn=Doxygen::memberNameDict[imd->name()]))
+ {
+ mn->append(md);
+ }
+ else
+ {
+ mn = new MemberName(imd->name());
+ mn->append(md);
+ Doxygen::memberNameDict.insert(imd->name(),mn);
+ Doxygen::memberNameList.append(mn);
+ }
+#endif
}
- m_templateMapping->insert(formal,new QCString(actual));
}
}
-QCString ClassDef::getTemplateArgumentMapping(const char *formal) const
+QCString ClassDef::getReference() const
{
- if (m_templateMapping && formal)
+ if (m_templateMaster)
{
- QCString *s = m_templateMapping->find(formal);
- if (s)
- {
- return *s;
- }
+ return m_templateMaster->getReference();
+ }
+ else
+ {
+ return Definition::getReference();
}
- return "";
}
diff --git a/src/classdef.h b/src/classdef.h
index b39b87d..323b7bd 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -26,6 +26,7 @@
#include "entry.h"
#include "memberlist.h"
#include "definition.h"
+#include "sortdict.h"
class MemberDict;
class ClassList;
@@ -67,8 +68,10 @@ class ClassDef : public Definition
};
DefType definitionType() { return TypeClass; }
QCString getOutputFileBase() const;
+ QCString getInstanceOutputFileBase() const;
QCString getFileBase() const;
QCString getSourceFileBase() const;
+ QCString getReference() const;
bool hasDocumentation() const;
@@ -106,12 +109,12 @@ class ClassDef : public Definition
/*! returns TRUE iff a link is possible to an item within this project.
*/
- bool isLinkableInProject();
+ bool isLinkableInProject() const;
/*! return TRUE iff a link to this class is possible (either within
* this project, or as a cross-reference to another project).
*/
- bool isLinkable()
+ bool isLinkable() const
{
return isLinkableInProject() || isReference();
}
@@ -156,6 +159,15 @@ class ClassDef : public Definition
*/
int isTemplateBaseClass() const { return m_isTemplBaseClass; }
+ /*! Returns a sorted dictionary with all template instances found for
+ * this template class. Returns 0 if not a template or no instances.
+ */
+ QDict<ClassDef> *getTemplateInstances() const { return m_templateInstances; }
+ /*! Returns the template master of which this class is an instance.
+ * Returns 0 if not applicable.
+ */
+ ClassDef *templateMaster() const { return m_templateMaster; }
+
UsesClassDict *usedImplementationClasses() const
{
return m_usesImplClassDict;
@@ -166,8 +178,13 @@ class ClassDef : public Definition
return m_usesIntfClassDict;
}
+ /*! Returns the definition of a nested compound if
+ * available, or 0 otherwise.
+ * @param name The name of the nested compound
+ */
virtual Definition *findInnerCompound(const char *name);
+
/* member lists by protection */
MemberList pubMembers;
MemberList proMembers;
@@ -224,16 +241,24 @@ class ClassDef : public Definition
void setTemplateArguments(ArgumentList *al);
void mergeMembers();
void setFileDef(FileDef *fd) { m_fileDef=fd; }
- void determineImplUsageRelation();
- void determineIntfUsageRelation();
+ //void determineImplUsageRelation();
+ //void determineIntfUsageRelation();
void setSubGrouping(bool enabled) { m_subGrouping = enabled; }
void setProtection(Protection p) { m_prot=p; }
void setGroupDefForAllMembers(GroupDef *g,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs);
void addInnerCompound(Definition *d);
void setIsTemplateBaseClass(int num) { m_isTemplBaseClass = num; }
- void initTemplateMapping();
- void setTemplateArgumentMapping(const char *formal,const char *actual);
- QCString getTemplateArgumentMapping(const char *formal) const;
+ void addUsedClass(ClassDef *cd,const char *accessName);
+ //void initTemplateMapping();
+ //void setTemplateArgumentMapping(const char *formal,const char *actual);
+ //QCString getTemplateArgumentMapping(const char *formal) const;
+ ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,
+ const QCString &templSpec,bool &freshInstance);
+ void setTemplateBaseClassNames(QDict<int> *templateNames);
+ QDict<int> *getTemplateBaseClassNames() const;
+ void setTemplateMaster(ClassDef *tm) { m_templateMaster=tm; }
+ void addMembersToTemplateInstance(ClassDef *cd,const char *templSpec);
+ void setClassIsArtificial() { m_artificial = TRUE; }
/*! Creates a new compound definition.
* \param outerScope class, file or namespace in which this class is
@@ -351,11 +376,22 @@ class ClassDef : public Definition
*/
int m_isTemplBaseClass;
- /*! A mapping used by template classes, which maps formal
- * template arguments to their actual instantiations.
- * This is used while generating inheritance graphs.
+ /*! Template instances that exists of this class, the key in the
+ * dictionary is the template argument list.
+ */
+ QDict<ClassDef> *m_templateInstances;
+
+ QDict<int> *m_templBaseClassNames;
+
+ /*! The class this class is an instance of. */
+ ClassDef *m_templateMaster;
+
+ /*! Indicated whether this class exists because it is used by
+ * some other class only (TRUE) or if some class inherits from
+ * it (FALSE). This is need to remove used-only classes from
+ * the inheritance tree.
*/
- StringDict *m_templateMapping;
+ bool m_artificial;
};
/*! \brief Class that contains information about a usage relation.
diff --git a/src/code.l b/src/code.l
index 69bb8f3..69bf1a3 100644
--- a/src/code.l
+++ b/src/code.l
@@ -21,7 +21,7 @@
* includes
*/
#include <stdio.h>
-#include <iostream.h>
+//#include <iostream.h>
#include <assert.h>
#include <ctype.h>
#include <qregexp.h>
diff --git a/src/config.h b/src/config.h
index 8874cff..02a3389 100644
--- a/src/config.h
+++ b/src/config.h
@@ -290,7 +290,7 @@ class ConfigBool : public ConfigOption
t << endl;
}
t << m_name << m_spaces.left(MAX_OPTION_LENGTH-m_name.length()) << "= ";
- if (upd)
+ if (upd && !m_valueString.isEmpty())
{
writeStringValue(t,m_valueString);
}
diff --git a/src/config.l b/src/config.l
index dd704b0..9ffdf55 100644
--- a/src/config.l
+++ b/src/config.l
@@ -19,7 +19,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
-#include <iostream.h>
+//#include <iostream.h>
#include <assert.h>
#include <ctype.h>
diff --git a/src/constexp.h b/src/constexp.h
index 2b09ed9..6f230f9 100644
--- a/src/constexp.h
+++ b/src/constexp.h
@@ -22,10 +22,12 @@
#include "qtbc.h"
#include "cppvalue.h"
-extern bool parseCppExpression(const QCString &s);
+extern bool parseCppExpression(const char *fileName,int line,const QCString &s);
extern int cppExpYYparse();
extern int cppExpYYdebug;
-extern QCString strToken;
-extern CPPValue resultValue;
+extern QCString g_strToken;
+extern CPPValue g_resultValue;
+extern QCString g_constExpFileName;
+extern int g_constExpLineNr;
#endif
diff --git a/src/constexp.l b/src/constexp.l
index b6604ff..92b3da4 100644
--- a/src/constexp.l
+++ b/src/constexp.l
@@ -25,11 +25,13 @@
#define YY_NO_UNPUT
#define YY_NEVER_INTERACTIVE 1
-QCString strToken;
+QCString g_strToken;
+CPPValue g_resultValue;
+int g_constExpLineNr;
+QCString g_constExpFileName;
-static const char *inputString;
-static int inputPosition;
-CPPValue resultValue;
+static const char *g_inputString;
+static int g_inputPosition;
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
@@ -37,9 +39,9 @@ CPPValue resultValue;
static int yyread(char *buf,int max_size)
{
int c=0;
- while( c < max_size && inputString[inputPosition] )
+ while( c < max_size && g_inputString[g_inputPosition] )
{
- *buf = inputString[inputPosition++] ;
+ *buf = g_inputString[g_inputPosition++] ;
c++; buf++;
}
return c;
@@ -74,36 +76,38 @@ static int yyread(char *buf,int max_size)
"(" { return TOK_LPAREN; }
")" { return TOK_RPAREN; }
"'"(([^\'\n\r\\]+)|(\\(([ntvbrfa\\?'\"])|([0-9]+)|([xX][0-9a-fA-F]+))))"'" {
- strToken=yytext;
+ g_strToken=yytext;
return TOK_CHARACTER;
}
-0[0-7]*[uUlL]* { strToken=yytext;
+0[0-7]*[uUlL]* { g_strToken=yytext;
return TOK_OCTALINT;
}
-[1-9][0-9]*[uUlL]* { strToken=yytext;
+[1-9][0-9]*[uUlL]* { g_strToken=yytext;
return TOK_DECIMALINT;
}
-(0x|0X)[0-9a-fA-F]+[uUlL]* { strToken=yytext; return TOK_HEXADECIMALINT; }
+(0x|0X)[0-9a-fA-F]+[uUlL]* { g_strToken=yytext; return TOK_HEXADECIMALINT; }
(([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+))([eE]([\-\+])?[0-9]+)?([fFlL])? {
- strToken=yytext; return TOK_FLOAT;
+ g_strToken=yytext; return TOK_FLOAT;
}
([0-9]+[eE])([\-\+])?[0-9]+([fFlL])? {
- strToken=yytext; return TOK_FLOAT;
+ g_strToken=yytext; return TOK_FLOAT;
}
.
\n
%%
-bool parseCppExpression(const QCString &s)
+bool parseCppExpression(const char *fileName,int lineNr,const QCString &s)
{
//printf("Expression: `%s'\n",s.data());
- inputString = s;
- inputPosition = 0;
+ g_constExpFileName = fileName;
+ g_constExpLineNr = lineNr;
+ g_inputString = s;
+ g_inputPosition = 0;
cppExpYYrestart( cppExpYYin );
cppExpYYparse();
//printf("Result: %ld\n",(long)resultValue);
- return (long)resultValue!=0;
+ return (long)g_resultValue!=0;
}
extern "C" {
diff --git a/src/constexp.y b/src/constexp.y
index f5565bc..9063c52 100644
--- a/src/constexp.y
+++ b/src/constexp.y
@@ -20,6 +20,7 @@
#include "cppvalue.h"
#include "constexp.h"
+#include "message.h"
#if defined(_MSC_VER)
#define MSDOS
@@ -32,7 +33,8 @@
int cppExpYYerror(const char *s)
{
- printf("Error in constant expression evaluation: %s\n",s);
+ warn(g_constExpFileName,g_constExpLineNr,
+ "Problem during constant expression evaluation: %s",s);
return 0;
}
@@ -73,7 +75,7 @@ int cppExpYYlex();
%%
start: constant_expression
- { resultValue = $1; return 0; }
+ { g_resultValue = $1; return 0; }
;
constant_expression: logical_or_expression
diff --git a/src/cppvalue.cpp b/src/cppvalue.cpp
index 62d73dd..be1018a 100644
--- a/src/cppvalue.cpp
+++ b/src/cppvalue.cpp
@@ -24,7 +24,7 @@
CPPValue parseOctal()
{
long val = 0;
- for (const char *p = strToken.data(); *p != 0; p++)
+ for (const char *p = g_strToken.data(); *p != 0; p++)
{
if (*p >= '0' && *p <= '7') val = val * 8 + *p - '0';
}
@@ -34,7 +34,7 @@ CPPValue parseOctal()
CPPValue parseDecimal()
{
long val = 0;
- for (const char *p = strToken.data(); *p != 0; p++)
+ for (const char *p = g_strToken.data(); *p != 0; p++)
{
if (*p >= '0' && *p <= '9') val = val * 10 + *p - '0';
}
@@ -44,7 +44,7 @@ CPPValue parseDecimal()
CPPValue parseHexadecimal()
{
long val = 0;
- for (const char *p = strToken.data(); *p != 0; p++)
+ for (const char *p = g_strToken.data(); *p != 0; p++)
{
if (*p >= '0' && *p <= '9') val = val * 16 + *p - '0';
else if (*p >= 'a' && *p <= 'f') val = val * 16 + *p - 'a' + 10;
@@ -55,9 +55,9 @@ CPPValue parseHexadecimal()
CPPValue parseCharacter() // does not work for '\n' and the alike
{
- if (strToken[1]=='\\')
+ if (g_strToken[1]=='\\')
{
- switch(strToken[2])
+ switch(g_strToken[2])
{
case 'n': return CPPValue((long)'\n');
case 't': return CPPValue((long)'\t');
@@ -73,14 +73,14 @@ CPPValue parseCharacter() // does not work for '\n' and the alike
case '0': return parseOctal();
case 'x':
case 'X': return parseHexadecimal();
- default: printf("Invalid escape sequence %s found!\n",strToken.data());
+ default: printf("Invalid escape sequence %s found!\n",g_strToken.data());
return CPPValue(0L);
}
}
- return CPPValue((long)strToken[1]);
+ return CPPValue((long)g_strToken[1]);
}
CPPValue parseFloat()
{
- return CPPValue(atof(strToken));
+ return CPPValue(atof(g_strToken));
}
diff --git a/src/cppvalue.h b/src/cppvalue.h
index 159e217..def31c9 100644
--- a/src/cppvalue.h
+++ b/src/cppvalue.h
@@ -24,13 +24,9 @@
class CPPValue
{
- friend CPPValue parseOctal();
- friend CPPValue parseDecimal();
- friend CPPValue parseHexadecimal();
- friend CPPValue parseCharacter();
- friend CPPValue parseFloat();
-
public:
+
+
enum Type { Int, Float };
CPPValue(long val=0) : type(Int) { v.l = val; }
@@ -57,4 +53,10 @@ class CPPValue
} v;
};
+extern CPPValue parseOctal();
+extern CPPValue parseDecimal();
+extern CPPValue parseHexadecimal();
+extern CPPValue parseCharacter();
+extern CPPValue parseFloat();
+
#endif
diff --git a/src/declinfo.l b/src/declinfo.l
index 6a689c0..18e39d8 100644
--- a/src/declinfo.l
+++ b/src/declinfo.l
@@ -21,7 +21,7 @@
* includes
*/
#include <stdio.h>
-#include <iostream.h>
+//#include <iostream.h>
#include <assert.h>
#include <ctype.h>
diff --git a/src/defargs.l b/src/defargs.l
index 68eaa91..ebdb6ad 100644
--- a/src/defargs.l
+++ b/src/defargs.l
@@ -47,7 +47,7 @@
*/
#include "qtbc.h"
#include <stdio.h>
-#include <iostream.h>
+//#include <iostream.h>
#include <assert.h>
#include <ctype.h>
#include <qregexp.h>
diff --git a/src/definition.cpp b/src/definition.cpp
index 87f5855..f17d980 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -452,7 +452,11 @@ void Definition::addInnerCompound(Definition *)
QCString Definition::qualifiedName() const
{
//printf("start Definition::qualifiedName()\n");
- if (m_outerScope==0) return m_localName; // TODO: remove this check
+ if (m_outerScope==0)
+ {
+ if (m_localName=="<globalScope>") return "";
+ else return m_localName;
+ }
QCString qualifiedName;
if (m_outerScope->name()=="<globalScope>")
diff --git a/src/definition.h b/src/definition.h
index 6136cc6..e881e43 100644
--- a/src/definition.h
+++ b/src/definition.h
@@ -76,12 +76,12 @@ class Definition
void setBriefDescription(const char *b);
/*! Returns TRUE iff the definition is documented */
virtual bool hasDocumentation() const;
- virtual bool isLinkableInProject() = 0;
- virtual bool isLinkable() = 0;
+ virtual bool isLinkableInProject() const = 0;
+ virtual bool isLinkable() const = 0;
+ virtual QCString getReference() const { return m_ref; }
bool isReference() const { return !m_ref.isEmpty(); }
void setReference(const char *r) { m_ref=r; }
- QCString getReference() const { return m_ref; }
/*! Add the list of anchors that mark the sections that are found in the
* documentation.
diff --git a/src/doc.l b/src/doc.l
index cd70588..017a4f0 100644
--- a/src/doc.l
+++ b/src/doc.l
@@ -22,7 +22,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
-#include <iostream.h>
+//#include <iostream.h>
#include <assert.h>
#include <ctype.h>
@@ -828,7 +828,7 @@ ID [a-z_A-Z][a-z_A-Z0-9]*
SCOPENAME (({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID})
SCOPEMASK {ID}?(("::"|"#")?(~)?{ID})+
URLMASK [a-z_A-Z0-9\~\:\?\@\&\%\#\.\-\+\/\=]+
-NONTERM [\{\}\[\]\`\~\@\|\-\+\#\$\/\\\!\%\^\&\*()a-z_A-Z<>0-9]
+NONTERM [\{\}\[\]\`\~\@\|\-\+\#\$\/\\\!\%\^\&\*()a-z_A-Z<>0-9\x80-\xff]
WORD ({NONTERM}+([^\n\t ]*{NONTERM}+)?)|("\""[^\n\"]"\"")
ATTR ({B}+[^>\n]*)?
A [aA]
diff --git a/src/dot.cpp b/src/dot.cpp
index f7be7d5..20666e6 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -176,6 +176,7 @@ static bool isLeaf(ClassDef *cd)
return TRUE;
}
+#if 0
/*! Builds a mapping from formal arguments of class \a tcd to the
* actual arguments stored in templSpec. To properly initialize
* the mapping with the default template values
@@ -320,6 +321,7 @@ static void computeTemplateInstance(
actualArg.resize(0);
result = 0;
}
+#endif
//--------------------------------------------------------------------
@@ -693,20 +695,24 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path)
QListIterator<DotNode> dnli(*m_rootSubgraphs);
DotNode *n;
+ int count=0;
for (dnli.toFirst();(n=dnli.current());++dnli)
{
- QCString baseName="inherit_graph_";
- QCString diskName=n->m_url.copy();
- int i=diskName.find('$');
- if (i!=-1)
- {
- diskName=diskName.right(diskName.length()-i-1);
- }
- else /* take the label name as the file name (and strip any template stuff) */
- {
- diskName=n->m_label;
- }
- baseName = convertNameToFile(baseName+diskName);
+ QCString baseName;
+ baseName.sprintf("inherit_graph_%d",count++);
+ //="inherit_graph_";
+ //QCString diskName=n->m_url.copy();
+ //int i=diskName.find('$');
+ //if (i!=-1)
+ //{
+ // diskName=diskName.right(diskName.length()-i-1);
+ //}
+ //else /* take the label name as the file name (and strip any template stuff) */
+ //{
+ // diskName=n->m_label;
+ //}
+ //baseName = convertNameToFile(baseName+diskName);
+ baseName = convertNameToFile(baseName);
QCString dotName=baseName+".dot";
QCString gifName=baseName+".gif";
QCString mapName=baseName+".map";
@@ -817,18 +823,9 @@ void DotGfxHierarchyTable::addHierarchy(DotNode *n,ClassDef *cd,bool hideSuper)
}
}
-DotGfxHierarchyTable::DotGfxHierarchyTable()
+void DotGfxHierarchyTable::addClassList(ClassSDict *cl)
{
- m_curNodeNumber=0;
- m_rootNodes = new QList<DotNode>;
- //m_rootNodes->setAutoDelete(TRUE); // rootNodes owns the nodes
- m_usedNodes = new QDict<DotNode>(1009); // virtualNodes only aliases nodes
- m_rootSubgraphs = new DotNodeList;
-
- // build a graph with each class as a node and the inheritance relations
- // as edges
- initClassHierarchy(&Doxygen::classSDict);
- ClassSDict::Iterator cli(Doxygen::classSDict);
+ ClassSDict::Iterator cli(*cl);
ClassDef *cd;
for (cli.toLast();(cd=cli.current());--cli)
{
@@ -857,6 +854,22 @@ DotGfxHierarchyTable::DotGfxHierarchyTable()
}
}
}
+}
+
+DotGfxHierarchyTable::DotGfxHierarchyTable()
+{
+ m_curNodeNumber=0;
+ m_rootNodes = new QList<DotNode>;
+ //m_rootNodes->setAutoDelete(TRUE); // rootNodes owns the nodes
+ m_usedNodes = new QDict<DotNode>(1009); // virtualNodes only aliases nodes
+ m_rootSubgraphs = new DotNodeList;
+
+ // build a graph with each class as a node and the inheritance relations
+ // as edges
+ initClassHierarchy(&Doxygen::classSDict);
+ initClassHierarchy(&Doxygen::hiddenClasses);
+ addClassList(&Doxygen::classSDict);
+ addClassList(&Doxygen::hiddenClasses);
// m_usedNodes now contains all nodes in the graph
// color the graph into a set of independent subgraphs
@@ -918,8 +931,6 @@ int DotClassGraph::m_curNodeNumber;
void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
const char *label,int distance,const char *usedName,const char *templSpec,bool base)
{
- //printf("DoxClassGraph::addClass(class=%s,parent=%s,prot=%d,label=%s,dist=%d,usedName=%s,templSpec=%s,base=%d)\n",
- // cd->name().data(),n->m_label.data(),prot,label,distance,usedName,templSpec,base);
int edgeStyle = label ? EdgeInfo::Dashed : EdgeInfo::Solid;
QCString className;
if (usedName) // name is a typedef
@@ -932,8 +943,10 @@ void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
}
else // just a normal name
{
- className=cd->name();
+ className=cd->displayName();
}
+ //printf("DotClassGraph::addClass(class=`%s',parent=%s,prot=%d,label=%s,dist=%d,usedName=%s,templSpec=%s,base=%d)\n",
+ // className.data(),n->m_label.data(),prot,label,distance,usedName,templSpec,base);
DotNode *bn = m_usedNodes->find(className);
if (bn) // class already inserted
{
@@ -955,7 +968,10 @@ void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
QCString displayName=className;
if (Config_getBool("HIDE_SCOPE_NAMES")) displayName=stripScope(displayName);
QCString tmp_url;
- if (cd->isLinkable()) tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
+ if (cd->isLinkable())
+ {
+ tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
+ }
bn = new DotNode(m_curNodeNumber++,
displayName,
tmp_url.data(),
@@ -973,7 +989,7 @@ void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
n->addParent(bn);
}
m_usedNodes->insert(className,bn);
- //printf(" add used node %s of %s\n",cd->name().data(),n->m_label.data());
+ //printf(" add new child node `%s' to %s\n",className.data(),n->m_label.data());
if (distance<m_recDepth) buildGraph(cd,bn,distance+1,base);
}
}
@@ -986,23 +1002,25 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
{
//printf("-------- inheritance relation %s->%s templ=`%s'\n",
// cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data());
- QCString templSpec;
- if (base) templSpec = substituteTemplateSpec(
- cd,bcd->templSpecifiers);
- ClassDef *acd=0;
- QCString actualArg;
- computeTemplateInstance(cd,bcd->classDef,templSpec,acd,actualArg);
+ //QCString templSpec;
+ //if (base) templSpec = substituteTemplateSpec(
+ // cd,bcd->templSpecifiers);
+ //ClassDef *acd=0;
+ //QCString actualArg;
+ //computeTemplateInstance(cd,bcd->classDef,templSpec,acd,actualArg);
//printf("acd=%p actualArg=%s\n",acd,actualArg.data());
- if (acd)
- {
- addClass(acd,n,bcd->prot,0,distance,actualArg,
- templSpec,base);
- }
- else
- {
- addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->usedName,
- templSpec,base);
- }
+ //if (acd)
+ //{
+ // addClass(acd,n,bcd->prot,0,distance,actualArg,
+ // templSpec,base);
+ //}
+ //else
+ //{
+ // addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->usedName,
+ // templSpec,base);
+ //}
+ addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->usedName,
+ bcd->templSpecifiers,base);
}
if (m_graphType != Inheritance)
{
@@ -1031,25 +1049,27 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
label+=QCString("\\n")+s;
}
}
- QCString actualArg;
- ClassDef *acd=0;
+ //QCString actualArg;
+ //ClassDef *acd=0;
//printf("-------- usage relation %s->%s templ=`%s'\n",
// cd->name().data(),ucd->classDef->name().data(),
// ucd->templSpecifiers.data());
- QCString templSpec = substituteTemplateSpec(
- cd,ucd->templSpecifiers);
- computeTemplateInstance(cd,ucd->classDef, templSpec, acd,actualArg);
- if (acd)
- {
- addClass(acd,n,EdgeInfo::Black,label,distance,actualArg,
- templSpec,base);
- }
- else
- {
- //printf("Found label=`%s'\n",label.data());
- addClass(ucd->classDef,n,EdgeInfo::Black,label,distance,0,
- templSpec,base);
- }
+ //QCString templSpec = substituteTemplateSpec(
+ // cd,ucd->templSpecifiers);
+ //computeTemplateInstance(cd,ucd->classDef, templSpec, acd,actualArg);
+ //if (acd)
+ //{
+ // addClass(acd,n,EdgeInfo::Black,label,distance,actualArg,
+ // templSpec,base);
+ //}
+ //else
+ //{
+ // //printf("Found label=`%s'\n",label.data());
+ // addClass(ucd->classDef,n,EdgeInfo::Black,label,distance,0,
+ // templSpec,base);
+ //}
+ addClass(ucd->classDef,n,EdgeInfo::Black,label,distance,0,
+ ucd->templSpecifiers,base);
}
}
}
@@ -1057,17 +1077,17 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
DotClassGraph::DotClassGraph(ClassDef *cd,GraphType t,int maxRecursionDepth)
{
- //printf("DotGfxUsage::DotGfxUsage %s\n",cd->name().data());
+ //printf("--------------- DotClassGraph::DotClassGraph `%s'\n",cd->displayName().data());
m_graphType = t;
m_maxDistance = 0;
m_recDepth = maxRecursionDepth;
QCString tmp_url="";
if (cd->isLinkable()) tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
QCString className = cd->displayName();
- if (cd->templateArguments())
- {
- className+=tempArgListToString(cd->templateArguments());
- }
+ //if (cd->templateArguments())
+ //{
+ // className+=tempArgListToString(cd->templateArguments());
+ //}
m_startNode = new DotNode(m_curNodeNumber++,
className,
tmp_url.data(),
@@ -1075,11 +1095,11 @@ DotClassGraph::DotClassGraph(ClassDef *cd,GraphType t,int maxRecursionDepth)
TRUE // is a root node
);
m_usedNodes = new QDict<DotNode>(1009);
- m_usedNodes->insert(cd->name(),m_startNode);
+ m_usedNodes->insert(className,m_startNode);
- ClassSDict::Iterator cli(Doxygen::classSDict);
- ClassDef *icd;
- for (cli.toFirst();(icd=cli.current());++cli) icd->initTemplateMapping();
+ //ClassSDict::Iterator cli(Doxygen::classSDict);
+ //ClassDef *icd;
+ //for (cli.toFirst();(icd=cli.current());++cli) icd->initTemplateMapping();
//printf("Root node %s\n",cd->name().data());
if (m_recDepth>0)
diff --git a/src/dot.h b/src/dot.h
index 296df0c..bfd518e 100644
--- a/src/dot.h
+++ b/src/dot.h
@@ -24,6 +24,7 @@ class ClassDef;
class FileDef;
class QTextStream;
class DotNodeList;
+class ClassSDict;
enum GraphOutputFormat { GIF , EPS };
@@ -105,6 +106,7 @@ class DotGfxHierarchyTable
private:
void addHierarchy(DotNode *n,ClassDef *cd,bool hide);
+ void addClassList(ClassSDict *cl);
QList<DotNode> *m_rootNodes;
QDict<DotNode> *m_usedNodes;
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 8d786ad..c7a64eb 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -65,8 +65,10 @@
#define pclose _pclose
#endif
+static QDict<Entry> classEntries(1009);
+
ClassSDict Doxygen::classSDict(1009);
-ClassList Doxygen::hiddenClasses;
+ClassSDict Doxygen::hiddenClasses(257);
NamespaceList Doxygen::namespaceList; // all namespaces
NamespaceDict Doxygen::namespaceDict(257);
@@ -209,7 +211,7 @@ static void addRelatedPage(const char *name,const QCString &ptitle,
)
{
PageInfo *pi=0;
- if ((pi=Doxygen::pageSDict->find(name)))
+ if ((pi=Doxygen::pageSDict->find(name)) && !tagInfo)
{
// append documentation block to the page.
pi->doc+="\n\n"+doc;
@@ -392,7 +394,8 @@ static void addRefItem(int todoId,int testId,int bugId,const char *prefix,
static void buildGroupList(Entry *root)
{
- if (root->section==Entry::GROUPDOC_SEC && !root->name.isEmpty())
+ if (root->section==Entry::GROUPDOC_SEC && !root->name.isEmpty() &&
+ (Config_getBool("EXTRACT_ALL") || root->tagInfo))
{
//printf("Found group %s title=`%s'\n",root->name.data(),root->type.data());
@@ -883,7 +886,6 @@ static void buildClassList(Entry *root)
cd->setBriefDescription(root->brief);
cd->insertUsedFile(root->fileName);
-
// add class to the list
//printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data());
Doxygen::classSDict.inSort(fullName,cd);
@@ -1336,6 +1338,7 @@ static MemberDef *addVariableToClass(
bool ambig;
md->setBodyDef(findFileDef(Doxygen::inputNameDict,root->fileName,ambig));
+ //printf("Adding member=%s\n",md->name().data());
// add the member to the global list
if (mn)
{
@@ -1510,6 +1513,7 @@ static MemberDef *addVariableToFile(
}
}
+ //printf("Adding member=%s\n",md->name().data());
// add member definition to the list of globals
if (mn)
{
@@ -1911,6 +1915,7 @@ static void buildMemberList(Entry *root)
);
// add member to the global list of all members
+ //printf("Adding member=%s class=%s\n",md->name().data(),cd->name().data());
MemberName *mn;
if ((mn=Doxygen::memberNameDict[name]))
{
@@ -1920,7 +1925,6 @@ static void buildMemberList(Entry *root)
{
mn = new MemberName(name);
mn->append(md);
- //printf("Adding memberName=%s\n",mn->memberName());
Doxygen::memberNameDict.insert(name,mn);
Doxygen::memberNameList.append(mn);
}
@@ -2109,6 +2113,7 @@ static void buildMemberList(Entry *root)
}
// add member to the list of file members
+ //printf("Adding member=%s\n",md->name().data());
MemberName *mn;
if ((mn=Doxygen::functionNameDict[name]))
{
@@ -2343,15 +2348,332 @@ static void replaceNamespaceAliases(QCString &scope,int i)
//printf("replaceNamespaceAliases() result=%s\n",scope.data());
}
+static QCString resolveTypeDef(const QCString &name)
+{
+ QCString typeName;
+ if (!name.isEmpty())
+ {
+ QCString *subst = Doxygen::typedefDict[name];
+ if (subst)
+ {
+ int count=0;
+ typeName=*subst;
+ QCString *newSubst;
+ while ((newSubst=Doxygen::typedefDict[typeName]) && count<10)
+ {
+ if (typeName==*newSubst) break; // prevent lock-up
+ typeName=*newSubst;
+ count++;
+ }
+ }
+ }
+ return typeName;
+}
+
+/*! make a dictionary of all template arguments of class cd
+ * that are part of the base class name.
+ * Example: A template class A with template arguments <R,S,T>
+ * that inherits from B<T,T,S> will have T and S in the dictionary.
+ */
+static QDict<int> *getTemplateArgumentsInName(ArgumentList *templateArguments,const QCString &name)
+{
+ QDict<int> *templateNames = new QDict<int>(17);
+ templateNames->setAutoDelete(TRUE);
+ static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*");
+ if (templateArguments)
+ {
+ ArgumentListIterator ali(*templateArguments);
+ Argument *arg;
+ int count=0;
+ for (ali.toFirst();(arg=ali.current());++ali,count++)
+ {
+ int i,p=0,l;
+ while ((i=re.match(name,p,&l))!=-1)
+ {
+ QCString n = name.mid(i,l);
+ if (n==arg->name)
+ {
+ if (templateNames->find(n)==0)
+ {
+ templateNames->insert(n,new int(count));
+ }
+ }
+ p=i+l;
+ }
+ }
+ }
+ return templateNames;
+}
+
+
+enum FindBaseClassRelation_Mode
+{
+ TemplateInstances,
+ DocumentedOnly,
+ Undocumented
+};
-static bool findBaseClassRelation(
+static bool findClassRelation(
Entry *root,
ClassDef *cd,
BaseInfo *bi,
- int isTemplBaseClass,
- bool insertUndocumented
+ QDict<int> *templateNames,
+ /*bool insertUndocumented*/
+ FindBaseClassRelation_Mode mode,
+ bool isArtificial
+ );
+
+
+static void findUsedClassesForClass(Entry *root,
+ ClassDef *masterCd,
+ ClassDef *instanceCd,
+ bool isArtificial,
+ ArgumentList *actualArgs=0,
+ QDict<int> *templateNames=0
+ )
+{
+ //if (masterCd->visited) return;
+ masterCd->visited=TRUE;
+ ArgumentList *formalArgs = masterCd->templateArguments();
+ MemberNameInfoSDict::Iterator mnili(*masterCd->memberNameInfoSDict());
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ MemberDef *md=mi->memberDef;
+ if (md->isVariable()) // for each member variable in this class
+ {
+ QCString type=removeRedundantWhiteSpace(md->typeString());
+ int pos=0;
+ QCString usedClassName;
+ QCString templSpec;
+ bool found=FALSE;
+ if (actualArgs)
+ {
+ type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs);
+ }
+ //printf("extractClassNameFromType(%s)\n",type.data());
+ while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec))
+ {
+ QCString typeName = resolveTypeDef(usedClassName);
+ QCString usedName = usedClassName+templSpec;
+ if (!typeName.isEmpty())
+ {
+ usedName=typeName;
+ }
+ //printf("usedName=`%s'\n",usedName.data());
+
+ bool delTempNames=FALSE;
+ if (templateNames==0)
+ {
+ templateNames = getTemplateArgumentsInName(formalArgs,usedName);
+ delTempNames=TRUE;
+ }
+ BaseInfo bi(usedName,Public,Normal);
+ findClassRelation(root,instanceCd,&bi,templateNames,TemplateInstances,isArtificial);
+
+ if (masterCd->templateArguments())
+ {
+ ArgumentListIterator ali(*masterCd->templateArguments());
+ Argument *arg;
+ int count=0;
+ for (ali.toFirst();(arg=ali.current());++ali,++count)
+ {
+ if (arg->name==usedName) // type is a template argument
+ {
+ found=TRUE;
+ Debug::print(Debug::Classes,0," New used class `%s'\n", usedName.data());
+
+ ClassDef *usedCd = Doxygen::hiddenClasses.find(usedName);
+ if (usedCd==0)
+ {
+ usedCd = new ClassDef(
+ masterCd->getDefFileName(),masterCd->getDefLine(),
+ usedName,ClassDef::Class);
+ usedCd->setIsTemplateBaseClass(count);
+ Doxygen::hiddenClasses.inSort(usedName,usedCd);
+ }
+ if (isArtificial) usedCd->setClassIsArtificial();
+ instanceCd->addUsedClass(usedCd,md->name());
+
+ //if (m_usesImplClassDict==0) m_usesImplClassDict = new UsesClassDict(257);
+ //UsesClassDef *ucd = new UsesClassDef(cd);
+ //m_usesImplClassDict->insert(cd->name(),ucd);
+ //ucd->templSpecifiers = templSpec;
+ //ucd->addAccessor(md->name());
+ }
+ }
+ }
+
+ if (!found)
+ {
+ Definition *scope=masterCd->getOuterScope();
+ ClassDef *usedCd=0;
+ do
+ {
+ QCString scopeName = scope ? scope->qualifiedName().data() : 0;
+ if (!scopeName.isEmpty())
+ {
+ usedCd=getResolvedClass(scopeName+"::"+usedName,0,&templSpec);
+ if (usedCd==0) usedCd=getResolvedClass(scopeName+"::"+usedClassName,0,&templSpec);
+ //printf("Search for class %s result=%p\n",(scopeName+"::"+usedName).data(),usedCd);
+ }
+ else
+ {
+ usedCd=getResolvedClass(usedName,0,&templSpec);
+ if (usedCd==0) usedCd=getResolvedClass(usedClassName,0,&templSpec);
+ //printf("Search for class %s result=%p\n",usedName.data(),usedCd);
+ }
+ if (scope) scope=scope->getOuterScope();
+ } while (scope && usedCd==0);
+
+ if (usedCd)
+ {
+ found=TRUE;
+ instanceCd->addUsedClass(usedCd,md->name()); // class exists
+ }
+ }
+ if (delTempNames)
+ {
+ delete templateNames;
+ templateNames=0;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void findBaseClassesForClass(
+ Entry *root,
+ ClassDef *masterCd,
+ ClassDef *instanceCd,
+ FindBaseClassRelation_Mode mode,
+ bool isArtificial,
+ ArgumentList *actualArgs=0,
+ QDict<int> *templateNames=0
+ )
+{
+ //if (masterCd->visited) return;
+ masterCd->visited=TRUE;
+ // The base class could ofcouse also be a non-nested class
+ ArgumentList *formalArgs = masterCd->templateArguments();
+ QListIterator<BaseInfo> bii(*root->extends);
+ BaseInfo *bi=0;
+ for (bii.toFirst();(bi=bii.current());++bii)
+ {
+ bool delTempNames=FALSE;
+ if (templateNames==0)
+ {
+ templateNames = getTemplateArgumentsInName(formalArgs,bi->name);
+ delTempNames=TRUE;
+ }
+ BaseInfo tbi(bi->name,bi->prot,bi->virt);
+ if (actualArgs) // substitute the formal template arguments of the base class
+ {
+ tbi.name = substituteTemplateArgumentsInString(bi->name,formalArgs,actualArgs);
+ }
+
+ if (mode==DocumentedOnly)
+ {
+ // find a documented base class in the correct scope
+ if (!findClassRelation(root,instanceCd,&tbi,templateNames,DocumentedOnly,isArtificial))
+ {
+ // no documented base class -> try to find an undocumented one
+ findClassRelation(root,instanceCd,&tbi,templateNames,Undocumented,isArtificial);
+ }
+ }
+ else if (mode==TemplateInstances)
+ {
+ findClassRelation(root,instanceCd,&tbi,templateNames,TemplateInstances,isArtificial);
+ }
+ if (delTempNames)
+ {
+ delete templateNames;
+ templateNames=0;
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+static bool findTemplateInstanceRelation(Entry *root,
+ ClassDef *templateClass,const QCString &templSpec,
+ QDict<int> *templateNames,
+ bool isArtificial)
+{
+ Debug::print(Debug::Classes,0," derived from template %s with parameters %s\n",
+ templateClass->name().data(),templSpec.data());
+ //printf("findTemplateInstanceRelation(base=%s templSpec=%s templateNames=",
+ // templateClass->name().data(),templSpec.data());
+ //if (templateNames)
+ //{
+ // QDictIterator<int> qdi(*templateNames);
+ // int *tempArgIndex;
+ // for (;(tempArgIndex=qdi.current());++qdi)
+ // {
+ // printf("(%s->%d) ",qdi.currentKey().data(),*tempArgIndex);
+ // }
+ //}
+ //printf("\n");
+
+ bool existingClass = (templSpec==tempArgListToString(templateClass->templateArguments()));
+ if (existingClass) return TRUE;
+
+ bool freshInstance=FALSE;
+ ClassDef *instanceClass = templateClass->insertTemplateInstance(
+ root->fileName,root->startLine,templSpec,freshInstance);
+ if (isArtificial) instanceClass->setClassIsArtificial();
+
+ if (freshInstance)
+ {
+ Doxygen::classSDict.inSort(instanceClass->name(),instanceClass);
+ instanceClass->setTemplateBaseClassNames(templateNames);
+
+ // search for new template instances caused by base classes of
+ // instanceClass
+ Entry *templateRoot = classEntries.find(templateClass->name());
+
+ ArgumentList *templArgs = new ArgumentList;
+ stringToArgumentList(templSpec,templArgs);
+ findBaseClassesForClass(templateRoot,templateClass,instanceClass,
+ TemplateInstances,isArtificial,templArgs,templateNames);
+
+ findUsedClassesForClass(templateRoot,templateClass,instanceClass,
+ isArtificial,templArgs,templateNames);
+
+ //Debug::print(Debug::Classes,0," Template instance %s : \n",instanceClass->name().data());
+ //ArgumentList *tl = templateClass->templateArguments();
+ }
+ return TRUE;
+}
+
+static bool findClassRelation(
+ Entry *root,
+ ClassDef *cd,
+ BaseInfo *bi,
+ QDict<int> *templateNames,
+ FindBaseClassRelation_Mode mode,
+ bool isArtificial
)
{
+ //printf("findClassRelation(class=%s base=%s templateNames=",
+ // cd->name().data(),bi->name.data());
+ //if (templateNames)
+ //{
+ // QDictIterator<int> qdi(*templateNames);
+ // int *tempArgIndex;
+ // for (;(tempArgIndex=qdi.current());++qdi)
+ // {
+ // printf("(%s->%d) ",qdi.currentKey().data(),*tempArgIndex);
+ // }
+ //}
+ //printf("\n");
+
+
Entry *parentNode=root->parent;
bool lastParent=FALSE;
do // for each parent scope, starting with the largest scope
@@ -2377,8 +2699,9 @@ static bool findBaseClassRelation(
// baseClass?baseClass->name().data():"<none>",
// templSpec.data()
// );
- if (baseClassName!=root->name) // check for base class with the same name,
- // look in the outer scope for a match
+ if (baseClassName!=root->name) // Check for base class with the same name.
+ // If found then look in the outer scope for a match
+ // and prevent recursion.
{
Debug::print(
Debug::Classes,0," class relation %s inherited by %s found (%s and %s)\n",
@@ -2420,7 +2743,7 @@ static bool findBaseClassRelation(
}
}
- bool found=baseClass!=0 && baseClass!=cd;
+ bool found=baseClass!=0 && (baseClass!=cd || mode==TemplateInstances);
NamespaceDef *nd=cd->getNamespaceDef();
if (!found && (i=baseClassName.findRev("::"))!=-1)
{
@@ -2520,25 +2843,60 @@ static bool findBaseClassRelation(
}
}
}
- if (isTemplBaseClass==-1 && found)
+ bool isATemplateArgument = templateNames!=0 && templateNames->find(bi->name)!=0;
+ if (!isATemplateArgument && found)
{
Debug::print(Debug::Classes,0," Documented base class `%s' templSpec=%s\n",bi->name.data(),templSpec.data());
// add base class to this class
- QCString usedName;
- if (baseClassIsTypeDef) usedName=bi->name;
- cd->insertBaseClass(baseClass,usedName,bi->prot,bi->virt,templSpec);
- // add this class as super class to the base class
- baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
+
+ // if templSpec is not empty then we should "instantiate"
+ // the template baseClass. A new ClassDef should be created
+ // to represent the instance. To be able to add the (instantiated)
+ // members and documentation of a template class
+ // (inserted in that template class at a later stage),
+ // the template should know about its instances.
+ // the instantiation process, should be done in a recursive way,
+ // since instantiating a template may introduce new inheritance
+ // relations.
+ if (!templSpec.isEmpty() && mode==TemplateInstances)
+ {
+ findTemplateInstanceRelation(root,baseClass,templSpec,templateNames,isArtificial);
+ }
+ else if (mode==DocumentedOnly)
+ {
+ QCString usedName;
+ if (baseClassIsTypeDef) usedName=bi->name;
+ cd->insertBaseClass(baseClass,usedName,bi->prot,bi->virt,templSpec);
+ // add this class as super class to the base class
+ baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
+ }
return TRUE;
}
- else if ((scopeOffset==0 && insertUndocumented) || isTemplBaseClass!=-1)
+ else if (mode==Undocumented && (scopeOffset==0 || isATemplateArgument))
{
Debug::print(Debug::Classes,0,
- " Undocumented base class `%s' baseClassName=%s\n",
+ " New undocumented base class `%s' baseClassName=%s\n",
bi->name.data(),baseClassName.data()
);
- baseClass=new ClassDef(root->fileName,root->startLine,
+ baseClass=0;
+ if (isATemplateArgument)
+ {
+ baseClass=Doxygen::hiddenClasses.find(baseClassName);
+ if (baseClass==0)
+ {
+ baseClass=new ClassDef(root->fileName,root->startLine,
baseClassName,ClassDef::Class);
+ Doxygen::hiddenClasses.inSort(baseClassName,baseClass);
+ if (isArtificial) baseClass->setClassIsArtificial();
+ }
+ }
+ else
+ {
+ baseClass=new ClassDef(root->fileName,root->startLine,
+ baseClassName,ClassDef::Class);
+ Doxygen::classSDict.inSort(baseClassName,baseClass);
+ if (isArtificial) baseClass->setClassIsArtificial();
+ }
// add base class to this class
cd->insertBaseClass(baseClass,bi->name,bi->prot,bi->virt,templSpec);
// add this class as super class to the base class
@@ -2547,15 +2905,16 @@ static bool findBaseClassRelation(
baseClass->insertUsedFile(root->fileName);
// is this an inherited template argument?
//printf("%s->setIsTemplateBaseClass(%d)\n",baseClass->name().data(),isTemplBaseClass);
- baseClass->setIsTemplateBaseClass(isTemplBaseClass);
+ if (isATemplateArgument)
+ {
+ baseClass->setIsTemplateBaseClass(*templateNames->find(bi->name));
+ }
// add class to the list
- if (isTemplBaseClass==-1)
+ if (!isATemplateArgument)
{
- Doxygen::classSDict.inSort(baseClassName,baseClass);
}
else
{
- Doxygen::hiddenClasses.append(baseClass);
}
return TRUE;
}
@@ -2591,23 +2950,54 @@ static bool findBaseClassRelation(
//----------------------------------------------------------------------
// Computes the base and super classes for each class in the tree
-static void computeClassRelations(Entry *root)
+static bool isClassSection(Entry *root)
{
- if (
+ return
+ (
(
- (
- // is it a compound (class, struct, union, interface ...)
- root->section & Entry::COMPOUND_MASK
- )
- ||
- (
- // is it a documentation block with inheritance info.
- (root->section & Entry::COMPOUNDDOC_MASK) && root->extends->count()>0
- )
+ (
+ // is it a compound (class, struct, union, interface ...)
+ root->section & Entry::COMPOUND_MASK
+ )
+ ||
+ (
+ // is it a documentation block with inheritance info.
+ (root->section & Entry::COMPOUNDDOC_MASK) && root->extends->count()>0
+ )
)
- &&
- !root->name.isEmpty() // sanity check
- )
+ && !root->name.isEmpty() // sanity check
+ );
+}
+
+
+/*! Builds a dictionary of all entry nodes in the tree starting with \a root
+ */
+static void findClassEntries(Entry *root)
+{
+ if (isClassSection(root))
+ {
+ classEntries.insert(root->name,root);
+ }
+ EntryListIterator eli(*root->sublist);
+ Entry *e;
+ for (;(e=eli.current());++eli)
+ {
+ findClassEntries(e);
+ }
+}
+
+/*! Using the dictionary build by findClassEntries(), this
+ * function will look for additional template specialization that
+ * exists as inheritance relations only. These instances will be
+ * added to the template they are derived from.
+ */
+static void findInheritedTemplateInstances()
+{
+ ClassSDict::Iterator cli(Doxygen::classSDict);
+ for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
+ QDictIterator<Entry> edi(classEntries);
+ Entry *root;
+ for (;(root=edi.current());++edi)
{
ClassDef *cd;
// strip any annonymous scopes first
@@ -2616,61 +3006,133 @@ static void computeClassRelations(Entry *root)
if ((cd=getClass(bName)))
{
//printf("Class %s %d\n",cd->name().data(),root->extends->count());
- if (!cd->visited) // check integrity of the tree
+ findBaseClassesForClass(root,cd,cd,TemplateInstances,FALSE);
+ }
+ }
+}
+
+static void findUsedTemplateInstances()
+{
+ ClassSDict::Iterator cli(Doxygen::classSDict);
+ for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
+ QDictIterator<Entry> edi(classEntries);
+ Entry *root;
+ for (;(root=edi.current());++edi)
+ {
+ ClassDef *cd;
+ // strip any annonymous scopes first
+ QCString bName=stripAnonymousNamespaceScope(root->name);
+ Debug::print(Debug::Classes,0," Class %s : \n",bName.data());
+ if ((cd=getClass(bName)))
+ {
+ findUsedClassesForClass(root,cd,cd,TRUE);
+ }
+ }
+}
+
+static void computeClassRelations()
+{
+ ClassSDict::Iterator cli(Doxygen::classSDict);
+ for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
+ QDictIterator<Entry> edi(classEntries);
+ Entry *root;
+ for (;(root=edi.current());++edi)
+ {
+ ClassDef *cd;
+ // strip any annonymous scopes first
+ QCString bName=stripAnonymousNamespaceScope(root->name);
+ Debug::print(Debug::Classes,0," Class %s : \n",bName.data());
+ if ((cd=getClass(bName)))
+ {
+ findBaseClassesForClass(root,cd,cd,DocumentedOnly,FALSE);
+ }
+ else if (bName.right(2)!="::")
+ {
+ if (!root->name.isEmpty() && root->name[0]!='@')
+ warn_undoc(
+ root->fileName,root->startLine,
+ "Warning: Compound %s is not documented.",
+ root->name.data()
+ );
+ }
+ }
+}
+
+static void computeTemplateClassRelations()
+{
+ QDictIterator<Entry> edi(classEntries);
+ Entry *root;
+ for (;(root=edi.current());++edi)
+ {
+ QCString bName=stripAnonymousNamespaceScope(root->name);
+ ClassDef *cd=getClass(bName);
+ // strip any annonymous scopes first
+ QDict<ClassDef> *templInstances = 0;
+ if (cd && (templInstances=cd->getTemplateInstances()))
+ {
+ Debug::print(Debug::Classes,0," Template class %s : \n",cd->name().data());
+ QDictIterator<ClassDef> tdi(*templInstances);
+ ClassDef *tcd;
+ for (tdi.toFirst();(tcd=tdi.current());++tdi) // for each template instance
{
- cd->visited=TRUE; // mark class as used
- if (root->extends->count()>0) // there are base classes
+ Debug::print(Debug::Classes,0," Template instance %s : \n",tcd->name().data());
+ //QCString templName = tcd->name();
+ //int index = templName.find('<');
+ //ASSERT(index!=-1);
+ // templName.right(templName.length()-index);
+ QCString templSpec = tdi.currentKey().data();
+ ArgumentList *templArgs = new ArgumentList;
+ stringToArgumentList(templSpec,templArgs);
+ QList<BaseInfo> *baseList=root->extends;
+ BaseInfo *bi=baseList->first();
+ while (bi) // for each base class of the template
{
-
- // The base class could ofcouse also be a non-nested class
- QList<BaseInfo> *baseList=root->extends;
- BaseInfo *bi=baseList->first();
- while (bi) // for each base class
+ // check if the base class is a template argument
+ BaseInfo tbi(bi->name,bi->prot,bi->virt);
+ ArgumentList *tl = cd->templateArguments();
+ if (tl)
{
- // check if the base class is a template argument
- int isTemplBaseClass = -1;
- ArgumentList *tl = cd->templateArguments();
- if (tl)
+ QDict<int> *baseClassNames = tcd->getTemplateBaseClassNames();
+ QDict<int> *templateNames = getTemplateArgumentsInName(tl,bi->name);
+ // for each template name that we inherit from we need to
+ // substitute the formal with the actual arguments
+ QDict<int> *actualTemplateNames = new QDict<int>(17);
+ actualTemplateNames->setAutoDelete(TRUE);
+ QDictIterator<int> qdi(*templateNames);
+ for (qdi.toFirst();qdi.current();++qdi)
{
- ArgumentListIterator ali(*tl);
- Argument *arg;
- int count=0;
- for (ali.toFirst();(arg=ali.current());++ali,++count)
+ int templIndex = *qdi.current();
+ Argument *actArg = 0;
+ if (templIndex<(int)templArgs->count())
{
- if (arg->name==bi->name) // base class is a template argument
- {
- isTemplBaseClass = count;
- break;
- }
+ actArg=templArgs->at(templIndex);
+ }
+ if (actArg!=0 &&
+ baseClassNames!=0 &&
+ baseClassNames->find(actArg->type)!=0 &&
+ actualTemplateNames->find(actArg->type)==0
+ )
+ {
+ actualTemplateNames->insert(actArg->type,new int(templIndex));
}
}
+ delete templateNames;
+
+ tbi.name = substituteTemplateArgumentsInString(bi->name,tl,templArgs);
// find a documented base class in the correct scope
- if (!findBaseClassRelation(root,cd,bi,isTemplBaseClass,FALSE))
+ if (!findClassRelation(root,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE))
{
// no documented base class -> try to find an undocumented one
- findBaseClassRelation(root,cd,bi,isTemplBaseClass,TRUE);
+ findClassRelation(root,tcd,&tbi,actualTemplateNames,Undocumented,FALSE);
}
- bi=baseList->next();
+ delete actualTemplateNames;
}
- } // class has no base classes
- } // else class is already found
- }
- else if (bName.right(2)!="::")
- {
- if (!root->name.isEmpty() && root->name[0]!='@')
- warn_undoc(
- root->fileName,root->startLine,
- "Warning: Compound %s is not documented.",
- root->name.data()
- );
+ bi=baseList->next();
+ }
+ delete templArgs;
+ } // class has no base classes
}
}
- EntryListIterator eli(*root->sublist);
- Entry *e;
- for (;(e=eli.current());++eli)
- {
- computeClassRelations(e);
- }
}
//-----------------------------------------------------------------------
@@ -2800,7 +3262,6 @@ static void addTodoTestBugReferences()
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"))
{
@@ -2994,7 +3455,7 @@ static ClassDef *findClassDefinition(FileDef *fd,NamespaceDef *nd,
{
cl=nd->getUsedClasses();
}
- else
+ else if (fd)
{
cl=fd->getUsedClasses();
}
@@ -3629,7 +4090,7 @@ static void findMember(Entry *root,
if (!isRelated && mn) // function name already found
{
Debug::print(Debug::FindMembers,0,
- "2. member name exists \n");
+ "2. member name exists (%d members with this name)\n",mn->count());
if (!className.isEmpty()) // class name is valid
{
int count=0;
@@ -3637,9 +4098,11 @@ static void findMember(Entry *root,
MemberDef *md;
for (mni.toFirst();(md=mni.current());++mni)
{
- Debug::print(Debug::FindMembers,0,
- "3. member definition found scopeName=`%s'\n",scopeName.data());
ClassDef *cd=md->getClassDef();
+ Debug::print(Debug::FindMembers,0,
+ "3. member definition found scope needed=`%s' scope=`%s' args=`%s'\n",
+ scopeName.data(),cd ? cd->name().data() : "<none>",
+ md->argsString());
//printf("Member %s (member scopeName=%s) (this scopeName=%s) classTempList=%s\n",md->name().data(),cd->name().data(),scopeName.data(),classTempList.data());
ClassDef *tcd=0;
@@ -3773,6 +4236,7 @@ static void findMember(Entry *root,
// root->inLine,md->isInline());
addMemberDocs(root,md,funcDecl,0,overloaded,nl);
count++;
+ break;
}
}
}
@@ -3985,9 +4449,9 @@ static void findMember(Entry *root,
cd->insertUsedFile(root->fileName);
md->setRefItems(root->todoId,root->testId,root->bugId);
addMemberToGroups(root,md);
+ //printf("Adding member=%s\n",md->name().data());
if (newMemberName)
{
- //printf("Adding memberName=%s\n",mn->memberName());
Doxygen::memberNameList.append(mn);
Doxygen::memberNameDict.insert(funcName,mn);
}
@@ -4077,14 +4541,7 @@ static void findMemberDocumentation(Entry *root)
compoundKeywordDict.find(root->type)==0 // that is not a keyword
// (to skip forward declaration of class etc.)
)
- ) /*
- && (!root->stat && !root->parent) // not static & global: TODO: fix this hack!
- && (
- !root->doc.isEmpty() || // has detailed docs
- !root->brief.isEmpty() || // has brief docs
- (root->memSpec&Entry::Inline) || // is inline
- root->mGrpId!=-1 || // is part of a group
- ) */
+ )
)
{
//printf("Documentation for member `%s' found args=`%s' excp=`%s'\n",
@@ -4261,6 +4718,7 @@ static void findEnums(Entry *root)
md->setDocumentation(root->doc);
md->setBriefDescription(root->brief);
+ //printf("Adding member=%s\n",md->name().data());
MemberName *mn;
if ((mn=(*mnd)[name]))
{
@@ -4545,13 +5003,37 @@ static void computeMemberRelations()
//----------------------------------------------------------------------------
-static void computeClassImplUsageRelations()
+//static void computeClassImplUsageRelations()
+//{
+// ClassDef *cd;
+// ClassSDict::Iterator cli(Doxygen::classSDict);
+// for (;(cd=cli.current());++cli)
+// {
+// cd->determineImplUsageRelation();
+// }
+//}
+
+//----------------------------------------------------------------------------
+
+static void createTemplateInstanceMembers()
{
- ClassDef *cd;
ClassSDict::Iterator cli(Doxygen::classSDict);
- for (;(cd=cli.current());++cli)
+ ClassDef *cd;
+ // for each class
+ for (cli.toFirst();(cd=cli.current());++cli)
{
- cd->determineImplUsageRelation();
+ // that is a template
+ QDict<ClassDef> *templInstances = cd->getTemplateInstances();
+ if (templInstances)
+ {
+ QDictIterator<ClassDef> qdi(*templInstances);
+ ClassDef *tcd=0;
+ // for each instance of the template
+ for (qdi.toFirst();(tcd=qdi.current());++qdi)
+ {
+ tcd->addMembersToTemplateInstance(cd,qdi.currentKey().data());
+ }
+ }
}
}
@@ -4747,8 +5229,8 @@ static void generateClassDocs()
for ( ; cli.current() ; ++cli )
{
ClassDef *cd=cli.current();
- if ( cd->isLinkableInProject() )
- // skip external references and anonymous compounds
+ if ( cd->isLinkableInProject() && cd->templateMaster()==0 )
+ // skip external references, anonymous compounds and template instances
{
msg("Generating docs for compound %s...\n",cd->name().data());
@@ -4892,6 +5374,7 @@ static void findDefineDocumentation(Entry *root)
FileDef *fd=findFileDef(Doxygen::inputNameDict,filePathName,ambig);
//printf("Searching for `%s' fd=%p\n",filePathName.data(),fd);
md->setFileDef(fd);
+ //printf("Adding member=%s\n",md->name().data());
MemberName *mn;
if ((mn=Doxygen::functionNameDict[root->name]))
{
@@ -6592,8 +7075,24 @@ void parseInput()
msg("Searching for documented defines...\n");
findDefineDocumentation(root);
- msg("Computing class relations...\n");
- computeClassRelations(root);
+ msg("Computing template instances...");
+ findClassEntries(root);
+ findInheritedTemplateInstances();
+ findUsedTemplateInstances();
+
+ msg("Creating members for template instances...\n");
+ createTemplateInstanceMembers();
+
+ //if (Config_getBool("HAVE_DOT") && Config_getBool("COLLABORATION_GRAPH"))
+ //{
+ // msg("Computing class implementation usage relations...\n");
+ // computeClassImplUsageRelations();
+ //}
+
+ msg("Computing class relations...");
+ computeTemplateClassRelations();
+ computeClassRelations();
+ classEntries.clear();
msg("Searching for enumerations...\n");
findEnums(root);
@@ -6631,12 +7130,6 @@ void parseInput()
msg("Adding classes to their packages...\n");
addClassesToPackages();
- if (Config_getBool("HAVE_DOT") && Config_getBool("COLLABORATION_GRAPH"))
- {
- msg("Computing class implementation usage relations...\n");
- computeClassImplUsageRelations();
- }
-
msg("Adding members to member groups.\n");
addMembersToMemberGroup();
diff --git a/src/doxygen.h b/src/doxygen.h
index f81241a..47310b8 100644
--- a/src/doxygen.h
+++ b/src/doxygen.h
@@ -59,7 +59,7 @@ class Doxygen
{
public:
static ClassSDict classSDict;
- static ClassList hiddenClasses;
+ static ClassSDict hiddenClasses;
static PageSDict *exampleSDict;
static PageSDict *pageSDict;
static PageInfo *mainPage;
diff --git a/src/filedef.h b/src/filedef.h
index 2bdbbcf..79525b0 100644
--- a/src/filedef.h
+++ b/src/filedef.h
@@ -110,12 +110,12 @@ class FileDef : public Definition
/*! Returns the absolute path of this file. */
QCString getPath() const { return path; }
- bool isLinkableInProject()
+ bool isLinkableInProject() const
{
return hasDocumentation() && !isReference();
}
- bool isLinkable()
+ bool isLinkable() const
{
return isLinkableInProject() || isReference();
}
diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp
index 38c2e72..a49ff2f 100644
--- a/src/ftvhelp.cpp
+++ b/src/ftvhelp.cpp
@@ -311,13 +311,14 @@ static void generateFolderTreeViewData()
QTextStream t(&f);
t << "<html><head>" << endl;
t << "<link rel=\"stylesheet\" href=\"";
- if (Config_getString("HTML_STYLESHEET").isEmpty())
+ QCString cssname=Config_getString("HTML_STYLESHEET");
+ if (cssname.isEmpty())
{
t << "doxygen.css";
}
else
{
- QFileInfo cssfi(Config_getString("HTML_STYLESHEET"));
+ QFileInfo cssfi(cssname);
if (!cssfi.exists())
{
err("Error: user specified HTML style sheet file does not exist!\n");
diff --git a/src/groupdef.h b/src/groupdef.h
index c2d413a..b4a446e 100644
--- a/src/groupdef.h
+++ b/src/groupdef.h
@@ -62,11 +62,11 @@ class GroupDef : public Definition
bool containsGroup(const GroupDef *def); // true if def is already a subgroup
void writeDocumentation(OutputList &ol);
int countMembers() const;
- bool isLinkableInProject()
+ bool isLinkableInProject() const
{
return hasDocumentation() && !isReference();
}
- bool isLinkable()
+ bool isLinkable() const
{
return isLinkableInProject() || isReference();
}
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 0c82986..57ce664 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -46,10 +46,10 @@ static const char *defaultStyleSheet =
"A.codeRef { font-weight: normal; color: #4444ee }\n"
"DL.el { margin-left: -1cm }\n"
"DIV.fragment { width: 100%; border: none; background-color: #eeeeee }\n"
- "DIV.ah { background-color: black; margin-bottom: 3; margin-top: 3 }\n"
+ "DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }\n"
"TD.md { background-color: #f2f2ff }\n"
- "DIV.groupHeader { margin-left: 16; margin-top: 12; margin-bottom: 6; font-weight: bold }\n"
- "DIV.groupText { margin-left: 16; font-style: italic; font-size: smaller }\n"
+ "DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold }\n"
+ "DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller }\n"
"FONT.keyword { color: #008000 }\n"
"FONT.keywordtype { color: #604020 }\n"
"FONT.keywordflow { color: #e08000 }\n"
@@ -80,13 +80,14 @@ void HtmlGenerator::append(const OutputGenerator *g)
void HtmlGenerator::init()
{
- QDir d(Config_getString("HTML_OUTPUT"));
- if (!d.exists() && !d.mkdir(Config_getString("HTML_OUTPUT")))
+ QCString dname=Config_getString("HTML_OUTPUT");
+ QDir d(dname);
+ if (!d.exists() && !d.mkdir(dname))
{
- err("Could not create output directory %s\n",Config_getString("HTML_OUTPUT").data());
+ err("Could not create output directory %s\n",dname.data());
exit(1);
}
- writeLogo(Config_getString("HTML_OUTPUT"));
+ writeLogo(dname);
if (!Config_getString("HTML_HEADER").isEmpty()) g_header=fileToString(Config_getString("HTML_HEADER"));
if (!Config_getString("HTML_FOOTER").isEmpty()) g_footer=fileToString(Config_getString("HTML_FOOTER"));
}
@@ -117,7 +118,8 @@ static void writeDefaultHeaderFile(QTextStream &t,const char *title,
}
else
{
- QFileInfo cssfi(Config_getString("HTML_STYLESHEET"));
+ QCString cssname=Config_getString("HTML_STYLESHEET");
+ QFileInfo cssfi(cssname);
if (!cssfi.exists())
{
err("Error: user specified HTML style sheet file does not exist!\n");
@@ -278,7 +280,8 @@ void HtmlGenerator::writeStyleInfo(int part)
}
else // write user defined style sheet
{
- QFileInfo cssfi(Config_getString("HTML_STYLESHEET"));
+ QCString cssname=Config_getString("HTML_STYLESHEET");
+ QFileInfo cssfi(cssname);
if (!cssfi.exists() || !cssfi.isFile() || !cssfi.isReadable())
{
err("Error: style sheet %s does not exist or is not readable!", Config_getString("HTML_STYLESHEET").data());
@@ -286,7 +289,7 @@ void HtmlGenerator::writeStyleInfo(int part)
else
{
startPlainFile(cssfi.fileName());
- t << fileToString(Config_getString("HTML_STYLESHEET"));
+ t << fileToString(cssname);
endPlainFile();
}
}
@@ -813,7 +816,7 @@ void HtmlGenerator::endIndexList()
void HtmlGenerator::startAlphabeticalIndexList()
{
- t << "<table align=center width=\"95%\" border=0 cellspacing=0 cellpadding=0>" << endl;
+ t << "<table align=center width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">" << endl;
}
void HtmlGenerator::endAlphabeticalIndexList()
@@ -823,8 +826,8 @@ void HtmlGenerator::endAlphabeticalIndexList()
void HtmlGenerator::writeIndexHeading(const char *s)
{
- t << "<div class=\"ah\"><font color=\"white\"><b>&nbsp;&nbsp;" << s
- << "&nbsp;&nbsp;</b></font></div>";
+ t << "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td><div class=\"ah\">&nbsp;&nbsp;" << s
+ << "&nbsp;&nbsp;</td</tr></table>";
}
void HtmlGenerator::startImage(const char *name,const char *,bool hasCaption)
diff --git a/src/index.cpp b/src/index.cpp
index 9ce2f94..97957fe 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -356,6 +356,7 @@ void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper)
bool hasChildren = !cd->visited && !hideSuper && cd->subClasses()->count()>0;
if (cd->isLinkable())
{
+ //printf("Writing class %s\n",cd->displayName().data());
ol.writeIndexItem(cd->getReference(),cd->getOutputFileBase(),cd->displayName());
if (cd->isReference())
{
@@ -518,10 +519,8 @@ void writeClassTree(ClassSDict *d)
//----------------------------------------------------------------------------
-void writeClassHierarchy(OutputList &ol)
+static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started)
{
- initClassHierarchy(&Doxygen::classSDict);
-
HtmlHelp *htmlHelp=0;
FTVHelp *ftvHelp=0;
bool &generateHtml = Config_getBool("GENERATE_HTML") ;
@@ -536,8 +535,7 @@ void writeClassHierarchy(OutputList &ol)
ftvHelp = FTVHelp::getInstance();
}
- bool started=FALSE;
- ClassSDict::Iterator cli(Doxygen::classSDict);
+ ClassSDict::Iterator cli(*cl);
for (;cli.current(); ++cli)
{
ClassDef *cd=cli.current();
@@ -560,7 +558,7 @@ void writeClassHierarchy(OutputList &ol)
bool hasChildren = !cd->visited && cd->subClasses()->count()>0;
if (cd->isLinkable())
{
- //printf("Writing class %s\n",cd->name().data());
+ //printf("Writing class %s\n",cd->displayName().data());
ol.writeIndexItem(cd->getReference(),cd->getOutputFileBase(),cd->displayName());
if (cd->isReference())
{
@@ -597,6 +595,30 @@ void writeClassHierarchy(OutputList &ol)
}
}
}
+}
+
+void writeClassHierarchy(OutputList &ol)
+{
+ HtmlHelp *htmlHelp=0;
+ FTVHelp *ftvHelp=0;
+ bool &generateHtml = Config_getBool("GENERATE_HTML") ;
+ bool hasHtmlHelp = generateHtml && Config_getBool("GENERATE_HTMLHELP");
+ bool hasFtvHelp = generateHtml && Config_getBool("GENERATE_TREEVIEW");
+ if (hasHtmlHelp)
+ {
+ htmlHelp = HtmlHelp::getInstance();
+ }
+ if (hasFtvHelp)
+ {
+ ftvHelp = FTVHelp::getInstance();
+ }
+
+ initClassHierarchy(&Doxygen::classSDict);
+ initClassHierarchy(&Doxygen::hiddenClasses);
+
+ bool started=FALSE;
+ writeClassTreeForList(ol,&Doxygen::classSDict,started);
+ writeClassTreeForList(ol,&Doxygen::hiddenClasses,started);
if (started)
{
ol.endIndexList();
@@ -1062,7 +1084,7 @@ int countAnnotatedClasses()
ClassDef *cd;
for (;(cd=cli.current());++cli)
{
- if (cd->isLinkableInProject())
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
//printf("Annotated class %s\n",cd->name().data());
count++;
@@ -1085,7 +1107,7 @@ void writeAnnotatedClassList(OutputList &ol)
ClassDef *cd;
for (;(cd=cli.current());++cli)
{
- if (cd->isLinkableInProject())
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
QCString type=cd->compoundTypeString();
ol.writeStartAnnoItem(type,cd->getOutputFileBase(),0,cd->displayName());
@@ -1168,7 +1190,7 @@ void writeAlphabeticalClassList(OutputList &ol)
int headerItems=0;
for (;(cd=cli.current());++cli)
{
- if (cd->isLinkableInProject())
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
int index = getPrefixIndex(cd->name());
if (toupper(cd->name().at(index))!=startLetter) // new begin letter => new header
@@ -1201,7 +1223,7 @@ void writeAlphabeticalClassList(OutputList &ol)
startLetter=0;
for (cli.toFirst();(cd=cli.current());++cli)
{
- if (cd->isLinkableInProject())
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
int index = getPrefixIndex(cd->name());
if (toupper(cd->name().at(index))!=startLetter)
@@ -1443,7 +1465,7 @@ void writeMemberList(OutputList &ol,bool useSections)
if (
md->isLinkableInProject() &&
(cd=md->getClassDef()) &&
- cd->isLinkableInProject()
+ cd->isLinkableInProject() && cd->templateMaster()==0
)
{
found=TRUE;
@@ -1489,7 +1511,7 @@ void writeMemberList(OutputList &ol,bool useSections)
if (
md->isLinkableInProject() &&
prevName!=cd->displayName() &&
- cd->isLinkableInProject()
+ cd->isLinkableInProject() && cd->templateMaster()==0
)
{
if (count==0)
@@ -2632,6 +2654,26 @@ void writeIndex(OutputList &ol)
if (Doxygen::mainPage)
{
parseDoc(ol,defFileName,defLine,0,0,Doxygen::mainPage->doc);
+
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <compound kind=\"page\">" << endl
+ << " <filename>"
+ << convertToXML(Doxygen::mainPage->fileName)
+ << "</filename>"
+ << endl
+ << " <title>"
+ << convertToXML(Doxygen::mainPage->title)
+ << "</title>"
+ << endl
+ << " <name>"
+ << convertToXML(Doxygen::mainPage->name)
+ << "</name>"
+ << endl;
+
+ Doxygen::mainPage->writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </compound>" << endl;
+ }
}
endFile(ol);
diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in
index 319cf3a..c86e343 100644
--- a/src/libdoxygen.pro.in
+++ b/src/libdoxygen.pro.in
@@ -139,6 +139,7 @@ SOURCES = ce_lex.cpp \
searchindex.cpp \
suffixtree.cpp \
tagreader.cpp \
+ translator.cpp \
util.cpp \
version.cpp
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index 3a26976..bcefdf7 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -309,6 +309,7 @@ MemberDef::MemberDef(const char *df,int dl,
{
argList=0;
}
+ m_templateMaster=0;
}
/*! Destroys the member definition. */
@@ -361,7 +362,11 @@ bool MemberDef::hasExamples()
QCString MemberDef::getOutputFileBase() const
{
- if (classDef)
+ if (m_templateMaster)
+ {
+ return m_templateMaster->getOutputFileBase();
+ }
+ else if (classDef)
{
return classDef->getOutputFileBase();
}
@@ -570,6 +575,7 @@ void MemberDef::writeDeclaration(OutputList &ol,
Doxygen::tagFile << "\" static=\"yes";
}
Doxygen::tagFile << "\">" << endl;
+ Doxygen::tagFile << " <type>" << convertToXML(typeString()) << "</type>" << endl;
Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
Doxygen::tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
Doxygen::tagFile << " <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
@@ -963,7 +969,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),ldef.right(ldef.length()-ei));
}
}
- else
+ else // not an enum value
{
ol.startDoxyAnchor(cfname,cname,anchor(),doxyName);
ol.startMemberDoc(cname,name(),anchor(),name());
@@ -998,7 +1004,6 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
if (cd)
{
QCString cName=cd->name();
- //printf("cName=%s\n",cName.data());
int il=cName.find('<');
int ir=cName.findRev('>');
if (il!=-1 && ir!=-1 && ir>il)
@@ -1273,11 +1278,16 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
parseText(ol,reimplFromLine.left(markerPos)); //text left from marker
if (bmd->isLinkable()) // replace marker with link
{
- ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+ Definition *bd=bmd->group;
+ if (bd==0) bd=bcd;
+ ol.writeObjectLink(bd->getReference(),bd->getOutputFileBase(),
bmd->anchor(),bcd->name());
- if ( bcd->isLinkableInProject()/* && !Config_getBool("PDF_HYPERLINKS")*/ )
+
+ //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+ // bmd->anchor(),bcd->name());
+ if ( bd->isLinkableInProject() )
{
- writePageRef(ol,bcd->getOutputFileBase(),bmd->anchor());
+ writePageRef(ol,bd->getOutputFileBase(),bmd->anchor());
}
}
else
@@ -1348,11 +1358,17 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
if (ok && bcd && bmd) // write link for marker
{
- ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+ //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+ // bmd->anchor(),bcd->name());
+ Definition* bd;
+ if (bmd->group) bd=bmd->group; else bd=bcd;
+
+ ol.writeObjectLink(bd->getReference(),bd->getOutputFileBase(),
bmd->anchor(),bcd->name());
- if (bcd->isLinkableInProject()/* && !Config_getBool("PDF_HYPERLINKS")*/ )
+
+ if (bd->isLinkableInProject() )
{
- writePageRef(ol,bcd->getOutputFileBase(),bmd->anchor());
+ writePageRef(ol,bd->getOutputFileBase(),bmd->anchor());
}
}
++mli;
@@ -1415,7 +1431,7 @@ void MemberDef::warnIfUndocumented()
}
-bool MemberDef::isLinkableInProject()
+bool MemberDef::isLinkableInProject() const
{
return !name().isEmpty() && name().at(0)!='@' &&
((hasDocumentation() && !isReference())
@@ -1424,7 +1440,7 @@ bool MemberDef::isLinkableInProject()
(classDef!=0 || Config_getBool("EXTRACT_STATIC") || !isStatic()); // not a static file/namespace member
}
-bool MemberDef::isLinkable()
+bool MemberDef::isLinkable() const
{
return isLinkableInProject() || isReference();
}
@@ -1515,3 +1531,35 @@ void MemberDef::setNamespace(NamespaceDef *nd)
setOuterScope(nd);
}
+MemberDef *MemberDef::createTemplateInstanceMember(
+ ArgumentList *formalArgs,ArgumentList *actualArgs)
+{
+ //printf(" Member %s %s %s\n",typeString(),name().data(),argsString());
+ ArgumentList *actualArgList = 0;
+ if (argList)
+ {
+ actualArgList = new ArgumentList;
+ ArgumentListIterator ali(*argList);
+ Argument *arg;
+ for (;(arg=ali.current());++ali)
+ {
+ Argument *actArg = new Argument(*arg);
+ actArg->type = substituteTemplateArgumentsInString(actArg->type,formalArgs,actualArgs);
+ actualArgList->append(actArg);
+ }
+ }
+
+ MemberDef *imd = new MemberDef(
+ getDefFileName(),getDefLine(),
+ substituteTemplateArgumentsInString(type,formalArgs,actualArgs),
+ name(),
+ substituteTemplateArgumentsInString(args,formalArgs,actualArgs),
+ exception, prot,
+ virt, stat, related, mtype, 0, 0
+ );
+ imd->argList = actualArgList;
+ imd->def = substituteTemplateArgumentsInString(def,formalArgs,actualArgs);
+ // TODO: init other member variables.
+ return imd;
+}
+
diff --git a/src/memberdef.h b/src/memberdef.h
index bf40f1b..5a2e279 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -35,6 +35,7 @@ class ExampleSDict;
class OutputList;
class GroupDef;
class QTextStream;
+class ArgumentList;
struct SourceReference
{
@@ -121,8 +122,8 @@ class MemberDef : public Definition
bool isExternal() const { return explExt; }
// output info
- bool isLinkableInProject();
- bool isLinkable();
+ bool isLinkableInProject() const;
+ bool isLinkable() const;
bool hasDocumentation() const; // overrides hasDocumentation in definition.h
bool isBriefSectionVisible() const;
bool isDetailedSectionVisible(bool inGroup=FALSE) const;
@@ -219,10 +220,15 @@ class MemberDef : public Definition
int indentDepth() { return indDepth; }
bool visibleMemberGroup(bool hideNoHeader);
+ MemberDef *templateMaster() const { return m_templateMaster; }
QCString getScopeString() const;
ClassDef *getClassDefOfAnonymousType();
+ MemberDef *createTemplateInstanceMember(ArgumentList *formalArgs,
+ ArgumentList *actualArgs);
+ void setTemplateMaster(MemberDef *mt) { m_templateMaster=mt; }
+
private:
ClassDef *classDef; // member of or related to
@@ -285,7 +291,7 @@ class MemberDef : public Definition
QCString groupFileName; // file where this grouping was defined
int groupStartLine; // line " " " " "
bool groupHasDocs; // true if the entry that caused the grouping was documented
-
+ MemberDef *m_templateMaster;
// disable copying of member defs
diff --git a/src/namespacedef.h b/src/namespacedef.h
index bcfee88..514d250 100644
--- a/src/namespacedef.h
+++ b/src/namespacedef.h
@@ -57,14 +57,14 @@ class NamespaceDef : public Definition
void addUsingDeclaration(ClassDef *cd);
ClassList *getUsedClasses() const { return usingDeclList; }
- bool isLinkableInProject()
+ bool isLinkableInProject() const
{
int i = name().findRev("::");
if (i==-1) i=0; else i+=2;
return !name().isEmpty() && name().at(i)!='@' &&
hasDocumentation() && !isReference();
}
- bool isLinkable()
+ bool isLinkable() const
{
return isLinkableInProject() || isReference();
}
diff --git a/src/packagedef.h b/src/packagedef.h
index fbaefa5..945b229 100644
--- a/src/packagedef.h
+++ b/src/packagedef.h
@@ -38,11 +38,11 @@ class PackageDef : public Definition
QCString getOutputFileBase() const ;
void addClass(const ClassDef *def);
void writeDocumentation(OutputList &ol);
- bool isLinkableInProject()
+ bool isLinkableInProject() const
{
return hasDocumentation() && !isReference();
}
- bool isLinkable()
+ bool isLinkable() const
{
return isLinkableInProject() || isReference();
}
diff --git a/src/pre.l b/src/pre.l
index 45ac38e..77c4e10 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -22,7 +22,7 @@
*/
#include <stdio.h>
-#include <iostream.h>
+//#include <iostream.h>
#include <assert.h>
#include <ctype.h>
@@ -796,7 +796,7 @@ bool computeExpression(const QCString &expr)
e = removeIdsAndMarkers(e);
if (e.isEmpty()) return FALSE;
//printf("parsing `%s'\n",e.data());
- return parseCppExpression(e);
+ return parseCppExpression(g_yyFileName,g_yyLineNr,e);
}
/*! expands the macro definition in \a name
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index 4582025..e3345ca 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -1127,7 +1127,9 @@ void RTFGenerator::endIndexSection(IndexSections is)
case isMainPage:
t << "\\par " << Rtf_Style_Reset << endl;
t << "{\\tc \\v " << theTranslator->trMainPage() << "}"<< endl;
- t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"index.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+ t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+ if (Config_getBool("GENERATE_TREEVIEW")) t << "main"; else t << "index";
+ t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
break;
case isPackageIndex:
t << "\\par " << Rtf_Style_Reset << endl;
diff --git a/src/scanner.l b/src/scanner.l
index 087c258..eba34de 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -22,7 +22,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
-#include <iostream.h>
+//#include <iostream.h>
#include <assert.h>
#include <ctype.h>
@@ -727,9 +727,11 @@ TITLE [tT][iI][tT][lL][eE]
<FindMembers>{B}*"explicit"{BN}+ { current->memSpec|=Entry::Explicit;
lineCount();
}
+ /*
<FindMembers>{B}*"import"{BN}+ { // IDL import keyword
BEGIN( NextSemi );
}
+ */
<FindMembers>{B}*"typename"{BN}+ { lineCount(); }
<FindMembers>{B}*"namespace"{BN}*/[^a-z_A-Z0-9] {
isTypedef=FALSE;
@@ -1035,7 +1037,9 @@ TITLE [tT][iI][tT][lL][eE]
}
<FindMembers,FindMemberName>{SCOPENAME} {
// correct for misinterpreting return type as scope name: example: A<T> func()
- if (YY_START==FindMembers && current->tArgList && current->mtArgList==0)
+ //printf("YY_START=%d current->tArgList=%p current->mtArgList=%p\n",
+ // YY_START,current->tArgList,current->mtArgList);
+ if (YY_START==FindMembers /*&& current->tArgList*/ && current->mtArgList==0)
{
current->mtArgList=current->tArgList;
current->tArgList=0;
@@ -1046,6 +1050,10 @@ TITLE [tT][iI][tT][lL][eE]
{
BEGIN(CppQuote);
}
+ else if (insideIDL && yyleng==6 && strcmp(yytext,"import")==0)
+ {
+ BEGIN(NextSemi);
+ }
else if (insideIDL && strcmp(yytext,"case")==0)
{
BEGIN(IDLUnionCase);
@@ -3400,7 +3408,7 @@ TITLE [tT][iI][tT][lL][eE]
<DocBaseClass>{ID} {
//printf("Adding base class %s\n",yytext);
current->extends->append(
- new BaseInfo(yytext,Public,Normal)
+ new BaseInfo(removeRedundantWhiteSpace(yytext),Public,Normal)
);
}
<DocBaseClass>\n { yyLineNr++; BEGIN( ClassDoc ); }
diff --git a/src/tagreader.cpp b/src/tagreader.cpp
index ed684c9..26b2b0a 100644
--- a/src/tagreader.cpp
+++ b/src/tagreader.cpp
@@ -39,6 +39,7 @@ class TagMemberInfo
{
public:
TagMemberInfo() : prot(Public), virt(Normal), isStatic(FALSE) {}
+ QString type;
QString name;
QString anchor;
QString arglist;
@@ -54,13 +55,14 @@ class TagClassInfo
{
public:
enum Kind { Class, Struct, Union, Interface, Exception };
- TagClassInfo() { bases=0, members.setAutoDelete(TRUE); }
- ~TagClassInfo() { delete bases; }
+ TagClassInfo() { bases=0, templateArguments=0; members.setAutoDelete(TRUE); }
+ ~TagClassInfo() { delete bases; delete templateArguments; }
QString name;
QString filename;
QStrList docAnchors;
QList<BaseInfo> *bases;
QList<TagMemberInfo> members;
+ QList<QString> *templateArguments;
Kind kind;
};
@@ -168,7 +170,11 @@ class TagFileParser : public QXmlDefaultHandler
};
public:
- TagFileParser(const char *tagName) : m_tagName(tagName) {}
+ TagFileParser(const char *tagName) : m_startElementHandlers(17),
+ m_endElementHandlers(17),
+ m_tagName(tagName)
+ {
+ }
void startCompound( const QXmlAttributes& attrib )
{
@@ -351,6 +357,17 @@ class TagFileParser : public QXmlDefaultHandler
{
m_curString = "";
}
+ void endType()
+ {
+ if (m_state==InMember)
+ {
+ m_curMember->type = m_curString;
+ }
+ else
+ {
+ err("Error: Unexpected tag `type' found\n");
+ }
+ }
void endName()
{
switch (m_state)
@@ -386,7 +403,11 @@ class TagFileParser : public QXmlDefaultHandler
{
virt = Virtual;
}
- if (m_curClass->bases==0) m_curClass->bases = new QList<BaseInfo>;
+ if (m_curClass->bases==0)
+ {
+ m_curClass->bases = new QList<BaseInfo>;
+ m_curClass->bases->setAutoDelete(TRUE);
+ }
m_curClass->bases->append(new BaseInfo(m_curString,prot,virt));
}
else
@@ -405,6 +426,22 @@ class TagFileParser : public QXmlDefaultHandler
err("Error: Unexpected tag `base' found\n");
}
}
+ void endTemplateArg()
+ {
+ if (m_state==InClass && m_curClass)
+ {
+ if (m_curClass->templateArguments==0)
+ {
+ m_curClass->templateArguments = new QList<QString>;
+ m_curClass->templateArguments->setAutoDelete(TRUE);
+ }
+ m_curClass->templateArguments->append(new QString(m_curString));
+ }
+ else
+ {
+ err("Error: Unexpected tag `templarg' found\n");
+ }
+ }
void endFilename()
{
switch (m_state)
@@ -510,6 +547,8 @@ class TagFileParser : public QXmlDefaultHandler
m_startElementHandlers.insert("page", new StartElementHandler(this,&TagFileParser::startStringValue));
m_startElementHandlers.insert("docanchor", new StartElementHandler(this,&TagFileParser::startStringValue));
m_startElementHandlers.insert("tagfile", new StartElementHandler(this,&TagFileParser::startIgnoreElement));
+ m_startElementHandlers.insert("templarg", new StartElementHandler(this,&TagFileParser::startStringValue));
+ m_startElementHandlers.insert("type", new StartElementHandler(this,&TagFileParser::startStringValue));
m_endElementHandlers.insert("compound", new EndElementHandler(this,&TagFileParser::endCompound));
m_endElementHandlers.insert("member", new EndElementHandler(this,&TagFileParser::endMember));
@@ -527,6 +566,8 @@ class TagFileParser : public QXmlDefaultHandler
m_endElementHandlers.insert("page", new EndElementHandler(this,&TagFileParser::endPage));
m_endElementHandlers.insert("docanchor", new EndElementHandler(this,&TagFileParser::endDocAnchor));
m_endElementHandlers.insert("tagfile", new EndElementHandler(this,&TagFileParser::endIgnoreElement));
+ m_endElementHandlers.insert("templarg", new EndElementHandler(this,&TagFileParser::endTemplateArg));
+ m_endElementHandlers.insert("type", new EndElementHandler(this,&TagFileParser::endType));
return TRUE;
}
@@ -811,6 +852,7 @@ void TagFileParser::buildMemberList(Entry *ce,QList<TagMemberInfo> &members)
for (;(tmi=mii.current());++mii)
{
Entry *me = new Entry;
+ me->type = tmi->type;
me->name = tmi->name;
me->args = tmi->arglist;
me->protection = tmi->prot;
@@ -929,6 +971,18 @@ void TagFileParser::buildLists(Entry *root)
{
ce->extends = tci->bases; tci->bases = 0;
}
+ if (tci->templateArguments)
+ {
+ if (ce->tArgList==0) ce->tArgList = new ArgumentList;
+ QListIterator<QString> sli(*tci->templateArguments);
+ QString *argName;
+ for (;(argName=sli.current());++sli)
+ {
+ Argument *a = new Argument;
+ a->name = *argName;
+ ce->tArgList->append(a);
+ }
+ }
buildMemberList(ce,tci->members);
root->addSubEntry(ce);
diff --git a/src/translator.cpp b/src/translator.cpp
new file mode 100644
index 0000000..1cb3040
--- /dev/null
+++ b/src/translator.cpp
@@ -0,0 +1,84 @@
+#include "translator.h"
+
+const char Translator::WinToISOTab[] =
+{
+ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',
+ '\x88', '\x89', '\xA9', '\x8B', '\xA6', '\xAB', '\xAE', '\xAC',
+ '\x90', '\x91', '\x92', '\x93', '\x94', '\x2E', '\x96', '\x97',
+ '\x98', '\x99', '\xB9', '\x9B', '\xB6', '\xBB', '\xBE', '\xBC',
+ '\xA0', '\x20', '\x20', '\xA3', '\xA4', '\xA1', '\xA6', '\xA7',
+ '\x22', '\xA9', '\xAA', '\x3C', '\xAC', '\x2D', '\xAE', '\xAF',
+ '\x2E', '\x2B', '\x20', '\xB3', '\x27', '\x75', '\xB6', '\xB7',
+ '\x20', '\xB1', '\xBA', '\x3E', '\xA5', '\x22', '\xB5', '\xBF',
+ '\xC0', '\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7',
+ '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE', '\xCF',
+ '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5', '\xD6', '\xD7',
+ '\xD8', '\xD9', '\xDA', '\xDB', '\xDC', '\xDD', '\xDE', '\xDF',
+ '\xE0', '\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7',
+ '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE', '\xEF',
+ '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5', '\xF6', '\x2D',
+ '\xF8', '\xF9', '\xFA', '\xFB', '\xFC', '\xFD', '\xFE', '\xFF',
+ '\0'
+};
+
+
+const char Translator::ISOToWinTab[] = {
+ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',
+ '\x88', '\x89', '\x8A', '\x8B', '\x8C', '\x8D', '\x8E', '\x8F',
+ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97',
+ '\x98', '\x99', '\x9A', '\x9B', '\x9C', '\x9D', '\x9E', '\x9F',
+ '\xA0', '\xA5', '\xA2', '\xA3', '\xA4', '\xBC', '\x8C', '\xA7',
+ '\xA8', '\x8A', '\xAA', '\x8D', '\x8F', '\xAD', '\x8E', '\xAF',
+ '\xB0', '\xB9', '\xB2', '\xB3', '\xB4', '\xBE', '\x9C', '\xB7',
+ '\xB8', '\x9A', '\xBA', '\x9D', '\x9F', '\xBD', '\x9E', '\xBF',
+ '\xC0', '\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7',
+ '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE', '\xCF',
+ '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5', '\xD6', '\xD7',
+ '\xD8', '\xD9', '\xDA', '\xDB', '\xDC', '\xDD', '\xDE', '\xDF',
+ '\xE0', '\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7',
+ '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE', '\xEF',
+ '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5', '\xF6', '\xF7',
+ '\xF8', '\xF9', '\xFA', '\xFB', '\xFC', '\xFD', '\xFE', '\xFF',
+ '\0'
+};
+
+Q_UINT16 Translator::koi8_r[128] =
+{ 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
+ 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
+ 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219/**/, 0x221A, 0x2248,
+ 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
+ 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
+ 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
+ 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
+ 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9,
+ 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
+ 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
+ 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
+ 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
+ 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
+ 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
+ 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
+ 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
+};
+
+
+Q_UINT16 Translator::windows_1251[128] =
+{ 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
+ 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
+ 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
+ 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
+ 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
+ 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
+};
+
+
diff --git a/src/translator.h b/src/translator.h
index 1119118..852b997 100644
--- a/src/translator.h
+++ b/src/translator.h
@@ -26,6 +26,10 @@
class Translator
{
protected:
+ static const char WinToISOTab[];
+ static const char ISOToWinTab[];
+ static Q_UINT16 koi8_r[128];
+ static Q_UINT16 windows_1251[128];
/*! Returns the string converted from windows-1250 to iso-8859-2. */
/* The method was designed initially for translator_cz.h.
* It is used for on-line encoding conversion related to
@@ -46,25 +50,6 @@ class Translator
{
// The conversion table for characters >127
//
- static const char WinToISOTab[] = {
- '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',
- '\x88', '\x89', '\xA9', '\x8B', '\xA6', '\xAB', '\xAE', '\xAC',
- '\x90', '\x91', '\x92', '\x93', '\x94', '\x2E', '\x96', '\x97',
- '\x98', '\x99', '\xB9', '\x9B', '\xB6', '\xBB', '\xBE', '\xBC',
- '\xA0', '\x20', '\x20', '\xA3', '\xA4', '\xA1', '\xA6', '\xA7',
- '\x22', '\xA9', '\xAA', '\x3C', '\xAC', '\x2D', '\xAE', '\xAF',
- '\x2E', '\x2B', '\x20', '\xB3', '\x27', '\x75', '\xB6', '\xB7',
- '\x20', '\xB1', '\xBA', '\x3E', '\xA5', '\x22', '\xB5', '\xBF',
- '\xC0', '\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7',
- '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE', '\xCF',
- '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5', '\xD6', '\xD7',
- '\xD8', '\xD9', '\xDA', '\xDB', '\xDC', '\xDD', '\xDE', '\xDF',
- '\xE0', '\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7',
- '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE', '\xEF',
- '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5', '\xF6', '\x2D',
- '\xF8', '\xF9', '\xFA', '\xFB', '\xFC', '\xFD', '\xFE', '\xFF',
- '\0'
- };
QCString result;
int len = sInput.length();
@@ -83,25 +68,6 @@ class Translator
{
// The conversion table for characters >127
//
- static const char ISOToWinTab[] = {
- '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',
- '\x88', '\x89', '\x8A', '\x8B', '\x8C', '\x8D', '\x8E', '\x8F',
- '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97',
- '\x98', '\x99', '\x9A', '\x9B', '\x9C', '\x9D', '\x9E', '\x9F',
- '\xA0', '\xA5', '\xA2', '\xA3', '\xA4', '\xBC', '\x8C', '\xA7',
- '\xA8', '\x8A', '\xAA', '\x8D', '\x8F', '\xAD', '\x8E', '\xAF',
- '\xB0', '\xB9', '\xB2', '\xB3', '\xB4', '\xBE', '\x9C', '\xB7',
- '\xB8', '\x9A', '\xBA', '\x9D', '\x9F', '\xBD', '\x9E', '\xBF',
- '\xC0', '\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7',
- '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE', '\xCF',
- '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5', '\xD6', '\xD7',
- '\xD8', '\xD9', '\xDA', '\xDB', '\xDC', '\xDD', '\xDE', '\xDF',
- '\xE0', '\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7',
- '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE', '\xEF',
- '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5', '\xF6', '\xF7',
- '\xF8', '\xF9', '\xFA', '\xFB', '\xFC', '\xFD', '\xFE', '\xFF',
- '\0'
- };
QCString result;
int len = sInput.length();
@@ -122,24 +88,6 @@ class Translator
*/
QCString Koi8RToWindows1251( const QCString & sInput )
{
- static Q_UINT16 koi8_r[128] =
- { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
- 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
- 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219/**/, 0x221A, 0x2248,
- 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
- 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
- 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
- 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
- 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9,
- 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
- 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
- 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
- 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
- 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
- 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
- 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
- 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
- };
QString result;
int len = sInput.length();
@@ -160,25 +108,6 @@ class Translator
Encoding table got from QT:qtextcodec.cpp */
QCString Windows1251ToKoi8R( const QCString & sInput )
{
- static Q_UINT16 windows_1251[128] =
- { 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
- 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
- 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
- 0xFFFD, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
- 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
- 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
- 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
- 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
- 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
- 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
- 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
- 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
- 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
- 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
- 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
- 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
- };
-
QString result;
int len = sInput.length();
@@ -267,7 +196,7 @@ class Translator
*/
virtual QCString trGeneratedAutomatically(const char *s) = 0;
- /*! put after an enum name in the list of all members */
+
virtual QCString trEnumName() = 0;
/*! put after an enum value in the list of all members */
diff --git a/src/translator_en.h b/src/translator_en.h
index 16b2c65..edffbb9 100644
--- a/src/translator_en.h
+++ b/src/translator_en.h
@@ -397,7 +397,16 @@ class TranslatorEnglish : public Translator
* the documentation of all classes, structs and unions.
*/
virtual QCString trClassDocumentation()
- { return "Class Documentation"; }
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Data Structure Documentation";
+ }
+ else
+ {
+ return "Class Documentation";
+ }
+ }
/*! This is used in LaTeX as the title of the chapter containing
* the documentation of all files.
@@ -1024,7 +1033,9 @@ class TranslatorEnglish : public Translator
{
return "Graph Legend";
}
- /*! page explaining how the dot graph's should be interpreted */
+ /*! page explaining how the dot graph's should be interpreted
+ * The %A in the text below are to prevent link to classes called "A".
+ */
virtual QCString trLegendDocs()
{
return
@@ -1062,21 +1073,21 @@ class TranslatorEnglish : public Translator
"<p>\n"
"The boxes in the above graph have the following meaning:\n"
"<ul>\n"
- "<li>A filled black box represents the struct or class for which the "
+ "<li>%A filled black box represents the struct or class for which the "
"graph is generated.\n"
- "<li>A box with a black border denotes a documented struct or class.\n"
- "<li>A box with a grey border denotes an undocumented struct or class.\n"
- "<li>A box with a red border denotes a documented struct or class for\n"
- "which not all inheritance/containment relations are shown. A graph is "
+ "<li>%A box with a black border denotes a documented struct or class.\n"
+ "<li>%A box with a grey border denotes an undocumented struct or class.\n"
+ "<li>%A box with a red border denotes a documented struct or class for\n"
+ "which not all inheritance/containment relations are shown. %A graph is "
"truncated if it does not fit within the specified boundaries."
"</ul>\n"
"The arrows have the following meaning:\n"
"<ul>\n"
- "<li>A dark blue arrow is used to visualize a public inheritance "
+ "<li>%A dark blue arrow is used to visualize a public inheritance "
"relation between two classes.\n"
- "<li>A dark green arrow is used for protected inheritance.\n"
- "<li>A dark red arrow is used for private inheritance.\n"
- "<li>A purple dashed arrow is used if a class is contained or used "
+ "<li>%A dark green arrow is used for protected inheritance.\n"
+ "<li>%A dark red arrow is used for private inheritance.\n"
+ "<li>%A purple dashed arrow is used if a class is contained or used "
"by another class. The arrow is labeled with the variable(s) "
"through which the pointed class or struct is accessible. \n"
"</ul>\n";
diff --git a/src/translator_fr.h b/src/translator_fr.h
index 82af3d5..c7a7f3f 100644
--- a/src/translator_fr.h
+++ b/src/translator_fr.h
@@ -15,18 +15,37 @@
*
* The translation into French was provided by
* Christophe Bordeux (bordeux@lig.di.epfl.ch)
+ * and after version 1.2.0 by Xavier Outhier (xouthier@yahoo.fr)
+ * member of of the non for profit association D2SET (http://www.d2set.org,
+ * d2set@d2set.org).
*/
#ifndef TRANSLATOR_FR_H
#define TRANSLATOR_FR_H
-#include "translator_adapter.h"
-
-class TranslatorFrench : public TranslatorAdapter_1_2_0
+class TranslatorFrench : public Translator
{
public:
QCString idLanguage()
{ return "french"; }
+ /*! Used to get the LaTeX command(s) for the language support.
+ * This method should return string with commands that switch
+ * LaTeX to the desired language. For example
+ * <pre>"\\usepackage[german]{babel}\n"
+ * </pre>
+ * or
+ * <pre>"\\usepackage{polski}\n"
+ * "\\usepackage[latin2]{inputenc}\n"
+ * "\\usepackage[T1]{fontenc}\n"
+ * </pre>
+ *
+ * The Dutch LaTeX does not use such commands. Because of this
+ * the empty string is returned in this implementation.
+ */
+ QCString latexLanguageSupportCommand()
+ {
+ return "\\usepackage[french]{babel}\n";
+ }
/*! returns the name of the package that is included by LaTeX */
QCString latexBabelPackage()
{ return "french"; }
@@ -851,7 +870,7 @@ class TranslatorFrench : public TranslatorAdapter_1_2_0
/*! Used as a marker that is put before a todo item */
virtual QCString trTodo()
{
- return "A Faire";
+ return "À Faire";
}
/*! Used as the header of the todo list */
virtual QCString trTodoList()
@@ -947,7 +966,7 @@ class TranslatorFrench : public TranslatorAdapter_1_2_0
"entre deux classes.\n"
"<li>Une flèche vert foncé est utilisée pour une relation d'héritage protégé.\n"
"<li>Une flèche rouge foncé est utilisée pour une relation d'héritage privé.\n"
- "<li>Une fléche violette en pointillés est utilisée si une classe est contenue ou "
+ "<li>Une flèche violette en pointillés est utilisée si une classe est contenue ou "
"utilisée par une autre classe. La flèche est étiquetée avec la ou les variable(s) "
"qui permettent d'acceder à la classe ou structure pointée. \n"
"</ul>\n";
@@ -957,6 +976,262 @@ class TranslatorFrench : public TranslatorAdapter_1_2_0
{
return "Légende";
}
-};
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "Test";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "Liste des tests";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for KDE-2 IDL methods */
+ virtual QCString trDCOPMethods()
+ {
+ return "Méthodes DCOP";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Propriétés";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Documentation des propriétés";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.4
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used for Java interfaces in the summary section of Java packages */
+ virtual QCString trInterfaces()
+ {
+ return "Interfaces";
+ }
+ /*! Used for Java classes in the summary section of Java packages */
+ virtual QCString trClasses()
+ {
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ return "Structures de données";
+ }
+ else
+ {
+ return "Classes";
+ }
+ }
+ /*! Used as the title of a Java package */
+ virtual QCString trPackage(const char *name)
+ {
+ return (QCString)"Paquetage "+name;
+ }
+ /*! Title of the package index page */
+ virtual QCString trPackageList()
+ {
+ return "Liste des paquetages";
+ }
+ /*! The description of the package index page */
+ virtual QCString trPackageListDescription()
+ {
+ return "Liste des paquetages avec une brève description (si disponible):";
+ }
+ /*! The link name in the Quick links header for each page */
+ virtual QCString trPackages()
+ {
+ return "Paquetages";
+ }
+ /*! Used as a chapter title for Latex & RTF output */
+ virtual QCString trPackageDocumentation()
+ {
+ return "Documentation des paquetages";
+ }
+ /*! Text shown before a multi-line define */
+ virtual QCString trDefineValue()
+ {
+ return "Valeur:";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a \\bug item */
+ virtual QCString trBug()
+ {
+ return "Bogue";
+ }
+ /*! Used as the header of the bug list */
+ virtual QCString trBugList()
+ {
+ return "Liste des bogues";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.6
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as ansicpg for RTF file
+ *
+ * The following table shows the correlation of Charset name, Charset Value and
+ * <pre>
+ * Codepage number:
+ * Charset Name Charset Value(hex) Codepage number
+ * ------------------------------------------------------
+ * DEFAULT_CHARSET 1 (x01)
+ * SYMBOL_CHARSET 2 (x02)
+ * OEM_CHARSET 255 (xFF)
+ * ANSI_CHARSET 0 (x00) 1252
+ * RUSSIAN_CHARSET 204 (xCC) 1251
+ * EE_CHARSET 238 (xEE) 1250
+ * GREEK_CHARSET 161 (xA1) 1253
+ * TURKISH_CHARSET 162 (xA2) 1254
+ * BALTIC_CHARSET 186 (xBA) 1257
+ * HEBREW_CHARSET 177 (xB1) 1255
+ * ARABIC _CHARSET 178 (xB2) 1256
+ * SHIFTJIS_CHARSET 128 (x80) 932
+ * HANGEUL_CHARSET 129 (x81) 949
+ * GB2313_CHARSET 134 (x86) 936
+ * CHINESEBIG5_CHARSET 136 (x88) 950
+ * </pre>
+ *
+ */
+ virtual QCString trRTFansicp()
+ {
+ return "1252";
+ }
+
+
+ /*! Used as ansicpg for RTF fcharset
+ * \see trRTFansicp() for a table of possible values.
+ */
+ virtual QCString trRTFCharSet()
+ {
+ return "0";
+ }
+
+ /*! Used as header RTF general index */
+ virtual QCString trRTFGeneralIndex()
+ {
+ return "Index";
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trClass(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Classe" : "classe"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trFile(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Fichier" : "fichier"));
+ if (!singular) result+="s";
+ return result;
+ }
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trNamespace(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Namespace" : "namespace"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGroup(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Groupe" : "groupe"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trPage(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Page" : "page"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trMember(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Membre" : "membre"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trField(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Champ" : "champ"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+ /*! This is used for translation of the word that will possibly
+ * be followed by a single name or by a list of names
+ * of the category.
+ */
+ virtual QCString trGlobal(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Global(e)" : "global(e)"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.7
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This text is generated when the \\author command is used and
+ * for the author section in man pages. */
+ virtual QCString trAuthor(bool first_capital, bool singular)
+ {
+ QCString result((first_capital ? "Auteur" : "auteur"));
+ if (!singular) result+="s";
+ return result;
+ }
+
+};
#endif
diff --git a/src/util.cpp b/src/util.cpp
index c4b2606..6a022af 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -715,7 +715,7 @@ QCString argListToString(ArgumentList *al)
result+=")";
if (al->constSpecifier) result+=" const";
if (al->volatileSpecifier) result+=" volatile";
- return result;
+ return removeRedundantWhiteSpace(result);
}
QCString tempArgListToString(ArgumentList *al)
@@ -743,7 +743,7 @@ QCString tempArgListToString(ArgumentList *al)
if (a) result+=", ";
}
result+=">";
- return result;
+ return removeRedundantWhiteSpace(result);
}
@@ -2804,8 +2804,7 @@ void addMembersToMemberGroup(MemberList *ml,MemberGroupDict *memberGroupDict,
* could form a class. When TRUE is returned the result is the
* class \a name and a template argument list \a templSpec.
*/
-bool extractClassNameFromType(const QCString &type,int &pos,
- QCString &name,QCString &templSpec)
+bool extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCString &templSpec)
{
static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*");
name.resize(0);
@@ -2818,7 +2817,8 @@ bool extractClassNameFromType(const QCString &type,int &pos,
{
int ts=i+l;
int te=ts;
- while (type.at(ts)==' ' && ts<typeLen) ts++; // skip any whitespace
+ int tl=0;
+ while (type.at(ts)==' ' && ts<typeLen) ts++,tl++; // skip any whitespace
if (type.at(ts)=='<') // assume template instance
{
// locate end of template
@@ -2837,12 +2837,68 @@ bool extractClassNameFromType(const QCString &type,int &pos,
te++;
}
}
- if (te>ts) templSpec = type.mid(ts,te-ts);
+ if (te>ts) templSpec = type.mid(ts,te-ts),tl+=te-ts;
name = type.mid(i,l);
- pos=i+l;
+ pos=i+l+tl;
+ //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=TRUE\n",
+ // type.data(),pos,name.data(),templSpec.data());
return TRUE;
}
}
+ //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=FALSE\n",
+ // type.data(),pos,name.data(),templSpec.data());
return FALSE;
}
+/*! Substitutes any occurrence of a formal argument from argument list
+ * \a formalArgs in \a name by the corresponding actual argument in
+ * argument list \a actualArgs. The result after substitution
+ * is returned as a string.
+ */
+QCString substituteTemplateArgumentsInString(
+ const QCString &name,ArgumentList *formalArgs,ArgumentList *actualArgs)
+{
+ if (formalArgs==0) return name;
+ QCString result;
+ static QRegExp re("[a-z_A-Z][:a-z_A-Z0-9]*");
+ int p=0,l,i;
+ // for each identifier in the base class name (e.g. B<T> -> B and T)
+ while ((i=re.match(name,p,&l))!=-1)
+ {
+ result += name.mid(p,i-p);
+ QCString n = name.mid(i,l);
+ ArgumentListIterator formAli(*formalArgs);
+ Argument *formArg;
+ Argument *actArg=actualArgs->first();
+
+ // if n is a template argument, then we substitute it
+ // for its template instance argument.
+ bool found=FALSE;
+ for (formAli.toFirst();
+ (formArg=formAli.current()) && !found;
+ ++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())
+ {
+ result += formArg->defval;
+ found=TRUE;
+ }
+ }
+ if (!found) result += n;
+ p=i+l;
+ }
+ result+=name.right(name.length()-p);
+ //printf(" Inheritance relation %s -> %s\n",
+ // name.data(),result.data());
+ return result;
+}
+
+
+
diff --git a/src/util.h b/src/util.h
index 695a289..ec5b197 100644
--- a/src/util.h
+++ b/src/util.h
@@ -150,6 +150,8 @@ void addMembersToMemberGroup(MemberList *ml,MemberGroupDict *memberGroupDict,
MemberGroupList *memberGroupList);
bool extractClassNameFromType(const QCString &type,int &pos,
QCString &name,QCString &templSpec);
+QCString substituteTemplateArgumentsInString(
+ const QCString &name,ArgumentList *formalArgs,ArgumentList *actualArgs);
#endif