summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2001-08-05 12:03:04 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2001-08-05 12:03:04 (GMT)
commit490b7178adcf627892b0686b80016422e64dcfa3 (patch)
treeae6f91b471c21991428c9b75a29ff8df55d1889d /src
parentecb8f53e30524a6eca3c28db4d1a1d708a5a0976 (diff)
downloadDoxygen-490b7178adcf627892b0686b80016422e64dcfa3.zip
Doxygen-490b7178adcf627892b0686b80016422e64dcfa3.tar.gz
Doxygen-490b7178adcf627892b0686b80016422e64dcfa3.tar.bz2
Release-1.2.9.1
Diffstat (limited to 'src')
-rw-r--r--src/classdef.cpp23
-rw-r--r--src/classdef.h2
-rw-r--r--src/classlist.cpp8
-rw-r--r--src/declinfo.h1
-rw-r--r--src/declinfo.l6
-rw-r--r--src/definition.cpp9
-rw-r--r--src/doc.l13
-rw-r--r--src/doxygen.cpp295
-rw-r--r--src/htmlgen.h4
-rw-r--r--src/index.cpp6
-rw-r--r--src/latexgen.cpp6
-rw-r--r--src/latexgen.h4
-rw-r--r--src/mangen.h4
-rw-r--r--src/memberdef.cpp13
-rw-r--r--src/memberdef.h1
-rw-r--r--src/rtfgen.cpp8
-rw-r--r--src/scanner.l125
-rw-r--r--src/util.cpp300
-rw-r--r--src/util.h2
-rw-r--r--src/xmlgen.cpp4
20 files changed, 575 insertions, 259 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 0a600a2..c0feb10 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -88,15 +88,15 @@ ClassDef::ClassDef(
m_memberGroupList->setAutoDelete(TRUE);
m_memberGroupDict = new MemberGroupDict(17);
m_innerClasses = new ClassSDict(17);
- int i=name().findRev("::");
- if (i==-1)
- {
- m_scopelessName=name();
- }
- else
- {
- m_scopelessName=name().right(name().length()-i-2);
- }
+ //int i=name().findRev("::"); // TODO: broken if A<N::C> is the class name
+ //if (i==-1)
+ //{
+ // m_scopelessName=name();
+ //}
+ //else
+ //{
+ // m_scopelessName=name().right(name().length()-i-2);
+ //}
m_subGrouping=TRUE;
m_isTemplBaseClass=-1;
m_templateInstances = 0;
@@ -415,7 +415,7 @@ void ClassDef::insertMember(MemberDef *md)
enumValMembers.append(md);
break;
case MemberDef::Function:
- if (md->name()==m_scopelessName || // constructor
+ if (md->name()==localName() || // constructor
(md->name().find('~')!=-1 && // hack to detect destructor
md->name().find("operator")==-1
)
@@ -2232,6 +2232,7 @@ void ClassDef::getTemplateParameterLists(QList<ArgumentList> &lists) const
QCString ClassDef::qualifiedNameWithTemplateParameters(
QList<ArgumentList> *actualParams) const
{
+ //printf("qualifiedNameWithTemplateParameters() localName=%s\n",localName().data());
QCString scName;
Definition *d=getOuterScope();
if (d)
@@ -2268,7 +2269,7 @@ QCString ClassDef::qualifiedNameWithTemplateParameters(
}
}
}
- //printf("scope=%s qualifiedName=%s\n",name().data(),scName.data());
+ //printf("qualifiedNameWithTemplateParameters: scope=%s qualifiedName=%s\n",name().data(),scName.data());
return scName;
}
diff --git a/src/classdef.h b/src/classdef.h
index 924c56f..939cd90 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -325,7 +325,7 @@ class ClassDef : public Definition
/*! Bare name of the class without any scoping prefixes
* (like for nested classes and classes inside namespaces)
*/
- QCString m_scopelessName;
+ //QCString m_scopelessName;
/*! List of base class (or super-classes) from which this class derives
* directly.
diff --git a/src/classlist.cpp b/src/classlist.cpp
index ca05275..7c69d73 100644
--- a/src/classlist.cpp
+++ b/src/classlist.cpp
@@ -35,8 +35,8 @@ int ClassList::compareItems(GCI item1, GCI item2)
{
ClassDef *c1=(ClassDef *)item1;
ClassDef *c2=(ClassDef *)item2;
- return stricmp(c1->name().data()+getPrefixIndex(c1->name()),
- c2->name().data()+getPrefixIndex(c2->name())
+ return stricmp(c1->name().data()+getPrefixIndex(c1->localName()),
+ c2->name().data()+getPrefixIndex(c2->localName())
);
}
@@ -44,8 +44,8 @@ int ClassSDict::compareItems(GCI item1, GCI item2)
{
ClassDef *c1=(ClassDef *)item1;
ClassDef *c2=(ClassDef *)item2;
- return stricmp(c1->name().data()+getPrefixIndex(c1->name()),
- c2->name().data()+getPrefixIndex(c2->name())
+ return stricmp(c1->name().data()+getPrefixIndex(c1->localName()),
+ c2->name().data()+getPrefixIndex(c2->localName())
);
}
diff --git a/src/declinfo.h b/src/declinfo.h
index b337aae..0b183d7 100644
--- a/src/declinfo.h
+++ b/src/declinfo.h
@@ -23,7 +23,6 @@
extern void parseFuncDecl(const QCString &decl,
QCString &clName,
- QCString &classTempList,
QCString &type,
QCString &name,
QCString &args,
diff --git a/src/declinfo.l b/src/declinfo.l
index 5548b56..d06f824 100644
--- a/src/declinfo.l
+++ b/src/declinfo.l
@@ -206,7 +206,7 @@ ID ([a-z_A-Z][a-z_A-Z0-9]*)|(@[0-9]+)
/*@ ----------------------------------------------------------------------------
*/
-void parseFuncDecl(const QCString &decl,QCString &cl,QCString &ctl,QCString &t,
+void parseFuncDecl(const QCString &decl,QCString &cl,QCString &t,
QCString &n,QCString &a,QCString &ftl,QCString &exc)
{
inputString = decl;
@@ -256,9 +256,11 @@ void parseFuncDecl(const QCString &decl,QCString &cl,QCString &ctl,QCString &t,
cl+=c;
}
}
-#endif
cl=stripTemplateSpecifiersFromScope(removeRedundantWhiteSpace(scope),FALSE);
ctl.resize(0);
+#endif
+
+ cl=scope;
n=removeRedundantWhiteSpace(name);
int il,ir;
if ((il=n.find('<'))!=-1 && (ir=n.findRev('>'))!=-1)
diff --git a/src/definition.cpp b/src/definition.cpp
index e4ea9c3..fc764f7 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -34,12 +34,7 @@ Definition::Definition(const char *df,int dl,
m_defFileName = df;
m_defLine = dl;
m_name=name;
- m_localName=name;
- int i=m_localName.findRev("::");
- if (i!=-1)
- {
- m_localName=m_localName.right(m_localName.length()-i-2);
- }
+ m_localName=stripScope(name);
m_brief=b;
m_doc=d;
m_sectionDict=0,
@@ -451,7 +446,7 @@ void Definition::addInnerCompound(Definition *)
QCString Definition::qualifiedName() const
{
- //printf("start Definition::qualifiedName()\n");
+ //printf("start Definition::qualifiedName() localName=%s\n",m_localName.data());
if (m_outerScope==0)
{
if (m_localName=="<globalScope>") return "";
diff --git a/src/doc.l b/src/doc.l
index 2d7ddbe..974f54b 100644
--- a/src/doc.l
+++ b/src/doc.l
@@ -892,7 +892,6 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG})
%x DocEmphasis
%x DocBold
%x DocCode
-%x DocIf
%x DocCodeBlock
%x DocInternal
%x DocLink
@@ -1506,9 +1505,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG})
inParamBlock=TRUE;
currentListIndent.push("D");
outDoc->startParamList();
- outDoc->startBold();
scanString(theTranslator->trParameters()+": ");
- outDoc->endBold();
outDoc->endDescTitle();
outDoc->writeDescItem();
outDoc->startDescTable();
@@ -1532,9 +1529,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG})
inRetValBlock=TRUE;
currentListIndent.push("D");
outDoc->startParamList();
- outDoc->startBold();
scanString(theTranslator->trReturnValues()+": ");
- outDoc->endBold();
outDoc->endDescTitle();
outDoc->writeDescItem();
outDoc->startDescTable();
@@ -1558,9 +1553,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG})
inExceptionBlock=TRUE;
currentListIndent.push("D");
outDoc->startParamList();
- outDoc->startBold();
scanString(theTranslator->trExceptions()+": ");
- outDoc->endBold();
outDoc->endDescTitle();
outDoc->writeDescItem();
outDoc->startDescTable();
@@ -1574,18 +1567,14 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG})
<DocScan>"\\capt".*
<DocParam>({DOCPARAM}{BN}*","{BN}*)*{DOCPARAM}{BSEP}* {
outDoc->startDescTableTitle();
- outDoc->startEmphasis();
outDoc->docify(substitute(yytext,"\"","").stripWhiteSpace());
- outDoc->endEmphasis();
outDoc->endDescTableTitle();
outDoc->startDescTableData();
BEGIN(DocScan);
}
<DocException>{SCOPENAME} {
outDoc->startDescTableTitle();
- outDoc->startEmphasis();
outDoc->docify(yytext);
- outDoc->endEmphasis();
outDoc->endDescTableTitle();
outDoc->startDescTableData();
BEGIN(DocScan);
@@ -1646,6 +1635,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG})
<DocScan>{CMD}"refitem"/{BN} {
BEGIN(DocRefItem);
}
+ /*
<DocScan>{CMD}"if"/{BN} {
outDoc->pushGeneratorState();
depthIf++;
@@ -1671,6 +1661,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG})
}
BEGIN(DocScan);
}
+ */
<DocRefName>{SCOPENAME}|{FILE} {
QCString ref=yytext;
SectionInfo *sec;
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index a0dd54c..70f7d98 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -353,6 +353,7 @@ static void addRefItem(int todoId,int testId,int bugId,const char *prefix,
doc += "</dt>\n<dd>";
doc += item->text;
doc += "</dd></dl>\n";
+ //printf("Test page: %s\n",doc.data());
addRelatedPage("test",theTranslator->trTestList(),doc,0,"generated",1,0,0,0);
item->written=TRUE;
@@ -675,34 +676,29 @@ static Definition *findScope(Entry *root,int level=0)
static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n)
{
//printf("findScopeFromQualifiedName(%s,%s)\n",startScope ? startScope->name().data() : 0, n.data());
- QCString name(n);
- if (startScope==0) startScope=Doxygen::globalScope;
- int i = name.find("::");
- if (i==-1)
- {
- return startScope;
- }
-
- QCString scope=stripTemplateSpecifiersFromScope(name,FALSE);
- //printf("name=%s -> scope=%s\n",name.data(),scope.data());
- while ((i = scope.find("::"))!=-1)
- {
- //int ti = name.find('<');
- //if (ti!=-1 && ti<i) i=ti; // strip template specifiers
- QCString nestedNameSpecifier = scope.left(i);
- //Definition *oldScope = startScope;
- startScope = startScope->findInnerCompound(nestedNameSpecifier);
- //printf("Trying %s result=%p\n",nestedNameSpecifier.data(),startScope);
- if (startScope==0)
+ Definition *resultScope=startScope;
+ if (resultScope==0) resultScope=Doxygen::globalScope;
+ QCString scope=stripTemplateSpecifiersFromScope(n,FALSE);
+ int l1=0,i1;
+ i1=getScopeFragment(scope,0,&l1);
+ if (i1==-1) return resultScope;
+ int p=i1+l1,l2=0,i2;
+ while ((i2=getScopeFragment(scope,p,&l2))!=-1)
+ {
+ QCString nestedNameSpecifier = scope.mid(i1,l1);
+ //Definition *oldScope = resultScope;
+ resultScope = resultScope->findInnerCompound(nestedNameSpecifier);
+ if (resultScope==0)
{
//printf("name %s not found in scope %s\n",nestedNameSpecifier.data(),oldScope->name().data());
return 0;
}
- scope = scope.right(scope.length()-i-2);
- //printf("scope=%s\n",scope.data());
+ i1=i2;
+ l1=l2;
+ p=i2+l2;
}
- //printf("findScopeFromQualifiedName() result=%s\n",startScope ? startScope->name().data() : 0);
- return startScope;
+ //printf("scope %s\n",resultScope->name().data());
+ return resultScope;
}
ArgumentList *getTemplateArgumentsFromName(
@@ -834,6 +830,15 @@ static void buildClassList(Entry *root)
addClassToGroups(root,cd);
cd->setRefItems(root->todoId,root->testId,root->bugId);
if (!root->subGrouping) cd->setSubGrouping(FALSE);
+
+ if (cd->templateArguments()==0)
+ {
+ // this happens if a template class declared with @class is found
+ // before the actual definition.
+ ArgumentList *tArgList =
+ getTemplateArgumentsFromName(fullName,root->tArgLists);
+ cd->setTemplateArguments(tArgList);
+ }
}
else // new class
{
@@ -1981,6 +1986,7 @@ static void buildMemberList(Entry *root)
addMemberToGroups(root,md);
root->section = Entry::EMPTY_SEC;
+ md->setRefItems(root->todoId,root->testId,root->bugId);
}
else if (root->parent &&
!(root->parent->section & Entry::COMPOUND_MASK) &&
@@ -2015,10 +2021,12 @@ static void buildMemberList(Entry *root)
QCString nsName,rnsName;
if (nd) nsName = nd->name().copy();
if (rnd) rnsName = rnd->name().copy();
+ //printf("matching arguments for %s\n",md->name().data());
if (
matchArguments(md->argumentList(),root->argList,0,nsName)
)
{
+ //printf("match!\n");
// see if we need to create a new member
found=(nd && rnd && nsName==rnsName) || // members are in the same namespace
((fd!=0 && // no external reference and
@@ -3206,8 +3214,96 @@ static void computeMemberReferences()
//----------------------------------------------------------------------
+static void addClassMemberTodoTestBufReferences(Definition *compound)
+{
+ MemberNameListIterator mnli(Doxygen::memberNameList);
+ MemberName *mn=0;
+ for (mnli.toFirst();(mn=mnli.current());++mnli)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md=0;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ Definition *d=md->getClassDef();
+ QCString scopeName;
+ if (d) scopeName=d->name();
+ if (d==0) d=md->getGroupDef();
+ if (d==0) d=md->getFileDef();
+ if (compound==d || (compound==0 && d!=0 && !md->visited))
+ {
+ QCString memLabel;
+ md->visited=TRUE;
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ memLabel=theTranslator->trField(TRUE,TRUE);
+ }
+ else
+ {
+ memLabel=theTranslator->trMember(TRUE,TRUE);
+ }
+ addRefItem(md->todoId(),md->testId(),md->bugId(),memLabel,d->getOutputFileBase()+":"+md->anchor(),scopeName+"::"+md->name(),md->argsString());
+ }
+ }
+ }
+}
+
+static void addFileMemberTodoTestBufReferences(Definition *compound)
+{
+ MemberNameListIterator fnli(Doxygen::functionNameList);
+ MemberName *mn=0;
+ for (fnli.toFirst();(mn=fnli.current());++fnli)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md=0;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ Definition *d=md->getNamespaceDef();
+ QCString scopeName;
+ if (d) scopeName=d->name();
+ if (d==0) d=md->getGroupDef();
+ if (d==0) d=md->getFileDef();
+ if (compound==d || (compound==0 && d!=0 && !md->visited))
+ {
+ QCString memLabel;
+ md->visited=TRUE;
+ if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
+ {
+ memLabel=theTranslator->trGlobal(TRUE,TRUE);
+ }
+ else
+ {
+ memLabel=theTranslator->trMember(TRUE,TRUE);
+ }
+ addRefItem(md->todoId(),md->testId(),md->bugId(),memLabel,d->getOutputFileBase()+":"+md->anchor(),md->name(),md->argsString());
+ }
+ }
+ }
+}
+
static void addTodoTestBugReferences()
{
+ MemberNameListIterator mnli(Doxygen::memberNameList);
+ MemberName *mn=0;
+ for (mnli.toFirst();(mn=mnli.current());++mnli)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md=0;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ md->visited=FALSE;
+ }
+ }
+ MemberNameListIterator fnli(Doxygen::functionNameList);
+ for (fnli.toFirst();(mn=fnli.current());++fnli)
+ {
+ MemberNameIterator mni(*mn);
+ MemberDef *md=0;
+ for (mni.toFirst();(md=mni.current());++mni)
+ {
+ md->visited=FALSE;
+ }
+ }
+
ClassSDict::Iterator cli(Doxygen::classSDict);
ClassDef *cd=0;
for (cli.toFirst();(cd=cli.current());++cli)
@@ -3216,6 +3312,7 @@ static void addTodoTestBugReferences()
theTranslator->trClass(TRUE,TRUE),
cd->getOutputFileBase(),cd->name()
);
+ addClassMemberTodoTestBufReferences(cd);
}
FileName *fn=Doxygen::inputNameList.first();
while (fn)
@@ -3226,6 +3323,7 @@ static void addTodoTestBugReferences()
addRefItem(fd->todoId(),fd->testId(),fd->bugId(),
theTranslator->trFile(TRUE,TRUE),
fd->getOutputFileBase(),fd->name());
+ addFileMemberTodoTestBufReferences(fd);
fd=fn->next();
}
fn=Doxygen::inputNameList.next();
@@ -3236,6 +3334,7 @@ static void addTodoTestBugReferences()
addRefItem(nd->todoId(),nd->testId(),nd->bugId(),
theTranslator->trNamespace(TRUE,TRUE),
nd->getOutputFileBase(),nd->name());
+ addFileMemberTodoTestBufReferences(nd);
nd=Doxygen::namespaceList.next();
}
GroupDef *gd=Doxygen::groupList.first();
@@ -3244,6 +3343,7 @@ static void addTodoTestBugReferences()
addRefItem(gd->todoId(),gd->testId(),gd->bugId(),
theTranslator->trGroup(TRUE,TRUE),
gd->getOutputFileBase(),gd->groupTitle());
+ addFileMemberTodoTestBufReferences(gd);
gd=Doxygen::groupList.next();
}
PageSDictIterator pdi(*Doxygen::pageSDict);
@@ -3254,62 +3354,8 @@ static void addTodoTestBugReferences()
theTranslator->trPage(TRUE,TRUE),
pi->name,pi->title);
}
- MemberNameListIterator mnli(Doxygen::memberNameList);
- MemberName *mn=0;
- for (mnli.toFirst();(mn=mnli.current());++mnli)
- {
- MemberNameIterator mni(*mn);
- MemberDef *md=0;
- for (mni.toFirst();(md=mni.current());++mni)
- {
- Definition *d=md->getClassDef();
- QCString scopeName;
- if (d) scopeName=d->name();
- if (d==0) d=md->getGroupDef();
- if (d==0) d=md->getFileDef();
- // TODO: i18n this
- QCString memLabel;
- if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
- {
- memLabel=theTranslator->trField(TRUE,TRUE);
- }
- else
- {
- memLabel=theTranslator->trMember(TRUE,TRUE);
- }
- if (d)
- {
- addRefItem(md->todoId(),md->testId(),md->bugId(),memLabel,d->getOutputFileBase()+":"+md->anchor(),scopeName+"::"+md->name(),md->argsString());
- }
- }
- }
- MemberNameListIterator fnli(Doxygen::functionNameList);
- for (fnli.toFirst();(mn=fnli.current());++fnli)
- {
- MemberNameIterator mni(*mn);
- MemberDef *md=0;
- for (mni.toFirst();(md=mni.current());++mni)
- {
- Definition *d=md->getNamespaceDef();
- QCString scopeName;
- if (d) scopeName=d->name();
- if (d==0) d=md->getGroupDef();
- if (d==0) d=md->getFileDef();
- QCString memLabel;
- if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
- {
- memLabel=theTranslator->trGlobal(TRUE,TRUE);
- }
- else
- {
- memLabel=theTranslator->trMember(TRUE,TRUE);
- }
- if (d)
- {
- addRefItem(md->todoId(),md->testId(),md->bugId(),memLabel,d->getOutputFileBase()+":"+md->anchor(),md->name(),md->argsString());
- }
- }
- }
+ addClassMemberTodoTestBufReferences(0);
+ addFileMemberTodoTestBufReferences(0);
}
@@ -3458,29 +3504,10 @@ static void addMemberDocs(Entry *root,
// find a class definition given the scope name and (optionally) a
// template list specifier
-static ClassDef *findSimpleClassDefinition(const char *scopeName,const char *classTempList)
-{
- ClassDef *tcd=0;
- if (classTempList) // try to find the correct specialization
- {
- tcd=getClass(
- insertTemplateSpecifierInScope(
- scopeName,
- classTempList
- )
- ); // try specialization
- }
- if (tcd==0)
- {
- tcd=getClass(scopeName); // try general class
- }
- return tcd;
-}
-
static ClassDef *findClassDefinition(FileDef *fd,NamespaceDef *nd,
- const char *scopeName,const char *classTempList)
+ const char *scopeName)
{
- ClassDef *tcd = findSimpleClassDefinition(scopeName,classTempList);
+ ClassDef *tcd = getClass(scopeName);
if (tcd==0) // try using declaration
{
ClassList *cl = 0;
@@ -3507,7 +3534,7 @@ static ClassDef *findClassDefinition(FileDef *fd,NamespaceDef *nd,
if (rightScopeMatch(cd->name(),scope))
{
//printf("Trying to find `%s'\n",(cd->name()+scName.right(scName.length()-scopeOffset)).data());
- tcd = findSimpleClassDefinition(cd->name()+scName.right(scName.length()-scopeOffset),classTempList);
+ tcd = getClass(cd->name()+scName.right(scName.length()-scopeOffset));
}
scopeOffset=scName.findRev("::",scopeOffset-1);
} while (scopeOffset>=0 && tcd==0);
@@ -3532,7 +3559,7 @@ static ClassDef *findClassDefinition(FileDef *fd,NamespaceDef *nd,
for (;(nd=nli.current()) && tcd==0;++nli)
{
//printf("Trying with scope=%s\n",nd->name().data());
- tcd = findSimpleClassDefinition(nd->name()+"::"+scopeName,classTempList);
+ tcd = getClass(nd->name()+"::"+scopeName);
}
}
}
@@ -3708,34 +3735,6 @@ static void substituteTemplatesInArgList(
}
-static QCString mergeScopes(const QCString &leftScope,const QCString &rightScope)
-{
- // case leftScope=="A" rightScope=="A::B" => result = "A::B"
- if (leftScopeMatch(rightScope,leftScope)) return rightScope;
- QCString result;
- int i=0,p=leftScope.length();
-
- // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
- // case leftScope=="A::B" rightScope=="B" => result = "A::B"
- bool found=FALSE;
- while ((i=leftScope.findRev("::",p))!=-1)
- {
- if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
- {
- result = leftScope.left(i+2)+rightScope;
- found=TRUE;
- }
- p=i-1;
- }
- if (found) return result;
-
- // case leftScope=="A" rightScope=="B" => result = "A::B"
- result=leftScope.copy();
- if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
- result+=rightScope;
- return result;
-}
-
/*! This function tries to find a member (in a documented class/file/namespace)
* that corresponds to the function/variable declaration given in \a funcDecl.
@@ -3774,7 +3773,7 @@ static void findMember(Entry *root,
QCString scopeName;
QCString className;
QCString namespaceName;
- QCString classTempList;
+ //QCString classTempList;
QCString funcType;
QCString funcName;
QCString funcArgs;
@@ -3816,7 +3815,19 @@ static void findMember(Entry *root,
done=FALSE;
}
} while (!done);
-
+
+ if (isFriend)
+ {
+ if (funcDecl.left(6)=="class ")
+ {
+ funcDecl=funcDecl.right(funcDecl.length()-6);
+ }
+ else if (funcDecl.left(7)=="struct ")
+ {
+ funcDecl=funcDecl.right(funcDecl.length()-7);
+ }
+ }
+
// delete any ; from the function declaration
int sep;
while ((sep=funcDecl.find(';'))!=-1)
@@ -3837,12 +3848,12 @@ static void findMember(Entry *root,
);
// extract information from the declarations
- parseFuncDecl(funcDecl,scopeName,classTempList,funcType,funcName,
+ parseFuncDecl(funcDecl,scopeName,funcType,funcName,
funcArgs,funcTempList,exceptions
);
//printf("scopeName=`%s' funcType=`%s' funcName=`%s'\n",
// scopeName.data(),funcType.data(),funcName.data());
-
+
// the class name can also be a namespace name, we decide this later.
// if a related class name is specified and the class name could
// not be derived from the function declaration, then use the
@@ -3852,11 +3863,10 @@ static void findMember(Entry *root,
if (!related.isEmpty() && !isRelated)
{ // related member, prefix user specified scope
isRelated=TRUE;
- //scopeName=resolveDefines(related);
- if (!scopeName.isEmpty() && scopeName!=related)
- scopeName+="::"+related;
+ if (getClass(related)==0 && !scopeName.isEmpty())
+ scopeName= mergeScopes(scopeName,related);
else
- scopeName=related.copy();
+ scopeName = related.copy();
}
if (related.isEmpty() && root->parent &&
@@ -3864,8 +3874,9 @@ static void findMember(Entry *root,
!root->parent->name.isEmpty())
{
scopeName = mergeScopes(root->parent->name,scopeName);
- scopeName = stripTemplateSpecifiersFromScope(scopeName);
}
+ scopeName=stripTemplateSpecifiersFromScope(
+ removeRedundantWhiteSpace(scopeName),FALSE);
// split scope into a namespace and a class part
extractNamespaceName(scopeName,className,namespaceName);
@@ -3966,7 +3977,6 @@ static void findMember(Entry *root,
"findMember() Parse results:\n"
" namespaceName=`%s'\n"
" className=`%s`\n"
- " classTempList=`%s'\n"
" funcType=`%s'\n"
" funcName=`%s'\n"
" funcArgs=`%s'\n"
@@ -3977,7 +3987,7 @@ static void findMember(Entry *root,
" isRelated=%d\n"
" isFriend=%d\n"
" isFunc=%d\n\n",
- namespaceName.data(),className.data(),classTempList.data(),
+ namespaceName.data(),className.data(),
funcType.data(),funcName.data(),funcArgs.data(),funcTempList.data(),
funcDecl.data(),related.data(),exceptions.data(),isRelated,isFriend,
isFunc
@@ -4019,7 +4029,7 @@ static void findMember(Entry *root,
NamespaceDef *nd=0;
if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName);
- ClassDef *tcd=findClassDefinition(fd,nd,scopeName,classTempList);
+ ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
if (cd && tcd==cd) // member's classes match
{
@@ -4241,6 +4251,7 @@ static void findMember(Entry *root,
{
if (className.isEmpty()) className=related.copy();
ClassDef *cd;
+ //printf("scopeName=`%s'\n",scopeName.data());
if ((cd=getClass(scopeName)))
{
bool newMember=TRUE; // assume we have a new member
diff --git a/src/htmlgen.h b/src/htmlgen.h
index a471433..9bc9ffb 100644
--- a/src/htmlgen.h
+++ b/src/htmlgen.h
@@ -209,9 +209,9 @@ class HtmlGenerator : public OutputGenerator
void endDescTable()
{ t << "</table>" << endl; }
void startDescTableTitle()
- { t << "<tr><td valign=top>"; }
+ { t << "<tr><td valign=top><em>"; }
void endDescTableTitle()
- { t << endl << "&nbsp;</td>"; }
+ { t << endl << "</em>&nbsp;</td>"; }
void startDescTableData()
{ t << "<td>" << endl; }
void endDescTableData()
diff --git a/src/index.cpp b/src/index.cpp
index 2f149dd..5e3e53f 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -1194,7 +1194,7 @@ void writeAlphabeticalClassList(OutputList &ol)
{
if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
- int index = getPrefixIndex(cd->name());
+ int index = getPrefixIndex(cd->localName());
if (toupper(cd->name().at(index))!=startLetter) // new begin letter => new header
{
startLetter=toupper(cd->name().at(index));
@@ -1227,7 +1227,7 @@ void writeAlphabeticalClassList(OutputList &ol)
{
if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
- int index = getPrefixIndex(cd->name());
+ int index = getPrefixIndex(cd->localName());
if (toupper(cd->name().at(index))!=startLetter)
{
// insert a new header using a dummy class pointer.
@@ -1275,7 +1275,7 @@ void writeAlphabeticalClassList(OutputList &ol)
if (cd)
{
//printf("head ClassDef=%p %s\n",cd,cd ? cd->name().data() : "<none>");
- int index = getPrefixIndex(cd->name());
+ int index = getPrefixIndex(cd->localName());
startLetter=toupper(cd->name().at(index));
char s[2]; s[0]=startLetter; s[1]=0;
ol.writeIndexHeading(s);
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index fb7777e..7ffa258 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -540,7 +540,7 @@ void LatexGenerator::startIndexSection(IndexSections is)
bool found=FALSE;
for (cli.toFirst();(cd=cli.current()) && !found;++cli)
{
- if (cd->isLinkableInProject())
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
if (compactLatex) t << "\\section"; else t << "\\chapter";
t << "{"; //Compound Documentation}\n";
@@ -711,7 +711,7 @@ void LatexGenerator::endIndexSection(IndexSections is)
bool found=FALSE;
for (cli.toFirst();(cd=cli.current()) && !found;++cli)
{
- if (cd->isLinkableInProject())
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
t << "}\n\\input{" << cd->getOutputFileBase() << "}\n";
found=TRUE;
@@ -719,7 +719,7 @@ void LatexGenerator::endIndexSection(IndexSections is)
}
for (;(cd=cli.current());++cli)
{
- if (cd->isLinkableInProject())
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
if (compactLatex) t << "\\input"; else t << "\\include";
t << "{" << cd->getOutputFileBase() << "}\n";
diff --git a/src/latexgen.h b/src/latexgen.h
index 2e2c8e4..f2fca5a 100644
--- a/src/latexgen.h
+++ b/src/latexgen.h
@@ -217,9 +217,9 @@ class LatexGenerator : public OutputGenerator
void endDescTable()
{ t << "\\end{description}" << endl; }
void startDescTableTitle()
- { t << "\\item[" << endl; }
+ { t << "\\item[{\\em " << endl; }
void endDescTableTitle()
- { t << "]"; }
+ { t << "}]"; }
void startDescTableData() {}
void endDescTableData() {}
void lastIndexPage() {}
diff --git a/src/mangen.h b/src/mangen.h
index 4d0f774..92fcc3a 100644
--- a/src/mangen.h
+++ b/src/mangen.h
@@ -201,8 +201,8 @@ class ManGenerator : public OutputGenerator
void startDescTable() {}
void endDescTable() {}
- void startDescTableTitle() { writeListItem(); startBold(); }
- void endDescTableTitle() { endBold(); }
+ void startDescTableTitle() { writeListItem(); startBold(); startEmphasis(); }
+ void endDescTableTitle() { endEmphasis(); endBold(); }
void startDescTableData() { t << endl; firstCol=TRUE; }
void endDescTableData() {}
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index 3b22fd7..9c04b94 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -553,7 +553,8 @@ bool MemberDef::isBriefSectionVisible() const
// only include members that are non-private unless EXTRACT_PRIVATE is
// set to YES or the member is part of a group
bool visibleIfPrivate = (protection()!=Private ||
- Config_getBool("EXTRACT_PRIVATE")
+ Config_getBool("EXTRACT_PRIVATE") ||
+ mtype==Friend
);
bool visible = visibleIfStatic && visibleIfDocumented &&
@@ -666,7 +667,7 @@ void MemberDef::writeDeclaration(OutputList &ol,
if (tArgList)
{
writeTemplatePrefix(ol,tArgList);
- ol.lineBreak();
+ //ol.lineBreak();
}
QCString ltype(type);
@@ -879,7 +880,8 @@ bool MemberDef::isDetailedSectionLinkable() const
// only include members that are non-private unless EXTRACT_PRIVATE is
// set to YES or the member is part of a group
bool privateFilter = (protection()!=Private ||
- Config_getBool("EXTRACT_PRIVATE")
+ Config_getBool("EXTRACT_PRIVATE") ||
+ mtype==Friend
);
// member is part of an anonymous scope that is the type of
@@ -1198,9 +1200,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
if (a->hasDocumentation())
{
ol.startDescTableTitle();
- ol.startEmphasis();
ol.docify(a->name);
- ol.endEmphasis();
ol.endDescTableTitle();
ol.startDescTableData();
parseDoc(ol,m_defFileName,m_defLine,scopeName,name(),a->docs+"\n");
@@ -1475,7 +1475,8 @@ bool MemberDef::isLinkableInProject() const
return !name().isEmpty() && name().at(0)!='@' &&
((hasDocumentation() && !isReference())
) &&
- (prot!=Private || Config_getBool("EXTRACT_PRIVATE")) && // not a private class member
+ (prot!=Private || Config_getBool("EXTRACT_PRIVATE") ||
+ mtype==Friend) && // not a hidden member due to protection
(classDef!=0 || Config_getBool("EXTRACT_STATIC") ||
!isStatic()); // not a static file/namespace member
}
diff --git a/src/memberdef.h b/src/memberdef.h
index 6fa3b37..9f28afc 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -231,6 +231,7 @@ class MemberDef : public Definition
ArgumentList *actualArgs);
void setTemplateMaster(MemberDef *mt) { m_templateMaster=mt; }
+ bool visited;
private:
ClassDef *classDef; // member of or related to
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index 4605ae6..e79646b 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -1005,7 +1005,7 @@ void RTFGenerator::startIndexSection(IndexSections is)
bool found=FALSE;
for (cli.toFirst();(cd=cli.current()) && !found;++cli)
{
- if (cd->isLinkableInProject())
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
beginRTFChapter();
found=TRUE;
@@ -1238,7 +1238,7 @@ void RTFGenerator::endIndexSection(IndexSections is)
t << "{\\tc \\v " << theTranslator->trClassDocumentation() << "}"<< endl;
for (cli.toFirst();(cd=cli.current()) && !found;++cli)
{
- if (cd->isLinkableInProject())
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
t << "\\par " << Rtf_Style_Reset << endl;
t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
@@ -1249,7 +1249,7 @@ void RTFGenerator::endIndexSection(IndexSections is)
}
for (;(cd=cli.current());++cli)
{
- if (cd->isLinkableInProject())
+ if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
t << "\\par " << Rtf_Style_Reset << endl;
beginRTFSection();
@@ -2230,11 +2230,13 @@ void RTFGenerator::startDescTableTitle()
//t << Rtf_BList_DepthStyle() << endl;
DBG_RTF(t << "{\\comment (startDescTableTitle) }" << endl)
startBold();
+ startEmphasis();
}
void RTFGenerator::endDescTableTitle()
{
DBG_RTF(t << "{\\comment (endDescTableTitle) }" << endl)
+ endEmphasis();
endBold();
t << " ";
}
diff --git a/src/scanner.l b/src/scanner.l
index 239af2e..9f60f21 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -76,6 +76,7 @@ static int lastAnchorContext;
static int lastInitializerContext;
static int lastClassTemplSpecContext;
static int lastSkipHtmlCommentContext;
+static int lastIfContext;
static int nextDefContext;
static int overloadContext;
static Protection protection;
@@ -84,7 +85,6 @@ static int sharpCount = 0 ;
static int roundCount = 0 ;
static int curlyCount = 0 ;
static int squareCount = 0 ;
-static int ifCount = 0 ;
static int padCount = 0 ;
static int todoStartContext = 0;
static QCString todoString;
@@ -148,6 +148,8 @@ static Grouping lastDefGroup( "", Grouping::GROUPING_LOWEST );
static bool insideFormula;
static bool insideTryBlock=FALSE;
+static int depthIf;
+
//-----------------------------------------------------------------------------
static void initParser()
@@ -161,7 +163,6 @@ static void initParser()
sharpCount = 0;
roundCount = 0;
curlyCount = 0;
- ifCount = 0;
memberGroupId = NOGROUP;
mtype = Method;
gstat = FALSE;
@@ -171,6 +172,8 @@ static void initParser()
autoGroupStack.clear();
insideTryBlock = FALSE;
insideIDL = FALSE;
+ autoGroupStack.setAutoDelete(TRUE);
+ lastDefGroup.groupname.resize(0);
}
static void initEntry()
@@ -481,6 +484,9 @@ TITLE [tT][iI][tT][lL][eE]
%x SkipSharp
%x SkipRound
%x SkipSquare
+%x SkipSection
+%x IfGuard
+%x IfNotGuard
%x TypedefName
%x TryFunctionBlock
%x TryFunctionBlockEnd
@@ -1297,7 +1303,7 @@ TITLE [tT][iI][tT][lL][eE]
BEGIN(AfterDoc);
}
}
-<FindMembers,FindFields>"//"([!/]?){B}*{CMD}"{"|"/*"([!*]?){B}*{CMD}"{" {
+<FindMembers,FindFields>("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") {
startGroup();
tmpDocType=-1;
if (current_root->section & Entry::SCOPE_MASK)
@@ -2624,7 +2630,9 @@ TITLE [tT][iI][tT][lL][eE]
current->inside = current_root->name+"::";
BEGIN( LineDoc );
}
-<FindMembers>"extern"{BN}+"\"C"("++")?"\""{BN}*("{")?
+<FindMembers>"extern"{BN}+"\"C"("++")?"\""{BN}*("{")? {
+ lineCount();
+ }
<FindMembers>"{" {
current->type.resize(0);
current->name.resize(0);
@@ -3411,6 +3419,102 @@ TITLE [tT][iI][tT][lL][eE]
<PageDocTitle>\n { yyLineNr++; current->args+=" "; }
<PageDocTitle>[^\n\<] { current->args+=yytext; }
<PageDocTitle>"</"{TITLE}">" { BEGIN( PageDoc ); }
+
+ /* escaped versions of the conditional commands (for putting them in the docs) */
+<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"if"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; }
+<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"ifnot"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; }
+<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"elseif"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; }
+<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"else"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; }
+<ClassDoc,Doc,AfterDoc,PageDoc,ExampleDoc>{CMD}{CMD}"endif"/[^a-z_A-Z0-9] { current->doc+=&yytext[1]; }
+<LineDoc,JavaDoc>{CMD}{CMD}"if"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; }
+<LineDoc,JavaDoc>{CMD}{CMD}"ifnot"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; }
+<LineDoc,JavaDoc>{CMD}{CMD}"elseif"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; }
+<LineDoc,JavaDoc>{CMD}{CMD}"else"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; }
+<LineDoc,JavaDoc>{CMD}{CMD}"endif"/[^a-z_A-Z0-9] { current->brief+=&yytext[1]; }
+
+ /* conditional commands */
+<ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"if"{B}+ {
+ lastIfContext = YY_START;
+ BEGIN(IfGuard);
+ }
+<ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"ifnot"{B}+ {
+ lastIfContext = YY_START;
+ BEGIN(IfNotGuard);
+ }
+<ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"if"(\r?)\n |
+<IfGuard>\n {
+ warn(yyFileName,yyLineNr,"Missing guard for if statement!");
+ yyLineNr++;
+ }
+<IfGuard>[^\n\t ]+ {
+ if (Config_getList("ENABLED_SECTIONS").find(yytext)==-1) // not enabled
+ {
+ BEGIN(SkipSection);
+ depthIf=1;
+ }
+ else // section enabled
+ {
+ BEGIN(lastIfContext);
+ }
+ }
+<IfNotGuard>\n {
+ warn(yyFileName,yyLineNr,"Missing guard for ifnot statement!");
+ yyLineNr++;
+ }
+<IfNotGuard>[^\n\t ]+ {
+ if (Config_getList("ENABLED_SECTIONS").find(yytext)==-1) // not enabled
+ {
+ BEGIN(lastIfContext);
+ }
+ else // section enabled
+ {
+ depthIf=1;
+ BEGIN(SkipSection);
+ }
+ }
+<SkipSection>{CMD}"if"/[^a-z_A-Z0-9] {
+ depthIf++;
+ }
+<SkipSection>{CMD}"endif"/[^a-z_A-Z0-9] {
+ if (--depthIf<=0)
+ {
+ BEGIN(lastIfContext);
+ }
+ }
+<SkipSection>{CMD}"else"/[^a-z_A-Z0-9] {
+ if (depthIf==1)
+ {
+ depthIf=0;
+ BEGIN(lastIfContext);
+ }
+ }
+<SkipSection>{CMD}"elseif"/[^a-z_A-Z0-9] {
+ if (depthIf==1)
+ {
+ BEGIN(IfGuard);
+ }
+ }
+<SkipSection>"*/" {
+ unput('/');unput('*');
+ BEGIN( lastIfContext );
+ }
+<SkipSection>\n {
+ yyLineNr++;
+ }
+<SkipSection>"//"|"*/"
+<ClassDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"elseif"/[^a-z_A-Z0-9] {
+ // previous section enabled => absorb else
+ }
+<ClassDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"else"/[^a-z_A-Z0-9] {
+ // section was enable => skip now
+ depthIf=1;
+ BEGIN(SkipSection);
+ }
+<ClassDoc,Doc,JavaDoc,AfterDoc,PageDoc,ExampleDoc>{CMD}"endif"/[^a-z_A-Z0-9] {
+ // section enabled => absorb endif
+ }
+
+
<ClassDoc,LineDoc,Doc,JavaDoc,AfterDoc>{CMD}"ingroup"{B}+ {
lastGroupContext = YY_START;
lineCount();
@@ -3868,7 +3972,9 @@ static void parseCompounds(Entry *rt)
// ce->name.data(),ce->program.data());
// init scanner state
padCount=0;
+ depthIf = 0;
inputString = ce->program;
+ lastDefGroup.groupname.resize(0);
inputPosition = 0;
scanYYrestart( scanYYin ) ;
if (ce->section==Entry::ENUM_SEC)
@@ -3900,6 +4006,11 @@ static void parseCompounds(Entry *rt)
scanYYlex() ;
delete current; current=0;
ce->program.resize(0);
+
+ if (depthIf>0)
+ {
+ warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
+ }
}
parseCompounds(ce);
}
@@ -3911,6 +4022,7 @@ void parseMain(Entry *rt)
{
initParser();
anonCount = 0;
+ depthIf = 0;
protection = Public;
mtype = Method;
gstat = FALSE;
@@ -3920,10 +4032,13 @@ void parseMain(Entry *rt)
current = new Entry;
inputString = rt->program;
inputPosition = 0;
- ifCount=0;
scanYYrestart( scanYYin );
BEGIN( FindMembers );
scanYYlex();
+ if (depthIf>0)
+ {
+ warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
+ }
rt->program.resize(0);
delete current; current=0;
parseCompounds(rt);
diff --git a/src/util.cpp b/src/util.cpp
index 576e1c1..e766b3f 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -557,7 +557,7 @@ QCString removeRedundantWhiteSpace(const QCString &s)
{
result+=" >"; // insert extra space for layouting (nested) templates
}
- else if (i>0 && i<l-1 && c==',' && isId(s.at(i-1)) && isId(s.at(i+1)))
+ else if (i>0 && i<l-1 && c==',' && !isspace(s.at(i-1)) && isId(s.at(i+1)))
{
result+=", ";
}
@@ -1014,28 +1014,71 @@ int minClassDistance(ClassDef *cd,ClassDef *bcd,int level)
//}
// strip any template specifiers that follow className in string s
-static QCString trimTemplateSpecifiers(const QCString &className,const QCString &s)
+static QCString trimTemplateSpecifiers(
+ const QCString &namespaceName,
+ const QCString &className,
+ const QCString &s
+)
{
- //printf("trimTemplateSpecifiers(%s,%s)\n",className.data(),s.data());
- ClassDef *cd=getClass(className);
- if (cd==0) return s;
+ //printf("trimTemplateSpecifiers(%s,%s,%s)\n",namespaceName.data(),className.data(),s.data());
+ QCString scopeName=mergeScopes(namespaceName,className);
+ ClassDef *cd=getClass(scopeName);
+ if (cd==0) return s; // should not happen, but guard anyway.
+ QCString result=s;
+
+ int i=className.length()-1;
+ if (className.at(i)=='>') // template specialization
+ {
+ // replace unspecialized occurrences in s, with their specialized versions.
+ int count=1;
+ int cl=i+1;
+ while (i>=0)
+ {
+ char c=className.at(i);
+ if (c=='>') count++,i--;
+ else if (c=='<') { count--; if (count==0) break; }
+ else i--;
+ }
+ QCString unspecClassName=className.left(i);
+ int l=i;
+ int p=0;
+ while ((i=result.find(unspecClassName,p))!=-1)
+ {
+ if (result.at(i+l)!='<') // unspecialized version
+ {
+ result=result.left(i)+className+result.right(result.length()-i-l);
+ l=cl;
+ }
+ p=i+l;
+ }
+ }
+
+ //printf("result after specialization: %s\n",result.data());
+
QCString qualName=cd->qualifiedNameWithTemplateParameters();
//printf("QualifiedName = %s\n",qualName.data());
// We strip the template arguments following className (if any)
- QCString result=s;
if (!qualName.isEmpty()) // there is a class name
{
- int i,p=0;
- // TODO: also try smaller parts of the qualName, since we
- // could be inside a namespace or class.
- while ((i=result.find(qualName,p))!=-1) // class name is in the argument type
+ int is,ps=0;
+ int p=0,l,i;
+
+ while ((is=getScopeFragment(qualName,ps,&l))!=-1)
{
- int ql=qualName.length();
- result=result.left(i)+cd->name()+result.right(result.length()-i-ql);
- p=i+cd->name().length();
+ QCString qualNamePart = qualName.right(qualName.length()-is);
+ //printf("qualNamePart=%s\n",qualNamePart.data());
+ while ((i=result.find(qualNamePart,p))!=-1)
+ {
+ int ql=qualNamePart.length();
+ result=result.left(i)+cd->name()+result.right(result.length()-i-ql);
+ p=i+cd->name().length();
+ }
+ ps=is+l;
}
}
+ //printf("result=%s\n",result.data());
+
return result;
}
@@ -1203,9 +1246,9 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA,
// before matching. This should use className and namespaceName
// and usingNamespaces and usingClass to determine which typedefs
// are in-scope, so it will not be very efficient :-(
-
- QCString srcAType=trimTemplateSpecifiers(className,srcA->type);
- QCString dstAType=trimTemplateSpecifiers(className,dstA->type);
+
+ QCString srcAType=trimTemplateSpecifiers(namespaceName,className,srcA->type);
+ QCString dstAType=trimTemplateSpecifiers(namespaceName,className,dstA->type);
if (srcAType.left(6)=="class ") srcAType=srcAType.right(srcAType.length()-6);
if (dstAType.left(6)=="class ") dstAType=dstAType.right(dstAType.length()-6);
@@ -1235,6 +1278,9 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA,
stripIrrelevantConstVolatile(srcAType);
stripIrrelevantConstVolatile(dstAType);
+ srcAType = removeRedundantWhiteSpace(srcAType);
+ dstAType = removeRedundantWhiteSpace(dstAType);
+
//srcAType=stripTemplateSpecifiersFromScope(srcAType,FALSE);
//dstAType=stripTemplateSpecifiersFromScope(dstAType,FALSE);
@@ -1446,9 +1492,23 @@ static void mergeArgument(Argument *srcA,Argument *dstA,
dstA->type+=dstA->name;
dstA->name.resize(0);
}
+ if (srcA->name=="const" || srcA->name=="volatile")
+ {
+ srcA->type+=" ";
+ srcA->type+=srcA->name;
+ srcA->type=removeRedundantWhiteSpace(srcA->type);
+ srcA->name.resize(0);
+ }
+ if (dstA->name=="const" || dstA->name=="volatile")
+ {
+ dstA->type+=" ";
+ dstA->type+=dstA->name;
+ dstA->type=removeRedundantWhiteSpace(dstA->type);
+ dstA->name.resize(0);
+ }
- QCString srcAType=trimTemplateSpecifiers(className,srcA->type);
- QCString dstAType=trimTemplateSpecifiers(className,dstA->type);
+ QCString srcAType=trimTemplateSpecifiers(namespaceName,className,srcA->type);
+ QCString dstAType=trimTemplateSpecifiers(namespaceName,className,dstA->type);
if (srcAType.left(6)=="class ") srcAType=srcAType.right(srcAType.length()-6);
if (dstAType.left(6)=="class ") dstAType=dstAType.right(dstAType.length()-6);
@@ -1617,10 +1677,16 @@ static void mergeArgument(Argument *srcA,Argument *dstA,
if (i>0 && i<(int)srcAType.length()-1 && srcAType.at(i)!=':')
// there is (probably) a name
{
- srcA->name=srcAType.right(srcAType.length()-i-1);
- srcA->type=srcAType.left(i+1).stripWhiteSpace();
- dstA->name=dstAType.right(dstAType.length()-i-1);
- dstA->type=dstAType.left(i+1).stripWhiteSpace();
+ QCString srcAName=srcAType.right(srcAType.length()-i-1);
+ QCString dstAName=dstAType.right(dstAType.length()-i-1);
+ if (srcAName!="const" && srcAName!="volatile" &&
+ dstAName!="const" && dstAName!="volatile")
+ {
+ srcA->name=srcAName;
+ srcA->type=srcAType.left(i+1).stripWhiteSpace();
+ dstA->name=dstAName;
+ dstA->type=dstAType.left(i+1).stripWhiteSpace();
+ }
}
}
else if (!dstA->name.isEmpty())
@@ -1655,11 +1721,11 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
QCString namespaceName=ns;
// strip template specialization from class name if present
- int til=className.find('<'),tir=className.find('>');
- if (til!=-1 && tir!=-1 && tir>til)
- {
- className=className.left(til)+className.right(className.length()-tir-1);
- }
+ //int til=className.find('<'),tir=className.find('>');
+ //if (til!=-1 && tir!=-1 && tir>til)
+ //{
+ // className=className.left(til)+className.right(className.length()-tir-1);
+ //}
//printf("matchArguments(%s,%s) className=%s namespaceName=%s checkCV=%d usingNamespaces=%d usingClasses=%d\n",
// srcAl ? argListToString(srcAl).data() : "",
@@ -2670,24 +2736,22 @@ QCString substituteKeywords(const QCString &s,const char *title)
*/
int getPrefixIndex(const QCString &name)
{
- int ni = name.findRev("::");
- if (ni==-1) ni=0; else ni+=2;
//printf("getPrefixIndex(%s) ni=%d\n",name.data(),ni);
QStrList &sl = Config_getList("IGNORE_PREFIX");
char *s = sl.first();
while (s)
{
const char *ps=s;
- const char *pd=name.data()+ni;
+ const char *pd=name.data();
int i=0;
while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++;
if (*ps==0 && *pd!=0)
{
- return ni+i;
+ return i;
}
s = sl.next();
}
- return ni;
+ return 0;
}
//----------------------------------------------------------------------------
@@ -2868,17 +2932,52 @@ QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &te
return result;
}
+/*! Strips the scope from a name. Examples: A::B will return A
+ * and A<T>::B<N::C<D> > will return A<T>.
+ * \todo deal with cases like A< s<<2 >::B
+ */
QCString stripScope(const char *name)
{
QCString result = name;
- int ti=result.find('<'); // find start of template
- if (ti==-1) ti=result.length();
- int i = ti>2 ? result.findRev("::",ti-2) : -1; // find scope just before template
- if (i!=-1) // found scope
+ int l=result.length();
+ int p=l-1;
+ bool done;
+ int count;
+
+ while (p>=0)
{
- result=result.right(result.length()-i-2);
+ char c=result.at(p);
+ switch (c)
+ {
+ case ':':
+ //printf("stripScope(%s)=%s\n",name,result.right(l-p-1).data());
+ return result.right(l-p-1);
+ case '>':
+ count=1;
+ done=FALSE;
+ //printf("pos < = %d\n",p);
+ p--;
+ while (p>=0 && !done)
+ {
+ c=result.at(p--);
+ switch (c)
+ {
+ case '>': count++; break;
+ case '<': count--; if (count<=0) done=TRUE; break;
+ default:
+ //printf("c=%c count=%d\n",c,count);
+ break;
+ }
+ }
+ //printf("pos > = %d\n",p+1);
+ break;
+ default:
+ p--;
+ }
}
- return result;
+ //printf("stripScope(%s)=%s\n",name,name);
+ return name;
+
}
/*! Converts a string to an XML-encoded string */
@@ -3015,6 +3114,8 @@ bool extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCStr
QCString substituteTemplateArgumentsInString(
const QCString &name,ArgumentList *formalArgs,ArgumentList *actualArgs)
{
+ //printf("substituteTemplateArgumentsInString(name=%s formal=%s actualArg=%s)\n",
+ // name.data(),argListToString(formalArgs).data(),argListToString(actualArgs).data());
if (formalArgs==0) return name;
QCString result;
static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*");
@@ -3036,16 +3137,19 @@ QCString substituteTemplateArgumentsInString(
++formAli,actArg=actualArgs->next()
)
{
- if (formArg->name==n && actArg && !actArg->type.isEmpty()) // base class is a template argument
- {
- // replace formal argument with the actual argument of the instance
- result += actArg->type;
- found=TRUE;
- }
- else if (formArg->name==n && actArg==0 && !formArg->defval.isEmpty())
+ if (formArg->type=="class" || formArg->type=="typename")
{
- result += formArg->defval;
- found=TRUE;
+ if (formArg->name==n && actArg && !actArg->type.isEmpty()) // base class is a template argument
+ {
+ // replace formal argument with the actual argument of the instance
+ result += actArg->type;
+ found=TRUE;
+ }
+ else if (formArg->name==n && actArg==0 && !formArg->defval.isEmpty())
+ {
+ result += formArg->defval;
+ found=TRUE;
+ }
}
}
if (!found) result += n;
@@ -3109,10 +3213,8 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName,
int p=0;
int l=fullName.length();
int i=fullName.find('<');
- int si= i==-1 ? -1 : fullName.find("::",i);
- while (i!=-1 && (!parentOnly || i<si))
+ while (i!=-1)
{
- result+=fullName.mid(p,i-p);
//printf("1:result+=%s\n",fullName.mid(p,i-p).data());
int e=i+1;
bool done=FALSE;
@@ -3130,18 +3232,112 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName,
done = count==0;
}
}
+ int si= fullName.find("::",e);
+
+ if (parentOnly && si==-1) break;
+ // we only do the parent scope, so we stop here if needed
+
+ result+=fullName.mid(p,i-p);
//printf(" trying %s\n",(result+fullName.mid(i,e-i)).data());
- if (getClass(result+fullName.mid(i,e-i))!=0)
+ if (getClass(result+fullName.mid(i,e-i))!=0)
{
result+=fullName.mid(i,e-i);
//printf("2:result+=%s\n",fullName.mid(i,e-i-1).data());
}
p=e;
i=fullName.find('<',p);
- si= i==-1 ? -1 : fullName.find("::",i);
}
result+=fullName.right(l-p);
//printf("3:result+=%s\n",fullName.right(l-p).data());
return result;
}
+/*! Merges two scope parts together. The parts may (partially) overlap.
+ * Example1: \c A::B and \c B::C will result in \c A::B::C <br>
+ * Example2: \c A and \c B will be \c A::B <br>
+ * Example3: \c A::B and B will be \c A::B
+ *
+ * @param leftScope the left hand part of the scope.
+ * @param rightScope the right hand part of the scope.
+ * @returns the merged scope.
+ */
+QCString mergeScopes(const QCString &leftScope,const QCString &rightScope)
+{
+ // case leftScope=="A" rightScope=="A::B" => result = "A::B"
+ if (leftScopeMatch(rightScope,leftScope)) return rightScope;
+ QCString result;
+ int i=0,p=leftScope.length();
+
+ // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
+ // case leftScope=="A::B" rightScope=="B" => result = "A::B"
+ bool found=FALSE;
+ while ((i=leftScope.findRev("::",p))!=-1)
+ {
+ if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
+ {
+ result = leftScope.left(i+2)+rightScope;
+ found=TRUE;
+ }
+ p=i-1;
+ }
+ if (found) return result;
+
+ // case leftScope=="A" rightScope=="B" => result = "A::B"
+ result=leftScope.copy();
+ if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
+ result+=rightScope;
+ return result;
+}
+
+/*! Returns a fragment from scope \a s, starting at position \a p.
+ *
+ * @param s the scope name as a string.
+ * @param p the start position (0 is the first).
+ * @param l the resulting length of the fragment.
+ * @returns the location of the fragment, or -1 if non is found.
+ */
+int getScopeFragment(const QCString &s,int p,int *l)
+{
+ int sl=s.length();
+ int sp=p;
+ int count=0;
+ bool done;
+ if (sp>=sl) return -1;
+ while (sp<sl)
+ {
+ char c=s.at(sp);
+ if (c==':') sp++,p++; else break;
+ }
+ while (sp<sl)
+ {
+ char c=s.at(sp);
+ switch (c)
+ {
+ case ':': // found next part
+ goto found;
+ case '<': // skip template specifier
+ count=1;sp++;
+ done=FALSE;
+ while (sp<sl && !done)
+ {
+ // TODO: deal with << and >> operators!
+ char c=s.at(sp++);
+ switch(c)
+ {
+ case '<': count++; break;
+ case '>': count--; if (count==0) done=TRUE; break;
+ default: break;
+ }
+ }
+ break;
+ default:
+ sp++;
+ break;
+ }
+ }
+found:
+ *l=sp-p;
+ //printf("getScopeFragment(%s,%d)=%s\n",s.data(),p,s.mid(p,*l).data());
+ return p;
+}
+
diff --git a/src/util.h b/src/util.h
index e15f516..04fd752 100644
--- a/src/util.h
+++ b/src/util.h
@@ -160,6 +160,8 @@ QList<ArgumentList> *copyArgumentLists(const QList<ArgumentList> *srcLists);
QCString stripTemplateSpecifiersFromScope(const QCString &fullName,
bool parentOnly=TRUE);
QCString resolveTypeDef(Definition *d,const QCString &name);
+QCString mergeScopes(const QCString &leftScope,const QCString &rightScope);
+int getScopeFragment(const QCString &s,int p,int *l);
#endif
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index 8b9ed39..3b9d404 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -38,8 +38,8 @@ static inline void writeXMLString(QTextStream &t,const char *s)
t << convertToXML(s);
}
-static void writeXMLLink(QTextStream &t,const char *compoundId,const char *memId,
- const char *text)
+static void writeXMLLink(QTextStream &t,const char *compoundId,
+ const char *memId,const char *text)
{
if (memId==0)
{