diff options
-rw-r--r-- | INSTALL | 4 | ||||
-rw-r--r-- | README | 4 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | doc/commands.doc | 11 | ||||
-rw-r--r-- | doc/config.doc | 9 | ||||
-rw-r--r-- | doc/grouping.doc | 8 | ||||
-rw-r--r-- | doc/language.doc | 2 | ||||
-rw-r--r-- | doc/translator.py | 2 | ||||
-rw-r--r-- | packages/rpm/doxygen.spec | 2 | ||||
-rw-r--r-- | src/classdef.cpp | 9 | ||||
-rw-r--r-- | src/code.l | 176 | ||||
-rw-r--r-- | src/commentcnv.l | 7 | ||||
-rw-r--r-- | src/config.l | 8 | ||||
-rw-r--r-- | src/definition.cpp | 10 | ||||
-rw-r--r-- | src/docparser.cpp | 5 | ||||
-rw-r--r-- | src/dot.cpp | 2 | ||||
-rw-r--r-- | src/doxygen.cpp | 101 | ||||
-rw-r--r-- | src/entry.h | 4 | ||||
-rw-r--r-- | src/htmlgen.cpp | 14 | ||||
-rw-r--r-- | src/htmlgen.h | 2 | ||||
-rw-r--r-- | src/index.cpp | 3 | ||||
-rw-r--r-- | src/latexgen.h | 2 | ||||
-rw-r--r-- | src/mangen.h | 2 | ||||
-rw-r--r-- | src/memberdef.cpp | 26 | ||||
-rw-r--r-- | src/memberdef.h | 8 | ||||
-rw-r--r-- | src/outputgen.h | 2 | ||||
-rw-r--r-- | src/outputlist.cpp | 1 | ||||
-rw-r--r-- | src/outputlist.h | 5 | ||||
-rw-r--r-- | src/pre.l | 38 | ||||
-rw-r--r-- | src/rtfgen.h | 2 | ||||
-rw-r--r-- | src/scanner.l | 39 | ||||
-rw-r--r-- | src/translator_nl.h | 5 | ||||
-rw-r--r-- | src/util.cpp | 14 | ||||
-rw-r--r-- | src/util.h | 1 |
34 files changed, 427 insertions, 103 deletions
@@ -1,7 +1,7 @@ -DOXYGEN Version 1.3.6-20040222 +DOXYGEN Version 1.3.6-20040307 Please read the installation section of the manual (http://www.doxygen.org/install.html) for instructions. -------- -Dimitri van Heesch (22 February 2004) +Dimitri van Heesch (07 March 2004) @@ -1,4 +1,4 @@ -DOXYGEN Version 1.3.6_20040222 +DOXYGEN Version 1.3.6_20040307 Please read INSTALL for compilation instructions. @@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives. Enjoy, -Dimitri van Heesch (dimitri@stack.nl) (22 February 2004) +Dimitri van Heesch (dimitri@stack.nl) (07 March 2004) @@ -1 +1 @@ -1.3.6-20040222 +1.3.6-20040307 diff --git a/doc/commands.doc b/doc/commands.doc index b315af3..4d3d804 100644 --- a/doc/commands.doc +++ b/doc/commands.doc @@ -109,6 +109,7 @@ documentation: \refitem cmdparam \\param \refitem cmdpost \\post \refitem cmdpre \\pre +\refitem cmdproperty \\property \refitem cmdref \\ref \refitem cmdrelates \\relates \refitem cmdrelatesalso \\relatesalso @@ -540,6 +541,16 @@ See section \ref memgroup for an example. \ref cmdref "\\ref". <hr> +\section cmdproperty \property (qualified property name) + + \addindex \\property + Indicates that a comment block contains documentation for a + property (either global or as a member of a class). + This command is equivalent to \\var and \\fn. + + \sa section \ref cmdfn "\\fn" and \ref cmdvar "\\var". + +<hr> \section cmdrelates \relates <name> \addindex \\relates diff --git a/doc/config.doc b/doc/config.doc index ca6105d..fb671b8 100644 --- a/doc/config.doc +++ b/doc/config.doc @@ -92,6 +92,7 @@ followed by the descriptions of the tags grouped by category. \refitem cfg_extra_packages EXTRA_PACKAGES \refitem cfg_extract_all EXTRACT_ALL \refitem cfg_extract_local_classes EXTRACT_LOCAL_CLASSES +\refitem cfg_extract_local_methods EXTRACT_LOCAL_METHODS \refitem cfg_extract_private EXTRACT_PRIVATE \refitem cfg_extract_static EXTRACT_STATIC \refitem cfg_file_patterns FILE_PATTERNS @@ -467,6 +468,14 @@ followed by the descriptions of the tags grouped by category. If set to NO only classes defined in header files are included. Does not have any effect for Java sources. +\anchor cfg_extract_local_methods +<dt>\c EXTRACT_LOCAL_METHODS <dd> + \addindex EXTRACT_LOCAL_METHODS + This flag is only useful for Objective-C code. When set to \c YES local + methods, which are defined in the implementation section but not in + the interface are included in the documentation. + If set to \c NO (the default) only methods in the interface are included. + \anchor cfg_hide_undoc_members <dt>\c HIDE_UNDOC_MEMBERS <dd> \addindex HIDE_UNDOC_MEMBERS diff --git a/doc/grouping.doc b/doc/grouping.doc index 2a1fe89..e87b596 100644 --- a/doc/grouping.doc +++ b/doc/grouping.doc @@ -105,6 +105,14 @@ int IntegerVariable; /*@}*/ \endverbatim +The \ref cmdref "\\ref" command can be used to refer to a group. +The first argument of the \\ref command should be group's label. +To use a custom link name, you can put the name of the links in +double quotes after the label, as shown by the following example +\verbatim +This is the \ref group_label "link" to this group. +\endverbatim + The priorities of grouping definitions are (from highest to lowest): \ref cmdingroup "\\ingroup", \ref cmddefgroup "\\defgroup", \ref cmdaddtogroup "\\addtogroup", \ref cmdweakgroup "\\weakgroup". diff --git a/doc/language.doc b/doc/language.doc index dcb3783..fb25b1b 100644 --- a/doc/language.doc +++ b/doc/language.doc @@ -23,7 +23,7 @@ text fragments, generated by doxygen, can be produced in languages other than English (the default). The output language is chosen through the configuration file (with default name and known as Doxyfile). -Currently (version 1.3.6), 28 languages +Currently (version 1.3.6-20040222), 28 languages are supported (sorted alphabetically): Brazilian Portuguese, Catalan, Chinese, Chinese Traditional, Croatian, Czech, Danish, Dutch, English, Finnish, French, German, Greek, diff --git a/doc/translator.py b/doc/translator.py index aa182f0..4ec7d2f 100644 --- a/doc/translator.py +++ b/doc/translator.py @@ -1266,7 +1266,7 @@ class TrManager: self.numLang -= 1 # the couple will be counted as one # Extract the version of Doxygen. - f = file(os.path.join(self.doxy_path, 'version')) + f = file(os.path.join(self.doxy_path, 'VERSION')) self.doxVersion = f.readline().strip() f.close() diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec index f289012..96436aa 100644 --- a/packages/rpm/doxygen.spec +++ b/packages/rpm/doxygen.spec @@ -1,6 +1,6 @@ Summary: A documentation system for C/C++. Name: doxygen -Version: 1.3.6_20040222 +Version: 1.3.6_20040307 Release: 1 Epoch: 1 Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz 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); @@ -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>"; // "; } -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\"> ) </td>" << endl; + t << " <td class=\"md\" valign=\"top\">"; + if (closeBracket) t << " )"; + t << " </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\">) </td>" << endl; + t << " <td class=\"md\">"; + if (closeBracket) t << ")"; + t << " </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); @@ -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; @@ -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 |