summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authordimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2005-12-27 20:36:39 (GMT)
committerdimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2005-12-27 20:36:39 (GMT)
commitd4da97f32ddc6c44df781b3b7b762be0101b9bac (patch)
tree0e4517c465cd2c2702cd62de3f3f29bc068bc1da /src
parentcbb944eb7796b2501628c65de1c014d7cca48dcd (diff)
downloadDoxygen-d4da97f32ddc6c44df781b3b7b762be0101b9bac.zip
Doxygen-d4da97f32ddc6c44df781b3b7b762be0101b9bac.tar.gz
Doxygen-d4da97f32ddc6c44df781b3b7b762be0101b9bac.tar.bz2
Release-1.4.5-20051227
Diffstat (limited to 'src')
-rw-r--r--src/code.l34
-rw-r--r--src/commentcnv.l2
-rw-r--r--src/commentscan.l17
-rw-r--r--src/compound.xsd1
-rw-r--r--src/compound_xsd.h1
-rw-r--r--src/docparser.cpp23
-rw-r--r--src/doxygen.cpp196
-rw-r--r--src/filedef.cpp2
-rw-r--r--src/groupdef.h4
-rw-r--r--src/htmlgen.cpp4
-rw-r--r--src/index.cpp5
-rw-r--r--src/namespacedef.cpp2
-rw-r--r--src/pagedef.cpp1
-rw-r--r--src/pagedef.h3
-rw-r--r--src/parserintf.h3
-rw-r--r--src/pre.l7
-rw-r--r--src/pyscanner.h1
-rw-r--r--src/scanner.h1
-rw-r--r--src/scanner.l16
-rw-r--r--src/translator.h3
-rw-r--r--src/util.cpp204
-rw-r--r--src/util.h107
-rw-r--r--src/xmlgen.cpp7
23 files changed, 475 insertions, 169 deletions
diff --git a/src/code.l b/src/code.l
index a6da646..f0d285a 100644
--- a/src/code.l
+++ b/src/code.l
@@ -98,6 +98,7 @@ static bool g_inFunctionTryBlock = FALSE;
static int g_lastSpecialCContext;
static int g_lastStringContext;
+static int g_lastSkipCppContext;
static int g_lastVerbStringContext;
static int g_memCallContext;
static int g_lastCContext;
@@ -105,6 +106,7 @@ static int g_lastCContext;
static bool g_insideObjC;
static bool g_insideProtocolList;
+
// context for an Objective-C method call
struct ObjCCallCtx
{
@@ -881,19 +883,20 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName,
Definition *d = g_currentDefinition;
//printf("d=%p g_sourceFileDef=%p\n",d,g_currentDefinition);
cd = getResolvedClass(d,g_sourceFileDef,className,&md);
- //printf("non-local variable name=%s context=%d cd=%s md=%s!\n",
+ //fprintf(stderr,"non-local variable name=%s context=%d cd=%s md=%s!\n",
// className.data(),g_theVarContext.count(),cd?cd->name().data():"<none>",
// md?md->name().data():"<none>");
if (cd==0 && md==0 && (i=className.find('<'))!=-1)
{
- QCString bareName = stripTemplateSpecifiersFromScope(className);
+ QCString bareName = className.left(i); //stripTemplateSpecifiersFromScope(className);
+ //fprintf(stderr,"bareName=%s\n",bareName.data());
if (bareName!=className)
{
cd=getResolvedClass(d,g_sourceFileDef,bareName,&md); // try unspecialized version
}
}
//printf("md=%s\n",md?md->name().data():"<none>");
- //printf("is found as a type %s\n",cd?cd->name().data():"<null>");
+ //fprintf(stderr,"is found as a type %s\n",cd?cd->name().data():"<null>");
if (cd==0 && md==0) // also see if it is variable or enum or enum value
{
if (getLink(g_classScope,clName,ol,clName))
@@ -1756,6 +1759,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
}
<Body>^[ \t]*"#" {
startFontClass("preprocessor");
+ g_lastSkipCppContext = YY_START;
g_code->codify(yytext);
BEGIN( SkipCPP ) ;
}
@@ -1768,7 +1772,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
<SkipCPP>\n/.*\n {
codifyLines(yytext);
endFontClass();
- BEGIN( Body ) ;
+ BEGIN( g_lastSkipCppContext ) ;
}
<SkipCPP>"//" {
g_code->codify(yytext);
@@ -2053,13 +2057,13 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
codifyLines(yytext);
endFontClass();
}
-<Body>{KEYWORD}/{B}*"(" {
+<Body>{KEYWORD}/{BN}*"(" {
startFontClass("keyword");
codifyLines(yytext);
endFontClass();
g_name.resize(0);g_type.resize(0);
}
-<Body>{FLOWKW}/{B}*"(" {
+<Body>{FLOWKW}/{BN}*"(" {
startFontClass("keywordflow");
codifyLines(yytext);
endFontClass();
@@ -2125,7 +2129,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
generateClassOrGlobalLink(*g_code,yytext);
g_name+=yytext;
}
-<Body>{SCOPENAME}/{B}*[;,)\]] { // "int var;" or "var, var2" or "debug(f) macro"
+<Body>{SCOPENAME}/{BN}*[;,)\]] { // "int var;" or "var, var2" or "debug(f) macro"
addType();
generateClassOrGlobalLink(*g_code,yytext/*,TRUE*/);
g_name+=yytext;
@@ -2143,7 +2147,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
addType();
g_name=varname;
}
-<Body>{SCOPETNAME}/{B}*"(" { // a() or c::a() or t<A,B>::a()
+<Body>{SCOPETNAME}/{BN}*"(" { // a() or c::a() or t<A,B>::a()
addType();
generateFunctionLink(*g_code,yytext);
//g_theVarContext.addVariable(g_type,yytext);
@@ -2221,7 +2225,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
g_memCallContext = YY_START;
BEGIN( MemberCall );
}
-<MemberCall>{SCOPETNAME}/{B}*"(" {
+<MemberCall>{SCOPETNAME}/{BN}*"(" {
if (g_theCallContext.getClass())
{
if (!generateClassMemberLink(*g_code,g_theCallContext.getClass(),yytext))
@@ -2463,11 +2467,15 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
g_code->codify(yytext);
endFontClass();
}
-<MemberCall2,FuncCall>[a-z_A-Z][:a-z_A-Z0-9]*({B}*"<"[^\n\[\](){}<>]*">")? {
+<MemberCall2,FuncCall>{ID}(({B}*"<"[^\n\[\](){}<>]*">")?({B}*"::"{B}*{ID})?)* {
addParmType();
g_parmName=yytext;
generateClassOrGlobalLink(*g_code,yytext,!g_insideBody);
}
+<FuncCall>";" { // probably a cast, not a function call
+ g_code->codify(yytext);
+ BEGIN( Body );
+ }
<MemberCall2,FuncCall>, {
g_code->codify(yytext);
g_theVarContext.addVariable(g_parmType,g_parmName);
@@ -2619,6 +2627,12 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
if (*yytext==';') g_parmType.resize(0);
g_parmName.resize(0);
}
+<CallEnd,OldStyleArgs>"#" {
+ startFontClass("preprocessor");
+ g_lastSkipCppContext = Body;
+ g_code->codify(yytext);
+ BEGIN( SkipCPP );
+ }
<CallEnd>. {
unput(*yytext);
if (!g_insideBody)
diff --git a/src/commentcnv.l b/src/commentcnv.l
index cb065ec..ce217f9 100644
--- a/src/commentcnv.l
+++ b/src/commentcnv.l
@@ -320,7 +320,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
copyToOutput(yytext,yyleng);
BEGIN(CComment);
}
-<CComment,ReadLine>[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly"|"dot"|"code"|"f$"|"f["|"f{")/[^a-z_A-Z0-9] { /* start of a verbatim block */
+<CComment,ReadLine>[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly"|"dot"|"code"|"f$"|"f["|"f{"[a-z]*)/[^a-z_A-Z0-9] { /* start of a verbatim block */
copyToOutput(yytext,yyleng);
if (yytext[2]=='[')
{
diff --git a/src/commentscan.l b/src/commentscan.l
index 76f50f1..fba617b 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -698,8 +698,8 @@ static int yyread(char *buf,int max_size)
/* start command character */
CMD ("\\"|"@")
-DCMD1 ("arg"|"attention"|"author"|"bug"|"code")
-DCMD2 ("date"|"deprecated"|"dot"|"dotfile"|"example")
+DCMD1 ("arg"|"attention"|"author"|"code")
+DCMD2 ("date"|"dot"|"dotfile"|"example")
DCMD3 ("htmlinclude"|"htmlonly"|"image"|"include")
DCMD4 ("includelineno"|"internal"|"invariant")
DCMD5 ("latexonly"|"li"|"line"|"manonly"|"name")
@@ -707,9 +707,10 @@ DCMD6 ("note"|"par"|"paragraph"|"param"|"post")
DCMD7 ("pre"|"remarks"|(("relate"[sd])("also")?))
DCMD8 ("remarks"|("return"[s]?)|"retval"|"sa"|"section")
DCMD9 ("see"|"since"|"subsection"|"subsubsection")
-DCMD10 ("test"|"throw"|"todo"|"until"|"verbatim")
-DCMD11 ("verbinclude"|"version"|"warning"|"xrefitem")
+DCMD10 ("throw"|"until"|"verbatim")
+DCMD11 ("verbinclude"|"version"|"warning")
DETAILEDCMD {CMD}({DCMD1}|{DCMD2}|{DCMD3}|{DCMD4}|{DCMD5}|{DCMD6}|{DCMD7}|{DCMD8}|{DCMD9}|{DCMD10}|{DCMD11})
+XREFCMD {CMD}("bug"|"deprecated"|"test"|"todo"|"xrefitem")
PRE [pP][rR][eE]
TABLE [tT][aA][bB][lL][eE]
P [pP]
@@ -810,7 +811,7 @@ MAILADR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]
<Comment>("\\"[a-z_A-Z]+)+"\\" { // directory (or chain of commands!)
addOutput(yytext);
}
-<Comment>{DETAILEDCMD}/[^a-z_A-Z]* { // command that can end a brief description
+<Comment>{XREFCMD}/[^a-z_A-Z]* { // command that can end a brief description
if (inContext!=OutputXRef)
{
briefEndsAtDot=FALSE;
@@ -819,6 +820,12 @@ MAILADR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]
// continue with the same input
REJECT;
}
+<Comment>{DETAILEDCMD}/[^a-z_A-Z]* { // command that can end a brief description
+ briefEndsAtDot=FALSE;
+ setOutput(OutputDoc);
+ // continue with the same input
+ REJECT;
+ }
<Comment>"<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description
setOutput(OutputDoc);
// continue with the same input
diff --git a/src/compound.xsd b/src/compound.xsd
index e737939..627fab5 100644
--- a/src/compound.xsd
+++ b/src/compound.xsd
@@ -122,6 +122,7 @@
<xsd:element name="name" />
<xsd:element name="read" minOccurs="0" />
<xsd:element name="write" minOccurs="0" />
+ <xsd:element name="bitfield" minOccurs="0" />
<xsd:element name="reimplements" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="reimplementedby" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
diff --git a/src/compound_xsd.h b/src/compound_xsd.h
index a35c4fa..3783b45 100644
--- a/src/compound_xsd.h
+++ b/src/compound_xsd.h
@@ -122,6 +122,7 @@
" <xsd:element name=\"name\" />\n"
" <xsd:element name=\"read\" minOccurs=\"0\" />\n"
" <xsd:element name=\"write\" minOccurs=\"0\" />\n"
+" <xsd:element name=\"bitfield\" minOccurs=\"0\" />\n"
" <xsd:element name=\"reimplements\" type=\"reimplementType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n"
" <xsd:element name=\"reimplementedby\" type=\"reimplementType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n"
" <xsd:element name=\"param\" type=\"paramType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n"
diff --git a/src/docparser.cpp b/src/docparser.cpp
index b8d11e7..8bac157 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -868,9 +868,13 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children)
QString name = linkToText(g_token->name,TRUE);
int len = g_token->name.length();
ClassDef *cd=0;
- //printf("handleLinkedWord(%s)\n",name.data());
+ //printf("handleLinkedWord(%s) g_context=%s\n",name.data(),g_context.data());
if (!g_insideHtmlLink &&
- resolveRef(g_context,g_token->name,g_inSeeBlock,&compound,&member))
+ (resolveRef(g_context,g_token->name,g_inSeeBlock,&compound,&member)
+ || (!g_context.isEmpty() && // also try with global scope
+ resolveRef("",g_token->name,g_inSeeBlock,&compound,&member))
+ )
+ )
{
//printf("resolveRef %s = %p (linkable?=%d)\n",g_token->name.data(),member,member ? member->isLinkable() : FALSE);
if (member && member->isLinkable()) // member link
@@ -2144,12 +2148,9 @@ QString DocLink::parse(bool isJavaLink)
}
endlink:
- if (isJavaLink)
+ if (m_children.isEmpty()) // no link text
{
- if (m_children.isEmpty()) // no link text
- {
- m_children.append(new DocWord(this,m_refText));
- }
+ m_children.append(new DocWord(this,m_refText));
}
handlePendingStyleCommands(this,m_children);
@@ -5551,7 +5552,13 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
}
else if (ctx && ctx->definitionType()==Definition::TypePage)
{
- g_context = ctx->getOuterScope()->name();
+ Definition *scope = ((PageDef*)ctx)->getPageScope();
+ if (scope) g_context = scope->name();
+ }
+ else if (ctx && ctx->definitionType()==Definition::TypeGroup)
+ {
+ Definition *scope = ((GroupDef*)ctx)->getGroupScope();
+ if (scope) g_context = scope->name();
}
else
{
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 66406bb..e4ba2aa 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -372,6 +372,28 @@ static void addSTLClasses(Entry *root)
//----------------------------------------------------------------------------
+static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n,
+ FileDef *fileScope=0);
+
+static void addPageToContext(PageDef *pd,Entry *root)
+{
+ if (root->parent) // add the page to it's scope
+ {
+ QCString scope = root->parent->name;
+ if (root->parent->section==Entry::PACKAGEDOC_SEC)
+ {
+ scope=substitute(scope,".","::");
+ }
+ scope = stripAnonymousNamespaceScope(scope);
+ scope+="::"+pd->name();
+ Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope);
+ if (d)
+ {
+ pd->setPageScope(d);
+ }
+ }
+}
+
static void addRelatedPage(Entry *root)
{
GroupDef *gd=0;
@@ -399,7 +421,7 @@ static void addRelatedPage(Entry *root)
if (pd)
{
pd->addSectionsToDefinition(root->anchors);
- //pi->context = ctx;
+ addPageToContext(pd,root);
}
}
@@ -478,6 +500,36 @@ static void buildGroupList(Entry *root)
buildGroupListFiltered(root,TRUE);
}
+static void findGroupScope(Entry *root)
+{
+ if (root->section==Entry::GROUPDOC_SEC && !root->name.isEmpty() &&
+ root->parent && !root->parent->name.isEmpty())
+ {
+ GroupDef *gd;
+ if ((gd=Doxygen::groupSDict[root->name]))
+ {
+ QCString scope = root->parent->name;
+ if (root->parent->section==Entry::PACKAGEDOC_SEC)
+ {
+ scope=substitute(scope,".","::");
+ }
+ scope = stripAnonymousNamespaceScope(scope);
+ scope+="::"+gd->name();
+ Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope);
+ if (d)
+ {
+ gd->setGroupScope(d);
+ }
+ }
+ }
+ EntryListIterator eli(*root->sublist);
+ Entry *e;
+ for (;(e=eli.current());++eli)
+ {
+ findGroupScope(e);
+ }
+}
+
static void organizeSubGroupsFiltered(Entry *root,bool additional)
{
if (root->section==Entry::GROUPDOC_SEC && !root->name.isEmpty())
@@ -773,7 +825,7 @@ static Definition *buildScopeFromQualifiedName(const QCString name,int level)
}
static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n,
- FileDef *fileScope=0)
+ FileDef *fileScope)
{
//printf("findScopeFromQualifiedName(%s,%s)\n",startScope ? startScope->name().data() : 0, n.data());
Definition *resultScope=startScope;
@@ -781,13 +833,18 @@ static Definition *findScopeFromQualifiedName(Definition *startScope,const QCStr
QCString scope=stripTemplateSpecifiersFromScope(n,FALSE);
int l1=0,i1;
i1=getScopeFragment(scope,0,&l1);
- if (i1==-1) return resultScope;
+ if (i1==-1)
+ {
+ //printf("no fragments!\n");
+ return resultScope;
+ }
int p=i1+l1,l2=0,i2;
while ((i2=getScopeFragment(scope,p,&l2))!=-1)
{
QCString nestedNameSpecifier = scope.mid(i1,l1);
Definition *orgScope = resultScope;
resultScope = resultScope->findInnerCompound(nestedNameSpecifier);
+ //printf("resultScope=%p\n",resultScope);
if (resultScope==0)
{
if (orgScope==Doxygen::globalScope && fileScope)
@@ -839,7 +896,7 @@ static Definition *findScopeFromQualifiedName(Definition *startScope,const QCStr
l1=l2;
p=i2+l2;
}
- //printf("scope %s\n",resultScope->name().data());
+ //printf("findScopeFromQualifiedName scope %s\n",resultScope->name().data());
return resultScope;
}
@@ -1935,10 +1992,10 @@ static MemberDef *addVariableToFile(
*/
static int findFunctionPtr(const QCString &type,int *pLength=0)
{
- static const QRegExp re("([^)]*)");
+ static const QRegExp re("([^)]*\\*[^)]*)");
int i=-1,l;
if (!type.isEmpty() && // return type is non-empty
- (i=re.match(type,0,&l))!=-1 && // contains a (*
+ (i=re.match(type,0,&l))!=-1 && // contains (...*...)
type.find("operator")==-1 && // not an operator
type.find(")(")==-1 // not a function pointer return type
)
@@ -2029,6 +2086,19 @@ static bool isVarWithConstructor(Entry *root)
result=FALSE; // arg type is a known type
goto done;
}
+ if (checkIfTypedef(ctx,fd,a->type))
+ {
+ //printf("%s:%d: false (arg is typedef)\n",__FILE__,__LINE__);
+ result=FALSE; // argument is a typedef
+ goto done;
+ }
+ if (a->type.at(a->type.length()-1)=='*' ||
+ a->type.at(a->type.length()-1)=='&')
+ // type ends with * or & => pointer or reference
+ {
+ result=FALSE;
+ goto done;
+ }
if (a->type.find(initChars)==0)
{
result=TRUE; // argument type starts with typical initializer char
@@ -2280,7 +2350,7 @@ nextMember:
// If found they are stored in their class or in the global list.
static void addMethodToClass(Entry *root,ClassDef *cd,
- const QCString &rname,/*const QCString &scope,*/bool isFriend)
+ const QCString &rname,bool isFriend)
{
int l,i;
static QRegExp re("([a-z_A-Z0-9: ]*[ *]*[ ]*");
@@ -4491,9 +4561,27 @@ static bool findGlobalMember(Entry *root,
return TRUE;
}
+static bool isSpecialization(
+ const QList<ArgumentList> &srcTempArgLists,
+ const QList<ArgumentList> &dstTempArgLists
+ )
+{
+ QListIterator<ArgumentList> srclali(srcTempArgLists);
+ QListIterator<ArgumentList> dstlali(dstTempArgLists);
+ for (;srclali.current();++srclali,++dstlali)
+ {
+ ArgumentList *sal = srclali.current();
+ ArgumentList *dal = dstlali.current();
+ if (!(sal && dal && sal->count()==dal->count())) return TRUE;
+ }
+ return FALSE;
+}
+
+
static QCString substituteTemplatesInString(
const QList<ArgumentList> &srcTempArgLists,
const QList<ArgumentList> &dstTempArgLists,
+ ArgumentList *funcTempArgList, // can be used to match template specializations
const QCString &src
)
{
@@ -4514,17 +4602,32 @@ static QCString substituteTemplatesInString(
{
ArgumentListIterator tsali(*srclali.current());
ArgumentListIterator tdali(*dstlali.current());
- Argument *tsa =0,*tda=0;
+ Argument *tsa =0,*tda=0, *fa=0;
+ if (funcTempArgList)
+ {
+ fa=funcTempArgList->first();
+ }
for (tsali.toFirst();(tsa=tsali.current()) && !found;++tsali)
{
tda = tdali.current();
- if (tda && name==tsa->name)
+ if (name==tsa->name)
{
- name=tda->name; // substitute
- found=TRUE;
+ if (tda)
+ {
+ name=tda->name; // substitute
+ found=TRUE;
+ }
+ else if (fa)
+ {
+ name=fa->type;
+ found=TRUE;
+ }
}
- if (tda) ++tdali;
+ if (tda)
+ ++tdali;
+ else if (fa)
+ fa=funcTempArgList->next();
}
}
dst+=name;
@@ -4538,7 +4641,9 @@ static void substituteTemplatesInArgList(
const QList<ArgumentList> &srcTempArgLists,
const QList<ArgumentList> &dstTempArgLists,
ArgumentList *src,
- ArgumentList *dst)
+ ArgumentList *dst,
+ ArgumentList *funcTempArgs = 0
+ )
{
ArgumentListIterator sali(*src);
Argument *sa=0;
@@ -4547,9 +4652,11 @@ static void substituteTemplatesInArgList(
for (sali.toFirst();(sa=sali.current());++sali) // for each member argument
{
QCString dstType = substituteTemplatesInString(
- srcTempArgLists,dstTempArgLists,sa->type);
+ srcTempArgLists,dstTempArgLists,funcTempArgs,
+ sa->type);
QCString dstArray = substituteTemplatesInString(
- srcTempArgLists,dstTempArgLists,sa->array);
+ srcTempArgLists,dstTempArgLists,funcTempArgs,
+ sa->array);
if (da==0)
{
da=new Argument(*sa);
@@ -4933,18 +5040,6 @@ static void findMember(Entry *root,
{
Debug::print(Debug::FindMembers,0,
"4. class definition %s found\n",cd->name().data());
- //int ci;
- //ArgumentList *classTemplArgs = cd->templateArguments();
- //ArgumentList *funcTemplArgs = md->memberDefTemplateArguments();
- //if ((ci=cd->name().find("::"))!=-1) // nested class
- //{
- // ClassDef *parentClass = getClass(cd->name().left(ci));
- // if (parentClass)
- // classTemplArgs = parentClass->templateArguments();
- //}
- ////printf("cd->name=%s classTemplArgs=%s\n",cd->name().data(),
- //// argListToString(classTemplArgs).data());
-
// get the template parameter lists found at the member declaration
QList<ArgumentList> declTemplArgs;
@@ -5008,10 +5103,22 @@ static void findMember(Entry *root,
if (matching) // replace member's argument list
{
md->setDefinitionTemplateParameterLists(root->tArgLists);
- md->setArgumentList(argList);
+ md->setArgumentList(argList); // new owner of the list => no delete
}
- else // no match -> delete argument list
+ else // no match
{
+ if (!funcTempList.isEmpty() &&
+ isSpecialization(declTemplArgs,*defTemplArgs))
+ {
+ // check if we are dealing with a partial template
+ // specialization. In this case we add it to the class
+ // even though the member arguments do not match.
+
+ // TODO: copy other aspects?
+ root->protection=md->protection(); // copy protection level
+ addMethodToClass(root,cd,md->name(),isFriend);
+ return;
+ }
delete argList;
}
}
@@ -5041,11 +5148,8 @@ static void findMember(Entry *root,
{
if (root->tArgLists && md->templateArguments() &&
root->tArgLists->getLast()->count()<=md->templateArguments()->count())
- { // assume we have found a template specialization
- // for which there is only a definition, no declaration in
- // the class. TODO: we should actually check whether
- // the arguments match!
- addMethodToClass(root,cd,md->name(),/*cd->name(),*/isFriend);
+ {
+ addMethodToClass(root,cd,md->name(),isFriend);
return;
}
candidates++;
@@ -6738,10 +6842,22 @@ static void findDefineDocumentation(Entry *root)
}
else if (!root->doc.isEmpty() || !root->brief.isEmpty()) // define not found
{
- warn(root->fileName,root->startLine,
- "Warning: documentation for unknown define %s found.\n",
- root->name.data()
- );
+ static bool preEnabled = Config_getBool("ENABLE_PREPROCESSING");
+ if (preEnabled)
+ {
+ warn(root->fileName,root->startLine,
+ "Warning: documentation for unknown define %s found.\n",
+ root->name.data()
+ );
+ }
+ else
+ {
+ warn(root->fileName,root->startLine,
+ "Warning: found documented #define but ignoring it because "
+ "ENABLE_PREPROCESSING is NO.\n",
+ root->name.data()
+ );
+ }
}
}
EntryListIterator eli(*root->sublist);
@@ -6851,6 +6967,7 @@ static void findMainPage(Entry *root)
indexName, root->brief+root->doc,title);
//setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
Doxygen::mainPage->setFileName(indexName);
+ addPageToContext(Doxygen::mainPage,root);
// a page name is a label as well!
SectionInfo *si=new SectionInfo(
@@ -8728,6 +8845,9 @@ void parseInput()
computePageRelations(root);
checkPageRelations();
+ msg("Determining the scope of groups...\n");
+ findGroupScope(root);
+
msg("Sorting lists...\n");
Doxygen::memberNameSDict.sort();
Doxygen::functionNameSDict.sort();
diff --git a/src/filedef.cpp b/src/filedef.cpp
index 688d641..a15ee3b 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -1243,7 +1243,7 @@ void FileDef::acquireFileVersion()
if (!vercmd.isEmpty())
{
msg("Version of %s : ",filepath.data());
- FILE *f=popen("\""+vercmd+"\" \""+filepath+"\"","r");
+ FILE *f=popen(vercmd+" \""+filepath+"\"","r");
if (!f)
{
err("Error: could not execute %s\n",vercmd.data());
diff --git a/src/groupdef.h b/src/groupdef.h
index 1f594a0..70f9a54 100644
--- a/src/groupdef.h
+++ b/src/groupdef.h
@@ -89,6 +89,9 @@ class GroupDef : public Definition
friend void writeGroupTreeNode(OutputList&, GroupDef*, int);
// make accessible for writing tree view of group in index.cpp - KPW
+ void setGroupScope(Definition *d) { groupScope = d; }
+ Definition *getGroupScope() const { return groupScope; }
+
// members in the declaration part of the documentation
MemberList decDefineMembers;
MemberList decProtoMembers;
@@ -135,6 +138,7 @@ class GroupDef : public Definition
MemberList *allMemberList;
MemberNameInfoSDict *allMemberNameInfoSDict;
+ Definition *groupScope;
};
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 45f495b..69aa87c 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -1788,7 +1788,9 @@ static void writeDefaultQuickLinks(QTextStream &t,bool compact,
//-------------------------------------------------------------------------
// write sub indices
- if ((hli==HLI_Namespaces || hli==HLI_NamespaceMembers || hli==HLI_NamespaceVisible) &&
+ if ((hli==HLI_Namespaces || hli==HLI_NamespaceMembers ||
+ hli==HLI_NamespaceVisible
+ ) &&
documentedNamespaces>0 &&
documentedNamespaceMembers[NMHL_All]>0)
{
diff --git a/src/index.cpp b/src/index.cpp
index ca9ff6a..08b4fda 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -3277,7 +3277,10 @@ void writeIndex(OutputList &ol)
ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString("PROJECT_NUMBER"),TRUE,FALSE);
ol.endProjectNumber();
}
- if (Config_getBool("DISABLE_INDEX") && Doxygen::mainPage==0) ol.writeQuickLinks(FALSE,HLI_Main);
+ if (Config_getBool("DISABLE_INDEX") && Doxygen::mainPage==0)
+ {
+ ol.writeQuickLinks(FALSE,HLI_Main);
+ }
if (Doxygen::mainPage)
{
diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp
index 32bdf87..b5ee936 100644
--- a/src/namespacedef.cpp
+++ b/src/namespacedef.cpp
@@ -525,7 +525,7 @@ Definition *NamespaceDef::findInnerCompound(const char *n)
}
if (d==0 && usingDeclList)
{
- d = usingDirList->find(n);
+ d = usingDeclList->find(n);
}
}
return d;
diff --git a/src/pagedef.cpp b/src/pagedef.cpp
index e820273..a965946 100644
--- a/src/pagedef.cpp
+++ b/src/pagedef.cpp
@@ -14,6 +14,7 @@ PageDef::PageDef(const char *f,int l,const char *n,
{
setDocumentation(d,f,l);
subPageDict = new PageSDict(7);
+ pageScope = 0;
}
PageDef::~PageDef()
diff --git a/src/pagedef.h b/src/pagedef.h
index d63eb33..ab8639f 100644
--- a/src/pagedef.h
+++ b/src/pagedef.h
@@ -49,12 +49,15 @@ class PageDef : public Definition
bool visibleInIndex() const;
bool documentedPage() const;
bool hasSubPages() const;
+ void setPageScope(Definition *d){ pageScope = d; }
+ Definition *getPageScope() const { return pageScope; }
private:
QCString m_fileName;
QCString m_title;
GroupDef *m_inGroup;
PageSDict *subPageDict; // list of pages in the group
+ Definition *pageScope;
};
class PageSDict : public SDict<PageDef>
diff --git a/src/parserintf.h b/src/parserintf.h
index ce1f649..61bed85 100644
--- a/src/parserintf.h
+++ b/src/parserintf.h
@@ -34,6 +34,7 @@ class MemberDef;
class ParserInterface
{
public:
+ virtual ~ParserInterface() {}
/** Parses a single input file with the goal to build an Entry tree.
* @param[in] fileName The full name of the file.
* @param[in] fileBuf The contents of the file (zero terminated).
@@ -113,7 +114,7 @@ class ParserManager
* a given input file.
*/
ParserManager(ParserInterface *defaultParser)
- : m_defaultParser(defaultParser) {}
+ : m_defaultParser(defaultParser) { m_parsers.setAutoDelete(TRUE); }
/** Registers an additional parser.
* @param[in] extension The file extension that will trigger
diff --git a/src/pre.l b/src/pre.l
index cc1705b..ad9e630 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -1839,11 +1839,16 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
outputChar('/');outputChar('*');
//g_commentCount++;
}
-<SkipCComment>[\\@][\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly"|"dot"|"code"|"f{"|"f$"|"f["){BN}+ {
+<SkipCComment>[\\@][\\@]("f{"|"f$"|"f[") {
outputArray(yytext,yyleng);
}
+<SkipCComment>[\\@][\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly"|"dot"|"code"){BN}+ {
+ outputArray(yytext,yyleng);
+ g_yyLineNr+=QCString(yytext).contains('\n');
+ }
<SkipCComment>[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly"|"dot"|"code"){BN}+ {
outputArray(yytext,yyleng);
+ g_yyLineNr+=QCString(yytext).contains('\n');
if (yytext[1]=='f')
{
g_blockName="f";
diff --git a/src/pyscanner.h b/src/pyscanner.h
index fa009a0..6172375 100644
--- a/src/pyscanner.h
+++ b/src/pyscanner.h
@@ -34,6 +34,7 @@
class PythonLanguageScanner : public ParserInterface
{
public:
+ virtual ~PythonLanguageScanner() {}
void parseInput(const char * fileName,
const char *fileBuf,
Entry *root);
diff --git a/src/scanner.h b/src/scanner.h
index 2c3ac6a..147caa0 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -29,6 +29,7 @@
class CLanguageScanner : public ParserInterface
{
public:
+ virtual ~CLanguageScanner() {}
void parseInput(const char *fileName,
const char *fileBuf,
Entry *root);
diff --git a/src/scanner.l b/src/scanner.l
index b41027f..4465b9a 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -374,7 +374,7 @@ static void prependScope()
static bool checkForKnRstyleC()
{
if (((QCString)yyFileName).right(2).lower()!=".c") return FALSE; // must be a C file
- if (!current->argList) return FALSE;
+ if (!current->argList) return FALSE; // must have arguments
ArgumentListIterator ali(*current->argList);
Argument *a;
for (ali.toFirst();(a=ali.current());++ali)
@@ -2447,15 +2447,14 @@ IDLATTR ("["[^\]]*"]"){BN}*
lineCount();
int i=0,l=yyleng,j;
while (i<l && (!isId(yytext[i]))) i++;
- msName = yytext;
- msName = msName.right(msName.length()-i);
+ msName = QCString(yytext).right(l-i).stripWhiteSpace();
j=msName.find("[");
if (j!=-1)
{
msArgs=msName.right(msName.length()-j);
msName=msName.left(j);
}
- msType = yytext; msType=msType.left(i);
+ msType=QCString(yytext).left(i);
// handle *pName in: typedef { ... } name, *pName;
if (firstTypedefEntry)
@@ -2505,7 +2504,8 @@ IDLATTR ("["[^\]]*"]"){BN}*
p=p->parent;
}
}
- if (!msName.isEmpty())
+ //printf("msName=%s current->name=%s\n",msName.data(),current->name.data());
+ if (!msName.isEmpty() && msName!=current->name) // skip typedef T {} T;
{
Entry *varEntry=new Entry;
varEntry->protection = current->protection ;
@@ -3243,7 +3243,7 @@ IDLATTR ("["[^\]]*"]"){BN}*
}
else // a global function prototype or function variable
{
- static QRegExp re("([^)]*)");
+ static QRegExp re("([^)]*\\*[^)]*)"); // (...*...)
//printf("Scanner.l: prototype? type=`%s' name=`%s' args=`%s'\n",current->type.data(),current->name.data(),current->args.data());
if (!current->type.isEmpty() &&
(current->type.find(re,0)!=-1 || current->type.left(8)=="typedef "))
@@ -3356,6 +3356,7 @@ IDLATTR ("["[^\]]*"]"){BN}*
}
}
<SkipCurly>"}"{BN}*("/*!"|"/**"|"//!"|"///")"<" {
+ lineCount();
if ( curlyCount )
{
//addToBody(yytext);
@@ -3364,7 +3365,6 @@ IDLATTR ("["[^\]]*"]"){BN}*
else
{
current->endBodyLine=yyLineNr;
- lineCount();
tempEntry = current; // temporarily switch to the previous entry
current = previous;
@@ -4310,7 +4310,7 @@ static void newEntry()
static void handleCommentBlock(const QCString &doc,bool brief)
{
int position=0;
- bool needsEntry;
+ bool needsEntry=FALSE;
if (docBlockInBody)
{
if (previous==0)
diff --git a/src/translator.h b/src/translator.h
index 9626996..a976c59 100644
--- a/src/translator.h
+++ b/src/translator.h
@@ -23,6 +23,7 @@
#include "util.h"
#include "config.h"
+
class Translator
{
private:
@@ -438,6 +439,8 @@ class Translator
//////////////////////////////////////////////////////////////////////////
virtual QCString trOverloadText() = 0;
+
+ virtual ~Translator() {}
};
diff --git a/src/util.cpp b/src/util.cpp
index 50e0fb3..78a0c05 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -76,6 +76,8 @@ extern char **environ;
//#define MAP_ALGO ALGO_CRC16
#define MAP_ALGO ALGO_MD5
+#define REL_PATH_TO_ROOT "../../"
+
//------------------------------------------------------------------------
// TextGeneratorOLImpl implementation
//------------------------------------------------------------------------
@@ -809,6 +811,12 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item)
//fprintf(stderr,"<isAccesibleFrom(scope=%s,item=%s itemScope=%s)\n",
// scope->name().data(),item->name().data(),item->getOuterScope()->name().data());
+ QCString key;
+ key.sprintf("%p:%p:%p",scope,fileScope,item);
+ static QDict<void> visitedDict;
+ if (visitedDict.find(key)) return -1; // already looked at this
+ visitedDict.insert(key,(void *)0x8);
+
int result=0; // assume we found it
int i;
@@ -862,6 +870,7 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item)
result= (i==-1) ? -1 : i+1;
}
done:
+ visitedDict.remove(key);
//Doxygen::lookupCache.insert(key,new int(result));
return result;
}
@@ -871,14 +880,21 @@ done:
* if item in not in this scope. The explicitScopePart limits the search
* to scopes that match \a scope plus the explicit part.
*/
-int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope,Definition *item,
- const QCString &explicitScopePart)
+int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope,
+ Definition *item,const QCString &explicitScopePart)
{
if (explicitScopePart.isEmpty())
{
// handle degenerate case where there is no explicit scope.
return isAccessibleFrom(scope,fileScope,item);
}
+
+ QCString key;
+ key.sprintf("%p:%p:%p:%s",scope,fileScope,item,explicitScopePart.data());
+ static QDict<void> visitedDict;
+ if (visitedDict.find(key)) return -1; // already looked at this
+ visitedDict.insert(key,(void *)0x8);
+
//printf("<isAccessibleFromWithExpScope(%s,%s,%s)\n",scope?scope->name().data():"<global>",
// item?item->name().data():"<none>",
// explicitScopePart.data());
@@ -996,6 +1012,7 @@ int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope,Definition
}
}
done:
+ visitedDict.remove(key);
//Doxygen::lookupCache.insert(key,new int(result));
return result;
}
@@ -2264,6 +2281,7 @@ static void stripIrrelevantString(QCString &target,const QCString &str)
if (target==str) { target.resize(0); return; }
int i,p=0;
int l=str.length();
+ bool changed=FALSE;
while ((i=target.find(str,p))!=-1)
{
bool isMatch = (i==0 || !isId(target.at(i-1))) && // not a character before str
@@ -2276,17 +2294,20 @@ static void stripIrrelevantString(QCString &target,const QCString &str)
{
// strip str from target at index i
target=target.left(i)+target.right(target.length()-i-l);
+ changed=TRUE;
i-=l;
}
else if ((i1!=-1 && i<i1) || (i2!=-1 && i<i2)) // str before * or &
{
// move str to front
target=str+" "+target.left(i)+target.right(target.length()-i-l);
+ changed=TRUE;
i++;
}
}
p = i+l;
}
+ if (changed) target=target.stripWhiteSpace();
}
/*! According to the C++ spec and Ivan Vecerina:
@@ -2739,91 +2760,65 @@ static QCString getCanonicalTypeForIdentifier(
if (word.findRev("::")!=-1 && !(tmpName=stripScope(word)).isEmpty())
{
- symName=tmpName;
+ symName=tmpName; // name without scope
}
else
{
symName=word;
}
-#if 0 // I've commented this out because it leads to obscure errors
- // while not gaining much w.r.t. speed.
- if (!symName.isEmpty() && !templSpec.isEmpty() &&
- (defList=Doxygen::symbolMap->find(symName+templSpec)) &&
- defList->count()==1) // word without scope but with template specs
- // is a unique symbol in the symbol map
+ ClassDef *cd = 0;
+ MemberDef *mType = 0;
+ QCString ts;
+ if (!templSpec.isEmpty())
{
- QCString ts;
- result = resolveSymbolName(fs,defList->first(),ts);
- if (tSpec) *tSpec="";
+ cd = getResolvedClass(d,fs,word+templSpec,&mType,&ts,TRUE);
+ if (cd && tSpec) *tSpec="";
}
- else if (!symName.isEmpty() &&
- (defList=Doxygen::symbolMap->find(symName)) &&
- defList->count()==1) // word without scope is a
- // unique symbol in the symbol map
+ if (cd==0)
{
- QCString ts;
- //printf("unique symName=%s templSpec=%s\n",symName.data(),templSpec.data());
- result = resolveSymbolName(fs,defList->first(),ts)+templSpec;
- //printf("result=%s ts=%s\n",result.data(),ts.data());
- if (tSpec) *tSpec="";
+ cd = getResolvedClass(d,fs,word,&mType,&ts,TRUE);
}
- else // symbol not unique, try to find the one in the right scope
-#endif
- {
- 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)
- {
- 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(),
- // cd?cd->name().data():"<none>",
- // d?d->name().data():"<none>",
- // fs?fs->name().data():"<none>"
- // );
+ if (!ts.isEmpty() && templSpec.isEmpty())
+ {
+ templSpec = stripDeclKeywords(ts);
+ }
+ //printf("symbol=%s word=%s cd=%s d=%s fs=%s\n",
+ // symName.data(),
+ // word.data(),
+ // cd?cd->name().data():"<none>",
+ // d?d->name().data():"<none>",
+ // fs?fs->name().data():"<none>"
+ // );
- //printf(">>>> word '%s' => '%s' templSpec=%s ts=%s\n",
- // (word+templSpec).data(),
- // cd?cd->qualifiedNameWithTemplateParameters().data():"<none>",
- // templSpec.data(),ts.data());
- if (cd) // known type
+ //printf(">>>> word '%s' => '%s' templSpec=%s ts=%s\n",
+ // (word+templSpec).data(),
+ // cd?cd->qualifiedNameWithTemplateParameters().data():"<none>",
+ // templSpec.data(),ts.data());
+ if (cd) // known type
+ {
+ //result = cd->qualifiedNameWithTemplateParameters();
+ result = removeRedundantWhiteSpace(cd->qualifiedName()+templSpec);
+ if (cd->isTemplate() && tSpec)
{
- //result = cd->qualifiedNameWithTemplateParameters();
- result = removeRedundantWhiteSpace(cd->qualifiedName()+templSpec);
- if (cd->isTemplate() && tSpec)
- {
- *tSpec="";
- }
+ *tSpec="";
}
- else if (mType && mType->isEnumerate()) // an enum
+ }
+ else if (mType && mType->isEnumerate()) // an enum
+ {
+ result = mType->qualifiedName();
+ }
+ else // not known as a class
+ {
+ QCString resolvedType = resolveTypeDef(d,word);
+ if (resolvedType.isEmpty()) // not known as a typedef either
{
- result = mType->qualifiedName();
+ result = word;
}
- else // not known as a class
+ else
{
- QCString resolvedType = resolveTypeDef(d,word);
- if (resolvedType.isEmpty()) // not known as a typedef either
- {
- result = word;
- }
- else
- {
- result = resolvedType;
- }
+ result = resolvedType;
}
}
return result;
@@ -2845,7 +2840,7 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,const Argument *a
type+=name;
}
- // strip const and volatile keywords that are not relatevant for the type
+ // strip const and volatile keywords that are not relevant for the type
stripIrrelevantConstVolatile(type);
// strip leading keywords
@@ -2911,15 +2906,21 @@ static bool matchArgument2(
NOMATCH
return FALSE;
}
- QCString sSrcName=" "+srcA->name;
- QCString sDstName=" "+dstA->name;
- if (sSrcName==dstA->type.right(sSrcName.length()))
+ QCString sSrcName = " "+srcA->name;
+ QCString sDstName = " "+dstA->name;
+ QCString srcType = srcA->type;
+ QCString dstType = dstA->type;
+ stripIrrelevantConstVolatile(srcType);
+ stripIrrelevantConstVolatile(dstType);
+ //printf("'%s'<->'%s'\n",sSrcName.data(),dstType.right(sSrcName.length()).data());
+ //printf("'%s'<->'%s'\n",sDstName.data(),srcType.right(sDstName.length()).data());
+ if (sSrcName==dstType.right(sSrcName.length()))
{ // case "unsigned int" <-> "unsigned int i"
srcA->type+=sSrcName;
srcA->name="";
srcA->canType=""; // invalidate cached type value
}
- else if (sDstName==srcA->type.right(sDstName.length()))
+ else if (sDstName==srcType.right(sDstName.length()))
{ // case "unsigned int i" <-> "unsigned int"
dstA->type+=sDstName;
dstA->name="";
@@ -5695,4 +5696,57 @@ SrcLangExt getLanguageFromFileName(const QCString fileName)
return SrcLangExt_Cpp; // not listed => assume C-ish language.
}
+/*! Returns true iff the given name string appears to be a typedef in scope. */
+bool checkIfTypedef(Definition *scope,FileDef *fileScope,const char *n)
+{
+ if (scope==0 ||
+ (scope->definitionType()!=Definition::TypeClass &&
+ scope->definitionType()!=Definition::TypeNamespace
+ )
+ )
+ {
+ scope=Doxygen::globalScope;
+ }
+
+ QCString name = n;
+ if (name.isEmpty())
+ return FALSE; // no name was given
+
+ DefinitionList *dl = Doxygen::symbolMap->find(name);
+ if (dl==0)
+ return FALSE; // could not find any matching symbols
+
+ // mostly copied from getResolvedClassRec()
+ QCString explicitScopePart;
+ int qualifierIndex = computeQualifiedIndex(name);
+ if (qualifierIndex!=-1)
+ {
+ explicitScopePart = name.left(qualifierIndex);
+ replaceNamespaceAliases(explicitScopePart,explicitScopePart.length());
+ name = name.mid(qualifierIndex+2);
+ }
+ // find the closest closest matching definition
+ DefinitionListIterator dli(*dl);
+ Definition *d;
+ int minDistance = 10000;
+ MemberDef *bestMatch = 0;
+ for (dli.toFirst();(d=dli.current());++dli)
+ {
+ if (d->definitionType()==Definition::TypeMember)
+ {
+ g_visitedNamespaces.clear();
+ int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart);
+ if (distance!=-1 && distance<minDistance)
+ {
+ minDistance = distance;
+ bestMatch = (MemberDef *)d;
+ }
+ }
+ }
+
+ if (bestMatch && bestMatch->isTypedef())
+ return TRUE; // closest matching symbol is a typedef
+ else
+ return FALSE;
+}
diff --git a/src/util.h b/src/util.h
index 00d52ee..52b2316 100644
--- a/src/util.h
+++ b/src/util.h
@@ -28,6 +28,8 @@
#include <ctype.h>
#include "sortdict.h"
+//--------------------------------------------------------------------
+
class ClassDef;
class FileDef;
class MemberList;
@@ -81,6 +83,19 @@ class TextGeneratorOLImpl : public TextGeneratorIntf
//--------------------------------------------------------------------
+enum SrcLangExt
+{
+ SrcLangExt_IDL = 0x008,
+ SrcLangExt_Java = 0x010,
+ SrcLangExt_CSharp = 0x020,
+ SrcLangExt_D = 0x040,
+ SrcLangExt_PHP = 0x080,
+ SrcLangExt_ObjC = 0x100,
+ SrcLangExt_Cpp = 0x200,
+};
+
+//--------------------------------------------------------------------
+
void linkifyText(const TextGeneratorIntf &ol,
Definition *scope,
FileDef *fileScope,
@@ -90,9 +105,13 @@ void linkifyText(const TextGeneratorIntf &ol,
bool external=TRUE,
bool keepSpaces=FALSE
);
+
void setAnchors(ClassDef *cd,char id,MemberList *ml,int groupId=-1);
+
QCString fileToString(const char *name,bool filter=FALSE);
+
QCString dateToString(bool);
+
bool getDefs(const QCString &scopeName,
const QCString &memberName,
const char *,
@@ -124,28 +143,30 @@ bool resolveLink(/* in */ const char *scName,
bool generateRef(OutputDocInterface &od,const char *,
const char *,bool inSeeBlock,const char * =0);
+
bool generateLink(OutputDocInterface &od,const char *,
const char *,bool inSeeBlock,const char *);
void generateFileRef(OutputDocInterface &od,const char *,
const char *linkTxt=0);
+
void writePageRef(OutputDocInterface &od,const char *cn,const char *mn);
-#if 0
-bool matchArguments(ArgumentList *,ArgumentList *,
- const char *cl=0,const char *ns=0,bool checkCV=TRUE,
- NamespaceSDict *usingNamespaces=0,
- SDict<Definition> *usingClasses=0);
-#endif
bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *srcAl,
Definition *dstScope,FileDef *dstFileScope,ArgumentList *dstAl,
bool checkCV
);
+
void mergeArguments(ArgumentList *,ArgumentList *,bool forceNameOverwrite=FALSE);
+
QCString substituteClassNames(const QCString &s);
+
QCString substitute(const char *s,const char *src,const char *dst);
+
QCString resolveDefines(const char *n);
+
ClassDef *getClass(const char *key);
+
ClassDef *getResolvedClass(Definition *scope,
FileDef *fileScope,
const char *key,
@@ -153,61 +174,102 @@ ClassDef *getResolvedClass(Definition *scope,
QCString *pTemplSpec=0,
bool mayBeUnlinkable=FALSE,
bool mayBeHidden=FALSE);
+
NamespaceDef *getResolvedNamespace(const char *key);
+
FileDef *findFileDef(const FileNameDict *fnDict,const char *n,
bool &ambig);
+
QCString showFileDefMatches(const FileNameDict *fnDict,const char *n);
+
int guessSection(const char *name);
+
bool isId(char c);
+
QCString removeRedundantWhiteSpace(const QCString &s);
+
QCString argListToString(ArgumentList *al,bool useCanonicalType=FALSE);
+
QCString tempArgListToString(ArgumentList *al);
+
QCString generateMarker(int id);
+
void writeExample(OutputList &ol,ExampleSDict *el);
+
QCString stripAnonymousNamespaceScope(const QCString &s);
+
QCString stripFromPath(const QCString &path);
+
QCString stripFromIncludePath(const QCString &path);
+
bool rightScopeMatch(const QCString &scope, const QCString &name);
+
bool leftScopeMatch(const QCString &scope, const QCString &name);
+
QCString substituteKeywords(const QCString &s,const char *title,const QCString &relPath="");
+
int getPrefixIndex(const QCString &name);
+
QCString removeAnonymousScopes(const QCString &s);
+
QCString replaceAnonymousScopes(const QCString &s);
+
void initClassHierarchy(ClassSDict *cl);
+
bool hasVisibleRoot(BaseClassList *bcl);
+
int minClassDistance(ClassDef *cd,ClassDef *bcd,int level=0);
+
QCString convertNameToFile(const char *name,bool allowDots=FALSE);
+
void extractNamespaceName(const QCString &scopeName,
QCString &className,QCString &namespaceName,
bool allowEmptyClass=FALSE);
+
QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &templ);
+
QCString stripScope(const char *name);
+
int iSystem(const char *command,const char *args,bool isBatchFile=FALSE);
+
QCString convertToHtml(const char *s);
+
QCString convertToXML(const char *s);
+
QCString getOverloadDocs();
+
void addMembersToMemberGroup(MemberList *ml,
MemberGroupSDict *memberGroupSDict,
Definition *context);
+
int extractClassNameFromType(const QCString &type,int &pos,
QCString &name,QCString &templSpec);
+
QCString substituteTemplateArgumentsInString(
const QCString &name,
ArgumentList *formalArgs,
ArgumentList *actualArgs);
ArgumentList *copyArgumentList(const ArgumentList *src);
+
QList<ArgumentList> *copyArgumentLists(const QList<ArgumentList> *srcLists);
+
QCString stripTemplateSpecifiersFromScope(const QCString &fullName,
bool parentOnly=TRUE,
QCString *lastScopeStripped=0);
+
QCString resolveTypeDef(Definition *d,const QCString &name,
Definition **typedefContext=0);
+
QCString mergeScopes(const QCString &leftScope,const QCString &rightScope);
+
int getScopeFragment(const QCString &s,int p,int *l);
+
int filterCRLF(char *buf,int len);
+
void addRefItem(const QList<ListItemInfo> *sli,const char *prefix,
const char *name,const char *title,const char *args=0);
+
PageDef *addRelatedPage(const char *name,const QCString &ptitle,
const QCString &doc,QList<SectionInfo> *anchors,
const char *fileName,int startLine,
@@ -215,44 +277,53 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle,
GroupDef *gd=0,
TagInfo *tagInfo=0
);
+
QCString escapeCharsInString(const char *name,bool allowDots);
+
void addGroupListToTitle(OutputList &ol,Definition *d);
+
void filterLatexString(QTextStream &t,const char *str,
bool insideTabbing=FALSE,bool insidePre=FALSE,
bool insideItem=FALSE);
+
QCString rtfFormatBmkStr(const char *name);
+
QCString linkToText(const char *link,bool isFileName);
+
QCString stripExtension(const char *fName);
+
void replaceNamespaceAliases(QCString &scope,int i);
+
int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item);
+
int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope,Definition *item,
const QCString &explicitScopePart);
+
int computeQualifiedIndex(const QCString &name);
+
void addDirPrefix(QCString &fileName);
+
QCString relativePathToRoot(const char *name);
-#define REL_PATH_TO_ROOT "../../"
+
void createSubDirs(QDir &d);
+
QCString stripPath(const char *s);
+
bool containsWord(const QCString &s,const QCString &word);
+
bool findAndRemoveWord(QCString &s,const QCString &word);
+
QCString stripLeadingAndTrailingEmptyLines(const QCString &s);
+
void stringToSearchIndex(const QCString &docUrlBase,const QCString &title,
const QCString &str, bool priority=FALSE,
const QCString &anchor="");
-enum SrcLangExt
-{
- SrcLangExt_IDL = 0x008,
- SrcLangExt_Java = 0x010,
- SrcLangExt_CSharp = 0x020,
- SrcLangExt_D = 0x040,
- SrcLangExt_PHP = 0x080,
- SrcLangExt_ObjC = 0x100,
- SrcLangExt_Cpp = 0x200,
-};
-
SrcLangExt getLanguageFromFileName(const QCString fileName);
+bool checkIfTypedef(Definition *scope,FileDef *fileScope,const char *n);
+
+
#endif
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index 3126adc..22f8e68 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -605,6 +605,7 @@ static void generateXMLForMember(MemberDef *md,QTextStream &ti,QTextStream &t,De
t << " mutable=\"";
if (md->isMutable()) t << "yes"; else t << "no";
t << "\"";
+
}
else if (md->memberType() == MemberDef::Property)
{
@@ -646,6 +647,12 @@ static void generateXMLForMember(MemberDef *md,QTextStream &ti,QTextStream &t,De
if (md->isWritable())
t << " <write>" << convertToXML(md->getWriteAccessor()) << "</write>" << endl;
}
+ if (md->memberType()==MemberDef::Variable && md->bitfieldString())
+ {
+ QCString bitfield = md->bitfieldString();
+ if (bitfield.at(0)==':') bitfield=bitfield.mid(1);
+ t << " <bitfield>" << bitfield << "</bitfield>" << endl;
+ }
MemberDef *rmd = md->reimplements();
if (rmd)