hello Dimitri,
thanks for merging UNO IDL patches :)
i've had some more time to spend on doxygen this week, and results are
looking quite good now (in LibreOffice feature/doxygen branch).
1. there were still a few bugs, fixed by the attached patch
2. one problem i've had is that we have not only the generated
per-entity reference documentation but also another form of
documentation in the form of a large number of Wiki pages, with
links in both directions.
the legacy "autodoc" tool has native support for reading a special
file that essentially contains links into the Wiki that need to be
inserted into the generated per-entity reference documentation.
i've played around a bit and found that i could generate an extra
dummy input file that contains empty definitions, and put the
Wiki links on them as doxygen comments, and feed that as the last
input file (to prevent spurious references to generated file)
and doxygen will combine the docs nicely.
http://cgit.freedesktop.org/libreoffice/core/commit/?h=feature/doxygen&id=b3dbf93c5e18b6f31b11f9bcc08a105b2e0d3b10
3. for the other direction there are some issues... the Wiki
documentation links to the per-entity reference documentation with
some convenient template like;
<idl>com.sun.star.ucb.XContentIdentifierFactory</idl>
to get this to work the target URLs need to be generated
automatically just from the namespace qualified entity name.
this required some changes to doxygen, adding a new PREDICTABLE_URLS
config option, see attached patch.
4. we are currently just a couple weeks away from the LO 4.1 feature
freeze, and i'd like to merge this into the 4.1 release.... which
distributions will package... so we would need a release of doxygen
with all the UNO IDL patches that distros can package as build-dep.
i'll follow up in a separate mail on this.
regards,
michael
>From e457a43287d204e20dd74df27198c0bcb3e30a8f Mon Sep 17 00:00:00 2001
From: Michael Stahl <[email protected]>
Date: Thu, 2 May 2013 00:16:21 +0200
Subject: [PATCH 1/2] UNO IDL: fix some bugs
- support body-less definition of service and singleton:
A complete defintion may look like "service Foo : XFoo;", this is not a
forward declaration and must be documented.
- display "optional" inheritance as "Protected" (looks better)
- fix lookup of interface/service members
For an example like:
published service Pipe
{
interface com::sun::star::io::XPipe;
interface ::com::sun::star::io::XPipe;
interface XPipe;
};
the second and third one worked but for the first one findClassRelation
doesn't find anything - the isRecursiveBaseClass is always true,
and with no "::" prefix the explicitGlobalScope case is false too,
so add an ugly extra case for this.
---
src/doxygen.cpp | 13 ++++++++++---
src/scanner.l | 33 ++++++++++++++++++++++++++++++++-
2 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 4dd39e3..c956902 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -3094,8 +3094,9 @@ static void addInterfaceOrServiceToServiceOrSingleton(
// add member to the class cd
cd->insertMember(md);
// also add the member as a "base" (to get nicer diagrams)
- // hmm... should "optional" interface/service be handled differently?
- BaseInfo base(rname,Public,Normal);
+ // "optional" interface/service get Protected which turns into dashed line
+ BaseInfo base(rname,
+ (root->spec & (Entry::Optional)) ? Protected : Public,Normal);
findClassRelation(rootNav,cd,cd,&base,0,DocumentedOnly,true)
|| findClassRelation(rootNav,cd,cd,&base,0,Undocumented,true);
// add file to list of used files
@@ -4592,7 +4593,13 @@ static bool findClassRelation(
// ) // Check for base class with the same name.
// // If found then look in the outer scope for a match
// // and prevent recursion.
- if (!isRecursiveBaseClass(rootNav->name(),baseClassName) || explicitGlobalScope)
+ if (!isRecursiveBaseClass(rootNav->name(),baseClassName)
+ || explicitGlobalScope
+ // sadly isRecursiveBaseClass always true for UNO IDL ifc/svc members
+ // (i.e. this is needed for addInterfaceOrServiceToServiceOrSingleton)
+ || (rootNav->lang()==SrcLangExt_IDL &&
+ (rootNav->section()==Entry::EXPORTED_INTERFACE_SEC ||
+ rootNav->section()==Entry::INCLUDED_SERVICE_SEC)))
{
Debug::print(
Debug::Classes,0," class relation %s inherited/used by %s found (%s and %s) templSpec='%s'\n",
diff --git a/src/scanner.l b/src/scanner.l
index 452632b..31d926e 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -5065,7 +5065,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
unput(':');
BEGIN(ClassVar);
}
-<Bases,CompoundName>";" {
+<CompoundName>";" {
current->section = Entry::EMPTY_SEC ;
current->type.resize(0) ;
current->name.resize(0) ;
@@ -5073,6 +5073,37 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
current->argList->clear();
BEGIN( FindMembers ) ;
}
+<Bases>";" {
+ if (insideIDL && (current->spec & (Entry::Singleton |
+ Entry::Service)))
+ {
+ // in UNO IDL a service or singleton may be defined
+ // completely like this: "service Foo : XFoo;"
+ if (!current->name.isEmpty() && !current_root->name.isEmpty())
+ {
+ prependScope();
+ }
+ current->name = current->name.stripWhiteSpace();
+ // there can be only one base class here
+ if (!baseName.isEmpty())
+ {
+ current->extends->append(
+ new BaseInfo(baseName,Public,Normal));
+ baseName.resize(0);
+ }
+ current_root->addSubEntry( current ) ;
+ current = new Entry;
+ }
+ else
+ {
+ current->section = Entry::EMPTY_SEC ;
+ current->type.resize(0) ;
+ current->name.resize(0) ;
+ current->args.resize(0) ;
+ current->argList->clear();
+ }
+ BEGIN( FindMembers ) ;
+ }
<CompoundName>{SCOPENAME}{BN}*/"<" {
sharpCount = 0;
current->name = yytext ;
--
1.8.1.4
>From e661e91c5cc3cc8c32e70e43e898bae986b4abaf Mon Sep 17 00:00:00 2001
From: Michael Stahl <[email protected]>
Date: Fri, 3 May 2013 00:14:43 +0200
Subject: [PATCH 2/2] add PREDICTABLE_URLS configuration option
This allows to predict the generated URL for classes and members from
only the class and member name.
Enumerations get their own page too and are no longer documented on
the namespace page.
---
doc/config.doc | 10 ++++++++++
src/classdef.cpp | 12 +++++++++++-
src/config.xml | 7 +++++++
src/configoptions.cpp | 6 ++++++
src/memberdef.cpp | 13 +++++++++++--
src/namespacedef.cpp | 36 ++++++++++++++++++++++++++++++++----
src/namespacedef.h | 2 +-
7 files changed, 78 insertions(+), 8 deletions(-)
diff --git a/doc/config.doc b/doc/config.doc
index c5aca26..86a96e1 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -241,6 +241,7 @@ followed by the descriptions of the tags grouped by category.
\refitem cfg_perlmod_makevar_prefix PERLMOD_MAKEVAR_PREFIX
\refitem cfg_perlmod_pretty PERLMOD_PRETTY
\refitem cfg_predefined PREDEFINED
+\refitem cfg_predictable_urls PREDICTABLE_URLS
\refitem cfg_project_brief PROJECT_BRIEF
\refitem cfg_project_logo PROJECT_LOGO
\refitem cfg_project_name PROJECT_NAME
@@ -711,6 +712,15 @@ page (for HTML and Man pages) or section (for LaTeX and RTF).
formula: \f$2^{(16+\mbox{LOOKUP\_CACHE\_SIZE})}\f$. The valid range is 0..9, the default is 0,
corresponding to a cache size of \f$2^{16} = 65536\f$ symbols.
+\anchor cfg_predictable_urls
+<dt>\c PREDICTABLE_URLS<dd>
+ \addindex PREDICTABLE_URLS
+ If the \c PREDICTABLE_URLS tag is set to YES, then doxygen will create
+ file names that can be predicted from the namespace qualified class names,
+ and member anchors that can be predicted from the member names.
+ Warning: This assumes no overloading or template specialization is taking
+ place, so it may not be suitable for every input language or project.
+
</dl>
\section config_build Build related options
diff --git a/src/classdef.cpp b/src/classdef.cpp
index dd32918..e32a524 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -199,7 +199,17 @@ void ClassDefImpl::init(const char *defFileName, const char *name,
}
else
{
- fileName=ctStr+name;
+ static bool predictableURLs = Config_getBool("PREDICTABLE_URLS");
+ if (predictableURLs)
+ {
+ QCString fname(name);
+ int index=fname.find('<'); // strip type parameters
+ fileName = (index==-1) ? fname : fname.left(index);
+ }
+ else
+ {
+ fileName=ctStr+name;
+ }
}
exampleSDict = 0;
inherits = 0;
diff --git a/src/config.xml b/src/config.xml
index db51172..7e9b8f7 100644
--- a/src/config.xml
+++ b/src/config.xml
@@ -353,6 +353,13 @@ If the cache is too large, memory is wasted. The cache size is given by this
formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
corresponding to a cache size of 2^16 = 65536 symbols.
' minval='0' maxval='9' defval='0'/>
+ <option type='bool' id='PREDICTABLE_URLS' docs='
+If the PREDICTABLE_URLS tag is set to YES, then doxygen will create
+file names that can be predicted from the namespace qualified class names,
+and member anchors that can be predicted from the member names.
+Warning: This assumes no overloading or template specialization is taking
+place, so it may not be suitable for every input language or project.
+' defval='0'/>
</group>
<group name='Build' docs='Build related configuration options'>
<option type='bool' id='EXTRACT_ALL' docs='
diff --git a/src/configoptions.cpp b/src/configoptions.cpp
index 327c883..3b45e73 100644
--- a/src/configoptions.cpp
+++ b/src/configoptions.cpp
@@ -492,6 +492,12 @@ void addConfigOptions(Config *cfg)
"corresponding to a cache size of 2^16 = 65536 symbols.",
0,9,0
);
+ //----
+ cb = cfg->addBool(
+ "PREDICTABLE_URLS",
+ "If the PREDICTABLE_URLS tag is set to YES, then doxygen will create file names that can be predicted from the namespace qualified class names, and member anchors that can be predicted from the member names. Warning: This assumes no overloading or template specialization is taking place, so it may not be suitable for every input language or project.",
+ FALSE
+ );
//---------------------------------------------------------------------------
cfg->addInfo("Build","Build related configuration options");
//---------------------------------------------------------------------------
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index cdf5686..b2b7562 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -988,6 +988,7 @@ QCString MemberDef::getOutputFileBase() const
{
makeResident();
static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");
+ static bool predictableURLs = Config_getBool("PREDICTABLE_URLS");
QCString baseName;
//printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n",
// name().data(),m_impl->templateMaster,m_impl->group,m_impl->classDef,
@@ -1025,13 +1026,14 @@ QCString MemberDef::getOutputFileBase() const
);
return "dummy";
}
- else if (separateMemberPages)
+ else if (separateMemberPages || predictableURLs)
{
+ // put only enums on separate page when PREDICTABLE_URLS is set
if (getEnumScope()) // enum value, which is part of enum's documentation
{
baseName+="_"+getEnumScope()->anchor();
}
- else
+ else if (separateMemberPages || isEnumerate())
{
baseName+="_"+anchor();
}
@@ -3205,8 +3207,15 @@ static QCString escapeAnchor(const QCString &anchor)
void MemberDef::setAnchor()
{
+ static bool predictableURLs = Config_getBool("PREDICTABLE_URLS");
makeResident();
QCString memAnchor = name();
+ if (predictableURLs)
+ {
+ // assumes name() contains only valid fragment chars
+ m_impl->anc = memAnchor;
+ return;
+ }
if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args;
memAnchor.prepend(definition()); // actually the method name is now included
diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp
index b95cec8..b46e68c 100644
--- a/src/namespacedef.cpp
+++ b/src/namespacedef.cpp
@@ -46,8 +46,21 @@ NamespaceDef::NamespaceDef(const char *df,int dl,int dc,
}
else
{
- fileName="namespace";
- fileName+=name;
+ static int predictable = 2; // means: not initialized
+ // argh... namespace <globalScope> created before Doxyfile is read :(
+ if (predictable == 2 && strcmp(df,"<globalScope>"))
+ {
+ predictable = Config_getBool("PREDICTABLE_URLS") ? 1 : 0;
+ }
+ if (predictable == 1)
+ {
+ fileName = name;
+ }
+ else
+ {
+ fileName="namespace";
+ fileName+=name;
+ }
}
classSDict = new ClassSDict(17);
namespaceSDict = new NamespaceSDict(17);
@@ -629,9 +642,16 @@ void NamespaceDef::writeDocumentation(OutputList &ol)
if (allMemberList) allMemberList->sort();
writeMemberPages(ol);
}
+ else if (Config_getBool("PREDICTABLE_URLS"))
+ {
+ // put enums on separate pages
+ MemberList *enumMemberList = getMemberList(MemberListType_docEnumMembers);
+ if (enumMemberList) enumMemberList->sort(); // is this really needed?
+ writeMemberPages(ol,true);
+ }
}
-void NamespaceDef::writeMemberPages(OutputList &ol)
+void NamespaceDef::writeMemberPages(OutputList &ol, bool onlyEnum)
{
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
@@ -642,7 +662,10 @@ void NamespaceDef::writeMemberPages(OutputList &ol)
{
if (ml->listType()&MemberListType_documentationLists)
{
- ml->writeDocumentationPage(ol,displayName(),this);
+ if (!onlyEnum || ml->listType()==MemberListType_docEnumMembers)
+ {
+ ml->writeDocumentationPage(ol,displayName(),this);
+ }
}
}
ol.popGeneratorState();
@@ -1047,6 +1070,11 @@ void NamespaceDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,cons
void NamespaceDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title)
{
+ static bool predictableURLs = Config_getBool("PREDICTABLE_URLS");
+ if (predictableURLs && (MemberListType_docEnumMembers == lt))
+ {
+ return; // enums get separate pages, see NamespaceDef::writeDocumentation()
+ }
MemberList * ml = getMemberList(lt);
if (ml) ml->writeDocumentation(ol,displayName(),this,title);
}
diff --git a/src/namespacedef.h b/src/namespacedef.h
index ff64107..f119f10 100644
--- a/src/namespacedef.h
+++ b/src/namespacedef.h
@@ -48,7 +48,7 @@ class NamespaceDef : public Definition
void insertUsedFile(const char *fname);
void writeDocumentation(OutputList &ol);
- void writeMemberPages(OutputList &ol);
+ void writeMemberPages(OutputList &ol, bool onlyEnum=false);
void writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const;
void insertClass(ClassDef *cd);
--
1.8.1.4
------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite
It's a free troubleshooting tool designed for production
Get down to code-level detail for bottlenecks, with <2% overhead.
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap2
_______________________________________________
Doxygen-develop mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/doxygen-develop