summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authordimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2004-04-13 19:01:22 (GMT)
committerdimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2004-04-13 19:01:22 (GMT)
commit4088d90d9abafaa51250e55a5f48a787a921ed98 (patch)
tree17a9c5d727d7c9aee93cdd92b7f832a4a09c1b2a /src
parent02b5f51ef09a211e16e0158e5115ddf5b33d194d (diff)
downloadDoxygen-4088d90d9abafaa51250e55a5f48a787a921ed98.zip
Doxygen-4088d90d9abafaa51250e55a5f48a787a921ed98.tar.gz
Doxygen-4088d90d9abafaa51250e55a5f48a787a921ed98.tar.bz2
Release-1.3.6-20040413
Diffstat (limited to 'src')
-rw-r--r--src/classdef.cpp64
-rw-r--r--src/classdef.h8
-rw-r--r--src/classlist.cpp22
-rw-r--r--src/cmdmapper.cpp1
-rw-r--r--src/cmdmapper.h3
-rw-r--r--src/code.l570
-rw-r--r--src/compound.xsd2
-rw-r--r--src/compound_xsd.h2
-rw-r--r--src/config.l98
-rw-r--r--src/docparser.cpp5
-rw-r--r--src/docparser.h2
-rw-r--r--src/doxygen.cpp38
-rw-r--r--src/entry.h3
-rw-r--r--src/filedef.cpp2
-rw-r--r--src/htmldocvisitor.cpp22
-rw-r--r--src/htmlgen.cpp38
-rw-r--r--src/htmlgen.h4
-rw-r--r--src/index.cpp2
-rw-r--r--src/latexdocvisitor.cpp11
-rw-r--r--src/mandocvisitor.cpp14
-rw-r--r--src/memberlist.cpp4
-rw-r--r--src/perlmodgen.cpp12
-rw-r--r--src/pre.l4
-rw-r--r--src/printdocvisitor.h1
-rw-r--r--src/rtfdocvisitor.cpp15
-rw-r--r--src/scanner.l114
-rw-r--r--src/tagreader.cpp2
-rw-r--r--src/translator_hu.h28
-rw-r--r--src/util.cpp63
-rw-r--r--src/util.h3
-rw-r--r--src/xmldocvisitor.cpp10
-rw-r--r--src/xmlgen.cpp9
32 files changed, 980 insertions, 196 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 802b9cd..0ba7b6e 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -93,6 +93,7 @@ ClassDef::ClassDef(
m_isStatic = FALSE;
m_isObjC = FALSE;
m_membersMerged = FALSE;
+ m_categoryOf = 0;
QCString ns;
extractNamespaceName(m_name,m_className,ns);
//printf("m_name=%s m_className=%s ns=%s\n",m_name.data(),m_className.data(),ns.data());
@@ -141,6 +142,10 @@ QCString ClassDef::displayName() const
{
n=substitute(n,"::",".");
}
+ if (m_compType==ClassDef::Protocol && n.right(2)=="-p")
+ {
+ n="< "+n.left(n.length()-2)+" >";
+ }
return n;
}
@@ -2044,7 +2049,7 @@ void ClassDef::mergeMembers()
//printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt);
if ((srcMi->virt!=Normal && dstMi->virt!=Normal) ||
bClass->name()+"::"+srcMi->scopePath == dstMi->scopePath ||
- dstMd->getClassDef()->compoundType()==ClassDef::Interface
+ dstMd->getClassDef()->compoundType()==Interface
)
{
found=TRUE;
@@ -2184,6 +2189,52 @@ void ClassDef::mergeMembers()
//----------------------------------------------------------------------------
+/*! Merges the members of a Objective-C category into this class.
+ */
+void ClassDef::mergeCategory(ClassDef *category)
+{
+ category->m_categoryOf = this;
+
+ MemberNameInfoSDict *srcMnd = category->m_allMemberNameInfoSDict;
+ MemberNameInfoSDict *dstMnd = m_allMemberNameInfoSDict;
+
+ MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
+ MemberNameInfo *srcMni;
+ for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
+ {
+ MemberNameInfo *dstMni=dstMnd->find(srcMni->memberName());
+ if (dstMni) // method is already defined in the class
+ {
+ // TODO: we should remove the other member and insert this one.
+ }
+ else // new method name
+ {
+ // create a deep copy of the list (only the MemberInfo's will be
+ // copied, not the actual MemberDef's)
+ MemberNameInfo *newMni = 0;
+ newMni = new MemberNameInfo(srcMni->memberName());
+
+ // copy the member(s) from the category to this class
+ MemberNameInfoIterator mnii(*srcMni);
+ MemberInfo *mi;
+ for (;(mi=mnii.current());++mnii)
+ {
+ //printf("Adding!\n");
+ MemberInfo *newMi=new MemberInfo(mi->memberDef,mi->prot,mi->virt,mi->inherited);
+ newMi->scopePath=mi->scopePath;
+ newMi->ambigClass=mi->ambigClass;
+ newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope.copy();
+ newMni->append(newMi);
+ }
+
+ // add it to the dictionary
+ dstMnd->append(newMni->memberName(),newMni);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
void ClassDef::addUsedClass(ClassDef *cd,const char *accessName)
{
if (m_usesImplClassDict==0)
@@ -2418,13 +2469,9 @@ void ClassDef::determineIntfUsageRelation()
}
#endif
-//PackageDef *ClassDef::packageDef() const
-//{
-// return m_fileDef ? m_fileDef->packageDef() : 0;
-//}
-
QCString ClassDef::compoundTypeString() const
{
+ if (m_compType==Interface && m_isObjC) return "class";
switch (m_compType)
{
case Class: return "class";
@@ -2773,7 +2820,6 @@ MemberDef *ClassDef::getMemberByName(const QCString &name)
{
MemberDef *xmd = 0;
MemberNameInfo *mni = m_allMemberNameInfoSDict->find(name);
- //printf("getMemberByName(%s)=%p\n",name.data(),mni);
if (mni)
{
const int maxInheritanceDepth = 100000;
@@ -2783,8 +2829,9 @@ MemberDef *ClassDef::getMemberByName(const QCString &name)
for (mnii.toFirst();(mi=mnii.current());++mnii)
{
ClassDef *mcd=mi->memberDef->getClassDef();
- //printf("found member in %s\n",mcd->name().data());
int m=minClassDistance(this,mcd);
+ //printf("found member in %s linkable=%d m=%d\n",
+ // mcd->name().data(),mcd->isLinkable(),m);
if (m<mdist && mcd->isLinkable())
{
mdist=m;
@@ -2792,6 +2839,7 @@ MemberDef *ClassDef::getMemberByName(const QCString &name)
}
}
}
+ //printf("getMemberByName(%s)=%p\n",name.data(),xmd);
return xmd;
}
diff --git a/src/classdef.h b/src/classdef.h
index fb7dd88..d745f83 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -202,6 +202,8 @@ class ClassDef : public Definition
/*! Returns TRUE if this class is implemented in Objective-C */
bool isObjectiveC() const { return m_isObjC; }
+ ClassDef *categoryOf() const { return m_categoryOf; }
+
/*! returns the name of the class including outer classes, but not
* including namespaces.
*/
@@ -273,6 +275,7 @@ class ClassDef : public Definition
void setNamespace(NamespaceDef *nd) { m_nspace = nd; }
void setTemplateArguments(ArgumentList *al);
void mergeMembers();
+ void mergeCategory(ClassDef *category);
void setFileDef(FileDef *fd) { m_fileDef=fd; }
//void determineImplUsageRelation();
//void determineIntfUsageRelation();
@@ -442,6 +445,11 @@ class ClassDef : public Definition
/*! class name with outer class scope, but without namespace scope. */
QCString m_className;
+
+ /*! If this class is a Objective-C category, then this points to the
+ * class which is extended.
+ */
+ ClassDef *m_categoryOf;
};
/*! \brief Class that contains information about a usage relation.
diff --git a/src/classlist.cpp b/src/classlist.cpp
index 7a52556..d538cbb 100644
--- a/src/classlist.cpp
+++ b/src/classlist.cpp
@@ -102,15 +102,15 @@ void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *f
}
ol.startMemberItem(FALSE);
QCString tmp = cd->compoundTypeString();
- QCString cname;
- if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
- {
- cname = substitute(cd->className(),"::",".");
- }
- else
- {
- cname = cd->className();
- }
+ QCString cname = cd->displayName();
+ //if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
+ //{
+ // cname = substitute(cd->className(),"::",".");
+ //}
+ //else
+ //{
+ // cname = cd->className();
+ //}
ol.writeString(tmp);
ol.writeString(" ");
ol.insertMemberAlign();
@@ -141,12 +141,12 @@ void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *f
{
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
- ol.endEmphasis();
+ //ol.endEmphasis();
ol.docify(" ");
ol.startTextLink(cd->getOutputFileBase(),"_details");
ol.parseText(theTranslator->trMore());
ol.endTextLink();
- ol.startEmphasis();
+ //ol.startEmphasis();
ol.popGeneratorState();
}
ol.endMemberDescription();
diff --git a/src/cmdmapper.cpp b/src/cmdmapper.cpp
index 959be75..b3047e2 100644
--- a/src/cmdmapper.cpp
+++ b/src/cmdmapper.cpp
@@ -105,6 +105,7 @@ CommandMap cmdMap[] =
{ "enddot", CMD_ENDDOT },
{ "manonly", CMD_MANONLY },
{ "endmanonly", CMD_ENDMANONLY },
+ { "includelineno", CMD_INCWITHLINES },
{ 0, 0 }
};
diff --git a/src/cmdmapper.h b/src/cmdmapper.h
index 18e43e3..a68d2bc 100644
--- a/src/cmdmapper.h
+++ b/src/cmdmapper.h
@@ -105,7 +105,8 @@ enum CommandType
CMD_DOT = 71,
CMD_ENDDOT = 72,
CMD_MANONLY = 73,
- CMD_ENDMANONLY = 74
+ CMD_ENDMANONLY = 74,
+ CMD_INCWITHLINES = 75
};
enum HtmlTagType
diff --git a/src/code.l b/src/code.l
index d0b7058..5bf9935 100644
--- a/src/code.l
+++ b/src/code.l
@@ -53,7 +53,6 @@
static BaseCodeDocInterface * g_code;
static ClassSDict g_codeClassSDict(17);
-//static ClassDef *g_curClassDef;
static QCString g_curClassName;
static QStrList g_curClassBases;
@@ -104,6 +103,35 @@ static int g_memCallContext;
static int g_lastCContext;
static bool g_insideObjC;
+static bool g_insideProtocolList;
+
+// context for an Objective-C method call
+struct ObjCCallCtx
+{
+ int id;
+ QCString methodName;
+ QCString objectTypeOrName;
+ ClassDef *objectType;
+ MemberDef *objectVar;
+ MemberDef *method;
+ QCString format;
+ int lexState;
+ int braceCount;
+};
+
+// globals for objective-C method calls
+static ObjCCallCtx *g_currentCtx=0;
+static int g_currentCtxId=0;
+static int g_currentNameId=0;
+static int g_currentObjId=0;
+static QStack<ObjCCallCtx> g_contextStack;
+static QIntDict<ObjCCallCtx> g_contextDict;
+static QIntDict<QCString> g_nameDict;
+static QIntDict<QCString> g_objectDict;
+static int g_braceCount=0;
+
+static void saveObjCContext();
+static void restoreObjCContext();
//-------------------------------------------------------------------
@@ -184,7 +212,8 @@ void VariableContext::addVariable(const QCString &type,const QCString &name)
ltype = ltype.right(ltype.length()-6);
}
if (ltype.isEmpty() || lname.isEmpty()) return;
- DBG_CTX((stderr,"** AddVariable trying: type=%s name=%s\n",ltype.data(),lname.data()));
+ DBG_CTX((stderr,"** addVariable trying: type=%s name=%s g_currentDefinition=%s\n",
+ ltype.data(),lname.data(),g_currentDefinition?g_currentDefinition->name().data():"<none>"));
Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast();
ClassDef *varType;
int i=0;
@@ -193,17 +222,17 @@ void VariableContext::addVariable(const QCString &type,const QCString &name)
(varType=getResolvedClass(g_currentDefinition,g_sourceFileDef,ltype)) // look for global class definitions
)
{
- DBG_CTX((stderr,"** AddVariable type=%s name=%s\n",ltype.data(),lname.data()));
+ DBG_CTX((stderr,"** addVariable type=%s name=%s\n",ltype.data(),lname.data()));
scope->append(lname,varType); // add it to a list
}
else if ((i=ltype.find('<'))!=-1)
{
- // probably a template class, try without arguments as well
+ // probably a template class, try without template arguments as well
addVariable(ltype.left(i),name);
}
- else // add a dummy entry so the name is hidden
+ else // add a dummy entry so the name is hidden to avoid false links
{
- //printf("adding dummy context!\n");
+ DBG_CTX((stderr,"** addVariable: dummy context\n"));
scope->append(lname,dummyContext);
}
}
@@ -567,7 +596,7 @@ static ClassDef *stripClassName(const char *s)
static MemberDef *setCallContextForVar(const QCString &name)
{
if (name.isEmpty()) return 0;
- //printf("setCallContextForVar(%s) g_classScope=%s\n",name.data(),g_classScope.data());
+ //fprintf(stderr,"setCallContextForVar(%s) g_classScope=%s\n",name.data(),g_classScope.data());
int scopeEnd = name.findRev("::");
if (scopeEnd!=-1) // name with explicit scope
@@ -592,10 +621,10 @@ static MemberDef *setCallContextForVar(const QCString &name)
ClassDef *mcd = g_theVarContext.findVariable(name);
if (mcd) // local variable
{
- //printf("local variable\n");
+ //fprintf(stderr,"local variable\n");
if (mcd!=VariableContext::dummyContext)
{
- //printf("local var `%s' mcd=%s\n",name.data(),mcd->name().data());
+ //fprintf(stderr,"local var `%s' mcd=%s\n",name.data(),mcd->name().data());
g_theCallContext.setClass(mcd);
}
}
@@ -605,12 +634,14 @@ static MemberDef *setCallContextForVar(const QCString &name)
mcd = getClass(g_classScope);
if (mcd)
{
+ //fprintf(stderr,"Inside class %s\n",mcd->name().data());
MemberDef *md=mcd->getMemberByName(name);
if (md)
{
+ //fprintf(stderr,"Found member %s\n",md->name().data());
if (g_scopeStack.top()!=CLASSBLOCK)
{
- //printf("class member `%s' mcd=%s\n",name.data(),mcd->name().data());
+ //fprintf(stderr,"class member `%s' mcd=%s\n",name.data(),mcd->name().data());
g_theCallContext.setClass(stripClassName(md->typeString()));
}
return md;
@@ -680,7 +711,7 @@ static void generateClassOrGlobalLink(BaseCodeDocInterface &ol,char *clName,
bool typeOnly=FALSE)
{
int i=0;
- //printf("generateClassOrGlobalLink(clName=%s)\n",clName);
+ //fprintf(stderr,"generateClassOrGlobalLink(clName=%s)\n",clName);
if (*clName=='~') // correct for matching negated values i.s.o. destructors.
{
g_code->codify("~");
@@ -688,6 +719,10 @@ static void generateClassOrGlobalLink(BaseCodeDocInterface &ol,char *clName,
}
QCString className=clName;
if (className.isEmpty()) return;
+ if (g_insideProtocolList)
+ {
+ className+="-p";
+ }
ClassDef *cd=0;
MemberDef *md=0;
@@ -715,7 +750,7 @@ static void generateClassOrGlobalLink(BaseCodeDocInterface &ol,char *clName,
g_anchorCount++;
}
}
- writeMultiLineCodeLink(ol,cd->getReference(),cd->getOutputFileBase(),0,className);
+ writeMultiLineCodeLink(ol,cd->getReference(),cd->getOutputFileBase(),0,clName);
addToSearchIndex(className);
if (md)
{
@@ -728,7 +763,7 @@ static void generateClassOrGlobalLink(BaseCodeDocInterface &ol,char *clName,
}
}
}
- else
+ else // not a class, maybe a global member
{
//printf("class %s not linkable! cd=%p md=%p typeOnly=%d\n",clName,cd,md,typeOnly);
if (md!=0 || (cd==0 && !typeOnly)) // not a class, see if it is a global enum/variable/typedef.
@@ -736,7 +771,15 @@ static void generateClassOrGlobalLink(BaseCodeDocInterface &ol,char *clName,
if (md==0) // not found as a typedef
{
md = setCallContextForVar(clName);
- if (md && g_currentDefinition!=0 &&
+ if (md && g_currentDefinition)
+ {
+ //fprintf(stderr,"%s accessible from %s? %d md->getOuterScope=%s\n",
+ // md->name().data(),g_currentDefinition->name().data(),
+ // isAccessibleFrom(g_currentDefinition,g_sourceFileDef,md),
+ // md->getOuterScope()->name().data());
+ }
+
+ if (md && g_currentDefinition &&
isAccessibleFrom(g_currentDefinition,g_sourceFileDef,md)==-1)
{
md=0; // variable not accessible
@@ -762,6 +805,7 @@ static void generateClassOrGlobalLink(BaseCodeDocInterface &ol,char *clName,
}
}
+ // nothing found, just write out the word
codifyLines(clName);
addToSearchIndex(clName);
}
@@ -1055,8 +1099,313 @@ static void startFontClass(const char *s)
g_currentFontClass=s;
}
+//----------------------------------------------------------------------------
+
+// recursively writes a linkified Objective-C method call
+static void writeObjCMethodCall(ObjCCallCtx *ctx)
+{
+ if (ctx==0) return;
+ const char *p = ctx->format.data();
+ //printf("writeObjCMethodCall(%s) obj=%s method=%s\n",
+ // ctx->format.data(),ctx->objectTypeOrName.data(),ctx->methodName.data());
+ char c;
+ if (!ctx->objectTypeOrName.isEmpty() && ctx->objectTypeOrName.at(0)!='$')
+ {
+ //printf("Looking for object=%s method=%s\n",ctx->objectTypeOrName.data(),
+ // ctx->methodName.data());
+ ClassDef *cd = g_theVarContext.findVariable(ctx->objectTypeOrName);
+ if (cd==0) // not a local variable
+ {
+ if (ctx->objectTypeOrName=="self")
+ {
+ if (g_currentDefinition &&
+ g_currentDefinition->definitionType()==Definition::TypeClass)
+ {
+ ctx->objectType = (ClassDef *)g_currentDefinition;
+ }
+ }
+ else
+ {
+ ctx->objectType = getResolvedClass(
+ g_currentDefinition,
+ g_sourceFileDef,
+ ctx->objectTypeOrName,
+ &ctx->method);
+ }
+ //printf(" object is class? %p\n",ctx->objectType);
+ if (ctx->objectType) // found class
+ {
+ ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
+ //printf(" yes->method=%s\n",ctx->method?ctx->method->name().data():"<none>");
+ }
+ else if (ctx->method==0) // search for class variable with the same name
+ {
+ //printf(" no\n");
+ //printf("g_currentDefinition=%p\n",g_currentDefinition);
+ if (g_currentDefinition &&
+ g_currentDefinition->definitionType()==Definition::TypeClass)
+ {
+ ctx->objectVar = ((ClassDef *)g_currentDefinition)->getMemberByName(ctx->objectTypeOrName);
+ //printf(" ctx->objectVar=%p\n",ctx->objectVar);
+ if (ctx->objectVar)
+ {
+ ctx->objectType = stripClassName(ctx->objectVar->typeString());
+ //printf(" ctx->objectType=%p\n",ctx->objectType);
+ if (ctx->objectType)
+ {
+ ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
+ //printf(" ctx->method=%p\n",ctx->method);
+ }
+ }
+ }
+ }
+ }
+ else // local variable
+ {
+ //printf(" object is local variable\n");
+ if (cd!=VariableContext::dummyContext)
+ {
+ ctx->method = cd->getMemberByName(ctx->methodName);
+ //printf(" class=%p method=%p\n",cd,ctx->method);
+ }
+ }
+ }
+
+ //printf("[");
+ while ((c=*p++)) // for each character in ctx->format
+ {
+ if (c=='$')
+ {
+ char nc=*p++;
+ if (nc=='$') // escaped $
+ {
+ g_code->codify("$");
+ }
+ else // name fragment or reference to a nested call
+ {
+ if (nc=='n') // name fragment
+ {
+ nc=*p++;
+ QCString refIdStr;
+ while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
+ p--;
+ int refId=refIdStr.toInt();
+ QCString *pName = g_nameDict.find(refId);
+ if (pName)
+ {
+ if (ctx->method && ctx->method->isLinkable())
+ {
+ writeMultiLineCodeLink(*g_code,
+ ctx->method->getReference(),
+ ctx->method->getOutputFileBase(),
+ ctx->method->anchor(),
+ pName->data());
+ if (g_currentMemberDef)
+ {
+ addDocCrossReference(g_currentMemberDef,ctx->method);
+ }
+ }
+ else
+ {
+ codifyLines(pName->data());
+ }
+ }
+ else
+ {
+ printf("Invalid name: id=%d\n",refId);
+ }
+ }
+ else if (nc=='o') // reference to potential object name
+ {
+ nc=*p++;
+ QCString refIdStr;
+ while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
+ p--;
+ int refId=refIdStr.toInt();
+ QCString *pObject = g_objectDict.find(refId);
+ if (pObject)
+ {
+ if (*pObject=="self")
+ {
+ if (g_currentDefinition &&
+ g_currentDefinition->definitionType()==Definition::TypeClass)
+ {
+ ctx->objectType = (ClassDef *)g_currentDefinition;
+ if (ctx->objectType->categoryOf())
+ {
+ ctx->objectType = ctx->objectType->categoryOf();
+ }
+ if (ctx->objectType)
+ {
+ ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
+ }
+ }
+ startFontClass("keyword");
+ codifyLines(pObject->data());
+ endFontClass();
+ }
+ else if (*pObject=="super")
+ {
+ if (g_currentDefinition &&
+ g_currentDefinition->definitionType()==Definition::TypeClass)
+ {
+ ClassDef *cd = (ClassDef *)g_currentDefinition;
+ if (cd->categoryOf())
+ {
+ cd = cd->categoryOf();
+ }
+ BaseClassList *bcd = cd->baseClasses();
+ if (bcd) // get direct base class (there should be only one)
+ {
+ BaseClassListIterator bli(*bcd);
+ BaseClassDef *bclass;
+ for (bli.toFirst();(bclass=bli.current());++bli)
+ {
+ if (bclass->classDef->compoundType()!=ClassDef::Protocol)
+ {
+ ctx->objectType = bclass->classDef;
+ if (ctx->objectType)
+ {
+ ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
+ }
+ }
+ }
+ }
+ }
+ startFontClass("keyword");
+ codifyLines(pObject->data());
+ endFontClass();
+ }
+ else if (ctx->objectVar && ctx->objectVar->isLinkable()) // object is class variable
+ {
+ writeMultiLineCodeLink(*g_code,
+ ctx->objectVar->getReference(),
+ ctx->objectVar->getOutputFileBase(),
+ ctx->objectVar->anchor(),
+ pObject->data());
+ if (g_currentMemberDef)
+ {
+ addDocCrossReference(g_currentMemberDef,ctx->objectVar);
+ }
+ }
+ else if (ctx->objectType &&
+ ctx->objectType!=VariableContext::dummyContext &&
+ ctx->objectType->isLinkable()
+ ) // object is class name
+ {
+ ClassDef *cd = ctx->objectType;
+ writeMultiLineCodeLink(*g_code,
+ cd->getReference(),
+ cd->getOutputFileBase(),
+ 0,
+ pObject->data());
+ }
+ else // object still needs to be resolved
+ {
+ ClassDef *cd = getResolvedClass(g_currentDefinition,
+ g_sourceFileDef, *pObject);
+ if (cd && cd->isLinkable())
+ {
+ if (ctx->objectType==0) ctx->objectType=cd;
+ writeMultiLineCodeLink(*g_code,
+ cd->getReference(),
+ cd->getOutputFileBase(),
+ 0,
+ pObject->data());
+ }
+ else
+ {
+ codifyLines(pObject->data());
+ }
+ }
+ }
+ else
+ {
+ printf("Invalid object: id=%d\n",refId);
+ }
+ }
+ else if (nc=='c') // reference to nested call
+ {
+ nc=*p++;
+ QCString refIdStr;
+ while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
+ p--;
+ int refId=refIdStr.toInt();
+ ObjCCallCtx *ictx = g_contextDict.find(refId);
+ if (ictx) // recurse into nested call
+ {
+ writeObjCMethodCall(ictx);
+ if (ictx->method) // link to nested call successfully
+ {
+ // get the ClassDef representing the method's return type
+ if (QCString(ictx->method->typeString())=="id")
+ {
+ // see if the method name is unique, if so we link to it
+ MemberName *mn=Doxygen::memberNameSDict.find(ctx->methodName);
+ //printf("mn->count=%d ictx->method=%s ctx->methodName=%s\n",
+ // mn==0?-1:(int)mn->count(),
+ // ictx->method->name().data(),
+ // ctx->methodName.data());
+ if (mn && mn->count()==1) // member name unique
+ {
+ ctx->method = mn->getFirst();
+ }
+ }
+ else
+ {
+ ctx->objectType = stripClassName(ictx->method->typeString());
+ if (ctx->objectType)
+ {
+ ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
+ }
+ }
+ //printf(" ***** method=%s -> object=%p\n",ictx->method->name().data(),ctx->objectType);
+ }
+ }
+ else
+ {
+ printf("Invalid context: id=%d\n",refId);
+ }
+ }
+ else // illegal marker
+ {
+ ASSERT(!"invalid escape sequence");
+ }
+ }
+ }
+ else // normal non-marker character
+ {
+ char s[2];
+ s[0]=c;s[1]=0;
+ codifyLines(s);
+ }
+ }
+ //printf("%s %s]\n",ctx->objectTypeOrName.data(),ctx->methodName.data());
+ //printf("}=(type='%s',name='%s')",
+ // ctx->objectTypeOrName.data(),
+ // ctx->methodName.data());
+}
+// Replaces an Objective-C method name fragment s by a marker of the form
+// $n12, the number (12) can later be used as a key for obtaining the name
+// fragment, from g_nameDict
+static QCString escapeName(const char *s)
+{
+ QCString result;
+ result.sprintf("$n%d",g_currentNameId);
+ g_nameDict.insert(g_currentNameId,new QCString(s));
+ g_currentNameId++;
+ return result;
+}
+static QCString escapeObject(const char *s)
+{
+ QCString result;
+ result.sprintf("$o%d",g_currentObjId);
+ g_objectDict.insert(g_currentObjId,new QCString(s));
+ g_currentObjId++;
+ return result;
+}
/* -----------------------------------------------------------------
*/
@@ -1087,6 +1436,7 @@ KEYWORD_OBJC ("@public"|"@private"|"@protected"|"@class"|"@implementation"|"@int
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")
+CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
%option noyywrap
@@ -1113,9 +1463,9 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
%x ObjCMethod
%x ObjCParams
%x ObjCParamType
-%x ObjCMemberCall
-%x ObjCMemberCall2
-%x ObjCMemberCall3
+%x ObjCCall
+%x ObjCMName
+%x ObjCSkipStr
%%
@@ -1146,8 +1496,13 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
endFontClass();
BEGIN( PackageName );
}
-<Body,ClassVar>"-"|"+" {
- if (!g_insideObjC)
+<ClassVar>\n {
+ if (!g_insideObjC) REJECT;
+ codifyLines(yytext);
+ BEGIN(Body);
+ }
+<Body,ClassVar,Bases>"-"|"+" {
+ if (!g_insideObjC || g_insideBody)
{
g_code->codify(yytext);
}
@@ -1170,8 +1525,22 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_code->codify(yytext);
if (*yytext=='{')
{
- g_insideBody=TRUE;
+ g_curlyCount++;
+ g_inClass=TRUE;
+ if (g_searchingForBody)
+ {
+ g_searchingForBody=FALSE;
+ g_insideBody=TRUE;
+ }
+ if (g_insideBody) g_bodyCurlyCount++;
+ if (!g_curClassName.isEmpty()) // valid class name
+ {
+ pushScope(g_curClassName);
+ g_scopeStack.push(SCOPEBLOCK);
+ }
}
+ g_type.resize(0);
+ g_name.resize(0);
BEGIN(Body);
}
<ObjCParams>{ID}{B}*":" {
@@ -1313,7 +1682,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
}
BEGIN(Body);
}
-<Body>"@end" {
+<Body,ClassVar>"@end" {
//printf("End of objc scope fd=%s\n",g_sourceFileDef->name().data());
if (g_sourceFileDef)
{
@@ -1326,12 +1695,16 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
{
g_insideObjC = FALSE;
}
- g_theVarContext.popScope();
-
- int *scope = g_scopeStack.pop();
- if (scope==SCOPEBLOCK || scope==CLASSBLOCK)
+ if (g_insideBody)
{
- popScope();
+ g_theVarContext.popScope();
+
+ int *scope = g_scopeStack.pop();
+ if (scope==SCOPEBLOCK || scope==CLASSBLOCK)
+ {
+ popScope();
+ }
+ g_insideBody=FALSE;
}
startFontClass("keyword");
@@ -1340,7 +1713,6 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_inClass=FALSE;
- g_insideBody=FALSE;
g_currentMemberDef=0;
if (g_currentDefinition)
g_currentDefinition=g_currentDefinition->getOuterScope();
@@ -1449,9 +1821,20 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
}
<Bases>"<" {
g_code->codify(yytext);
- g_sharpCount=1;
- BEGIN ( SkipSharp );
+ if (!g_insideObjC)
+ {
+ g_sharpCount=1;
+ BEGIN ( SkipSharp );
+ }
+ else
+ {
+ g_insideProtocolList=TRUE;
+ }
}
+<Bases>">" {
+ g_code->codify(yytext);
+ g_insideProtocolList=FALSE;
+ }
<SkipSharp>"<" {
g_code->codify(yytext);
++g_sharpCount;
@@ -1603,7 +1986,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_name+=yytext;
BEGIN( FuncCall );
}
-<FuncCall,Body,MemberCall,MemberCall2,ObjCMemberCall2,ObjCMemberCall3>\" {
+<FuncCall,Body,MemberCall,MemberCall2>\" {
startFontClass("stringliteral");
g_code->codify(yytext);
g_lastStringContext=YY_START;
@@ -1729,9 +2112,19 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
{
//printf("Found start of ObjC call!\n");
// start of a method call
- g_code->codify(yytext);
- g_theCallContext.pushScope();
- BEGIN(ObjCMemberCall);
+ g_contextDict.setAutoDelete(TRUE);
+ g_nameDict.setAutoDelete(TRUE);
+ g_objectDict.setAutoDelete(TRUE);
+ g_contextDict.clear();
+ g_nameDict.clear();
+ g_objectDict.clear();
+ g_currentCtxId = 0;
+ g_currentNameId = 0;
+ g_currentObjId = 0;
+ g_currentCtx = 0;
+ g_braceCount = 0;
+ unput('[');
+ BEGIN(ObjCCall);
}
else
{
@@ -1758,6 +2151,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_args.resize(0);
}
}
+ /*
<ObjCMemberCall>{ID} {
if (strcmp(yytext,"self")==0 || strcmp(yytext,"super")==0)
{
@@ -1802,6 +2196,70 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
g_code->codify(yytext);
BEGIN(Body);
}
+ */
+<ObjCCall,ObjCMName>"[" {
+ saveObjCContext();
+ g_currentCtx->format+=*yytext;
+ BEGIN(ObjCCall);
+ //printf("open\n");
+ }
+<ObjCCall,ObjCMName>"]" {
+ g_currentCtx->format+=*yytext;
+ restoreObjCContext();
+ BEGIN(ObjCMName);
+ if (g_currentCtx==0)
+ {
+ // end of call
+ writeObjCMethodCall(g_contextDict.find(0));
+ BEGIN(Body);
+ }
+ //printf("close\n");
+ }
+<ObjCCall>{ID} {
+ g_currentCtx->format+=escapeObject(yytext);
+ if (g_braceCount==0)
+ {
+ g_currentCtx->objectTypeOrName=yytext;
+ //printf("new type=%s\n",g_currentCtx->objectTypeOrName.data());
+ BEGIN(ObjCMName);
+ }
+ }
+<ObjCMName>{ID}/{BN}*"]" {
+ if (g_braceCount==0 &&
+ g_currentCtx->methodName.isEmpty())
+ {
+ g_currentCtx->methodName=yytext;
+ g_currentCtx->format+=escapeName(yytext);
+ }
+ else
+ {
+ g_currentCtx->format+=yytext;
+ }
+ }
+<ObjCMName>{ID}/{BN}*":" {
+ if (g_braceCount==0)
+ {
+ g_currentCtx->methodName+=yytext;
+ g_currentCtx->methodName+=":";
+ }
+ g_currentCtx->format+=escapeName(yytext);
+ }
+<ObjCSkipStr>[^\n\"$\\]* { g_currentCtx->format+=yytext; }
+<ObjCSkipStr>\\. { g_currentCtx->format+=yytext; }
+<ObjCSkipStr>"\"" { g_currentCtx->format+=yytext;
+ BEGIN(g_lastStringContext);
+ }
+<ObjCCall,ObjCMName>{CHARLIT} { g_currentCtx->format+=yytext; }
+<ObjCCall,ObjCMName>"@"?"\"" { g_currentCtx->format+=yytext;
+ g_lastStringContext=YY_START;
+ BEGIN(ObjCSkipStr);
+ }
+<ObjCCall,ObjCMName,ObjCSkipStr>"$" { g_currentCtx->format+="$$"; }
+<ObjCCall,ObjCMName>"(" { g_currentCtx->format+=*yytext; g_braceCount++; }
+<ObjCCall,ObjCMName>")" { g_currentCtx->format+=*yytext; g_braceCount--; }
+<ObjCCall,ObjCMName,ObjCSkipStr>. { g_currentCtx->format+=*yytext; }
+<ObjCCall,ObjCMName,ObjCSkipStr>\n { g_currentCtx->format+=*yytext; }
+
<Body>"]" {
g_theCallContext.popScope();
g_code->codify(yytext);
@@ -2314,6 +2772,52 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
/*@ ----------------------------------------------------------------------------
*/
+static void saveObjCContext()
+{
+ if (g_currentCtx)
+ {
+ g_currentCtx->format+=QCString().sprintf("$c%d",g_currentCtxId);
+ if (g_braceCount==0 && YY_START==ObjCCall)
+ {
+ g_currentCtx->objectTypeOrName=g_currentCtx->format.mid(1);
+ //printf("new type=%s\n",g_currentCtx->objectTypeOrName.data());
+ }
+ g_contextStack.push(g_currentCtx);
+ }
+ else
+ {
+ //printf("Trying to save NULL context!\n");
+ }
+ ObjCCallCtx *newCtx = new ObjCCallCtx;
+ newCtx->id = g_currentCtxId;
+ newCtx->lexState = YY_START;
+ newCtx->braceCount = g_braceCount;
+ newCtx->objectType = 0;
+ newCtx->objectVar = 0;
+ newCtx->method = 0;
+ //printf("save state=%d\n",YY_START);
+ g_contextDict.insert(g_currentCtxId,newCtx);
+ g_currentCtx = newCtx;
+ g_braceCount = 0;
+ g_currentCtxId++;
+}
+
+static void restoreObjCContext()
+{
+ //printf("restore state=%d->%d\n",YY_START,g_currentCtx->lexState);
+ BEGIN(g_currentCtx->lexState);
+ g_braceCount = g_currentCtx->braceCount;
+ if (!g_contextStack.isEmpty())
+ {
+ g_currentCtx = g_contextStack.pop();
+ }
+ else
+ {
+ g_currentCtx = 0;
+ //printf("Trying to pop context while g_contextStack is empty!\n");
+ }
+}
+
void initParseCodeContext()
{
g_theVarContext.clear();
diff --git a/src/compound.xsd b/src/compound.xsd
index aa45adf..ac77e4b 100644
--- a/src/compound.xsd
+++ b/src/compound.xsd
@@ -121,6 +121,8 @@
<xsd:attribute name="virt" type="DoxVirtualKind" />
<xsd:attribute name="volatile" type="DoxBool" />
<xsd:attribute name="mutable" type="DoxBool" />
+ <xsd:attribute name="readable" type="DoxBool" use="optional"/>
+ <xsd:attribute name="writable" type="DoxBool" use="optional"/>
</xsd:complexType>
<xsd:complexType name="descriptionType" mixed="true">
diff --git a/src/compound_xsd.h b/src/compound_xsd.h
index d43646e..6af2a92 100644
--- a/src/compound_xsd.h
+++ b/src/compound_xsd.h
@@ -121,6 +121,8 @@
" <xsd:attribute name=\"virt\" type=\"DoxVirtualKind\" />\n"
" <xsd:attribute name=\"volatile\" type=\"DoxBool\" />\n"
" <xsd:attribute name=\"mutable\" type=\"DoxBool\" />\n"
+" <xsd:attribute name=\"readable\" type=\"DoxBool\" use=\"optional\"/>\n"
+" <xsd:attribute name=\"writable\" type=\"DoxBool\" use=\"optional\"/>\n"
" </xsd:complexType>\n"
"\n"
" <xsd:complexType name=\"descriptionType\" mixed=\"true\">\n"
diff --git a/src/config.l b/src/config.l
index e63d0bb..f757a3d 100644
--- a/src/config.l
+++ b/src/config.l
@@ -829,6 +829,41 @@ void Config::substituteEnvironmentVars()
}
}
+static void cleanUpPaths(QStrList &str)
+{
+ char *sfp = str.first();
+ while (sfp)
+ {
+ register char *p = sfp;
+ if (p)
+ {
+ char c;
+ while ((c=*p))
+ {
+ if (c=='\\') *p='/';
+ p++;
+ }
+ }
+ QCString path = sfp;
+ if ((path.at(0)!='/' && (path.length()<=2 || path.at(1)!=':')) ||
+ path.at(path.length()-1)!='/'
+ )
+ {
+ QFileInfo fi(path);
+ if (fi.exists() && fi.isDir())
+ {
+ int i = str.at();
+ str.remove();
+ if (str.at()==i) // did not remove last item
+ str.insert(i,fi.absFilePath()+"/");
+ else
+ str.append(fi.absFilePath()+"/");
+ }
+ }
+ sfp = str.next();
+ }
+}
+
void Config::check()
{
//if (!projectName.isEmpty())
@@ -903,36 +938,12 @@ void Config::check()
}
else
{
- while (sfp)
- {
- register char *p = sfp;
- if (p)
- {
- char c;
- while ((c=*p))
- {
- if (c=='\\') *p='/';
- p++;
- }
- }
- QCString path = sfp;
- if (path.at(0)!='/' && (path.length()<=2 || path.at(1)!=':'))
- {
- QFileInfo fi(path);
- if (fi.exists() && fi.isDir())
- {
- int i = stripFromPath.at();
- stripFromPath.remove();
- if (stripFromPath.at()==i) // did not remove last item
- stripFromPath.insert(i,fi.absFilePath()+"/");
- else
- stripFromPath.append(fi.absFilePath()+"/");
- }
- }
- sfp = stripFromPath.next();
- }
+ cleanUpPaths(stripFromPath);
}
-
+
+ // expand the relative stripFromPath values
+ QStrList &stripFromIncPath = Config_getList("STRIP_FROM_INC_PATH");
+ cleanUpPaths(stripFromIncPath);
// Test to see if HTML header is valid
QCString &headerFile = Config_getString("HTML_HEADER");
@@ -1102,6 +1113,22 @@ void Config::check()
filePatternList.append("*.inc");
filePatternList.append("*.m");
filePatternList.append("*.mm");
+#if !defined(_WIN32)
+ // unix => case sensitive match => also include useful uppercase versions
+ filePatternList.append("*.C");
+ filePatternList.append("*.CC");
+ filePatternList.append("*.C++");
+ filePatternList.append("*.II");
+ filePatternList.append("*.I++");
+ filePatternList.append("*.H");
+ filePatternList.append("*.HH");
+ filePatternList.append("*.H++");
+ filePatternList.append("*.CS");
+ filePatternList.append("*.PHP");
+ filePatternList.append("*.PHP3");
+ filePatternList.append("*.M");
+ filePatternList.append("*.MM");
+#endif
}
// add default pattern if needed
@@ -1495,11 +1522,20 @@ void Config::create()
"If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag \n"
"can be used to strip a user-defined part of the path. Stripping is \n"
"only done if one of the specified strings matches the left-hand part of \n"
- "the path. It is allowed to use relative paths in the argument list. \n"
+ "the path. The tag can be used to show relative paths in the file list. \n"
"If left blank the directory from which doxygen is run is used as the \n"
"path to strip. \n"
);
cl->addDependency("FULL_PATH_NAMES");
+ cl = addList(
+ "STRIP_FROM_INC_PATH",
+ "The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of \n"
+ "the path mentioned in the documentation of a class, which tells \n"
+ "the reader which header file to include in order to use a class. \n"
+ "If left blank only the name of the header file containing the class \n"
+ "definition is used. Otherwise one should specify the include paths that \n"
+ "are normally passed to the compiler using the -I flag.\n"
+ );
cb = addBool(
"SHORT_NAMES",
"If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter \n"
@@ -2454,7 +2490,7 @@ void Config::create()
"INCLUDE_PATH",
"The INCLUDE_PATH tag can be used to specify one or more directories that \n"
"contain include files that are not input files but should be processed by \n"
- "the preprocessor. \n"
+ "the preprocessor.\n"
);
cl->setWidgetType(ConfigList::Dir);
cl->addDependency("ENABLE_PREPROCESSING");
diff --git a/src/docparser.cpp b/src/docparser.cpp
index ee0d83a..33cccff 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -1247,6 +1247,8 @@ void DocInclude::parse()
DBG(("DocInclude::parse(file=%s,text=%s)\n",m_file.data(),m_text.data()));
switch(m_type)
{
+ case IncWithLines:
+ // fall through
case Include:
// fall through
case DontInclude:
@@ -3819,6 +3821,9 @@ int DocPara::handleCommand(const QString &cmdName)
case CMD_INCLUDE:
handleInclude(cmdName,DocInclude::Include);
break;
+ case CMD_INCWITHLINES:
+ handleInclude(cmdName,DocInclude::IncWithLines);
+ break;
case CMD_DONTINCLUDE:
handleInclude(cmdName,DocInclude::DontInclude);
break;
diff --git a/src/docparser.h b/src/docparser.h
index 6ccb05c..8df9c53 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -380,7 +380,7 @@ class DocVerbatim : public DocNode
class DocInclude : public DocNode
{
public:
- enum Type { Include, DontInclude, VerbInclude, HtmlInclude };
+ enum Type { Include, DontInclude, VerbInclude, HtmlInclude, IncWithLines };
DocInclude(DocNode *parent,const QString &file,
const QString context, Type t,
bool isExample,const QString exampleFile) :
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 8a1dcec..d71e7c1 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -488,6 +488,10 @@ static void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root)
iName=iName.mid(1,iName.length()-2); // strip quotes or brackets
}
}
+ else if (!Config_getList("STRIP_FROM_INC_PATH").isEmpty())
+ {
+ iName=stripFromIncludePath(fd->absFilePath());
+ }
else // use name of the file containing the class definition
{
iName=fd->name();
@@ -822,21 +826,6 @@ static void addClassToContext(Entry *root)
cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
cd->insertUsedFile(root->fileName);
- //int bi;
- //if (root->objc && (bi=fullName.find('<'))!=-1 && root->extends->count()==0)
- //{
- // // add protocols as base classes
- // int be=fullName.find('>'),len;
- // static QRegExp re("[A-Z_a-z][A-Z_a-z0-9]*");
- // int p=0;
- // while ((p=re.match(fullName,bi+1,&len))!=-1 && p<be)
- // {
- // QCString baseName = fullName.mid(p,len);
- // printf("Adding artifical base class %s to %s\n",baseName.data(),fullName.data());
- // root->extends->append(new BaseInfo(baseName,Public,Normal));
- // bi=p+len;
- // }
- //}
// add class to the list
//printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data());
@@ -5754,10 +5743,26 @@ static void createTemplateInstanceMembers()
static void buildCompleteMemberLists()
{
ClassDef *cd;
- // merge the member list of base classes into the inherited classes.
+ // merge members of categories into the class they extend
ClassSDict::Iterator cli(Doxygen::classSDict);
for (cli.toFirst();(cd=cli.current());++cli)
{
+ int i=cd->name().find('(');
+ if (i!=-1) // it is an Objective-C category
+ {
+ QCString baseName=cd->name().left(i);
+ ClassDef *baseClass=Doxygen::classSDict.find(baseName);
+ if (baseClass)
+ {
+ //printf("*** merging members of category %s into %s\n",
+ // cd->name().data(),baseClass->name().data());
+ baseClass->mergeCategory(cd);
+ }
+ }
+ }
+ // merge the member list of base classes into the inherited classes.
+ for (cli.toFirst();(cd=cli.current());++cli)
+ {
if (// !cd->isReference() && // not an external class
cd->subClasses()->count()==0 && // is a root of the hierarchy
cd->baseClasses()->count()>0) // and has at least one base class
@@ -8372,6 +8377,7 @@ void generateOutput()
exit(1);
}
Doxygen::tagFile.setDevice(tag);
+ Doxygen::tagFile.setEncoding(QTextStream::Latin1);
Doxygen::tagFile << "<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>" << endl;
Doxygen::tagFile << "<tagfile>" << endl;
}
diff --git a/src/entry.h b/src/entry.h
index 4670a48..63ead7e 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -38,7 +38,8 @@ struct ListItemInfo
struct BaseInfo
{
/*! Creates an object representing an inheritance relation */
- BaseInfo(const char *n,Protection p,Specifier v) : name(n),prot(p),virt(v) {}
+ BaseInfo(const char *n,Protection p,Specifier v) :
+ name(n),prot(p),virt(v) {}
QCString name; //!< the name of the base class
Protection prot; //!< inheritance type
Specifier virt; //!< virtualness
diff --git a/src/filedef.cpp b/src/filedef.cpp
index 0642245..b04c5e3 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -55,7 +55,7 @@ class DevNullCodeDocInterface : public BaseCodeDocInterface
/*! create a new file definition, where \a p is the file path,
- \a the file name, and \a ref is an HTML anchor name if the
+ \a nm the file name, and \a ref is an HTML anchor name if the
file was read from a tag file or 0 otherwise
*/
FileDef::FileDef(const char *p,const char *nm,
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index 6d46942..a2ca11f 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -171,6 +171,7 @@ void HtmlDocVisitor::visit(DocStyleChange *s)
m_insidePre=FALSE;
m_t << "</pre>";
}
+ break;
case DocStyleChange::Div:
if (s->enable()) m_t << "<div" << htmlAttribsToString(s->attribs()) << ">"; else m_t << "</div>";
break;
@@ -245,9 +246,18 @@ void HtmlDocVisitor::visit(DocInclude *inc)
switch(inc->type())
{
case DocInclude::Include:
- m_t << "<div class=\"fragment\"><pre>";
+ m_t << "<pre class=\"fragment\"><div>";
parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile());
- m_t << "</pre></div>";
+ m_t << "</div></pre>";
+ case DocInclude::IncWithLines:
+ {
+ m_t << "<div class=\"fragment\"><pre>";
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath(), cfi.fileName() );
+ parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd);
+ m_t << "</pre></div>";
+ }
+ break;
break;
case DocInclude::DontInclude:
break;
@@ -255,9 +265,9 @@ void HtmlDocVisitor::visit(DocInclude *inc)
m_t << inc->text();
break;
case DocInclude::VerbInclude:
- m_t << "<div class=\"fragment\"><pre>";
+ m_t << "<pre class=\"fragment\"><div>";
filter(inc->text());
- m_t << "</pre></div>";
+ m_t << "</div></pre>";
break;
}
}
@@ -268,7 +278,7 @@ void HtmlDocVisitor::visit(DocIncOperator *op)
// op->type(),op->isFirst(),op->isLast(),op->text().data());
if (op->isFirst())
{
- if (!m_hide) m_t << "<div class=\"fragment\"><pre>";
+ if (!m_hide) m_t << "<pre class=\"fragment\"><div>";
pushEnabled();
m_hide=TRUE;
}
@@ -282,7 +292,7 @@ void HtmlDocVisitor::visit(DocIncOperator *op)
if (op->isLast())
{
popEnabled();
- if (!m_hide) m_t << "</pre></div>";
+ if (!m_hide) m_t << "</div></pre>";
}
else
{
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 46a797e..1e5666a 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -34,11 +34,12 @@
#include "htmldocvisitor.h"
#include "index.h"
#include "pagedef.h"
+#include "debug.h"
// #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"
@@ -308,7 +309,7 @@ void HtmlGenerator::writeStyleSheetFile(QFile &file)
}
static void writeDefaultHeaderFile(QTextStream &t, const char *title,
- const char *relPath)
+ const char *relPath,bool usePathCmd)
{
t << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
"<html><head>"
@@ -321,7 +322,11 @@ static void writeDefaultHeaderFile(QTextStream &t, const char *title,
t << "href=\"";
if (Config_getString("HTML_STYLESHEET").isEmpty())
{
- t << relPath << "doxygen.css";
+ if (usePathCmd)
+ t << "$relpath$";
+ else
+ t << relPath;
+ t << "doxygen.css";
}
else
{
@@ -344,7 +349,7 @@ void HtmlGenerator::writeHeaderFile(QFile &file)
#if QT_VERSION >= 200
t.setEncoding(QTextStream::Latin1);
#endif
- writeDefaultHeaderFile(t,"$title",relativePathToRoot(0));
+ writeDefaultHeaderFile(t,"$title",relativePathToRoot(0),TRUE);
}
void HtmlGenerator::writeFooterFile(QFile &file)
@@ -390,11 +395,11 @@ void HtmlGenerator::startFile(const char *name,const char *,
lastFile = fileName;
if (g_header.isEmpty())
{
- writeDefaultHeaderFile(t,dispTitle,relPath);
+ writeDefaultHeaderFile(t,dispTitle,relPath,FALSE);
}
else
{
- t << substituteKeywords(g_header,convertToHtml(lastTitle));
+ t << substituteKeywords(g_header,convertToHtml(lastTitle),relPath);
}
t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
<< versionString << " -->" << endl;
@@ -442,11 +447,22 @@ static void writePageFooter(QTextStream &t,const QCString &lastTitle,
t << endl << "<a href=\"http://www.doxygen.org/index.html\">";
t << endl << "<img src=\"" << relPath << "doxygen.png\" alt=\"doxygen\" "
<< "align=\"middle\" border=0 >" << "</a> " << versionString << " ";
- t << "</small></address>\n</body>\n</html>\n";
+ t << "</small></address>";
+ if (Debug::isFlagSet(Debug::Validate))
+ {
+ t << "<p><a href=\"http://validator.w3.org/check/referer\">"
+ "<img border=\"0\" src=\"http://www.w3.org/Icons/valid-html401\""
+ " height=\"31\" width=\"88\" alt=\"This page is Valid HTML 4.01 "
+ "Transitional!\"></a><a href=\"http://jigsaw.w3.org/css-validator/\">"
+ "<img style=\"border:0;width:88px;height:31px\" "
+ "src=\"http://jigsaw.w3.org/css-validator/images/vcss\" "
+ "alt=\"This page uses valid CSS!\"></a></p>";
+ }
+ t << "\n</body>\n</html>\n";
}
else
{
- t << substituteKeywords(g_footer,convertToHtml(lastTitle));
+ t << substituteKeywords(g_footer,convertToHtml(lastTitle),relPath);
}
}
@@ -1482,11 +1498,11 @@ void HtmlGenerator::writeSearchPage()
#endif
if (g_header.isEmpty())
{
- writeDefaultHeaderFile(t,"Search",0);
+ writeDefaultHeaderFile(t,"Search",0,FALSE);
}
else
{
- t << substituteKeywords(g_header,"Search");
+ t << substituteKeywords(g_header,"Search","");
}
t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
<< versionString << " -->" << endl;
diff --git a/src/htmlgen.h b/src/htmlgen.h
index f06318f..29d7385 100644
--- a/src/htmlgen.h
+++ b/src/htmlgen.h
@@ -112,8 +112,8 @@ class HtmlGenerator : public OutputGenerator
void writeRuler() { t << "<hr>"; }
void writeAnchor(const char *,const char *name)
{ t << "<a name=\"" << name <<"\"></a>"; }
- void startCodeFragment() { t << "<div class=\"fragment\"><pre>"; }
- void endCodeFragment() { t << "</pre></div>"; }
+ void startCodeFragment() { t << "<pre class=\"fragment\"><div>"; }
+ void endCodeFragment() { t << "</div></pre>"; }
void writeLineNumber(const char *,const char *,const char *,int);
void startCodeLine() { col=0; }
void endCodeLine() { codify("\n"); }
diff --git a/src/index.cpp b/src/index.cpp
index ecbf8dd..afc0f1d 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -3048,7 +3048,7 @@ void writeIndex(OutputList &ol)
QCString defFileName =
Doxygen::mainPage ? Doxygen::mainPage->getDefFileName().data() : "<generated>";
int defLine =
- Doxygen::mainPage ? Doxygen::mainPage->getDefLine() : 1;
+ Doxygen::mainPage ? Doxygen::mainPage->getDefLine() : -1;
QCString title;
if (!mainPageHasTitle())
diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp
index 0cb1bae..0da3849 100644
--- a/src/latexdocvisitor.cpp
+++ b/src/latexdocvisitor.cpp
@@ -15,7 +15,7 @@
* input used in their production; they are not affected by this license.
*
*/
-
+#include <qfileinfo.h>
#include "latexdocvisitor.h"
#include "docparser.h"
#include "language.h"
@@ -308,6 +308,15 @@ void LatexDocVisitor::visit(DocInclude *inc)
if (m_hide) return;
switch(inc->type())
{
+ case DocInclude::IncWithLines:
+ {
+ m_t << "\n\n\\footnotesize\\begin{verbatim}";
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath(), cfi.fileName() );
+ parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd);
+ m_t << "\\end{verbatim}\n\\normalsize" << endl;
+ }
+ break;
case DocInclude::Include:
m_t << "\n\n\\footnotesize\\begin{verbatim}";
parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile());
diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp
index 2345670..b560a27 100644
--- a/src/mandocvisitor.cpp
+++ b/src/mandocvisitor.cpp
@@ -25,6 +25,7 @@
#include "dot.h"
#include "util.h"
#include "message.h"
+#include <qfileinfo.h>
ManDocVisitor::ManDocVisitor(QTextStream &t,BaseCodeDocInterface &ci)
: DocVisitor(DocVisitor_Man), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_firstCol(TRUE),
@@ -220,6 +221,19 @@ void ManDocVisitor::visit(DocInclude *inc)
if (m_hide) return;
switch(inc->type())
{
+ case DocInclude::IncWithLines:
+ {
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_t << ".nf" << endl;
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath(), cfi.fileName() );
+ parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd);
+ if (!m_firstCol) m_t << endl;
+ m_t << ".PP" << endl;
+ m_firstCol=TRUE;
+ }
+ break;
case DocInclude::Include:
if (!m_firstCol) m_t << endl;
m_t << ".PP" << endl;
diff --git a/src/memberlist.cpp b/src/memberlist.cpp
index a995904..8a3ace5 100644
--- a/src/memberlist.cpp
+++ b/src/memberlist.cpp
@@ -323,7 +323,7 @@ void MemberList::writeDeclarations(OutputList &ol,
{
//printf("subtitle=`%s'\n",subtitle);
ol.startMemberSubtitle();
- ol.parseDoc("<generated>",1,0,0,subtitle,FALSE,FALSE);
+ ol.parseDoc("<generated>",-1,0,0,subtitle,FALSE,FALSE);
ol.endMemberSubtitle();
}
@@ -347,7 +347,7 @@ void MemberList::writeDeclarations(OutputList &ol,
{
//printf("Member group has docs!\n");
ol.startMemberGroupDocs();
- ol.parseDoc("<generated>",1,0,0,mg->documentation()+"\n",FALSE,FALSE);
+ ol.parseDoc("<generated>",-1,0,0,mg->documentation()+"\n",FALSE,FALSE);
ol.endMemberGroupDocs();
}
ol.startMemberGroup();
diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp
index 20520c1..c5c9858 100644
--- a/src/perlmodgen.cpp
+++ b/src/perlmodgen.cpp
@@ -642,6 +642,18 @@ void PerlModDocVisitor::visit(DocInclude *inc)
const char *type = 0;
switch(inc->type())
{
+ case DocInclude::IncWithLines:
+ #if 0
+ {
+ m_t << "<div class=\"fragment\"><pre>";
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath(), cfi.fileName() );
+ parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd);
+ m_t << "</pre></div>";
+ }
+ break;
+ #endif
+ return;
case DocInclude::Include:
#if 0
m_output.add("<programlisting>");
diff --git a/src/pre.l b/src/pre.l
index 490f2f5..c57f35b 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -1862,12 +1862,12 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
}
<DefineText>\\[\r]?\n {
g_defLitText+=yytext;
- outputChar('\n');
+ outputChar('\n');
g_defText += ' '; g_yyLineNr++;
}
<DefineText>\n {
- g_defLitText+=yytext;
QCString comment=extractTrailingComment(g_defLitText);
+ g_defLitText+=yytext;
if (!comment.isEmpty())
{
outputArray(comment,comment.length());
diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h
index 52062ec..a7a8b44 100644
--- a/src/printdocvisitor.h
+++ b/src/printdocvisitor.h
@@ -170,6 +170,7 @@ class PrintDocVisitor : public DocVisitor
switch(inc->type())
{
case DocInclude::Include: printf("include"); break;
+ case DocInclude::IncWithLines: printf("incwithlines"); break;
case DocInclude::DontInclude: printf("dontinclude"); break;
case DocInclude::HtmlInclude: printf("htmlinclude"); break;
case DocInclude::VerbInclude: printf("verbinclude"); break;
diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp
index 6c65ee2..2f2dd25 100644
--- a/src/rtfdocvisitor.cpp
+++ b/src/rtfdocvisitor.cpp
@@ -26,6 +26,7 @@
#include "util.h"
#include "rtfstyle.h"
#include "message.h"
+#include <qfileinfo.h>
RTFDocVisitor::RTFDocVisitor(QTextStream &t,BaseCodeDocInterface &ci)
: DocVisitor(DocVisitor_RTF), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_indentLevel(1)
@@ -366,7 +367,19 @@ void RTFDocVisitor::visit(DocInclude *inc)
if (m_hide) return;
switch(inc->type())
{
- case DocInclude::Include:
+ case DocInclude::IncWithLines:
+ {
+ m_t << "{" << endl;
+ m_t << "\\par" << endl;
+ m_t << rtf_Style_Reset << getStyle("CodeExample");
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath(), cfi.fileName() );
+ parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd);
+ m_t << "\\par" << endl;
+ m_t << "}" << endl;
+ }
+ break;
+ case DocInclude::Include:
m_t << "{" << endl;
m_t << "\\par" << endl;
m_t << rtf_Style_Reset << getStyle("CodeExample");
diff --git a/src/scanner.l b/src/scanner.l
index 349f156..457f5b0 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -79,7 +79,8 @@ static int lastSkipHtmlCommentContext;
static int lastIfContext;
static int lastInternalDocContext;
static int lastPreLineCtrlContext;
-static int lastSkipVerbStringContext;;
+static int lastSkipVerbStringContext;
+static int lastCommentInArgContext;
static int nextDefContext;
static int overloadContext;
static Protection protection;
@@ -130,6 +131,7 @@ static bool insideD = FALSE; //!< processing D code?
static bool insidePHP = FALSE; //!< processing PHP code?
static bool insideCppQuote = FALSE;
static bool insideObjC = FALSE; //!< processing Objective C code?
+static bool insideProtocolList = FALSE;
static int argRoundCount;
static int argSharpCount;
@@ -806,6 +808,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
%x ObjCReturnType
%x ObjCParams
%x ObjCParamType
+%x ObjCProtocolList
%x QtPropType
%x QtPropName
%x QtPropRW
@@ -2745,6 +2748,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
// as documentation for the argument
fullArgString+=yytext;
lastCopyArgChar=0;
+ lastCommentInArgContext=YY_START;
if (yytext[1]=='/')
BEGIN( CopyArgCommentLine );
else
@@ -2794,6 +2798,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
lastCopyArgChar=*yytext;
QCString text=&yytext[1];
text=text.stripWhiteSpace();
+ lastCommentInArgContext=YY_START;
fullArgString+=text;
if (text.find("//")!=-1)
BEGIN( CopyArgCommentLine );
@@ -2806,13 +2811,13 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
<CopyArgComment>"*/" { fullArgString+=yytext;
if (lastCopyArgChar!=0)
unput(lastCopyArgChar);
- BEGIN( ReadFuncArgType );
+ BEGIN( lastCommentInArgContext );
}
<CopyArgCommentLine>\n { fullArgString+=yytext;
yyLineNr++;
if (lastCopyArgChar!=0)
unput(lastCopyArgChar);
- BEGIN( ReadFuncArgType );
+ BEGIN( lastCommentInArgContext );
}
<CopyArgCommentLine>[^\\\@\n]+ { fullArgString+=yytext; }
<CopyArgCommentLine>. { fullArgString+=*yytext; }
@@ -3347,10 +3352,25 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
<CompoundName>{SCOPENAME}{BN}*/"<" {
sharpCount = 0;
current->name = yytext ;
+ if (current->section==Entry::PROTOCOL_SEC)
+ {
+ current->name+="-p";
+ }
lineCount();
lastClassTemplSpecContext = ClassVar;
- BEGIN( ClassTemplSpec );
+ if (insideObjC) // protocol list
+ {
+ BEGIN( ObjCProtocolList );
+ }
+ else // C++ template specialization
+ {
+ BEGIN( ClassTemplSpec );
+ }
}
+<ObjCProtocolList>"<" {
+ insideProtocolList=TRUE;
+ BEGIN( Bases );
+ }
<ClassTemplSpec>">"({BN}*"::"{BN}*{SCOPENAME})? {
current->name += yytext;
lineCount();
@@ -3386,8 +3406,12 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
<CompoundName>{SCOPENAME} {
current->name = yytext ;
lineCount();
- if (current->section == Entry::PROTOCOL_SEC ||
- current->section == Entry::OBJCIMPL_SEC)
+ if (current->section == Entry::PROTOCOL_SEC)
+ {
+ current->name += "-p";
+ }
+ if (current->section == Entry::PROTOCOL_SEC /*||
+ current->section == Entry::OBJCIMPL_SEC*/)
{
unput('{'); // fake start of body
}
@@ -3440,21 +3464,9 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
}
else
{
- //if (isTypedef)
- //{
- // //QCString dest = extractName(current->name);
- // //printf("3>>>>>>>>>> adding %s->%s\n",yytext,current->name.data());
- // QCString scope;
- // if (current_root->section & Entry::SCOPE_MASK) scope=current_root->name;
- // Doxygen::typedefDict.insert(yytext,new TypedefInfo(current->name,scope));
- // //current->extends->append(
- // // new BaseInfo(yytext,Public,Normal)
- // // );
- //}
current->type += ' ' ;
current->type += current->name ;
current->name = yytext ;
- //BEGIN( FindMembers );
}
}
<ClassVar>[(\[] {
@@ -3532,19 +3544,8 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
<BasesProt>{BN} { lineCount(); }
<BasesProt>. { unput(*yytext); BEGIN(Bases); }
<Bases>("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID} {
- //QCString bName = yytext;
- //bName = bName.stripWhiteSpace();
- //bool globalScope = bName.at(0)==':' && baseName.isEmpty();
- //if (!globalScope)
- // baseName += bName;
- //else
- // baseName += (bName.data()+2);
baseName+=yytext;
current->args += ' ';
- //if (!globalScope)
- // current->args += bName;
- //else
- // current->args += (bName.data()+2);
current->args += yytext;
}
<Bases>{BN}*{ID}("."{ID})* { // Java style class
@@ -3553,16 +3554,17 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
current->args += ' ';
current->args += name;
}
-<Bases>^{B}*/[\-+] {
- if (!insideObjC)
- {
+<ClassVar,Bases>\n/{BN}* {
+ if (!insideObjC)
+ {
REJECT;
}
else
{
- unput('{'); // insert start of fake body
+ yyLineNr++;
+ unput('{');
}
- }
+ }
<ClassVar,Bases>"@end" { // empty ObjC interface
unput('d'); // insert fake body: {}@end
unput('n');
@@ -3577,11 +3579,19 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
specName = &current->name;
BEGIN ( Specialization );
}
-<Bases>"<" { baseName += *yytext;
+<Bases>"<" {
sharpCount=1;
lastSkipSharpContext = YY_START;
- specName = &baseName;
- BEGIN ( Specialization );
+ if (insideObjC) // start of protocol list
+ {
+ unput(',');
+ }
+ else // template specialization
+ {
+ baseName += *yytext;
+ specName = &baseName;
+ BEGIN ( Specialization );
+ }
}
<Specialization>"<" { *specName += *yytext;
sharpCount++;
@@ -3606,22 +3616,46 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
<SkipRound>")" { if (--roundCount<=0)
BEGIN ( lastSkipRoundContext );
}
-<Bases>","|({BN}+"implements"{BN}*) { lineCount();
- current->args += ',' ;
+<Bases>","|">"|({BN}+"implements"{BN}*) { lineCount();
+ if (insideProtocolList)
+ {
+ baseName+="-p";
+ }
+ else
+ {
+ current->args += ',' ;
+ }
current->name = removeRedundantWhiteSpace(current->name);
if (!baseName.isEmpty())
+ {
current->extends->append(
new BaseInfo(baseName,baseProt,baseVirt)
);
+ }
if (current->section==Entry::INTERFACE_SEC ||
insideJava || insidePHP || insideCS ||
insideD || insideObjC)
+ {
baseProt=Public;
+ }
else
+ {
baseProt=Private;
+ }
baseVirt=Normal;
baseName.resize(0);
- BEGIN(BasesProt);
+ if (*yytext=='>')
+ { // end of a ObjC protocol list
+ insideProtocolList=FALSE;
+ }
+ else
+ {
+ if (*yytext==',' && insideObjC) // Begin of protocol list
+ {
+ insideProtocolList=TRUE;
+ }
+ BEGIN(BasesProt);
+ }
}
<Bases>{B}*"{"{B}* { current->fileName = yyFileName ;
current->startLine = yyLineNr ;
diff --git a/src/tagreader.cpp b/src/tagreader.cpp
index f3b5ee8..d8df9f8 100644
--- a/src/tagreader.cpp
+++ b/src/tagreader.cpp
@@ -950,6 +950,7 @@ void TagFileParser::buildMemberList(Entry *ce,QList<TagMemberInfo> &members)
else if (tmi->kind=="typedef")
{
me->section = Entry::VARIABLE_SEC; //Entry::TYPEDEF_SEC;
+ me->type.prepend("typedef ");
me->mtype = Method;
}
else if (tmi->kind=="enumeration")
@@ -975,6 +976,7 @@ void TagFileParser::buildMemberList(Entry *ce,QList<TagMemberInfo> &members)
else if (tmi->kind=="friend")
{
me->section = Entry::FUNCTION_SEC;
+ me->type.prepend("friend ");
me->mtype = Method;
}
else if (tmi->kind=="dcop")
diff --git a/src/translator_hu.h b/src/translator_hu.h
index ee6a438..ab61b18 100644
--- a/src/translator_hu.h
+++ b/src/translator_hu.h
@@ -21,15 +21,32 @@
*
* Extended, revised and updated by
* Ákos Kiss <akiss@users.sourceforge.net>
+ *
+ * Further extended, revised and updated by
+ * Tamási Ferenc <tf551@hszk.bme.hu>
*/
#ifndef TRANSLATOR_HU_H
#define TRANSLATOR_HU_H
#include "translator.h"
+#include "../qtools/qdatetime.h"
class TranslatorHungarian : public Translator
{
+ private:
+ const char * zed(char c)
+ {
+ switch (c & ~('a' ^ 'A')) {
+ case 'B': case 'C': case 'D': case 'F': case 'G':
+ case 'H': case 'J': case 'K': case 'L': case 'M':
+ case 'N': case 'P': case 'Q': case 'R': case 'S':
+ case 'T': case 'V': case 'W': case 'X': case 'Z':
+ return " ";
+ default:
+ return "z ";
+ }
+ }
public:
// --- Language control methods -------------------
@@ -110,12 +127,9 @@ class TranslatorHungarian : public Translator
QCString trIncludingInheritedMembers()
{ return " osztály tagjainak teljes listája, az örökölt tagokkal együtt."; }
- /*! this is put at the author sections at the bottom of man pages.
- * parameter s is name of the project name.
- */
QCString trGeneratedAutomatically(const char *s)
{ QCString result="Ezt a dokumentációt a Doxygen készítette ";
- if (s) result+=(QCString)" a(z) "+s+(QCString)" projekthez";
+ if (s) result+=(QCString)" a" + zed(s[0])+s+(QCString)" projekthez";
result+=" a forráskódból.";
return result;
}
@@ -512,7 +526,7 @@ class TranslatorHungarian : public Translator
/*! this text is put before a class diagram */
QCString trClassDiagram(const char *clName)
{
- return (QCString)"A(z) "+clName+" osztály származási diagramja:";
+ return (QCString)"A"+zed(clName[0])+clName+" osztály származási diagramja:";
}
/*! this text is generated when the \\internal command is used. */
@@ -835,12 +849,12 @@ class TranslatorHungarian : public Translator
/*! this text is put before a collaboration diagram */
QCString trCollaborationDiagram(const char *clName)
{
- return (QCString)"A(z) "+clName+" osztály együttműködési diagramja:";
+ return (QCString)"A"+zed(clName[0])+clName+" osztály együttműködési diagramja:";
}
/*! this text is put before an include dependency graph */
QCString trInclDepGraph(const char *fName)
{
- return (QCString)"A(z) "+fName+" definíciós fájl függési gráfja:";
+ return (QCString)"A"+zed(fName[0])+fName+" definíciós fájl függési gráfja:";
}
/*! header that is put before the list of constructor/destructors. */
QCString trConstructorDocumentation()
diff --git a/src/util.cpp b/src/util.cpp
index 5cc3ca8..c535634 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -368,12 +368,8 @@ QCString generateMarker(int id)
return result;
}
-/*! strip part of \a path if it matches
- * one of the paths in the Config_getList("STRIP_FROM_PATH") list
- */
-QCString stripFromPath(const QCString &path)
+static QCString stripFromPath(const QCString &path,QStrList &l)
{
- QStrList &l = Config_getList("STRIP_FROM_PATH");
const char *s=l.first();
while (s)
{
@@ -387,6 +383,22 @@ QCString stripFromPath(const QCString &path)
return path;
}
+/*! strip part of \a path if it matches
+ * one of the paths in the Config_getList("STRIP_FROM_PATH") list
+ */
+QCString stripFromPath(const QCString &path)
+{
+ return stripFromPath(path,Config_getList("STRIP_FROM_PATH"));
+}
+
+/*! strip part of \a path if it matches
+ * one of the paths in the Config_getList("INCLUDE_PATH") list
+ */
+QCString stripFromIncludePath(const QCString &path)
+{
+ return stripFromPath(path,Config_getList("STRIP_FROM_INC_PATH"));
+}
+
/*! try to determine if \a name is a source or a header file name by looking
* at the extension. A number of variations is allowed in both upper and
* lower case) If anyone knows or uses another extension please let me know :-)
@@ -759,19 +771,20 @@ bool accessibleViaUsingNamespace(const NamespaceSDict *nl,
*/
int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item)
{
- //printf("<isAccesibleFrom(%s,%s)\n",scope->name().data(),item->name().data());
- QCString key=scope->name()+"+"+item->name();
+ //fprintf(stderr,"<isAccesibleFrom(scope=%s,item=%s itemScope=%s)\n",
+ // scope->name().data(),item->name().data(),item->getOuterScope()->name().data());
+ QCString key=scope->name()+"+"+item->qualifiedName();
int *pval=g_accessibilityCache.find(key);
int result=0; // assume we found it
int i;
if (pval) // value was cached
{
- //printf("> found cached value=%d\n",*pval);
+ //fprintf(stderr,"> found cached value=%d\n",*pval);
return *pval;
}
if (item->getOuterScope()==scope)
{
- //printf("> found it\n");
+ //fprintf(stderr,"> found it\n");
}
else if (scope==Doxygen::globalScope)
{
@@ -780,17 +793,17 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item)
ClassSDict *cl = fileScope->getUsedClasses();
if (accessibleViaUsingClass(cl,fileScope,item))
{
- //printf("> found via used class\n");
+ //fprintf(stderr,"> found via used class\n");
goto done;
}
NamespaceSDict *nl = fileScope->getUsedNamespaces();
if (accessibleViaUsingNamespace(nl,fileScope,item))
{
- //printf("> found via used namespace\n");
+ //fprintf(stderr,"> found via used namespace\n");
goto done;
}
}
- //printf("> reached global scope\n");
+ //fprintf(stderr,"> reached global scope\n");
result=-1; // not found in path to globalScope
}
else // keep searching
@@ -802,19 +815,19 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item)
ClassSDict *cl = nscope->getUsedClasses();
if (accessibleViaUsingClass(cl,fileScope,item))
{
- //printf("> found via used class\n");
+ //fprintf(stderr,"> found via used class\n");
goto done;
}
NamespaceSDict *nl = nscope->getUsedNamespaces();
if (accessibleViaUsingNamespace(nl,fileScope,item))
{
- //printf("> found via used namespace\n");
+ //fprintf(stderr,"> found via used namespace\n");
goto done;
}
}
// repeat for the parent scope
i=isAccessibleFrom(scope->getOuterScope(),fileScope,item);
- //printf("> result=%d\n",i);
+ //fprintf(stderr,"> result=%d\n",i);
result= (i==-1) ? -1 : i+1;
}
done:
@@ -838,7 +851,7 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item,
//printf("<isAccesibleFrom(%s,%s,%s)\n",scope?scope->name().data():"<global>",
// item?item->name().data():"<none>",
// explicitScopePart.data());
- QCString key=scope->name()+"+"+item->name()+"+"+explicitScopePart;
+ QCString key=scope->name()+"+"+item->qualifiedName()+"+"+explicitScopePart;
int *pval=g_accessibilityCache.find(key);
int result=0; // assume we found it
if (pval) // value was cached
@@ -1019,6 +1032,7 @@ ClassDef *getResolvedClassRec(Definition *scope,
{
//printf(" found type %x name=%s\n",
// d->definitionType(),d->name().data());
+
// only look at classes and members
if (d->definitionType()==Definition::TypeClass ||
d->definitionType()==Definition::TypeMember)
@@ -1042,9 +1056,10 @@ ClassDef *getResolvedClassRec(Definition *scope,
else if (d->definitionType()==Definition::TypeMember)
{
MemberDef *md = (MemberDef *)d;
+ //printf(" member isTypedef()=%d\n",md->isTypedef());
if (md->isTypedef()) // d is a typedef
{
- //printf("found typedef!\n");
+ //printf(" found typedef!\n");
QCString spec;
ClassDef *typedefClass = newResolveTypedef(fileScope,md,&spec);
@@ -1056,13 +1071,17 @@ ClassDef *getResolvedClassRec(Definition *scope,
{
minDistance=distance;
bestMatch = typedefClass;
- //printf("bestTypeDef=%p\n",md);
+ //printf(" bestTypeDef=%p\n",md);
bestTypedef = md;
bestTemplSpec = spec;
}
}
}
} // if definition accessible
+ else
+ {
+ //printf(" Not accessible!\n");
+ }
} // if definition is a class or member
} // foreach definition
if (pTypeDef)
@@ -1683,6 +1702,11 @@ QCString yearToString()
int minClassDistance(ClassDef *cd,ClassDef *bcd,int level)
{
+ if (bcd->categoryOf()) // use class that is being extended in case of
+ // an Objective-C category
+ {
+ bcd=bcd->categoryOf();
+ }
if (cd==bcd) return level;
if (level==256)
{
@@ -3425,7 +3449,7 @@ QCString showFileDefMatches(const FileNameDict *fnDict,const char *n)
//----------------------------------------------------------------------
-QCString substituteKeywords(const QCString &s,const char *title)
+QCString substituteKeywords(const QCString &s,const char *title,const QCString &relPath)
{
QCString result = s.copy();
if (title) result = substitute(result,"$title",title);
@@ -3435,6 +3459,7 @@ QCString substituteKeywords(const QCString &s,const char *title)
result = substitute(result,"$doxygenversion",versionString);
result = substitute(result,"$projectname",Config_getString("PROJECT_NAME"));
result = substitute(result,"$projectnumber",Config_getString("PROJECT_NUMBER"));
+ result = substitute(result,"$relpath$",relPath);
return result;
}
diff --git a/src/util.h b/src/util.h
index e27b75e..1ed34c5 100644
--- a/src/util.h
+++ b/src/util.h
@@ -154,9 +154,10 @@ 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);
+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);
diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp
index 5d50020..423da30 100644
--- a/src/xmldocvisitor.cpp
+++ b/src/xmldocvisitor.cpp
@@ -26,6 +26,7 @@
#include "dot.h"
#include "message.h"
#include "util.h"
+#include <qfileinfo.h>
XmlDocVisitor::XmlDocVisitor(QTextStream &t,BaseCodeDocInterface &ci)
: DocVisitor(DocVisitor_XML), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE)
@@ -213,6 +214,15 @@ void XmlDocVisitor::visit(DocInclude *inc)
if (m_hide) return;
switch(inc->type())
{
+ case DocInclude::IncWithLines:
+ {
+ m_t << "<programlisting>";
+ QFileInfo cfi( inc->file() );
+ FileDef fd( cfi.dirPath(), cfi.fileName() );
+ parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd);
+ m_t << "</programlisting>";
+ }
+ break;
case DocInclude::Include:
m_t << "<programlisting>";
parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile());
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index f28bf7a..ef45139 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -590,6 +590,15 @@ static void generateXMLForMember(MemberDef *md,QTextStream &ti,QTextStream &t,De
t << "\"";
}
+ else if (md->memberType() == MemberDef::Property)
+ {
+ t << " readable=\"";
+ if (md->isReadable()) t << "yes"; else t << "no";
+ t << "\" writable=\"";
+ if (md->isWritable()) t << "yes"; else t << "no";
+ t << "\"";
+ }
+
t << ">" << endl;