summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authordimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2004-03-07 21:00:29 (GMT)
committerdimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2004-03-07 21:00:29 (GMT)
commitf12fe31aed103718f5d4c368473302cc6ac82a47 (patch)
treeecc570be1c038ecdb55dda6d9ffe794945151261 /src
parent5edb3c85109d09e5fa43529bf8b584382f7501a5 (diff)
downloadDoxygen-f12fe31aed103718f5d4c368473302cc6ac82a47.zip
Doxygen-f12fe31aed103718f5d4c368473302cc6ac82a47.tar.gz
Doxygen-f12fe31aed103718f5d4c368473302cc6ac82a47.tar.bz2
Release-1.3.6-20040307
Diffstat (limited to 'src')
-rw-r--r--src/classdef.cpp9
-rw-r--r--src/code.l176
-rw-r--r--src/commentcnv.l7
-rw-r--r--src/config.l8
-rw-r--r--src/definition.cpp10
-rw-r--r--src/docparser.cpp5
-rw-r--r--src/dot.cpp2
-rw-r--r--src/doxygen.cpp101
-rw-r--r--src/entry.h4
-rw-r--r--src/htmlgen.cpp14
-rw-r--r--src/htmlgen.h2
-rw-r--r--src/index.cpp3
-rw-r--r--src/latexgen.h2
-rw-r--r--src/mangen.h2
-rw-r--r--src/memberdef.cpp26
-rw-r--r--src/memberdef.h8
-rw-r--r--src/outputgen.h2
-rw-r--r--src/outputlist.cpp1
-rw-r--r--src/outputlist.h5
-rw-r--r--src/pre.l38
-rw-r--r--src/rtfgen.h2
-rw-r--r--src/scanner.l39
-rw-r--r--src/translator_nl.h5
-rw-r--r--src/util.cpp14
-rw-r--r--src/util.h1
25 files changed, 391 insertions, 95 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp
index ffc6779..7721925 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -1371,10 +1371,10 @@ void ClassDef::writeDocumentation(OutputList &ol)
// write the list of used files (not for man pages)
ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
if (Config_getBool("SHOW_USED_FILES"))
{
- ol.disable(OutputGenerator::Man);
ol.writeRuler();
ol.parseText(theTranslator->trGeneratedFromFiles(
m_isObjC && m_compType==Interface ? Class : m_compType,
@@ -1633,7 +1633,7 @@ void ClassDef::writeMemberList(OutputList &ol)
ol.writeString("<td>");
}
if (
- (prot!=Public || virt!=Normal ||
+ (prot!=Public || (virt!=Normal && !m_isObjC) ||
md->isFriend() || md->isRelated() || md->isExplicit() ||
md->isMutable() || (md->isInline() && Config_getBool("INLINE_INFO")) ||
md->isSignal() || md->isSlot() ||
@@ -1655,7 +1655,8 @@ void ClassDef::writeMemberList(OutputList &ol)
if (prot==Protected) sl.append("protected");
else if (prot==Private) sl.append("private");
else if (prot==Package) sl.append("package");
- if (virt==Virtual) sl.append("virtual");
+ if (virt==Virtual &&
+ !m_isObjC) sl.append("virtual");
else if (virt==Pure) sl.append("pure virtual");
if (md->isStatic()) sl.append("static");
if (md->isSignal()) sl.append("signal");
@@ -2572,7 +2573,7 @@ ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName,
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());
+ 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->setTemplateMaster(this);
diff --git a/src/code.l b/src/code.l
index 316b05f..d0b7058 100644
--- a/src/code.l
+++ b/src/code.l
@@ -103,6 +103,8 @@ static int g_lastVerbStringContext;
static int g_memCallContext;
static int g_lastCContext;
+static bool g_insideObjC;
+
//-------------------------------------------------------------------
/*! Represents a stack of variable to class mappings as found in the
@@ -860,6 +862,8 @@ static bool generateClassMemberLink(BaseCodeDocInterface &ol,ClassDef *mcd,const
if (xd)
{
+ //printf("g_currentDefiniton=%p g_currentMemberDef=%p xmd=%p g_insideBody=%d\n",g_currentDefinition,g_currentMemberDef,xmd,g_insideBody);
+
// add usage reference
if (g_currentDefinition && g_currentMemberDef &&
xmd!=g_currentMemberDef && g_insideBody)
@@ -1080,7 +1084,7 @@ TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">"
SCOPETNAME ((({ID}{TEMPLIST}?){BN}*"::"{BN}*)*)((~{BN}*)?{ID})
SCOPEPREFIX ({ID}{TEMPLIST}?{BN}*"::"{BN}*)+
KEYWORD_OBJC ("@public"|"@private"|"@protected"|"@class"|"@implementation"|"@interface"|"@end"|"@selector"|"@protocol")
-KEYWORD ("asm"|"auto"|"class"|"const"|"const_cast"|"delete"|"dynamic_cast"|"enum"|"explicit"|"extern"|"false"|"friend"|"inline"|"mutable"|"namespace"|"new"|"operator"|"private"|"protected"|"public"|"register"|"reinterpret_cast"|"sizeof"|"static"|"static_cast"|"struct"|"template"|"this"|"true"|"typedef"|"typeid"|"typename"|"union"|"using"|"virtual"|"volatile"|"abstract"|"final"|"import"|"synchronized"|"transient"|KEYWORD_OBJC)
+KEYWORD ("asm"|"auto"|"class"|"const"|"const_cast"|"delete"|"dynamic_cast"|"enum"|"explicit"|"extern"|"false"|"friend"|"inline"|"mutable"|"namespace"|"new"|"operator"|"private"|"protected"|"public"|"register"|"reinterpret_cast"|"sizeof"|"static"|"static_cast"|"struct"|"template"|"this"|"self"|"true"|"typedef"|"typeid"|"typename"|"union"|"using"|"virtual"|"volatile"|"abstract"|"final"|"import"|"synchronized"|"transient"|KEYWORD_OBJC)
FLOWKW ("break"|"case"|"catch"|"continue"|"default"|"do"|"else"|"for"|"goto"|"if"|"return"|"switch"|"throw"|"throws"|"try"|"while")
TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"|"void"|"wchar_t"|"boolean"|"id"|"SEL")
@@ -1106,6 +1110,12 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
%x ReadInclude
%x TemplDecl
%x CallEnd
+%x ObjCMethod
+%x ObjCParams
+%x ObjCParamType
+%x ObjCMemberCall
+%x ObjCMemberCall2
+%x ObjCMemberCall3
%%
@@ -1115,7 +1125,15 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_code->codify(yytext);
BEGIN( ReadInclude );
}
-<Body>("class"|"struct"|"union"|"namespace"|"@interface"|"@implementation"|"@interface")[ \t\n]+ {
+<Body>("@interface"|"@implementation"|"@protocol")[ \t\n]+ {
+ g_insideObjC=TRUE;
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ if (!g_insideTemplate)
+ BEGIN( ClassName );
+ }
+<Body>("class"|"struct"|"union"|"namespace")[ \t\n]+ {
startFontClass("keyword");
codifyLines(yytext);
endFontClass();
@@ -1128,6 +1146,63 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
endFontClass();
BEGIN( PackageName );
}
+<Body,ClassVar>"-"|"+" {
+ if (!g_insideObjC)
+ {
+ g_code->codify(yytext);
+ }
+ else // Start of Objective-C method
+ {
+ //printf("Method!\n");
+ g_code->codify(yytext);
+ BEGIN(ObjCMethod);
+ }
+ }
+<ObjCMethod>":" {
+ g_code->codify(yytext);
+ BEGIN(ObjCParams);
+ }
+<ObjCParams>"(" {
+ g_code->codify(yytext);
+ BEGIN(ObjCParamType);
+ }
+<ObjCParams,ObjCMethod>";"|"{" {
+ g_code->codify(yytext);
+ if (*yytext=='{')
+ {
+ g_insideBody=TRUE;
+ }
+ BEGIN(Body);
+ }
+<ObjCParams>{ID}{B}*":" {
+ g_code->codify(yytext);
+ }
+<ObjCParamType>{TYPEKW} {
+ startFontClass("keywordtype");
+ g_code->codify(yytext);
+ endFontClass();
+ g_parmType=yytext;
+ }
+<ObjCParamType>{ID} {
+ g_code->codify(yytext);
+ g_parmType=yytext;
+ }
+<ObjCParamType>")" {
+ g_code->codify(yytext);
+ BEGIN(ObjCParams);
+ }
+<ObjCParams>{ID} {
+ g_code->codify(yytext);
+ g_parmName=yytext;
+ g_theVarContext.addVariable(g_parmType,g_parmName);
+ g_parmType.resize(0);g_parmName.resize(0);
+ }
+<ObjCMethod,ObjCParams,ObjCParamType>. {
+ g_code->codify(yytext);
+ }
+<ObjCMethod,ObjCParams,ObjCParamType>\n {
+ codifyLines(yytext);
+ }
<ReadInclude>[^\n\"\>]+/(">"|"\"") {
//FileInfo *f;
bool ambig;
@@ -1239,6 +1314,18 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
BEGIN(Body);
}
<Body>"@end" {
+ //printf("End of objc scope fd=%s\n",g_sourceFileDef->name().data());
+ if (g_sourceFileDef)
+ {
+ FileDef *fd=g_sourceFileDef;
+ g_insideObjC = fd->name().lower().right(2)==".m" ||
+ fd->name().lower().right(3)==".mm";
+ //printf("insideObjC=%d\n",g_insideObjC);
+ }
+ else
+ {
+ g_insideObjC = FALSE;
+ }
g_theVarContext.popScope();
int *scope = g_scopeStack.pop();
@@ -1458,7 +1545,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_theCallContext.popScope();
}
}
-<Body,TemplDecl>{TYPEKW}/{B}* {
+<Body,TemplDecl,ObjCMethod>{TYPEKW}/{B}* {
startFontClass("keywordtype");
g_code->codify(yytext);
endFontClass();
@@ -1516,7 +1603,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_name+=yytext;
BEGIN( FuncCall );
}
-<FuncCall,Body,MemberCall,MemberCall2>\" {
+<FuncCall,Body,MemberCall,MemberCall2,ObjCMemberCall2,ObjCMemberCall3>\" {
startFontClass("stringliteral");
g_code->codify(yytext);
g_lastStringContext=YY_START;
@@ -1638,27 +1725,82 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
BEGIN(g_memCallContext);
}
<Body>[,=;\[] {
- g_code->codify(yytext);
- g_saveName = g_name.copy();
- g_saveType = g_type.copy();
- if (!g_type.isEmpty())
+ if (g_insideObjC && *yytext=='[')
+ {
+ //printf("Found start of ObjC call!\n");
+ // start of a method call
+ g_code->codify(yytext);
+ g_theCallContext.pushScope();
+ BEGIN(ObjCMemberCall);
+ }
+ else
{
- if (g_scopeStack.top()!=CLASSBLOCK)
+ g_code->codify(yytext);
+ g_saveName = g_name.copy();
+ g_saveType = g_type.copy();
+ if (!g_type.isEmpty())
+ {
+ if (g_scopeStack.top()!=CLASSBLOCK)
+ {
+ g_theVarContext.addVariable(g_type,g_name);
+ }
+ g_name.resize(0);
+ }
+ if (*yytext==';')
{
- g_theVarContext.addVariable(g_type,g_name);
+ g_type.resize(0);
+ g_name.resize(0);
}
- g_name.resize(0);
+ else if (*yytext=='[')
+ {
+ g_theCallContext.pushScope();
+ }
+ g_args.resize(0);
}
- if (*yytext==';')
+ }
+<ObjCMemberCall>{ID} {
+ if (strcmp(yytext,"self")==0 || strcmp(yytext,"super")==0)
{
- g_type.resize(0);
- g_name.resize(0);
+ // TODO: get proper base class for "super"
+ g_theCallContext.setClass(getClass(g_curClassName));
+ startFontClass("keyword");
+ g_code->codify(yytext);
+ endFontClass();
}
- else if (*yytext=='[')
+ else
{
+ generateClassOrGlobalLink(*g_code,yytext);
+ }
+ g_name.resize(0);
+ BEGIN(ObjCMemberCall2);
+ }
+<ObjCMemberCall>"[" {
+ g_code->codify(yytext);
g_theCallContext.pushScope();
+ }
+<ObjCMemberCall2>{ID}":"? {
+ g_name+=yytext;
+ if (g_theCallContext.getClass())
+ {
+ //printf("Calling method %s\n",g_name.data());
+ if (!generateClassMemberLink(*g_code,g_theCallContext.getClass(),g_name))
+ {
+ g_code->codify(yytext);
+ addToSearchIndex(g_name);
+ }
}
- g_args.resize(0);
+ else
+ {
+ g_code->codify(yytext);
+ addToSearchIndex(g_name);
+ }
+ g_name.resize(0);
+ BEGIN(ObjCMemberCall3);
+ }
+<ObjCMemberCall2,ObjCMemberCall3>"]" {
+ g_theCallContext.popScope();
+ g_code->codify(yytext);
+ BEGIN(Body);
}
<Body>"]" {
g_theCallContext.popScope();
@@ -2215,6 +2357,8 @@ void parseCode(BaseCodeDocInterface &od,const char *className,const QCString &s,
if (fd)
{
setCurrentDoc(fd->name(),fd->getSourceFileBase());
+ g_insideObjC = fd->name().lower().right(2)==".m" ||
+ fd->name().lower().right(3)==".mm";
}
g_currentDefinition = 0;
g_currentMemberDef = 0;
diff --git a/src/commentcnv.l b/src/commentcnv.l
index 668e2e9..7e7d6a4 100644
--- a/src/commentcnv.l
+++ b/src/commentcnv.l
@@ -112,6 +112,8 @@ void replaceComment(int offset);
%}
+CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
+
%option noyywrap
%x Scan
@@ -123,13 +125,16 @@ void replaceComment(int offset);
%%
-<Scan>[^\"\/\n\\]* { /* eat anything that is not " / or \n */
+<Scan>[^"'\/\n\\]* { /* eat anything that is not " / or \n */
copyToOutput(yytext,yyleng);
}
<Scan>"\"" { /* start of a string */
copyToOutput(yytext,yyleng);
BEGIN(SkipString);
}
+<Scan>{CHARLIT} {
+ copyToOutput(yytext,yyleng);
+ }
<Scan>\n { /* new line */
copyToOutput(yytext,yyleng);
}
diff --git a/src/config.l b/src/config.l
index 7c1cc28..faee601 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1608,6 +1608,14 @@ void Config::create()
TRUE
);
cb = addBool(
+ "EXTRACT_LOCAL_METHODS",
+ "This flag is only useful for Objective-C code. When set to YES local \n"
+ "methods, which are defined in the implementation section but not in \n"
+ "the interface are included in the documentation. \n"
+ "If set to NO (the default) only methods in the interface are included. \n",
+ FALSE
+ );
+ cb = addBool(
"HIDE_UNDOC_MEMBERS",
"If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \n"
"undocumented members of documented classes, files or namespaces. \n"
diff --git a/src/definition.cpp b/src/definition.cpp
index ac18ebe..a99549b 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -39,7 +39,7 @@
static void addToMap(const char *name,Definition *d)
{
QCString symbolName = name;
- int index=symbolName.findRev("::");
+ int index=computeQualifiedIndex(symbolName);
if (index!=-1) symbolName=symbolName.mid(index+2);
if (!symbolName.isEmpty())
{
@@ -58,7 +58,7 @@ static void addToMap(const char *name,Definition *d)
static void removeFromMap(Definition *d)
{
QCString symbolName = d->symbolName();
- int index=symbolName.findRev("::");
+ int index=computeQualifiedIndex(symbolName);
if (index!=-1) symbolName=symbolName.mid(index+2);
if (!symbolName.isEmpty())
{
@@ -512,8 +512,10 @@ void Definition::writeSourceRefList(OutputList &ol,const char *scopeName,
name.prepend(scope+"::");
}
}
- if (md->isFunction() || md->isSlot() ||
- md->isPrototype() || md->isSignal()
+ if (!md->isObjCMethod() &&
+ (md->isFunction() || md->isSlot() ||
+ md->isPrototype() || md->isSignal()
+ )
) name+="()";
//Definition *d = md->getOutputFileBase();
//if (d==Doxygen::globalScope) d=md->getBodyDef();
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 703ed07..645a8f9 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -252,13 +252,14 @@ static void checkArgumentName(const QString &name,bool isParam)
while ((i=re.match(name,p,&l))!=-1)
{
QString aName=name.mid(i,l);
- //printf("aName=%s\n",aName.data());
+ //printf("aName=`%s'\n",aName.data());
ArgumentListIterator ali(*al);
Argument *a;
bool found=FALSE;
for (ali.toFirst();(a=ali.current());++ali)
{
QString argName = g_memberDef->isDefine() ? a->type : a->name;
+ //printf("argName=`%s'\n",argName.data());
if (argName.right(3)=="...") argName=argName.left(argName.length()-3);
if (aName==argName)
{
@@ -4085,6 +4086,8 @@ int DocPara::handleHtmlStartTag(const QString &tagName,const HtmlAttribList &tag
break;
case HTML_UNKNOWN:
warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: Unsupported html tag <%s> found", tagName.data());
+ m_children.append(new DocWord(this, "<"+tagName+">"));
+ break;
break;
default:
// we should not get here!
diff --git a/src/dot.cpp b/src/dot.cpp
index d7de2db..86ef71e 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -486,7 +486,7 @@ static void writeBoxMemberList(QTextStream &t,char prot,MemberList &ml,ClassDef
if (mma->getClassDef() == scope)
{
t << prot << " " << convertLabel(mma->name());
- if (mma->isFunction()) t << "()";
+ if (!mma->isObjCMethod() && mma->isFunction()) t << "()";
t << "\\l";
}
}
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index bf1cbc9..fbfc687 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -187,6 +187,11 @@ void statistics()
static void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl,
ArgumentList *al,bool over_load,NamespaceSDict *nl=0);
+static void findMember(Entry *root,
+ QCString funcDecl,
+ bool overloaded,
+ bool isFunc
+ );
const char idMask[] = "[A-Za-z_][A-Za-z_0-9]*";
QCString spaces;
@@ -2914,7 +2919,7 @@ static QDict<int> *getTemplateArgumentsInName(ArgumentList *templateArguments,co
{
QDict<int> *templateNames = new QDict<int>(17);
templateNames->setAutoDelete(TRUE);
- static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*");
+ static QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*");
if (templateArguments)
{
ArgumentListIterator ali(*templateArguments);
@@ -3108,12 +3113,7 @@ static void findUsedClassesForClass(Entry *root,
}
// add any template arguments to the class
QCString usedName = usedClassName+templSpec;
-
- //if (!typeName.isEmpty())
- //{
- // usedName=typeName;
- //}
- //printf("usedName=`%s'\n",usedName.data());
+ //printf("usedName=%s\n",usedName.data());
bool delTempNames=FALSE;
if (templateNames==0)
@@ -3147,7 +3147,7 @@ static void findUsedClassesForClass(Entry *root,
if (usedCd)
{
if (isArtificial) usedCd->setClassIsArtificial();
- Debug::print(Debug::Classes,0," Adding used class `%s'\n", usedCd->name().data());
+ Debug::print(Debug::Classes,0," Adding used class `%s' (1)\n", usedCd->name().data());
instanceCd->addUsedClass(usedCd,md->name());
usedCd->addUsedByClass(instanceCd,md->name());
}
@@ -3160,10 +3160,10 @@ static void findUsedClassesForClass(Entry *root,
ClassDef *usedCd=findClassWithinClassContext(masterCd,usedName);
//printf("Looking for used class: result=%p master=%p\n",usedCd,masterCd);
- if (usedCd /*&& usedCd!=masterCd*/)
+ if (usedCd)
{
found=TRUE;
- Debug::print(Debug::Classes,0," Adding used class `%s'\n", usedCd->name().data());
+ Debug::print(Debug::Classes,0," Adding used class `%s' (2)\n", usedCd->name().data());
instanceCd->addUsedClass(usedCd,md->name()); // class exists
usedCd->addUsedByClass(instanceCd,md->name());
}
@@ -3192,7 +3192,7 @@ static void findUsedClassesForClass(Entry *root,
if (usedCd)
{
if (isArtificial) usedCd->setClassIsArtificial();
- Debug::print(Debug::Classes,0," Adding used class `%s'\n", usedCd->name().data());
+ Debug::print(Debug::Classes,0," Adding used class `%s' (3)\n", usedCd->name().data());
instanceCd->addUsedClass(usedCd,md->name());
usedCd->addUsedByClass(instanceCd,md->name());
}
@@ -3297,6 +3297,7 @@ static bool findTemplateInstanceRelation(Entry *root,
if (freshInstance)
{
+ Debug::print(Debug::Classes,0," found fresh instance!\n");
Doxygen::classSDict.append(instanceClass->name(),instanceClass);
instanceClass->setTemplateBaseClassNames(templateNames);
@@ -3305,6 +3306,7 @@ static bool findTemplateInstanceRelation(Entry *root,
Entry *templateRoot = classEntries.find(templateClass->name());
if (templateRoot)
{
+ Debug::print(Debug::Classes,0," template root found %s!\n",templateRoot->name.data());
ArgumentList *templArgs = new ArgumentList;
stringToArgumentList(templSpec,templArgs);
findBaseClassesForClass(templateRoot,templateClass,instanceClass,
@@ -3316,12 +3318,17 @@ static bool findTemplateInstanceRelation(Entry *root,
}
else
{
+ Debug::print(Debug::Classes,0," no template root entry found!\n");
// TODO: what happened if we get here?
}
//Debug::print(Debug::Classes,0," Template instance %s : \n",instanceClass->name().data());
//ArgumentList *tl = templateClass->templateArguments();
}
+ else
+ {
+ Debug::print(Debug::Classes,0," instance already exists!\n");
+ }
return TRUE;
}
@@ -4199,11 +4206,8 @@ static bool findGlobalMember(Entry *root,
}
else // got docs for an undefined member!
{
- if (root->parent && root->parent->section==Entry::OBJCIMPL_SEC)
- {
- // probably a local member ObjC method not found in the interface
- }
- else
+ if (root->type!="friend class" && root->type!="friend struct" &&
+ root->type!="friend union")
{
warn(root->fileName,root->startLine,
"Warning: documented function `%s' was not defined.",decl
@@ -4389,8 +4393,8 @@ static void findMember(Entry *root,
funcArgs,funcTempList,exceptions
);
}
- //printf("scopeName=`%s' funcType=`%s' funcName=`%s'\n",
- // scopeName.data(),funcType.data(),funcName.data());
+ //printf("scopeName=`%s' funcType=`%s' funcName=`%s' funcArgs=`%s'\n",
+ // scopeName.data(),funcType.data(),funcName.data(),funcArgs.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
@@ -4751,9 +4755,11 @@ static void findMember(Entry *root,
delete nl;
}
}
- if (count==0 && !(isFriend && funcType=="class") &&
- (root->parent==0 || root->parent->section!=Entry::OBJCIMPL_SEC)
- )
+ if (count==0 && root->parent && root->parent->section==Entry::OBJCIMPL_SEC)
+ {
+ goto localObjCMethod;
+ }
+ if (count==0 && !(isFriend && funcType=="class"))
{
int candidates=0;
if (mn->count()>0)
@@ -5050,6 +5056,59 @@ static void findMember(Entry *root,
);
}
}
+ else if (root->parent && root->parent->section==Entry::OBJCIMPL_SEC)
+ {
+localObjCMethod:
+ ClassDef *cd;
+ //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data());
+ if (Config_getBool("EXTRACT_LOCAL_METHODS") && (cd=getClass(scopeName)))
+ {
+ bool ambig;
+ //printf("Local objective C method `%s' of class `%s' found\n",root->name.data(),cd->name().data());
+ MemberDef *md=new MemberDef(
+ root->fileName,root->startLine,
+ funcType,funcName,funcArgs,exceptions,
+ root->protection,root->virt,root->stat,FALSE,
+ MemberDef::Function,0,root->argList);
+ if (root->tagInfo)
+ {
+ md->setAnchor(root->tagInfo->anchor);
+ md->setReference(root->tagInfo->tagName);
+ }
+ md->makeImplementationDetail();
+ md->setMemberClass(cd);
+ md->setDefinition(funcDecl);
+ md->enableCallGraph(root->callGraph);
+ md->setDocumentation(root->doc,root->docFile,root->docLine);
+ md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+ md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
+ md->setDocsForDefinition(!root->proto);
+ md->setPrototype(root->proto);
+ md->addSectionsToDefinition(root->anchors);
+ md->setBodySegment(root->bodyLine,root->endBodyLine);
+ FileDef *fd=findFileDef(Doxygen::inputNameDict,root->fileName,ambig);
+ md->setBodyDef(fd);
+ md->setMemberSpecifiers(root->memSpec);
+ md->setMemberGroupId(root->mGrpId);
+ cd->insertMember(md);
+ cd->insertUsedFile(root->fileName);
+ md->setRefItems(root->sli);
+ if ((mn=Doxygen::memberNameSDict[root->name]))
+ {
+ mn->append(md);
+ }
+ else
+ {
+ mn = new MemberName(root->name);
+ mn->append(md);
+ Doxygen::memberNameSDict.append(root->name,mn);
+ }
+ }
+ else
+ {
+ // local objective C method found for class without interface
+ }
+ }
else // unrelated not overloaded member found
{
bool globMem = findGlobalMember(root,namespaceName,funcName,funcTempList,funcArgs,funcDecl);
diff --git a/src/entry.h b/src/entry.h
index 44504fc..4670a48 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -237,7 +237,9 @@ class Entry
Explicit = 0x02,
Mutable = 0x04,
Settable = 0x08,
- Gettable = 0x10
+ Gettable = 0x10,
+ Readable = 0x20,
+ Writable = 0x40
};
Entry();
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 30d9a5c..66ecb52 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -37,8 +37,8 @@
// #define GROUP_COLOR "#ff8080"
-//#define DBG_HTML(x) x;
-#define DBG_HTML(x)
+#define DBG_HTML(x) x;
+//#define DBG_HTML(x)
static const char *defaultStyleSheet =
"H1 {\n"
@@ -1069,7 +1069,7 @@ void HtmlGenerator::startParameterName(bool oneArgOnly)
t << "\" nowrap>"; //&nbsp;";
}
-void HtmlGenerator::endParameterName(bool last,bool emptyList)
+void HtmlGenerator::endParameterName(bool last,bool emptyList,bool closeBracket)
{
DBG_HTML(t << "<!-- endParameterName -->" << endl;)
if (last)
@@ -1077,7 +1077,9 @@ void HtmlGenerator::endParameterName(bool last,bool emptyList)
if (emptyList)
{
t << " </td>" << endl;
- t << " <td class=\"md\" valign=\"top\">&nbsp;)&nbsp;</td>" << endl;
+ t << " <td class=\"md\" valign=\"top\">";
+ if (closeBracket) t << "&nbsp;)";
+ t << "&nbsp;</td>" << endl;
t << " <td class=\"md\" nowrap>";
}
else
@@ -1086,7 +1088,9 @@ void HtmlGenerator::endParameterName(bool last,bool emptyList)
t << " </tr>" << endl;
t << " <tr>" << endl;
t << " <td></td>" << endl;
- t << " <td class=\"md\">)&nbsp;</td>" << endl;
+ t << " <td class=\"md\">";
+ if (closeBracket) t << ")";
+ t << "&nbsp;</td>" << endl;
t << " <td class=\"md\" colspan=\"2\">";
}
}
diff --git a/src/htmlgen.h b/src/htmlgen.h
index 4c303d6..b832b35 100644
--- a/src/htmlgen.h
+++ b/src/htmlgen.h
@@ -200,7 +200,7 @@ class HtmlGenerator : public OutputGenerator
void startParameterType(bool first,const char *key);
void endParameterType();
void startParameterName(bool);
- void endParameterName(bool last,bool emptyList);
+ void endParameterName(bool last,bool emptyList,bool closeBracket);
void startParameterList(bool);
void endParameterList();
diff --git a/src/index.cpp b/src/index.cpp
index fa080ac..ecbf8dd 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -1650,7 +1650,8 @@ void writeMemberList(OutputList &ol,bool useSections,ClassMemberHighlight filter
)
{
found=TRUE;
- isFunc=md->isFunction() || md->isSlot() || md->isSignal();
+ isFunc=!md->isObjCMethod() &&
+ (md->isFunction() || md->isSlot() || md->isSignal());
}
md=mn->next();
}
diff --git a/src/latexgen.h b/src/latexgen.h
index 2ec1563..9272290 100644
--- a/src/latexgen.h
+++ b/src/latexgen.h
@@ -275,7 +275,7 @@ class LatexGenerator : public OutputGenerator
void startParameterType(bool,const char *) {}
void endParameterType() {}
void startParameterName(bool) {}
- void endParameterName(bool,bool) {}
+ void endParameterName(bool,bool,bool) {}
void startParameterList(bool) {}
void endParameterList() {}
diff --git a/src/mangen.h b/src/mangen.h
index a830a32..c9abef4 100644
--- a/src/mangen.h
+++ b/src/mangen.h
@@ -242,7 +242,7 @@ class ManGenerator : public OutputGenerator
void startParameterType(bool,const char *) {}
void endParameterType() {}
void startParameterName(bool) {}
- void endParameterName(bool,bool) {}
+ void endParameterName(bool,bool,bool) {}
void startParameterList(bool) {}
void endParameterList() {}
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index c47ab09..dfc0685 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -33,8 +33,6 @@
#include "docparser.h"
#include "dot.h"
#include "searchindex.h"
-//#include "xml.h"
-
//-----------------------------------------------------------------------------
@@ -197,7 +195,7 @@ static void writeDefArgumentList(OutputList &ol,ClassDef *cd,
key=a->attrib.mid(1,a->attrib.length()-2);
if (key!=",") key+=":"; // for normal keywords add colon
}
- ol.endParameterName(FALSE,FALSE);
+ ol.endParameterName(FALSE,FALSE,!md->isObjCMethod());
ol.startParameterType(FALSE,key);
}
}
@@ -212,13 +210,13 @@ static void writeDefArgumentList(OutputList &ol,ClassDef *cd,
if (!md->isDefine())
{
if (first) ol.startParameterName(defArgList->count()<2);
- ol.endParameterName(!md->isObjCMethod(),defArgList->count()<2);
+ ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod());
}
else
{
ol.endParameterType();
ol.startParameterName(TRUE);
- ol.endParameterName(TRUE,TRUE);
+ ol.endParameterName(TRUE,TRUE,!md->isObjCMethod());
}
ol.popGeneratorState();
if (defArgList->constSpecifier)
@@ -391,6 +389,7 @@ MemberDef::MemberDef(const char *df,int dl,
m_isTypedefValCached = FALSE;
m_cachedTypedefValue = 0;
m_inbodyLine = -1;
+ m_implOnly=FALSE;
}
/*! Destroys the member definition. */
@@ -1047,6 +1046,12 @@ void MemberDef::writeDeclaration(OutputList &ol,
linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),init);
}
}
+ if (isObjCMethod() && isImplementation())
+ {
+ ol.startTypewriter();
+ ol.docify(" [implementation]");
+ ol.endTypewriter();
+ }
if (!detailsVisible && !annMemb)
{
@@ -1385,7 +1390,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
isMutable() || (isInline() && Config_getBool("INLINE_INFO")) ||
isSignal() || isSlot() ||
isStatic() || (classDef && classDef!=container) ||
- isSettable() || isGettable()
+ isSettable() || isGettable() || isReadable() || isWritable()
)
)
{
@@ -1405,6 +1410,8 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
if (isStatic()) sl.append("static");
if (isGettable()) sl.append("get");
if (isSettable()) sl.append("set");
+ if (isReadable()) sl.append("read");
+ if (isWritable()) sl.append("write");
if (protection()==Protected) sl.append("protected");
else if (protection()==Private) sl.append("private");
else if (protection()==Package) sl.append("package");
@@ -1424,6 +1431,13 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
ol.docify("]");
ol.endTypewriter();
}
+ else if (isObjCMethod() && isImplementation())
+ {
+ ol.writeLatexSpacing();
+ ol.startTypewriter();
+ ol.docify(" [implementation]");
+ ol.endTypewriter();
+ }
if (!isDefine() && defArgList) ol.endParameterList();
ol.endMemberDoc();
ol.endDoxyAnchor(cfname,anchor());
diff --git a/src/memberdef.h b/src/memberdef.h
index b3dc90f..e880a12 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -125,6 +125,9 @@ class MemberDef : public Definition
bool isMutable() const { return (memSpec&Entry::Mutable)!=0; }
bool isGettable() const { return (memSpec&Entry::Gettable)!=0; }
bool isSettable() const { return (memSpec&Entry::Settable)!=0; }
+ bool isReadable() const { return (memSpec&Entry::Readable)!=0; }
+ bool isWritable() const { return (memSpec&Entry::Writable)!=0; }
+ bool isImplementation() const { return m_implOnly; }
bool isExternal() const { return explExt; }
bool isObjCMethod() const;
bool isConstructor() const;
@@ -229,6 +232,7 @@ class MemberDef : public Definition
MemberGroup *getMemberGroup() const { return memberGroup; }
void setMemberGroupId(int id) { grpId=id; }
int getMemberGroupId() const { return grpId; }
+ void makeImplementationDetail() { m_implOnly=TRUE; }
// anonymous scope members
void setFromAnonymousScope(bool b) { annScope=b; }
@@ -360,6 +364,10 @@ class MemberDef : public Definition
int m_inbodyLine;
QCString m_inbodyFile;
QCString m_inbodyDocs;
+
+ // objective-c
+ bool m_implOnly; // function found in implementation but not
+ // in the interface
};
#endif
diff --git a/src/outputgen.h b/src/outputgen.h
index cb85446..980dfdf 100644
--- a/src/outputgen.h
+++ b/src/outputgen.h
@@ -351,7 +351,7 @@ class OutputGenerator : public BaseOutputDocInterface
virtual void startParameterType(bool,const char *) = 0;
virtual void endParameterType() = 0;
virtual void startParameterName(bool) = 0;
- virtual void endParameterName(bool,bool) = 0;
+ virtual void endParameterName(bool,bool,bool) = 0;
virtual void startParameterList(bool) = 0;
virtual void endParameterList() = 0;
diff --git a/src/outputlist.cpp b/src/outputlist.cpp
index fbacc76..eaa7811 100644
--- a/src/outputlist.cpp
+++ b/src/outputlist.cpp
@@ -269,6 +269,7 @@ FORALL1(SectionTypes a1,a1)
FORALL1(bool a1,a1)
FORALL2(bool a1,int a2,a1,a2)
FORALL2(bool a1,bool a2,a1,a2)
+FORALL3(bool a1,bool a2,bool a3,a1,a2,a3)
FORALL4(const char *a1,const char *a2,const char *a3,bool a4,a1,a2,a3,a4)
#endif
FORALL2(int a1,bool a2,a1,a2)
diff --git a/src/outputlist.h b/src/outputlist.h
index 86600df..52fc346 100644
--- a/src/outputlist.h
+++ b/src/outputlist.h
@@ -339,8 +339,8 @@ class OutputList : public OutputDocInterface
{ forall(&OutputGenerator::endParameterType); }
void startParameterName(bool one)
{ forall(&OutputGenerator::startParameterName,one); }
- void endParameterName(bool last,bool one)
- { forall(&OutputGenerator::endParameterName,last,one); }
+ void endParameterName(bool last,bool one,bool bracket)
+ { forall(&OutputGenerator::endParameterName,last,one,bracket); }
void startParameterList(bool openBracket)
{ forall(&OutputGenerator::startParameterList,openBracket); }
void endParameterList()
@@ -388,6 +388,7 @@ class OutputList : public OutputDocInterface
FORALLPROTO1(bool);
FORALLPROTO2(bool,int);
FORALLPROTO2(bool,bool);
+ FORALLPROTO3(bool,bool,bool);
FORALLPROTO4(const char *,const char *,const char *,int);
#endif
FORALLPROTO2(int,bool);
diff --git a/src/pre.l b/src/pre.l
index 0eb3296..490f2f5 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -397,6 +397,18 @@ static void returnCharToStream(char c)
unput(c);
}
+static inline void addTillEndOfString(const QCString &expr,QCString *rest,
+ uint &pos,char term,QCString &arg)
+{
+ char cc;
+ while ((cc=getNextChar(expr,rest,pos))!=EOF)
+ {
+ if (cc=='\\') arg+=cc,cc=getNextChar(expr,rest,pos);
+ else if (cc==term) return;
+ arg+=cc;
+ }
+}
+
/*! replaces the function macro \a def whose argument list starts at
* \a pos in expression \a expr.
* Notice that this routine may scan beyond the \a expr string if needed.
@@ -449,28 +461,23 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int
{
int level=1;
arg+=c;
- char term='\0';
+ //char term='\0';
while ((cc=getNextChar(expr,rest,j))!=EOF)
{
char c=(char)cc;
+ //printf("processing %c: term=%c (%d)\n",c,term,term);
if (c=='\'' || c=='\"') // skip ('s and )'s inside strings
{
- if (term!='\0')
- {
- if (c==term && expr.at(j-2)!='\\') term='\0';
- }
- else
- {
- term=c;
- }
+ arg+=c;
+ addTillEndOfString(expr,rest,j,c,arg);
}
- if (term=='\0' && c==')')
+ if (c==')')
{
level--;
arg+=c;
if (level==0) break;
}
- else if (term=='\0' && c=='(')
+ else if (c=='(')
{
level++;
arg+=c;
@@ -625,7 +632,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int
{
inString=TRUE; // entering a literal string
}
- else if (inString && d.at(k)=='\"' && d.at(k-1)!='\\')
+ else if (inString && d.at(k)=='\"' && (d.at(k-1)!='\\' || d.at(k-2)=='\\'))
{
inString=FALSE; // leaving a literal string
}
@@ -665,10 +672,12 @@ static int getNextId(const QCString &expr,int p,int *l)
}
else if (c=='"') // skip string
{
- char pc=c;
+ char ppc=0,pc=c;
if (p<(int)expr.length()) c=expr.at(p);
- while (p<(int)expr.length() && (c!='"' || pc=='\\'))
+ while (p<(int)expr.length() && (c!='"' || (pc=='\\' && ppc!='\\')))
+ // continue as long as no " is found, but ignoring \", but not \\"
{
+ ppc=pc;
pc=c;
c=expr.at(p);
p++;
@@ -1189,6 +1198,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
Define *def=0;
if (skipFuncMacros &&
+ name!="Q_PROPERTY" &&
!(
(g_includeStack.isEmpty() || g_curlyCount>0) &&
g_macroExpansion &&
diff --git a/src/rtfgen.h b/src/rtfgen.h
index 65cd94e..bd611cf 100644
--- a/src/rtfgen.h
+++ b/src/rtfgen.h
@@ -245,7 +245,7 @@ class RTFGenerator : public OutputGenerator
void startParameterType(bool,const char *) {}
void endParameterType() {}
void startParameterName(bool) {}
- void endParameterName(bool,bool) {}
+ void endParameterName(bool,bool,bool) {}
void startParameterList(bool) {}
void endParameterList() {}
diff --git a/src/scanner.l b/src/scanner.l
index 70ae82e..2db9d21 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -807,6 +807,9 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
%x ObjCReturnType
%x ObjCParams
%x ObjCParamType
+%x QtPropType
+%x QtPropName
+%x QtPropRW
%%
@@ -1032,6 +1035,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
current->bodyLine = yyLineNr;
current->section = Entry::FUNCTION_SEC;
current->protection = protection = Public ;
+ current->virt = Virtual;
current->stat=yytext[0]=='+';
current->mtype = mtype = Method;
current->type.resize(0);
@@ -1110,14 +1114,6 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
lineCount();
}
<PackageName>{ID}("."{ID})* {
- //current->name = yytext;
- //current->fileName = yyFileName;
- //current->startLine = yyLineNr;
- //current->section=Entry::PACKAGE_SEC;
- //current_root->addSubEntry(current);
- //current = new Entry ;
- //initEntry();
-
isTypedef=FALSE;
current->name = yytext;
current->name = substitute(current->name,".","::");
@@ -1567,6 +1563,31 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
else
REJECT;
}
+<FindMembers>"Q_OBJECT" { // Qt object macro
+ }
+<FindMembers>"Q_PROPERTY" { // Qt property declaration
+ current->protection = protection = Public ;
+ current->mtype = mtype = Property;
+ BEGIN(QtPropType);
+ }
+<QtPropType>{ID} {
+ current->type=yytext;
+ BEGIN(QtPropName);
+ }
+<QtPropName>{ID} {
+ current->name=yytext;
+ BEGIN(QtPropRW);
+ }
+<QtPropRW>"READ" {
+ current->memSpec |= Entry::Readable;
+ }
+<QtPropRW>"WRITE" {
+ current->memSpec |= Entry::Writable;
+ }
+<QtPropRW>")" {
+ unput(';');
+ BEGIN(FindMembers);
+ }
<FindMembers,FindMemberName>{SCOPENAME} {
lineCount();
if (insideIDL && yyleng==9 && strcmp(yytext,"cpp_quote")==0)
@@ -3869,7 +3890,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
}
BEGIN( tmpDocType );
}
-<Doc,JavaDoc>{B}*{CMD}("fn"|"var"|"typedef"){B}+ {
+<Doc,JavaDoc>{B}*{CMD}("fn"|"var"|"typedef"|"property"){B}+ {
current->section = Entry::MEMBERDOC_SEC;
current->fileName = yyFileName;
current->startLine = yyLineNr;
diff --git a/src/translator_nl.h b/src/translator_nl.h
index 3e80326..91d8c73 100644
--- a/src/translator_nl.h
+++ b/src/translator_nl.h
@@ -707,9 +707,12 @@ class TranslatorDutch : public Translator
"relatie tussen twee klassen.\n"
"<li>Een donkergroene pijl wordt gebruikt voor protected inheritance.\n"
"<li>Een donkerrode pijl wordt gebruikt voor private inheritance.\n"
- "<li>Een paars gestreepte pijl wordt gebruikt indien een klasse bevat is of gebruikt wordt "
+ "<li>Een paars gestippelde pijl wordt gebruikt indien een klasse bevat is of gebruikt wordt "
"door een andere klasse. De pijl is gelabeled met de variable(n) "
"die toegang geven tot de aangewezen klasse of structure. \n"
+ "<li>Een geel gestippelde pijl wordt gebruikt om een relatie tussen een \n"
+ "template instantie en een template klasse aan te geven. De pijl is gelabeld met \n"
+ "template parameters van de instantie.\n"
"</ul>\n";
}
/*! text for the link to the legend page */
diff --git a/src/util.cpp b/src/util.cpp
index a72a968..5a1099a 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -959,6 +959,12 @@ done:
return result;
}
+int computeQualifiedIndex(const QString &name)
+{
+ int i = name.find('<');
+ return name.findRev("::",i==-1 ? name.length() : i);
+}
+
/* Find the fully qualified class name refered to by the input class
* or typedef name against the input scope.
* Loops through scope and each of its parent scopes looking for a
@@ -976,7 +982,9 @@ ClassDef *getResolvedClassRec(Definition *scope,
QCString name=n;
QCString explicitScopePart;
- int qualifierIndex = name.findRev("::"); // todo: deal with cases like A<B::C>
+ //int qualifierIndex = name.findRev("::"); // todo: deal with cases like A<B::C>
+ int qualifierIndex = computeQualifiedIndex(name);
+ //printf("name=%s qualifierIndex=%d\n",name.data(),qualifierIndex);
if (qualifierIndex!=-1) // qualified name
{
// split off the explicit scope part
@@ -1101,7 +1109,7 @@ ClassDef *getResolvedClass(Definition *scope,
}
//printf("getResolvedClass(%s,%s)=%s\n",scope?scope->name().data():"<global>",
// n,result?result->name().data():"<none>");
- //
+ //
//printf("-------- end\n");
return result;
}
@@ -1168,7 +1176,7 @@ QCString removeRedundantWhiteSpace(const QCString &s)
result+=' ';
result+=s.at(i);
}
- else if (c=='t' && csp==5 && !(isId(s.at(i+1)) || s.at(i+1)==' ')) // prevent const ::A from being converted to const::A
+ else if (c=='t' && csp==5 && !(isId(s.at(i+1)) || s.at(i+1)==' ' || s.at(i+1)==')' || s.at(i+1)==',' || s.at(i+1)=='\0')) // prevent const ::A from being converted to const::A
{
result+="t ";
csp=0;
diff --git a/src/util.h b/src/util.h
index 3f04349..dacb25e 100644
--- a/src/util.h
+++ b/src/util.h
@@ -212,6 +212,7 @@ void replaceNamespaceAliases(QCString &scope,int i);
int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item);
int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item,
const QCString &explicitScopePart);
+int computeQualifiedIndex(const QString &name);
#endif