summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2006-02-27 20:11:09 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2006-02-27 20:11:09 (GMT)
commitc8b3a0f8232656c1a11c185d595f19eb65c56c82 (patch)
tree5e27018c48206637a831c02760f69c7df275f1c9 /src
parent8b0ae7ca77a14eef79e972d6061a9470de9ae458 (diff)
downloadDoxygen-c8b3a0f8232656c1a11c185d595f19eb65c56c82.zip
Doxygen-c8b3a0f8232656c1a11c185d595f19eb65c56c82.tar.gz
Doxygen-c8b3a0f8232656c1a11c185d595f19eb65c56c82.tar.bz2
Release-1.4.6-20060227
Diffstat (limited to 'src')
-rw-r--r--src/commentscan.l36
-rw-r--r--src/doxygen.cpp16
-rw-r--r--src/htmlgen.cpp9
-rw-r--r--src/latexdocvisitor.cpp16
-rw-r--r--src/latexgen.cpp18
-rw-r--r--src/memberdef.cpp2
-rw-r--r--src/perlmodgen.cpp58
-rw-r--r--src/pyscanner.l18
-rw-r--r--src/scanner.l17
-rw-r--r--src/util.cpp93
-rw-r--r--src/util.h2
-rw-r--r--src/xmlgen.cpp2
12 files changed, 182 insertions, 105 deletions
diff --git a/src/commentscan.l b/src/commentscan.l
index fba617b..efd46b3 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -515,39 +515,6 @@ static QCString addFormula()
static void checkFormula();
//-----------------------------------------------------------------------------
-static void prependScope()
-{
-#if 0
- Entry *current_root = current->parent;
- if (current_root && current_root->section & Entry::SCOPE_MASK)
- {
- current->name.prepend(current_root->name+"::");
- if (current_root->tArgLists)
- {
- if (current->tArgLists==0)
- {
- current->tArgLists = new QList<ArgumentList>;
- current->tArgLists->setAutoDelete(TRUE);
- }
- QListIterator<ArgumentList> talsi(*current_root->tArgLists);
- ArgumentList *srcAl=0;
- for (talsi.toLast();(srcAl=talsi.current());--talsi)
- {
- ArgumentList *dstAl = new ArgumentList;
- dstAl->setAutoDelete(TRUE);
- QListIterator<Argument> tali(*srcAl);
- Argument *a;
- for (;(a=tali.current());++tali)
- {
- dstAl->append(new Argument(*a));
- }
- current->tArgLists->insert(0,dstAl);
- }
- }
- }
-#endif
-}
-
static void addSection()
{
sectionTitle+=yytext;
@@ -994,7 +961,6 @@ MAILADR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]
<EnumDocArg1>{SCOPEID} { // handle argument
current->name = yytext;
- prependScope();
BEGIN( Comment );
}
<EnumDocArg1>{LC} { // line continuation
@@ -1065,12 +1031,10 @@ MAILADR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]
current->name+="-p";
}
// prepend outer scope name
- prependScope();
BEGIN( ClassDocArg2 );
}
<CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" {
current->name = yytext;
- prependScope();
BEGIN( ClassDocArg2 );
}
<ClassDocArg1,CategoryDocArg1>{LC} { // line continuation
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 9b5bb60..abb655b 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -2185,13 +2185,14 @@ done:
static void buildVarList(Entry *root)
{
+ int isFuncPtr=-1;
if (!root->name.isEmpty() &&
(root->type.isEmpty() || compoundKeywordDict.find(root->type)==0) &&
(
(root->section==Entry::VARIABLE_SEC // it's a variable
) ||
(root->section==Entry::FUNCTION_SEC && // or maybe a function pointer variable
- findFunctionPtr(root->type)!=-1
+ (isFuncPtr=findFunctionPtr(root->type))!=-1
) ||
(root->section==Entry::FUNCTION_SEC && // class variable initialized by constructor
isVarWithConstructor(root)
@@ -2228,7 +2229,7 @@ static void buildVarList(Entry *root)
}
else
{
- int i=findFunctionPtr(root->type);
+ int i=isFuncPtr;
if (i!=-1) // function pointer
{
int ai = root->type.find('[',i);
@@ -2244,6 +2245,11 @@ static void buildVarList(Entry *root)
//printf("root->type=%s root->args=%s\n",root->type.data(),root->args.data());
}
}
+ else if (root->type.find("typedef ")!=-1 && root->type.right(2)=="()") // typedef void (func)(int)
+ {
+ root->type=root->type.left(root->type.length()-1);
+ root->args.prepend(")");
+ }
}
QCString scope,name=removeRedundantWhiteSpace(root->name);
@@ -3911,9 +3917,12 @@ static bool findClassRelation(
}
bool isATemplateArgument = templateNames!=0 && templateNames->find(biName)!=0;
+ // make templSpec canonical
+ templSpec = getCanonicalTemplateSpec(cd, cd->getFileDef(), templSpec);
+
if (found)
{
- Debug::print(Debug::Classes,0," Documented class `%s' templSpec=%s\n",biName.data(),templSpec.data());
+ Debug::print(Debug::Classes,0," Documented class `%s' templSpec=%s\n",biName.data(),templSpec.isEmpty()?"":templSpec.data());
// add base class to this class
// if templSpec is not empty then we should "instantiate"
@@ -8903,7 +8912,6 @@ void parseInput()
Doxygen::memberNameSDict.sort();
Doxygen::functionNameSDict.sort();
Doxygen::hiddenClasses.sort();
- printf("Sorting %d classes\n",Doxygen::classSDict.count());
Doxygen::classSDict.sort();
msg("Freeing entry tree\n");
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index c6666bd..e2df6a0 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -1817,7 +1817,14 @@ static void writeDefaultQuickLinks(QTextStream &t,bool compact,
{
startQuickIndexItem(t,"namespacemembers"+Doxygen::htmlFileExtension,
hli==HLI_NamespaceMembers,compact,first,relPath);
- t << fixSpaces(theTranslator->trNamespaceMembers());
+ if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
+ {
+ t << fixSpaces(theTranslator->trPackageMembers());
+ }
+ else
+ {
+ t << fixSpaces(theTranslator->trNamespaceMembers());
+ }
endQuickIndexItem(t);
}
endQuickIndexList(t,compact);
diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp
index edbe979..9712e27 100644
--- a/src/latexdocvisitor.cpp
+++ b/src/latexdocvisitor.cpp
@@ -36,7 +36,7 @@ static QString escapeLabelName(const char *s)
switch (c)
{
case '%': result+="\\%"; break;
- case '|': result+="\\texttt{\"|}"; break;
+ case '|': result+="\\tt{\"|}"; break;
case '!': result+="\"!"; break;
default: result+=c;
}
@@ -69,7 +69,7 @@ QString LatexDocVisitor::escapeMakeIndexChars(const char *s)
case '!': m_t << "\"!"; break;
case '"': m_t << "\"\""; break;
case '@': m_t << "\"@"; break;
- case '|': m_t << "\\texttt{\"|}"; break;
+ case '|': m_t << "\\tt{\"|}"; break;
case '[': m_t << "["; break;
case ']': m_t << "]"; break;
default: str[0]=c; filter(str); break;
@@ -191,7 +191,7 @@ void LatexDocVisitor::visit(DocURL *u)
if (u->isEmail()) m_t << "mailto:";
m_t << u->url() << "}";
}
- m_t << "\\texttt{";
+ m_t << "\\tt{";
filter(u->url());
m_t << "}";
}
@@ -214,13 +214,13 @@ void LatexDocVisitor::visit(DocStyleChange *s)
switch (s->style())
{
case DocStyleChange::Bold:
- if (s->enable()) m_t << "\\textbf{"; else m_t << "}";
+ if (s->enable()) m_t << "{\\bf "; else m_t << "}";
break;
case DocStyleChange::Italic:
- if (s->enable()) m_t << "\\textit{"; else m_t << "\\/}";
+ if (s->enable()) m_t << "{\\em "; else m_t << "\\/}";
break;
case DocStyleChange::Code:
- if (s->enable()) m_t << "\\texttt{ "; else m_t << "}";
+ if (s->enable()) m_t << "{\\tt "; else m_t << "}";
break;
case DocStyleChange::Subscript:
if (s->enable()) m_t << "$_{\\mbox{"; else m_t << "}}$ ";
@@ -718,7 +718,7 @@ void LatexDocVisitor::visitPre(DocHRef *href)
m_t << href->url();
m_t << "}";
}
- m_t << "\texttt{";
+ m_t << "{\\tt ";
}
void LatexDocVisitor::visitPost(DocHRef *)
@@ -972,7 +972,7 @@ void LatexDocVisitor::visitPre(DocXRefItem *x)
}
else
{
- m_t << "\\textbf{";
+ m_t << "\\bf{";
}
m_insideItem=TRUE;
filter(x->title());
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index 66aa16c..601c7f4 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -63,7 +63,7 @@ static QCString escapeLabelName(const char *s)
switch (c)
{
case '%': result+="\\%"; break;
- case '|': result+="\\texttt{\"|}"; break;
+ case '|': result+="\\tt{\"|}"; break;
case '!': result+="\"!"; break;
default: result+=c;
}
@@ -85,7 +85,7 @@ static QCString escapeMakeIndexChars(LatexGenerator *g,QTextStream &t,const char
case '!': t << "\"!"; break;
case '"': t << "\"\""; break;
case '@': t << "\"@"; break;
- case '|': t << "\\texttt{\"|}"; break;
+ case '|': t << "\\tt{\"|}"; break;
case '[': t << "["; break;
case ']': t << "]"; break;
default: str[0]=c; g->docify(str); break;
@@ -355,7 +355,7 @@ static void writeDefaultStyleSheetPart3(QTextStream &t)
t << " \\setlength{\\itemsep}{0pt}\n";
t << " \\setlength{\\parsep}{0pt}\n";
t << " \\setlength{\\topsep}{0pt}\n";
- t << " \\renewcommand{\\makelabel}{}}}\n";
+ t << " \\renewcommand{\\makelabel}{\\hfill}}}\n";
t << "{\\end{list}}\n";
t << "\\newenvironment{CompactItemize}\n";
t << "{\n";
@@ -377,7 +377,7 @@ static void writeDefaultStyleSheetPart3(QTextStream &t)
t << "}\n";
t << "{\\end{tabular*}\\par}\n";
t << "\\newcommand{\\entrylabel}[1]{\n";
- t << " {\\parbox[b]{\\labelwidth-4pt}{\\makebox[0pt][l]{\\textbf{#1}}\\\\}}}\n";
+ t << " {\\parbox[b]{\\labelwidth-4pt}{\\makebox[0pt][l]{\\textbf{#1}}\\vspace{1.5\\baselineskip}}}}\n";
t << "\\newenvironment{Desc}\n";
t << "{\\begin{list}{}\n";
t << " {\n";
@@ -924,7 +924,7 @@ void LatexGenerator::endHtmlLink()
void LatexGenerator::writeStartAnnoItem(const char *,const char *,
const char *path,const char *name)
{
- t << "\\item\\contentsline{section}{\\textbf{";
+ t << "\\item\\contentsline{section}{\\bf ";
if (path) docify(path);
docify(name);
t << "} ";
@@ -959,7 +959,7 @@ void LatexGenerator::endIndexValue(const char *name,bool hasBrief)
//void LatexGenerator::writeClassLink(const char *,const char *,
// const char *,const char *name)
//{
-// t << "\\textbf{";
+// t << "{\\bf";
// docify(name);
// t << "}";
//}
@@ -975,7 +975,7 @@ void LatexGenerator::startTextLink(const char *f,const char *anchor)
}
else
{
- t << "\\textbf{";
+ t << "{\\bf ";
}
}
@@ -999,7 +999,7 @@ void LatexGenerator::writeObjectLink(const char *ref, const char *f,
}
else
{
- t << "\\textbf{";
+ t << "\\bf{";
docify(text);
t << "}";
}
@@ -1420,7 +1420,7 @@ void LatexGenerator::endMemberList()
void LatexGenerator::startMemberGroupHeader(bool hasHeader)
{
if (hasHeader) t << "\\begin{Indent}";
- t << "\\textbf{";
+ t << "{\\bf ";
}
void LatexGenerator::endMemberGroupHeader()
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index 6d2761c..23d5a4b 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -2503,7 +2503,7 @@ void MemberDef::setTagInfo(TagInfo *ti)
{
if (ti)
{
- setAnchor(ti->anchor);
+ anc=ti->anchor;
setReference(ti->tagName);
explicitOutputFileBase = stripExtension(ti->fileName);
}
diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp
index 7e772ec..9ec71c6 100644
--- a/src/perlmodgen.cpp
+++ b/src/perlmodgen.cpp
@@ -2231,11 +2231,67 @@ bool PerlModGenerator::generateDoxyStructurePM()
"\t\t [ \"hash\", \"ClassDetailed\",\n"
"\t\t {\n"
"\t\t doc => [ \"doc\", \"ClassDetailedDoc\" ],\n"
- " \t\t },\n"
+ "\t\t },\n"
"\t\t ],\n"
"\t },\n"
"\t ],\n"
"\t ],\n"
+ "\tgroups =>\n"
+ "\t [ \"list\", \"Groups\",\n"
+ "\t [ \"hash\", \"Group\",\n"
+ "\t {\n"
+ "\t\tname => [ \"string\", \"GroupName\" ],\n"
+ "\t\ttitle => [ \"string\", \"GroupTitle\" ],\n"
+ "\t\tfiles =>\n"
+ "\t\t [ \"list\", \"Files\",\n"
+ "\t\t [ \"hash\", \"File\",\n"
+ "\t\t {\n"
+ "\t\t name => [ \"string\", \"Filename\" ]\n"
+ "\t\t }\n"
+ "\t\t ],\n"
+ "\t\t ],\n"
+ "\t\tclasses =>\n"
+ "\t\t [ \"list\", \"Classes\",\n"
+ "\t\t [ \"hash\", \"Class\",\n"
+ "\t\t {\n"
+ "\t\t name => [ \"string\", \"Classname\" ]\n"
+ "\t\t }\n"
+ "\t\t ],\n"
+ "\t\t ],\n"
+ "\t\tnamespaces =>\n"
+ "\t\t [ \"list\", \"Namespaces\",\n"
+ "\t\t [ \"hash\", \"Namespace\",\n"
+ "\t\t {\n"
+ "\t\t name => [ \"string\", \"NamespaceName\" ]\n"
+ "\t\t }\n"
+ "\t\t ],\n"
+ "\t\t ],\n"
+ "\t\tpages =>\n"
+ "\t\t [ \"list\", \"Pages\",\n"
+ "\t\t [ \"hash\", \"Page\","
+ "\t\t {\n"
+ "\t\t title => [ \"string\", \"PageName\" ]\n"
+ "\t\t }\n"
+ "\t\t ],\n"
+ "\t\t ],\n"
+ "\t\tgroups =>\n"
+ "\t\t [ \"list\", \"Groups\",\n"
+ "\t\t [ \"hash\", \"Group\",\n"
+ "\t\t {\n"
+ "\t\t title => [ \"string\", \"GroupName\" ]\n"
+ "\t\t }\n"
+ "\t\t ],\n"
+ "\t\t ],\n"
+ "\t\tfunctions => memberlist(\"GroupFunction\"),\n"
+ "\t\tdetailed =>\n"
+ "\t\t [ \"hash\", \"GroupDetailed\",\n"
+ "\t\t {\n"
+ "\t\t doc => [ \"doc\", \"GroupDetailedDoc\" ],\n"
+ "\t\t },\n"
+ "\t\t ],\n"
+ "\t }\n"
+ "\t ],\n"
+ "\t ],\n"
" },\n"
" ];\n"
"\n"
diff --git a/src/pyscanner.l b/src/pyscanner.l
index d29b2c1..ba6784a 100644
--- a/src/pyscanner.l
+++ b/src/pyscanner.l
@@ -414,6 +414,7 @@ EXPCHAR [#(){}\[\],:.%/\\=`*~|&<>!;+-]
NONEMPTYEXP [^ \t\n:]
PARAMNONEMPTY [^ \t\n():]
IDENTIFIER ({LETTER}|"_")({LETTER}|{DIGIT}|"_")*
+SCOPE {IDENTIFIER}("."{IDENTIFIER})*
BORDER ([^A-Za-z0-9])
TRISINGLEQUOTE "'''"(!)?
@@ -899,13 +900,15 @@ STARTDOCSYMS ^{B}"##"/[^#]
YY_CURRENT_BUFFER->yy_at_bol=TRUE;
BEGIN(Search);
}
- \n/"##" {
+ /*
+ ^{B}/"##" { // start of a special comment
yyLineNr++;
endOfDef();
g_hideClassDocs = FALSE;
YY_CURRENT_BUFFER->yy_at_bol=TRUE;
BEGIN(Search);
}
+ */
^{BB}/\n { // skip empty line
current->program+=yytext;
}
@@ -953,7 +956,7 @@ STARTDOCSYMS ^{B}"##"/[^#]
current->program+=*yytext;
yyLineNr++;
}
- ^{POUNDCOMMENT} { // normal comment
+ {POUNDCOMMENT} { // normal comment
current->program+=yytext;
}
. { // any character
@@ -1007,9 +1010,9 @@ STARTDOCSYMS ^{B}"##"/[^#]
BEGIN(ClassCaptureIndent);
}
- {IDENTIFIER} {
+ {SCOPE} {
current->extends->append(
- new BaseInfo(yytext,Public,Normal)
+ new BaseInfo(substitute(yytext,".","::"),Public,Normal)
);
//Has base class-do stuff
}
@@ -1040,7 +1043,7 @@ STARTDOCSYMS ^{B}"##"/[^#]
//fprintf(stderr,"setting indent %d\n",g_curIndent);
//printf("current->program=[%s]\n",current->program.data());
g_hideClassDocs = TRUE;
- BEGIN( ClassBody );
+ BEGIN(ClassBody);
}
""/({NONEMPTY}|{EXPCHAR}) {
@@ -1492,6 +1495,11 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt)
static void parsePrototype(const QCString &text)
{
//printf("**** parsePrototype(%s) begin\n",text.data());
+ if (text.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,"Empty prototype found!");
+ return;
+ }
//g_expectModuleDocs = FALSE;
g_specialBlock = FALSE;
diff --git a/src/scanner.l b/src/scanner.l
index bb941f7..7a3a8c0 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -543,7 +543,8 @@ ID "$"?[a-z_A-Z][a-z_A-Z0-9]*
LABELID [a-z_A-Z][a-z_A-Z0-9\-]*
SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID})
-TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&]*">")?
+TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,]*">")?
+FTSCOPE {ID}("<"[a-z_A-Z0-9\*\&,]*">")?
CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID})
ATTR ({B}+[^>\n]*)?
A [aA]
@@ -1486,7 +1487,7 @@ IDLATTR ("["[^\]]*"]"){BN}*
<QtPropType>{B}+ {
current->type+=yytext;
}
-<QtPropType>({ID}"::")*{ID} {
+<QtPropType>({FTSCOPE}"::")*{FTSCOPE} {
current->type+=yytext;
BEGIN(QtPropName);
}
@@ -2408,6 +2409,10 @@ IDLATTR ("["[^\]]*"]"){BN}*
<ReadBody,ReadNSBody,ReadBodyIntf>"{" { current->program += yytext ;
++curlyCount ;
}
+<ReadBodyIntf>"}" {
+ current->program += yytext ;
+ --curlyCount ;
+ }
<ReadBody,ReadNSBody>"}" { //err("ReadBody count=%d\n",curlyCount);
if ( curlyCount>0 )
{
@@ -2681,7 +2686,7 @@ IDLATTR ("["[^\]]*"]"){BN}*
}
<ReadBody,ReadNSBody,ReadBodyIntf>. { current->program += yytext ; }
-<FindMembers>"("/({BN}*{TSCOPE}{BN}*"::")*{TSCOPE}{BN}*")"{BN}*"(" | /* typedef void (A<int>::func_t)(args...) */
+<FindMembers>"("/{BN}*({TSCOPE}{BN}*"::")*{TSCOPE}{BN}*")"{BN}*"(" | /* typedef void (A<int>::func_t)(args...) */
<FindMembers>("("({BN}*{TSCOPE}{BN}*"::")*({BN}*"*"{BN}*)+)+ { /* typedef void (A::*ptr_t)(args...) */
current->bodyLine = yyLineNr;
lineCount();
@@ -3485,7 +3490,7 @@ IDLATTR ("["[^\]]*"]"){BN}*
yyLineNr++;
//addToBody(yytext);
}
-<SkipCurly,SkipCurlyCpp>[^\n"'@\\/{}]+ {
+<SkipCurly,SkipCurlyCpp>[^\n#"'@\\/{}]+ {
//addToBody(yytext);
}
<SkipCurlyCpp>\n {
@@ -3783,8 +3788,8 @@ IDLATTR ("["[^\]]*"]"){BN}*
current->name.sprintf("@%d",anonCount++);
}
curlyCount=0;
- if (/*current->section==Entry::PROTOCOL_SEC ||
- current->section==Entry::OBJCIMPL_SEC*/
+ if (current_root && // not a nested struct inside an @interface section
+ current_root->section!=Entry::INTERFACE_SEC &&
insideObjC
)
{ // ObjC body that ends with @end
diff --git a/src/util.cpp b/src/util.cpp
index 231910b..4164398 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -2750,13 +2750,24 @@ static QCString stripDeclKeywords(const QCString &s)
return s;
}
+// forward decl for circular dependencies
+static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type);
+
+QCString getCanonicalTemplateSpec(Definition *d,FileDef *fs,const QCString& spec)
+{
+ QCString templSpec = spec.stripWhiteSpace();
+ if (templSpec.isEmpty() || templSpec.at(0) != '<') return templSpec;
+ return "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1));
+}
+
+
static QCString getCanonicalTypeForIdentifier(
Definition *d,FileDef *fs,const QCString &word,
QCString *tSpec)
{
QCString symName,scope,result,templSpec,tmpName;
//DefinitionList *defList=0;
- if (tSpec) templSpec = stripDeclKeywords(*tSpec);
+ if (tSpec) templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,*tSpec));
if (word.findRev("::")!=-1 && !(tmpName=stripScope(word)).isEmpty())
{
@@ -2770,20 +2781,16 @@ static QCString getCanonicalTypeForIdentifier(
ClassDef *cd = 0;
MemberDef *mType = 0;
QCString ts;
- if (!templSpec.isEmpty())
- {
- cd = getResolvedClass(d,fs,word+templSpec,&mType,&ts,TRUE);
- if (cd && tSpec) *tSpec="";
- }
- if (cd==0)
+
+ // lookup class / class template instance
+ cd = getResolvedClass(d,fs,word+templSpec,&mType,&ts,TRUE);
+ bool isTemplInst = cd && !templSpec.isEmpty();
+ if (!cd && !templSpec.isEmpty())
{
+ // class template specialization not known, look up class template
cd = getResolvedClass(d,fs,word,&mType,&ts,TRUE);
}
- if (!ts.isEmpty() && templSpec.isEmpty())
- {
- templSpec = stripDeclKeywords(ts);
- }
//printf("symbol=%s word=%s cd=%s d=%s fs=%s\n",
// symName.data(),
// word.data(),
@@ -2794,12 +2801,25 @@ static QCString getCanonicalTypeForIdentifier(
//printf(">>>> word '%s' => '%s' templSpec=%s ts=%s\n",
// (word+templSpec).data(),
- // cd?cd->qualifiedNameWithTemplateParameters().data():"<none>",
+ // cd?cd->qualifiedName().data():"<none>",
// templSpec.data(),ts.data());
- if (cd) // known type
+
+ if (cd) // known class type
{
- //result = cd->qualifiedNameWithTemplateParameters();
- result = removeRedundantWhiteSpace(cd->qualifiedName()+templSpec);
+ if (isTemplInst)
+ {
+ // spec is already part of class type
+ templSpec="";
+ if (tSpec) *tSpec="";
+ }
+ else if (!ts.isEmpty() && templSpec.isEmpty())
+ {
+ // use formal template args for spec
+ templSpec = stripDeclKeywords(ts);
+ }
+
+ result = removeRedundantWhiteSpace(cd->qualifiedName() + templSpec);
+
if (cd->isTemplate() && tSpec)
{
*tSpec="";
@@ -2809,7 +2829,7 @@ static QCString getCanonicalTypeForIdentifier(
{
result = mType->qualifiedName();
}
- else // not known as a class
+ else
{
QCString resolvedType = resolveTypeDef(d,word);
if (resolvedType.isEmpty()) // not known as a typedef either
@@ -2824,21 +2844,9 @@ static QCString getCanonicalTypeForIdentifier(
return result;
}
-static QCString extractCanonicalType(Definition *d,FileDef *fs,const Argument *arg)
+static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type)
{
- QCString type = arg->type.stripWhiteSpace();
- QCString name = arg->name;
- //printf("extractCanonicalType(type=%s,name=%s)\n",type.data(),name.data());
- if ((type=="const" || type=="volatile") && !name.isEmpty())
- { // name is part of type => correct
- type+=" ";
- type+=name;
- }
- if (name=="const" || name=="volatile")
- { // name is part of type => correct
- if (!type.isEmpty()) type+=" ";
- type+=name;
- }
+ type = type.stripWhiteSpace();
// strip const and volatile keywords that are not relevant for the type
stripIrrelevantConstVolatile(type);
@@ -2851,7 +2859,7 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,const Argument *a
type.stripPrefix("typename ");
type = removeRedundantWhiteSpace(type);
- //printf("extractCanonicalTyp2(type=%s,name=%s)\n",type.data(),name.data());
+ //printf("extractCanonicalType(type=%s,name=%s)\n",type.data(),name.data());
static QRegExp id("[a-z_A-Z][:a-z_A-Z0-9]*");
@@ -2890,6 +2898,25 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,const Argument *a
return removeRedundantWhiteSpace(canType);
}
+static QCString extractCanonicalArgType(Definition *d,FileDef *fs,const Argument *arg)
+{
+ QCString type = arg->type.stripWhiteSpace();
+ QCString name = arg->name;
+ //printf("extractCanonicalArgType(type=%s,name=%s)\n",type.data(),name.data());
+ if ((type=="const" || type=="volatile") && !name.isEmpty())
+ { // name is part of type => correct
+ type+=" ";
+ type+=name;
+ }
+ if (name=="const" || name=="volatile")
+ { // name is part of type => correct
+ if (!type.isEmpty()) type+=" ";
+ type+=name;
+ }
+
+ return extractCanonicalType(d,fs,type);
+}
+
static bool matchArgument2(
Definition *srcScope,FileDef *srcFileScope,Argument *srcA,
Definition *dstScope,FileDef *dstFileScope,Argument *dstA
@@ -2929,11 +2956,11 @@ static bool matchArgument2(
if (srcA->canType.isEmpty())
{
- srcA->canType = extractCanonicalType(srcScope,srcFileScope,srcA);
+ srcA->canType = extractCanonicalArgType(srcScope,srcFileScope,srcA);
}
if (dstA->canType.isEmpty())
{
- dstA->canType = extractCanonicalType(dstScope,dstFileScope,dstA);
+ dstA->canType = extractCanonicalArgType(dstScope,dstFileScope,dstA);
}
if (srcA->canType==dstA->canType)
diff --git a/src/util.h b/src/util.h
index 52b2316..2add1da 100644
--- a/src/util.h
+++ b/src/util.h
@@ -152,6 +152,8 @@ void generateFileRef(OutputDocInterface &od,const char *,
void writePageRef(OutputDocInterface &od,const char *cn,const char *mn);
+QCString getCanonicalTemplateSpec(Definition *d,FileDef *fs,const QCString& spec);
+
bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *srcAl,
Definition *dstScope,FileDef *dstFileScope,ArgumentList *dstAl,
bool checkCV
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index a479842..ef19e15 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -613,7 +613,7 @@ static void generateXMLForMember(MemberDef *md,QTextStream &ti,QTextStream &t,De
if (md->isReadable()) t << "yes"; else t << "no";
t << "\"";
- t << "\" writable=\"";
+ t << " writable=\"";
if (md->isWritable()) t << "yes"; else t << "no";
t << "\"";
}