Commit f08c77a2 authored by Dimitri van Heesch's avatar Dimitri van Heesch

Release-1.3.6-20040413

parent cba24284
DOXYGEN Version 1.3.6-20040324
DOXYGEN Version 1.3.6-20040413
Please read the installation section of the manual
(http://www.doxygen.org/install.html) for instructions.
--------
Dimitri van Heesch (24 March 2004)
Dimitri van Heesch (13 April 2004)
DOXYGEN Version 1.3.6_20040324
DOXYGEN Version 1.3.6_20040413
Please read INSTALL for compilation instructions.
......@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives.
Enjoy,
Dimitri van Heesch (dimitri@stack.nl) (24 March 2004)
Dimitri van Heesch (dimitri@stack.nl) (13 April 2004)
1.3.6-20040324
1.3.6-20040413
......@@ -86,6 +86,7 @@ documentation:
\refitem cmdifnot \\ifnot
\refitem cmdimage \\image
\refitem cmdinclude \\include
\refitem cmdincludelineno \\includelineno
\refitem cmdingroup \\ingroup
\refitem cmdinternal \\internal
\refitem cmdinvariant \\invariant
......@@ -1308,6 +1309,15 @@ ALIASES = "english=\if english" \
\sa section \ref cmdexample "\\example" and \ref cmddontinclude "\\dontinclude".
<hr>
\section cmdincludelineno \includelineno <file-name>
\addindex \\includelineno
This command works the same way as \\include, but will add line
numbers to the included file.
\sa section \ref cmdinclude "\\include".
<hr>
\section cmdline \line ( pattern )
......
......@@ -188,6 +188,7 @@ followed by the descriptions of the tags grouped by category.
\refitem cfg_sort_member_docs SORT_MEMBER_DOCS
\refitem cfg_source_browser SOURCE_BROWSER
\refitem cfg_strip_code_comments STRIP_CODE_COMMENTS
\refitem cfg_strip_from_inc_path STRIP_FROM_INC_PATH
\refitem cfg_strip_from_path STRIP_FROM_PATH
\refitem cfg_subgrouping SUBGROUPING
\refitem cfg_tab_size TAB_SIZE
......@@ -326,16 +327,30 @@ followed by the descriptions of the tags grouped by category.
If the \c FULL_PATH_NAMES tag is set to \c YES then the \c STRIP_FROM_PATH tag
can be used to strip a user-defined part of the path. Stripping is
only done if one of the specified strings matches the left-hand part of the
path.
path. The tag can be used to show relative paths in the file list.
If left blank the directory from which doxygen is run is used as the
path to strip.
\anchor cfg_strip_from_inc_path
<dt>\c STRIP_FROM_INC_PATH
The \c STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
the path mentioned in the documentation of a class, which tells
the reader which header file to include in order to use a class.
If left blank only the name of the header file containing the class
definition is used. Otherwise one should specify the include paths that
are normally passed to the compiler using the -I flag.
\anchor cfg_case_sense_names
<dt>\c CASE_SENSE_NAMES <dd>
\addindex CASE_SENSE_NAMES
If the \c CASE_SENSE_NAMES tag is set to \c NO (the default) then doxygen
If the \c CASE_SENSE_NAMES tag is set to \c NO then doxygen
will only generate file names in lower-case letters. If set to
\c YES upper-case letters are also allowed. This is useful if you have
classes or files whose names only differ in case and if your file system
supports case sensitive file names.
supports case sensitive file names. Windows users are advised to set this
option to NO.
\anchor cfg_short_names
<dt>\c SHORT_NAMES <dd>
......@@ -888,13 +903,17 @@ function's detailed documentation block.
The following commands have a special meaning inside the header:
<code>\$title</code>, <code>\$datetime</code>, <code>\$date</code>,
<code>\$doxygenversion</code>, <code>\$projectname</code>,
<code>\$doxygenversion</code>, <code>\$projectname</code>, and
<code>\$projectnumber</code>.
Doxygen will replace them by respectively
the title of the page, the current date and time, only the current date,
the version number of doxygen, the project name (see \c PROJECT_NAME), or the
project number (see \c PROJECT_NUMBER).
If \c CREATE_SUBDIRS is enabled, the command <code>\$relpath\$</code> can be
used to produce a relative path to the root of the HTML output directory,
e.g. use \$relpath\$doxygen.css, to refer to the standard style sheet.
See also section \ref doxygen_usage for information on how to generate
the default header that doxygen normally uses.
......
......@@ -23,7 +23,7 @@ text fragments, generated by doxygen, can be produced in languages other
than English (the default). The output language is chosen through the
configuration file (with default name and known as Doxyfile).
Currently (version 1.3.6-20040222), 28 languages
Currently (version 1.3.6-20040413), 28 languages
are supported (sorted alphabetically):
Brazilian Portuguese, Catalan, Chinese, Chinese Traditional, Croatian,
Czech, Danish, Dutch, English, Finnish, French, German, Greek,
......
Summary: A documentation system for C/C++.
Name: doxygen
Version: 1.3.6_20040324
Version: 1.3.6_20040413
Release: 1
Epoch: 1
Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz
......
......@@ -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;
}
......
......@@ -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.
......
......@@ -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();
......
......@@ -105,6 +105,7 @@ CommandMap cmdMap[] =
{ "enddot", CMD_ENDDOT },
{ "manonly", CMD_MANONLY },
{ "endmanonly", CMD_ENDMANONLY },
{ "includelineno", CMD_INCWITHLINES },
{ 0, 0 }
};
......
......@@ -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
......
......@@ -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_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,6 +1695,8 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
{
g_insideObjC = FALSE;
}
if (g_insideBody)
{
g_theVarContext.popScope();
int *scope = g_scopeStack.pop();
......@@ -1333,6 +1704,8 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"
{
popScope();
}
g_insideBody=FALSE;
}
startFontClass("keyword");
g_code->codify(yytext);
......@@ -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);
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();
......
......@@ -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">
......
......@@ -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"
......
......@@ -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");
......
......@@ -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;
......
......@@ -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) :
......
......@@ -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,9 +5743,25 @@ 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
......@@ -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;
}
......
......@@ -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
......
......@@ -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,
......
......@@ -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 << "</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
{
......
......@@ -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;
......
......@@ -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"); }
......
......@@ -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())
......
......@@ -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());
......
......@@ -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;
......
......@@ -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();
......
......@@ -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>");
......
......@@ -1866,8 +1866,8 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
g_defText += ' '; g_yyLineNr++;
}
<DefineText>\n {
g_defLitText+=yytext;
QCString comment=extractTrailingComment(g_defLitText);
g_defLitText+=yytext;
if (!comment.isEmpty())
{
outputArray(comment,comment.length());
......
......@@ -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;
......
......@@ -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,6 +367,18 @@ void RTFDocVisitor::visit(DocInclude *inc)
if (m_hide) return;
switch(inc->type())
{
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;
......
......@@ -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;
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,14 +3554,15 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
current->args += ' ';
current->args += name;
}
<Bases>^{B}*/[\-+] {
<ClassVar,Bases>\n/{BN}* {
if (!insideObjC)
{
REJECT;
}
else
{
unput('{'); // insert start of fake body
yyLineNr++;
unput('{');
}
}
<ClassVar,Bases>"@end" { // empty ObjC interface
......@@ -3577,12 +3579,20 @@ 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;
if (insideObjC) // start of protocol list
{
unput(',');
}
else // template specialization
{
baseName += *yytext;
specName = &baseName;
BEGIN ( Specialization );
}
}
<Specialization>"<" { *specName += *yytext;
sharpCount++;
}
......@@ -3606,23 +3616,47 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
<SkipRound>")" { if (--roundCount<=0)
BEGIN ( lastSkipRoundContext );
}
<Bases>","|({BN}+"implements"{BN}*) { lineCount();
<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);
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 ;
current->name = removeRedundantWhiteSpace(current->name);
......
......@@ -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")
......
......@@ -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()
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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());
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment