Doxygen is able to document structs but it's not exporting any function declarations or macro definitions.
For instance these defined in headers are not exported.
/** Total instances */
#define TOTAL 10
/** Initializer */
void InitProduct(Product *product, const char *productName);
I'm using Doxygen GUI on Windows, appreciate a GUI reference.
Doxygen is fussy about what documentation it extracts when not EXTRACT_ALL.
Structures and classes are generally okay; functions and variables not so.
To get documentation extracted for functions and variables at the file-level scope, there needs to be a #file documentation element in that file:
/** #file frobulator.c
* Optionally describe the file...
*/
/** #brief My Frobulator.
*/
void frobulator () { ... }
This is for both headers and source files.
For functions and variables at namespace scope, the namespace also needs to be documented with #namespace or in situ. Unlike other elements, namespaces have no "single" point of declaration where documentation can be placed. I usually end up creating a separate .dox file to contain #namespace docs in C comment blocks.
Related
We do have several C-projects targeting resource-constrained systems, which rely heavily on enums defined through preprocessor macros in special resource files. These files get included within the enum definition.
This concept is used to have the user of our API to "be only allowed" to edit the resource definition file, but not needing to touch the header file where these enums are actually defined. Additionally it allows to generate strings for these events, too.
Example for a resource file
DEF_SOME_EVENT_TYPE(EVENT_ALERT)
DEF_OTHER_EVENT_TYPE(EVENT_OTHER_ALERT)
DEF_SOME_EVENT_TYPE(EVENT_FLASH)
DEF_SOME_EVENT_TYPE(EVENT_BEEP)
Example for the associated enum definition
enum some_event_e
{
#define DEF_SOME_EVENT_TYPE(name) name,
#define DEF_SOME_OTHER_EVENT_TYPE(name)
#include "resource_definitions.g"
#undef DEF_SOME_EVENT_TYPE
#undef DEF_SOME_OTHER_EVENT_TYPE
SOME_EVENT_COUNT
};
enum some_other_event_e
{
#define DEF_SOME_EVENT_TYPE(name) name,
#define DEF_SOME_OTHER_EVENT_TYPE(name)
#include "resource_definitions.g"
#undef DEF_SOME_EVENT_TYPE
#undef DEF_SOME_OTHER_EVENT_TYPE
SOME_OTHER_EVENT_COUNT
};
When trying to document the enumerators, doxygen seems to not properly expand these macros and include the resource definition file.
Suppose we have the following documentation block:
/*!
#enum some_event_e
#brief Some event identifiers
*/
/*!
#var some_event_e::EVENT_ALERT
#brief alert event
*/
/*!
#var some_event_e::SOME_EVENT_COUNT
#brief Total number of some events
*/
Doxygen will properly document SOME_EVENT_COUNT, but will throw a warnign for EVENT_ALERT.
warning: documented symbol 'some_event_e::EVENT_ALERT' was not declared or defined.
ENABLE_PREPROCESSING and MACRO_EXPANSION are both set to YES in Doxyfile and I've added *.g (the file-extension used for resource definitions) to the INCLUDE_FILE_PATTERNS and did add it to EXTENSION_MAPPING via g=C. I'm using doxygen version 1.8.16.
Is there a way to be able to document enum values declared in this manner? In some cases it is really useful to use this sort of macro-magic to define enums, so it would be immensely helpful if it was possible to document these with doxygen.
Is it possible in Doxygen to add a brief description of a struct declared but not defined? For example, running doxygen <config file> (where <config file> is the configuration file with default parameters) in the folder with the file mydefinition.h
#ifndef MYDEFINITION_H_
#define MYDEFINITION_H_
/** My super secret structure you can't access fields */
struct MyStructure;
/** The function that lets you use any instance of 'struct MyStructure'
* #param msobj the object
*/
void functionUsingMyStructure(struct MyStructure* msobj);
will generate the documentation of the functon but not the documentation of the structure.
I tried to modify the configuration file of Doxygen by setting OPTIMIZE_OUTPUT_FOR_C = YES but it doesn't change the situation.
Doxygen ignores forward declarations of structs. To workaround this, you have to explicitly state that the given comment block describes your struct.
/** #struct MyStructure
* My super secret structure you can't access fields
*/
struct MyStructure;
I have some includes in the source code where I want to add some "to do".
For example:
/** \todo Review. */
#include "anyfile.h"
/** todo Another to do. */
#define ANY_MACRO 1
The problem is that the first "to do" is inserted in the macro definition and not in the include, as followed:
-----------------------------------
**Todo List**
Global **ANY_MACRO**
Review.
Another to do.
-----------------------------------
Any idea how to solve this ?
Following the online doc:
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.
Then I handle your problem in the following manner: I must have a \file comment in both files, and above the include line, I mention that the todo part refers to the included file.
In other words, I write this in my source file afile.c:
/** \file anyfile.h
* \todo Review
*/
#include "anyfile.h"
/** \file afile.c
* \brief Some code
*/
/** \todo wait, a todo !*/
#define A_MACRO
int main()
{}
In the included file, I write a short comment about the file itself:
/** \file anyfile.h
* Very interesting header
*/
#define B_MACRO
As output, the todo comment is placed in the doc page of the included file. The awkward part according to me is that I have to put the block /** \file afile.c */ after the include line, otherwise it doesn't work.
I'm using doxygen to comment a pure C project. The documentation for a struct is of the following form:
/** #struct cl_options
* #brief This structure contains all ...
* #var cl_options::input_file
* Member 'input_file' contains ...
* #var cl_options::output_file
* Member 'output_file' contains ...
* #var cl_options::bitrate_mode
* ...
*/
struct cl_options {
FILE* input_file;
FILE* output_file;
....
};
Nevertheless I get warnings:
.../commandline.c:39: Warning: Member input_file (variable) of class cl_options is not documented.
.../commandline.c:40: Warning: Member output_file (variable) of class cl_options is not documented.
and so on. For all the structures within the project.
There is a decleration in the header file commandline.h
struct cl_options;
typedef struct cl_options cl_options;
but the doxygen is in the .c-File.
Now the generated doxygen has a link for the struct in the data structures section but it is not documented. Instead there is a link which says
The documentation for this struct was generated from the following
file: commandline.c
and then there is the documentation I provided in the .c-file. How can I avoid this?
I noticed a lot of warnings myself, while using doxygen, however most of the time the output seemed to be fine with me. You can turn, different warnings on and off. For more information visit the doxygen manual and choose which warnings your want to be enable.
However, you can try to move your #var tags from your .c file to your .h header. Just leave the documentation of functionality from your struct, in your .c.
Also, you might want to take a look at this post, with a similar question.
using-doxygen-with-c-do-you-comment-the-function-prototype-or-the-definition? Or both?
I have #define values in headers that I certainly want Doxygen to document but I have others in C files that I treat as static constants and I don't want Doxygen to document them. Something as simple and stupid as
#define NUMBER_OF(a) (sizeof((a))/sizeof((a)[0]))
#define MSTR(e) #e
How can I keep Doxygen from putting those #defines in the documentation it creates? I've tried marking it with #internal but that didn't seem to help.
A somewhat-related question on Doxygen and #define, how can I get:
#define SOME_CONSTANT 1234 /**< An explanation */
to put "SOME_CONSTANT" and "An explanation" but not "1234" in the output?
There is no need to use the \cond and \endcond commands. You can hide the initializer by simply using the \hideinitializer command:
#define SOME_CONSTANT 1234 /**< An explanation #hideinitializer */
Regarding the first question, you may set HIDE_UNDOC_MEMBERS = YES and only the macros having a Doxygen documentation block will be shown in the output.
You can set MAX_INITIALIZER_LINES = 0 in your doxyfile to hide the values of your defines.
You can exclude any part of code from Doxygen parsing with \cond ... \endcond tags.
edit: Some related questions:
How can Doxygen exclude a C++ class?
Exclude some classes from doxygen documentation
You only want to document what is declared in the .h files. I'm assuming you declare all static functions and variables as static in your .c files. All the remaining are declared in .h corresponding files also. These are your "public" members.
What I like to do in this case, and I believe doxygen was more designed to be used this way is:
in your Doxyfile, set EXTRACT_ALL = NO and add the directory where your .h files are to INPUT
add /** \file */ to all your .h files (but not your .c files).
This will index only what is contained in your .h files. You can still add the directory containing your .c files to INPUT at your Doxyfile, and they will be scanned for additional documentation for your "public" members...
It will no doubt still seem noisy and unnatural, but to address your other question, try:
/** An explanation */
#define SOME_CONSTANT /** #cond */ 1234 /** #endcond */
I solved this problem by moving my documentation from the .c file to the .h file. Then run doxygen only on the .h file.
Then the items that I want to document (the 'public' items) are intrinsically what doxygen picks up.
Because I have been previously careful to put 'public' items in the .h file and 'private' items in the .c file this works very well.
This technique came to mind when I noticed that doxygen was pulling in the includes. It struck me that if I were to also move the subset of includes that the calling module would need to use my module, then that list would be documented as well.
This technique has an additional benefit: I can put the documentation in one terminal window and the source in a different terminal window while updating the documentation.
Sometimes you may have a define which you want to document, but want doxygen to treat it differently (or even ignore it completely to avoid parsing errors).
For this you can define the #define in doxygen differently than in your sourcecode.
Example:
Some compilers allow variable linkage to specific segments, i.e.:
const int myvar # "segment_of_myvar_in_memory"=123;
=> doxygen would parse the "segment_of_myvar_in_memory" part as variable name which is not desired.
We could use a define for it:
#define __link_to_segment(name) # name
const int myvar __link_to_segment("segment_of_myvar_in_memory")=123;
If Preprocessing is active, Doxygen interprets our variable now as a function because of the function-like define using brackets..
But if we redefine our define within the Doxyfile, behaviour changes:
PREDEFINED = __link_to_segment(a)=
now the variable is parsed correctly as variable - also all types or keywords in front are correctly shown as keywords.
A nice side effekt:
In case you use 2 different IDEs with your code (one IDE for compiling&debugging, one for editing), you will also discover that some IDEs (i.e. Eclipse) have problems parsing variables with #"segment name". Using the approach above, you can redefine the __link_to_segment(name) there too:
#define __link_to_segment(name)
i.e. Eclipse will then show and parse the variable correctly, whereas the "compiling&debugging" IDE can still link the variable to its segment name.