Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doxygen copydoc tag to reuse code examples

I want to reuse a block of example code using the \copydoc tag.

To explain the problem. Let's say I have two documented functions:

/** Aquires resource. */
Resource* AquireResource( int id );

/** Releases resource.*/
void ReleaseResource( Resource* res );

In many cases I want to put in a small code example of how to use the function in a context, which often involves using a range of functions which all might be sufficiently depicted by the same code example, for instance:

/** Aquires resource.
 *
 * \par Example:
 * \code
 * Resource* res = AquireResource( 42 );
 * ReleaseResource( res );
 * \endcode
 */
Resource* AquireResource( int id );

/** Releases resource.
 *
 * \par Example:
 * \code
 * Resource* res = AquireResource( 42 );
 * ReleaseResource( res );
 * \endcode
 */
void ReleaseResource( Resource* res );

So the code example is duplicated, not good. I want to use copydoc, something like this:

/** \page ResourceExampleTag
 * \code
 * Resource* res = AquireResource( 42 );
 * ReleaseResource( res );
 * \endcode
 */    

/** Aquires resource.
 *
 * \par Example:
 * \copydoc ResourceExampleTag
 */
Resource* AquireResource( int id );

/** Releases resource.
 *
 * \par Example:
 * \copydoc ResourceExampleTag
 */
void ReleaseResource( Resource* res );

I.e. code example in one place, reused in other places.

This is actually as far as I have gotten, but I'm not satisfied with it since I don't know how to hide the dummy page 'ResourceExampleTag' I'm creating to copy from. So somewhere in the resulting documentation there's a page with some code completely out of context. As far as I can see the thing here is to find a tag which can be referenced by copydoc and which doesn't render any content on itself. However, that's just my line of thought, there might be far better ones.

I can also mention that I (for several reasons I won't bother to go into) don't wish to use the \example tag with external example code files.

Thanks.

like image 907
sharkin Avatar asked Feb 15 '11 11:02

sharkin


People also ask

How do I show code in doxygen?

You can put example source code in a special path defined in the doxygen config under EXAMPLE_PATH , and then insert examples with the @example tag. Doxygen will then generate an extra page containing the source of the example. It will also set a link to it from the class documentation containing the example tag.

What is a doxygen tag?

Doxytag is a small command line based utility. It can generate tag files. These tag files can be used with doxygen to generate references to external documentation (i.e. documentation not contained in the input files that are used by doxygen).

What is doxygen used for?

Doxygen is the de facto standard tool for generating documentation from annotated C++ sources, but it also supports other popular programming languages such as C, Objective-C, C#, PHP, Java, Python, IDL (Corba, Microsoft, and UNO/OpenOffice flavors), Fortran, and to some extent D.


2 Answers

This works for me:

class MyClass
{
  public:
    /**
     * @class hide_commonstuff
     * @par Example:
     * @code
     * The common example
     * @endcode
     */

    /**
     * First function.
     *
     * @copydoc hide_commonstuff
     */
    void first();

    /**
     * Second function.
     *
     * @copydoc hide_commonstuff
     */
    void second();
};

and then in the doxygen configuration you set EXCLUDE_SYMBOLS = hide_*

The the documentation is copied from the hide_commonstuff but this class is not shown in the class list.

Also: there needs to be a blank line before @copydoc or else it does not work (sometimes, not always...)

like image 50
rve Avatar answered Sep 17 '22 21:09

rve


I've found the @snippet command to be more useful for creating examples inline like you are trying to do. Basically I have a source file for my examples, my_examples.cpp

/// [exampleMyFirst]
void foo(void)
{
    Resource* foo = AquireResource(42);
    ReleaseResource(foo);
    foo = nullptr; //Or NULL
}
/// [exampleMyFirst]

/// [exampleTwo]
void bar(void)
{
    std::cout << "Unrelated to my first example." << std::endl;
}
/// [exampleTwo]

Then in the doxygen documentation block for your function use @snippet to use the example.

/// Aquires resource.
///
/// @par Example:
/// @snippet my_examples.cpp exampleMyFirst
Resource* AquireResource( int id );

... And of course only after finishing the answer, do I realize you didn't want to use an external file, but since I stumbled upon the question trying to do what I described here, it might be useful to someone!

like image 43
Tim Beaudet Avatar answered Sep 20 '22 21:09

Tim Beaudet