Project

General

Profile

Guidelines for API documentation

Find the current API doc in HTML form here: http://ftp.osmocom.org/api/latest/

We use doxygen for API documentation, following these guidelines:

Use the /*! (Qt-style) doxygen markers.

Since we are using the AUTOBRIEF feature, always end the first sentence with a full-stop "." to mark the end of the short description.
This allows omitting the \brief markers everywhere.

Never rely on line breaks as semantic separation or to end a sentence, always use proper punctuation. The API doc may be rendered with different line breaks than in the source file.

Locations

Header files usually contain merely function declarations bare of any API docs. The API doc comment should be in a .c file at the definition of a function.

Structs and enums defined in a header file, though, also have their API doc comments in that .h file.

Comments for single-line items like enum values or struct members can be placed on the same line using /*!< Description */.

Grammar

Always use the imperative form, i.e. omit wording like "This function does", and avoid writing documentation that merely mirrors a function's name. For example:

/*! Return a (static) buffer containing a hexdump of the msg.
 * \param[in] msg message buffer
 * \returns a pointer to a static char array
 */
const char *msgb_hexdump(const struct msgb *msg)
{
...

Parameters

All parameters of a function should be documented. Input params are documented with \param[in], where out-parameters (pointers to which returned data is written) are documented with \param[out]. Rarely, a param is both: \param[in,out].

/*! Apply nifty algorithm.
 * \param[in] x0  First factor.
 * \param[in] n   Amount of values to calculate.
 * \param[out] buf  Write calculated values to this buffer.
 *
 * Optional longer function description. */

It is also possible to document parameters without a direction, using merely \param param_name Description, however, it is desirable to always indicate [in], [out] or [inout].

File comments

If a file contains a descriptive comment, this comment should be right at the start of the file, as a doxygen \file section.
The first sentence must be ended by a full stop "." to mark the end of the short description.
The copyright notice shall not be part of such API doc file comment.

/*! \file foo.c
 * Short description. */
/*
 * (C) 2017 ... Copyright not in a doxygen comment
 * license information
 */

or

/*! \file foo.c
 * Short description.
 *
 * More information in multiple lines.
 */
/*
 * (C) 2017 ...
 */

If a file needs no description, it is ok to omit the \file tag entirely. Since we are using EXTRACT_ALL = YES, files lacking a \file tag are still listed in the API docs.

Groups

Doxygen allows grouping elements: a group can include code elements and also entire files.

This works by enclosing the items to be grouped between an opening and a closing marker:

  • A \defgroup initially defines a group, this shall exist only once.
  • More items can be added using an \addtogroup marker.
  • Both have to be closed by "@}".

For example:

/*! \defgroup groupname Short description of the group.
 * @{
 */

struct type_that_belongs_to_group {
 ...
};

void func_that_belongs_to_group()
{
 ...
}

/*! @} */

and

/*! \addtogroup groupname
 * @{
 */

...

/*! @} */

If a file should be added to a group, add a (possibly second) short descriptionless \file tag to the group start. To clearly mark that the purpose is to add to the group, do so within the same comment block:

/*! \file foo.c
 * File's description. */
/*
 * (C) ...
 */

/*! \addtogroup groupname
 * @{
 * \file foo.c */

...

/*! @} */

The point is that we like to have a file's short description near the start of the file, to also serve us well when we're reading only the .h file. But to be included in a group, the doxygen group start must precede the \file tag. Also, the doxygen group should rather not enclose #include directives, to clearly exclude those from the group. Hence, the best way is to keep the file's actual description at the top of the file, and add a second descriptionless \file with the group opening.

A group may contain a short as well as a longer description. We often \defgroup in a .h file but keep the longer description in an \addtogroup in a .c file. Any \file tags must follow after such description, or the description will be associated with the file instead of the group:

.h file:

/*! \defgroup groupname Short description of the group.
 * @{
 */

...

/*! @} */

@.c file:

/*! \addtogroup groupname
 * @{
 * Longer description of the group.
 * - contains a
 * - bullet list
 * 
 * As well as a 
 *
 *     Code example
 *     block
 *
 * All of which must not be below the directive adding this file to the group...
 *
 * \file foo.c */

[...]

/*! @} */

Often, a file's description matches or is identical with a group's description. In that case, the file's description header comment can be omitted to avoid duplicating identical descriptions.

/*
 * (C) 2017 ...
 */

/* \addtogroup group
 * @{
 * Description...
 *
 * \file foo.c */

...

/* @} */