Doxygen: specify layout per file - doxygen

I would like to change the page layout for a single source file. The other pages should be generated as before.
Other option would be to generate a seperate page referencing the relevant content from that source file.
To make it a little more concrete, I have the following file and would like to generate a documentation file only including these comments without the printing of includes, etc.
And as said this behavior is only intended for this single source file.
/**
* TreeNode
*xxx
*/
class TreeNode
/**
* TreeNode2
*xxx
*/
class TreeNode2
Thanks a lot!

I think your best approach is to exclude the bits you don't want by surrounding those parts in the file with #cond and #endcond markers. (The #if 0 of doxygen.)
In that way your file processing won't be complicated with file-specific layouts (which I'm not sure is possible anyway) and the 'special' handling of that file is visible within that file's content.

Related

Can I get Doxygen to use untagged comments, on function prototypes?

The company I'm working for does not use Doxygen, and in their coding standard explicitly prohibits "parseable comment styles such as javadoc, etc".
However, I've still found it very useful to run Doxygen myself just so I can see the class structure, and get nice per-class documentation of all the methods the a class has, including inherited ones.
The company does document the classes in the header files, with simple comments above each method declaration. It would be very useful if I could configure Doxygen to treat these comments as the function descriptions, even though they don't start with any Doxygen markers.
So: is it possible to get Doxygen to treat comments on the line above declarations as if they are the description for that item even when the comment is not marked with Doxygen's "parse this comment" markers?
The next best thing is to click on the #include <foo.h> links at the top of the class file to jump to the file itself, which I have been using. That doesn't help for seeing all of a derived class's methods in one place, though.
When the comments above the methods have only "normal" comments i.e. with /* or // the best thing to do would be that you write a small filter (see e.g. INPUT_FILTER with sed or awk or ... ) in which you convert (all?) /* / // comments into /** / /// so the comment blocks are parsed by doxygen. The result is not as nice as with "full" doxygen comments.
It is just a workaround and can lead to unexpected results when the INPUT_FILTER does not exclude e.g. // inside strings from consideration.

Doxygen (or other tool) document classes and namespaces similarly if at the same level

I have a bunch of namespaces (containing free functions) and classes (containing member functions, obviously), each of which has a Doxygen comment at the top level and some Doxygen comments for its members. They're within a top-level namespace (one for the whole project) and secondary namespaces (to break the project into packages). Like this:
proj/pkg1/foo.hpp: class proj::pkg1::Foo
proj/pkg1/bar.hpp: class proj::pkg1::Bar
proj/pkg1/baz.hpp: namespace proj::pkg1::Baz
proj/pkg2/one.hpp: class proj::pkg2::One
proj/pkg2/two.hpp: namespace proj::pkg2::Two
I don't have any #file comments. They'd be totally redundant, because there's already exactly one main comment per component, which is attached to the main class or namespace.
I tried running this through Doxygen, and the result is a mess:
The namespaces and classes are separated into two different hierarchies, both in the header row and the navigation panel. But I want them all in a single tree, because e.g. pkg2::One belongs alongside pkg2::Two.
The main hierarchy of namespaces is buried three levels down the navigation panel (Project name -> namespaces -> namespace list). It's next to "Namespace Members" - who uses that!?
There's another hierarchy for the files (and directories). This is redundant because these exactly match the hierarchy of namespaces (and classes).
This is digressing a bit now, but I'd also like to add comments to the package namespaces. These have the same problem of separating classes and namespaces (not such a big deal) but also show up various free functions e.g. operator<<(proj::pkg2::One.
Is there any way to clean things up a bit? Maybe with Sphinx and Breathe?
Example screen shot
Here is what Doxygen produces by default on the above code (it doesn't even mention Baz and Two!), and what I prefer it to look like:
This is a particularly horrible hack, but I mention it for the record. You could decide that classes are dealt with best by Doxygen, and relabel all the component namespaces (the third-level ones) to classes. Like this:
namespace proj {
namespace pkg1 {
/// #brief The Doxygen comment goes here.
#ifdef DOXYGEN
class
#else
namespace
#endif
Baz {
Then set PREDEFINED = DOXYGEN in the Doxyfile.
Obviously, the drawbacks to the this are that it looks ugly as sin in the source code, and it's confusing that it shows up as a "class" in the documentation.
To get the ball rolling, here's a possible solution:
Change expectations a bit: instead of hoping for the two level structure to be presented to readers all in one go, put up with part of it presented at a time. Make the user click through a separate page for each namespace in the tree:
The documentation page for the proj namespace shows all the packages it contains (i.e. in the example it shows namespaces pkg1 and pkg2).
Each package namespace page shows all of the classes and component namespaces in it (in separate lists, which is a little annoying, but at least all the stuff for each package is together).
You can hide the tree view with GENERATE_TREEVIEW=NO and hide the header row DISABLE_INDEX=YES.
The mainpage can just be a link to the top-level proj namespace page (with the usual content of the main page moved to the proj detailed description) with code like this:
/**
#mainpage
#ref proj "Click here for the proj documentation"
*/
A slight variation is to manually list the packages in the main page with code like this and bypass the proj namespace page. This would work well for a project that doesn't have an overall top-level namespace, or where you want finer control over the main page.
/**
#mainpage
Packages:
- #ref proj::pkg1 #n #copybrief proj::pkg1
- #ref proj::pkg2 #n #copybrief proj::pkg2
*/

What is the correct way to embed a resource in a reusable MFC class?

I am writing a C++ (MFC in particular) class which uses an external .gif image file and produces another image file after some processing. It would be nice if the initial image could be embedded in the code somehow. I have read in MSDN about using multiple .rc files and the whole thing seems quite complicated.
I would like to know from people who have gone through this before how to handle this problem.
EDIT : Sorry I was not clear. The class I am writing should be standalone, so I could use it again. If I put the image in a resource file, then the class will not compile if used in a fresh project.
You cannot embedd MFC resources inside a class or similar C++ container. They can only be embedded in DLL or EXE files - in a separate section of the produced binary. Since you want your class to be reusable, you must put it in a DLL. Hence, you must tag your class with the AFX_EXT_CLASS keyword.
There are two solutions.
Solution #1:
Create an MFC DLL project (MFC Extension DLL). Call it MyLibrary or whatever.
Put all your standalone classes in this DLL.
Embed all necessary resources.
Let your classes load resources from the HINSTANCE of your DLL as described below.
There are several ways to retrieve the HINSTANCE of your DLL. If you ask me, the best solution is to grab it in DllMain. This is done automatically if you choose the MFC Extension DLL configuration:
static AFX_EXTENSION_MODULE MyLibDLL = { NULL, NULL }; // Make this variable global!
// Then access the hInstance as follows:
LoadResource(MyLibDLL.hModule, ...)
Solution #2:
Store your resource as a byte buffer. Or better, convert it to Base64 and store it as an ASCII string. But remember not to blow the stack! Keep your resources small or increase the stack size in your project settings. Example:
const char *encodedResource = "SGVsbG8gd29ybGQh";
char *data = decode(encodedResource);
foo(data);
In the solution explorer go to resource view, Right click and click Add Resource then click Import and add the gif file. Now you can use your Resource ID to access the gif file in your code.
Just adding the file to a resource doesn't embed the file in the actual resource file it just links to the file. If you open your .rc file you'll see it says something like:
IDB_GIF_MYIMAGE GIF "artwork\\mygif.gif"
During the compilation face the resource will be included in the EXE, which you reference using the resource id IDB_GIF_MYIMAGE. You can reference the same file in other projects without having to duplicate the file.
To embed an image (or any other type of binary data) into your class without using resource files, use the bin2c utility, for example you can download it from here: http://www.opensource.apple.com/source/libpcap/libpcap-16/libpcap/msdos/bin2c.c . Running this on a file will produce what is basically a static array with the bytes of the file as members of that array. Stuff this array into a .h file (or put it in the header of your class, or make it a static member...) and then you will have that file available in-memory without having to use LoadResource() and its brethren.
If you want to use this with CImage::Load(), you will have to write your own class that derives from IStream, and implement a few of the methods in a way so that they 'read' from memory. I don't know of any ways to let CImage decode an image from an in-memory representation of a gif file.
I think the best solution is just to document that to use the class you must also import to your project a certain .gif file and give it a certain expected identifier (e.g. IDB_MYCLASS_MYGIF). You can then use the preprocessor to detect if the resource has been correctly added, e.g.:
#ifndef IDB_MYCLASS_MYGIF
#error Make sure you import mygif.gif to the project. See docs for more info.
#endif
This will prevent the class compiling until the user imports the image properly. Alternatively you could just use #ifdefs to fall back to code which does not use the default image if it is not provided.
Have a look at the CRuntimeDialog class presented in http://www.codeproject.com/Articles/5371/ToDoList-6-5-4-Feature-Release-An-effective-and-fl . It provides a way to create a dialog from the string that makes up the resource definition.

Doxygen autolink not working to global enum types

I am trying to use Doxygen Automatic link generation to document some enum types. However, it is not generating links for the global enum types. It does generates links for the global struct types. Is there something I am missing? I am using the example provided on the link above. As required, I have documented the file in which the types are defined.
update1: I am using Doxygen version 1.6.3
update2: global structs are ok
Yeah, I had that same issue; i think doxygen thinks they are private or something stupid like that. Try using the \public. Don't forget to do the /*! on the first line
/*! \public
* Enum description goes here
*/
typedef enum {
/**
* Printer control language ZPL
*/
PRINTER_LANGUAGE_ZPL,
/**
* Printer control language CPCL
*/
PRINTER_LANGUAGE_CPCL
} PrinterLanguage;
I was having the same issue. Some header files generated a link for enums and other header files did not. You must explicitly document the file.
Here is a excerpt from this page int the documentation.
http://www.doxygen.nl/manual/docblocks.html#memberdoc
To document a global C function, typedef, enum or preprocessor
definition you must first document the file that contains it (usually
this will be a header file, because that file contains the information
that is exported to other source files).
Attention
Let's repeat that, because it is often overlooked: to document global objects (functions, typedefs, enum, macros, etc), you must
document the file in which they are defined. In other words, there
must at least be a
/*! \file */
or a
/** #file */
line in this file.

Exclude some classes from doxygen documentation

I am building a Qt based project, and many Qt classes are found in the target documentation.
How can I tell Doxygen to disable documentation generation for some classes? For Q.*?
Working under the assumption that what you have is something like this: (The question is a little unclear in this regard)
/**
* Some documentation for class X
*/
class X: public osg::Drawable {
...
}
And your problem is that you want to include documentation for class X, but not for class osg::Drawable, the proper technique is to use EXCLUDE_SYMBOLS. For example, in the case above use
EXCLUDE_SYMBOLS = osg::Drawable
If you want to be slightly more rigorous, you can use
EXCLUDE_SYMBOLS = osg::Drawable \
Drawable
Wild-cards are also allowed, so this will also work
EXCLUDE_SYMBOLS = osg::*
If \internal tag does not work, you can try \cond ... \endcond tags for marking a portion of code to be hidden from Doxygen.
EDIT
If you want to exclude specific files, you can use EXCLUDE_PATTERNS variable in Doxyfile configuration file.
Its not the best way but one can mark some portion of the documentation (class, members, ...) with the private. This prevents the piece of code from being included in the output documentation. (I use this to hide copy/move constructors/operators from appearing in the API documentation.)
/*!
* \brief This is included.
*/
class API
{
public:
/*!
* \brief So is this.
*/
API() noexcept;
/// \private
~API() noexcept; /* But this not, though technically public. */
private:
int m_version; /* This is not either. */
}
One should note though that this is a Doxygen extension for PHP, which according to the documentation they should not be used.
For PHP files there are a number of additional commands, that can be used inside classes to make members public, private, or protected even though the language itself doesn't support this notion.
The other option is to use the solution mouviciel provided, but it requires at least two lines.
Though not the correct answer for the detailed question it might be helpful for readers of the question title (like me). It works for classe too!