How can I keep doxygen from documenting #defines in a C file? - c

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.

Related

What is the difference between '#include' and '##include'?

For example:
#include "pathtoheader1/header1.hh"
##include "pathtoheader2/header2.hh"
What is the difference between these two preprocessor directives?
Edit
From what I can tell, the ##include directive, in the context of the program I am working with, will prepend -I flags to the specified include path.
TRICK_CFLAGS += -Imodels
TRICK_CXXFLAGS += -Imodels
The compiler will now look for:
/models/pathtoheader1/header1.hh
instead of
/pathtoheader1/header1.hh
These flags are stored in a .mk file.
Additional Information
I am using NASA's Trick Simulation environment to build a simple 2-body simulation of the earth orbiting the sun. The specific tool I am using is called 'trick-CP', Trick's compilation tool.
https://github.com/nasa/trick
## is the token pasting operator in both the C and C++ preprocessors. It's used to concatenate two arguments.
Since it requires an argument either side, a line starting with it is not syntactically valid, unless it's a continuation of a previous line where that previous line has used the line continuation symbol \ or equivalent trigraph sequence.
Question is about NASA Trick. Trick extends C and C++ language with its own syntax.
From Trick documentation:
Headers files, that supply data-types for user-defined models should be included using ##include . Note the double hash (#).
The second one is a syntax error in C++, and I am pretty sure it is a syntax error in C too. The ## preprocessor operator is only valid inside a preprocessor macro (where it forces token pasting).
Here is what the Trick Documentation says about include:
Include files
There are two types of includes in the S_define file.
Single pound "#" includes.
Include files with a single pound "#" are parsed as they are part of the S_define file. They are treated just as #include files in C or C++ files. These files usually include other sim objects or instantiations as part of the S_define file.
Double pound "#" includes.
Include files with a double pound "##" are not parsed as part of the S_define file. These files are the model header files. They include the model class and structure definitions as well as C prototypes for functions used in the S_define file. Double pound files are copied, minus one pound, to S_source.hh.
Also here is a link to where it talks about it in the Trick documentation: https://nasa.github.io/trick/documentation/building_a_simulation/Simulation-Definition-File

Why is Doxygen grouping enums with the same name from different C files?

I'm using Doxygen 1.8.5 and having the same exact problem as in the following question, only the language is C and the enums are in the C files:
Doxygen C# XML comments: multiply enum's with same name and different scope got merged?
According to https://bugzilla.gnome.org/show_bug.cgi?id=522193 it was fixed in 1.6.0, but I'm guessing Doxygen isn't treating different C files as having different namespaces.
The enums in question pertain only to each specific file, but are called the same name because they are used for the same purpose in that file (for flags used to track status information about that module, for example). The C compiler has no problem with this, but Doxygen combines them.
Example:
file1.c
enum status_flags {
sfACTIVE,
sfSHUTDOWN,
sfWARNING,
};
file2.c
enum status_flags {
sfSTANDBY,
sfSCREEN_OWNED,
};
The doxygen file will generate a single blob of both enums combined, including the comments for each member, and reference them in the documentation for both files.
enum status_flags
Enumerator
sfACTIVE
sfSHUTDOWN
sfWARNING
sfSTANDBY
sfSCREEN_OWNED
Definition at line 42 of file file1.c.
and
enum status_flags
Enumerator
sfACTIVE
sfSHUTDOWN
sfWARNING
sfSTANDBY
sfSCREEN_OWNED
Definition at line 65 of file file2.c.
I've tried making each file a member of its own #addtogroup, and I've made sure each file has an #file at the top, but it's still mixing all of these enums together which are supposed to be private to that particular C file. It would be a bit of a pain if I were forced to rename each of these enums, as there are dozens of applications in the code which all follow a similar format and use private enums of the same name with different flags. The compiler is perfectly happy to work with them.
Any ideas?
Anonymous typedef enum also have this same issue,
typedef enum {
sfACTIVE,
sfSHUTDOWN,
sfWARNING
} status_flags;
results in the combining issue, but Doxygen appears
to give priority to the enumeration, so combining
does not happen when you do this:
typedef enum status_flags_f1 {
sfACTIVE,
sfSHUTDOWN,
sfWARNING
} status_flags;
typedef enum status_flags_f2 {
sfSTANDBY,
sfSCREEN_OWNED
} status_flags;
This only works if TYPEDEF_HIDES_STRUCT is set to NO in the Doxyfile configuration file, which is the default.

Include a header file for parsing of all other files with Doxygen preprocessor

I want to include the #defines from a h file for parsing of all other files with Doxygen.
Project background:
My C project includes a header file config.h on it's the build command.
It also defines a target MODEL_A on the same build command.
config.h creates defines depending on the target being built (not the same lists of defines for MODEL_A as for MODEL_B):
#if defined(MODEL_A)
#define HAS_FUNCTIONALITY_1
#define HAS_FUNCTIONALITY_2
#elif defined(MODEL_B)
#define HAS_FUNCTIONALITY_3
#define HAS_FUNCTIONALITY_4
#endif
My issue with Doxygen:
I try to generate documentation with Doxygen. I have in the Doxyfile:
# including of config.h to INPUT seems necessary.
INPUT = ./source/config.h \
./source
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
INCLUDE_PATH = ./source
INCLUDE_FILE_PATTERNS = ./source/config.h
PREDEFINED = MODEL_A
The code that is dependent on the defines HAS_FUNCTIONALITY_x is not included in the documentation, as if the preprocessor did not get the defines in config.h.
My findings so far:
I inspected the preprocessor output with help of doxygen -d Preprocessor, and could see that:
./source/config.h was parsed first, and correctly according to MODEL_A (I can see the correct #defines in the preprocessor output). #define HAS_FUNCTIONALITY_1 figures in the preprocessor output.
the preprocessing of C files which depend on HAS_FUNCTIONALITY_1 act as if it was not defined.
Defining HAS_FUNCTIONALITY_1 in the field PREDEFINED of the Doxyfile works as expected. This is not a practical solution, but still interesting.
How do I make sure that the #define rows that are preprocessed first from config.h stay defined when the preprocessor works on all subsequent C files?
It would probably be beneficial for you to show the C code itself. In general, Doxygen runs a standard preprocessor - i.e. the rendered code should be the same as if the compiler preprocessed it. In order to achieve the equivalent of #define HAS_FUNCTIONALITY_1 in the code - it has to be defined.
I understand from your reluctance to add it to the doxygen configuration that it is defined somewhere else in the project (or perhaps the Makefile) and that that is the reason that the actual code acts as though it was defined.
If this is the case, I don't see a plausible workaround other than more preprocessor trickery or simply adding it in the doxygen config file.
I ran into a very similar issue.
My headers were in a different directory from my source, e.g.:
doxy_input_dir/
|
+ src/
|
+ inc/
I had RECURSIVE input file option set to YES. I assumed the preprocessor would correctly find my headers. However, when I viewed the preprocessor output by running doxygen -d Predefined <doxyfile> I saw a lot of #include foo.h: not found! skipping....
The solution was to specify all of the header directories explicitly using the INCLUDE_PATH tag.

Configure Doxygen to hide certain names or keywords

I'm just getting started with Doxygen, and have done considerable searching on this, so forgive me if there's an obvious answer.
I'm working on an embedded project where functions can be tagged as debug or nodebug before the return type. In most of our libraries, we use a conditional macro to set libname_debug to either debug or nodebug at the top of the file, and then each function is prefaced with libname_debug.
For documentation purposes, I'd like to have Doxygen leave libname_debug out of the function documentation. It clutters up the function list and makes it harder to see the return types of each function.
Is it possible to tag the file in some way so Doxygen will leave that symbol out? At the moment, I'm wrapping each instance in #cond/#endcond:
/** #cond */ libname_debug /** #endcond */
But that's a pain and adds extra markup to the source.
There is also a doxygen page explaining how to handle such situations. You would enable MACRO_EXPANSION (which defaults to NO), tell doxygen to only expand some macros (EXPAND_ONLY_PREDEF) and add your symbol as macro with an empty expansion:
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = libname_debug=
You can define macros in the doxygen configuration file. Something like this
PREDEFINED += libname_debug

Auto defines in C editors... Why?

When Eclipse creates a new file (.c or .h file) in a C project the editor always auto creates a #define at the top of the file like this: If the file is named 'myCFile.c' there will be a #define at the start of the file like this
#ifndef MYCFILE_C_
#define MYCFILE_C_
I have seen other editors do this as well (Codewright and SlikEdit I think).
The #defines don't seem to do anything for the editor as I can just delete them without any problem, and I can't think of a reason why I would want to use them. Does anyone know why they are there?
It's to guard against multiple definitions.
Sometimes people include a whole .c file in other .c files (or even .h files), so it has the exact same purpose of preventing an include file from getting included multiple times and the compiler spitting out multiple definition errors.
It is strange, though, that it would be the default behavior of an editor to put this in anything but a .h file. This would be a rarely needed feature.
A more modern version of this is to use:
#pragma once
It is quite unusual to see this in a .c file, normally it is in the header files only.
I think it's a throwback of C include issues, where multiple copies of the source would get included - unless you are meticulous with include chains (One file includes n others).
Checking if a symbol is defined and including only if the symbol is defined - was a way out of this.

Resources