Fix explicit link warning - doxygen

I have rather big project with doxygen and some files marked as #internal, some not.
When I build internal documentation no warnings are generated, but when I try to build not internal I got some warnings:
some_header.h:61 warning: explicit link request to 'MyStruct' could not be resolved
some_header.h:58 warning: explicit link request to 'AnotherMyStruct' could not be resolved
some_header.h:58 warning: explicit link request to 'AnotherMyStruct' could not be resolved
some_header.h:61 warning: explicit link request to 'MyStruct' could not be resolved
But some_header.h is internal. As an idea I think that it is included in non internal file, but it is wrong. I deleted all includes of the header, but the message doesn't gone.
How can I fix this warning?
P.S. duplicates of warning mean that there 2 places with error?
$doxygen -x
FULL_PATH_NAMES = NO
JAVADOC_AUTOBRIEF = YES
OPTIMIZE_OUTPUT_FOR_C = YES
EXTRACT_STATIC = YES
QUIET = YES
WARN_IF_UNDOCUMENTED = NO
WARN_FORMAT =
FILE_PATTERNS = *.c *.h
RECURSIVE = YES
EXAMPLE_PATTERNS =
SOURCE_BROWSER = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
ALPHABETICAL_INDEX = NO
HTML_OUTPUT =
SEARCHENGINE = NO
GENERATE_LATEX = NO
LATEX_OUTPUT =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
RTF_OUTPUT =
MAN_LINKS = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = (a lot of)
TEMPLATE_RELATIONS = YES
Simple example to reproduce problem:
flags.h:
/**
* #file
* #brief Public Flags.
*/
#ifndef PUBLIC_FLAGS_H
#define PUBLIC_FLAGS_H
#pragma once
/**
* Public flags
*/
typedef enum {
FLAG_READ = 1, /**< reading allowed */
FLAG_WRITE = 2, /**< writing allowed */
} PublicFlags;
#endif /* PUBLIC_FLAGS_H */
info.h
/**
* #file
* #brief Public header.
*/
#ifndef TEST_PUBLIC_H
#define TEST_PUBLIC_H
#pragma once
#include "flags.h"
/**
* Defines public enum.
*/
typedef enum EPublicEnum {
TestEnum1, /**< enum 1 */
TestEnum2, /**< enum 2 */
TestEnum3 /**< enum 3 */
} PublicEnum;
/**
* Defines public struct.
*/
typedef struct SPublicStruct {
PublicEnum state; /**< state (see #PublicEnum). */
unsigned flags; /**< set of flags see #PublicFlags.*/
} PublicStruct;
#endif /* TEST_PUBLIC_H */
internal_enums.h
/**
* #internal
* #file
* #brief Internal Enums
*/
#ifndef INTERNAL_ENUMS_H
#define INTERNAL_ENUMS_H
#pragma once
#include "flags.h"
#include "info.h"
/**
* Possible types:
*
* TypeMisc - Misc type.
* TypeIo - IO type.
*/
typedef enum {
TypeMisc,
TypeIo,
} InternalEnumType;
/** Owner type. */
typedef enum {
Kernel = 0, /**< kernel. */
User = 1 /**< user. */
} InternalEnumOwner;
#endif /* INTERNAL_ENUMS_H */
internal_struct.h
/**
* #internal
* #file
* #brief Internal structures.
*/
#ifndef INTERNAL_STRUCT_H
#define INTERNAL_STRUCT_H
#include "internal_enums.h"
typedef struct SInternalStruct {
rtl_uint8_t owner : 1; /**< values from #InternalEnumOwner */
rtl_uint8_t type : 1; /**< values from #InternalEnumType */
} InternalStruct;
#endif /* INTERNAL_STRUCT_H */
problem:
warning: explicit link request to 'InternalEnumOwner' could not be resolved
warning: explicit link request to 'InternalEnumType' could not be resolved

There is a misunderstanding about what the \internal command does in doxygen does, from the documentation:
24.29 \internal
This command starts a documentation fragment that is meant for internal use only. The fragment naturally ends
at the end of the comment block. You can also force the internal section to end earlier by using the \endinternal
command.
If the \internal command is put inside a section (see for example \section) all subsections after the command
are considered to be internal as well. Only a new section at the same level will end the fragment that is considered
internal.
You can use INTERNAL_DOCS in the configuration file to show (YES) or hide (NO) the internal documentation.
This means that the comment between the \internal and the \endinternal (or end of the comment block) is not part of the documentation (unless the setting INTERNAL_DOCS is set), in this case it is just about the parts like:
/**
* #internal
* #file
* #brief Internal structures.
*/
so the \internal command here has not the desired effect and should be removed.
What actually is desired (when I understand it correctly) is that the entire file isn't used. This can be accomplished by means of either:
add the setting EXCLUDE_PATTERNS = internal*
or
explicitly listing all files and directories that should be used, her this is by adding the setting INPUT = info.h flags.h
In case only part of a file, i.e documentation and code, should not enter the documentation one can use the commands \cond ... \endcond. For disabling just part of a documentation block the commands \if .. \endif are useful. Both sets of commands go together with the setting ENABLED_SECTIONS.
For a description of the mentioned command see the doxygen manual (e.g. at https://www.doxygen.nl/manual/index.html and more specifically the chapters: https://www.doxygen.nl/manual/config.html and https://www.doxygen.nl/manual/commands.html)

Related

Doyxgen onetime macro expansion / expansion command

I have some code like the following example:
/** #file HelloPi.c */
/** The definition of pi */
#define PI 3.1415
/** #brief The main function.
* #details Prints the value of #PI, which is actual defined as 3.1415. */
void main()
{
printf("The value of pi is %f\n",PI);
}
In my doxygen dokumentation I would like to to have NO macro expansion for PI (and other defines) in general.
But on one paragraph in the documentation I need the value of pi (e.g. #details description of the main function).
Is there any possibility to expand the macro at this single part of documentation with a command or something? Something like /** #details ...the value of #PI is $(PI).*/
I only know the build-in MACRO_EXPANSION tag which works for the whole documentation: https://www.doxygen.nl/manual/preprocessing.html :-/
Thanks for help :)
Jan
Edit:
Add an other example which maybe better describes my Problem:
/** #file ErrorHandling.c */
#define ERR_CODE_POWERUNIT 1001 ///< Error in power unit */
/** #page errors
* [value of ERR_CODE_POWERUNIT ] means \copybrief ERR_CODE_POWERUNIT */
void errHandler(int error)
{
if(error=ERR_CODE_POWERUNIT)
printf("Error %d occur\n",ERR_CODE_POWERUNIT);
}
In the documentation I would like to have:
"1001 means Error in power unit"
In doxygen there is no possibility to do a conversion of a predefined variable (only) in the documentation.
You used in your documentation the an environment variable $(PI) but ths is quite cumbersome as you have to st the environment variable each time.
A better solution would be to use an ALIASES like:
ALIASES += pi=3.1415
or
ALIASES +\= "The value of PI = 3.14159265359..."
with which you define a command \pi that can be used in the documentation and will be replaced with the text / commands in the alias.
/** #details ...the value of #PI is \pi.*/
would result in something like (by head:
...the value of #PI is 3.1415

Is it possible for Doxygen to exclude undocumented functions from generated XML?

I want to generate documentation only for code that has Doxygen comments. I have created a Doxyfile via Doxygen version 1.8.9.1 and configured it to output only XML and to hide all undocumented code:
GENERATE_HTML = NO
GENERATE_LATEX = NO
GENERATE_XML = YES
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
After that I created a simple C header test.h with one documented and one non-documented function declaration:
void foo(int a);
/**
* "bar" function description
* #param b sample param
*/
void bar(int b);
By executing doxygen I expected only documentation for bar to be included in the resulting XML. Unfortunately, documentation for both functions is generated. Is it possible to generate documentation only for code that has Doxygen comments? Or will Doxygen always include everything in the XML output regardless of settings?
Before reading any further make sure EXTRACT_ALL is set to NO.
I'm not a fan of the following solution but it does work. Use doxygen's preprocessor
#ifdef PROJECT_NO_DOC
void foo(int a);
#endif /* PROJECT_NO_DOC */
/**
* * "bar" function description
* * #param b sample param
* */
void bar(int b);
Note, in their docs you have to set a PREDEFINED macro but at least in my version of doxygen this was not required. Their docs specify to do it this way set a predefined macro in the config to do it for you
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/* code that must be skipped by Doxygen */
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
around the blocks that should be hidden and put:
PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS
in the config file then all blocks should be skipped by doxygen as long as
ENABLE_PREPROCESSING = YES
There are other methods but they come with additional constraints ie to make sure no static method appear in your public docs you can set EXTRACT_STATIC to NO.
You can use \cond to hide parts of the source code from Doxygen. This avoids the need to use the preprocessor as in Harry's answer.
For example, here foo will not be seen by Doxygen, and hence not documented:
/** \cond */
void foo(int a);
/** \endcond */
/**
* "bar" function description
* #param b sample param
*/
void bar(int b);
Furthermore, it is possible to add section labels to \cond, and control which sections are included by listing them in the ENABLED_SECTIONS configuration option.
For example:
/// \cond CLASS_A
/// This function foos `a`.
void foo(int a);
/// \endcond
/// \cond CLASS_B
/// This function bars `b`.
void bar(int b);
/// \endcond
By setting ENABLED_SECTIONS = CLASS_A CLASS_B, both functions will show up in the documentation. Leaving one of the labels out will hide the corresponding function.

Doxygen: How do I link to a static variable?

I'm currently generating documentation for a pure C project.
In a file utilities.h file I have this:
/**
* #defgroup LOG_LEVELS Different levels of log file granularity
*
* \addtogroup LOG_LEVELS
* #{
* Each logging routine has a mandatory parameter defining the logging level
* of the current logging function call. Only if that level is less or equal
* to one of those predefined levels by the constants given here, that call
* will actually be logged. These constants are also used to set the current
* logging level in #currentLogPrio .
**/
#define LOGPRIO_ALWAYS 0 /**< always log this, although no error */
#define LOGPRIO_FATAL 0 /**< fatal errors */
#define LOGPRIO_ALERT 100 /**< alerts */
#define LOGPRIO_CRITICAL 200 /**< critical, but not fatal errors */
#define LOGPRIO_ERROR 300 /**< normal errors */
#define LOGPRIO_WARNING 400 /**< warnings */
#define LOGPRIO_NOTICE 500 /**< notices */
#define LOGPRIO_INFO 600 /**< informational texts */
#define LOGPRIO_TRACE 700 /**< tracing */
#define LOGPRIO_DEBUG 800 /**< debugging information */
/** #} **/
In the associated utilities.c file the static variable currentLogPrio is defined:
/**
* #var currentLogPrio
* #brief Current setting of the logging level.
*
* Only if a logging routine was called with its log level parameter set to a
* value less than or equal to the current logging priority the actual call of
* a logging routine will be written to the log.
**/
static logPrio_t currentLogPrio = LOGPRIO_ALWAYS;
Now, when I run doxygen on the complete project, I get the following warning:
...
Preprocessing utilities/logUtilities.c...
Parsing file utilities/logUtilities.c...
Preprocessing utilities/logUtilities.h...
Parsing file utilities/logUtilities.h...
...
Generating code for file utilities/logUtilities.c...
Generating code for file utilities/logUtilities.h...
...
Generating docs for file utilities/logUtilities.h...
Generating call graph for function logErrcode
Generating call graph for function logMsg_alert
Generating call graph for function logMsg_always
Generating caller graph for function logMsg_always
Generating call graph for function logMsg_critical
Generating call graph for function logMsg_debug
Generating caller graph for function logMsg_debug
Generating call graph for function logMsg_error
Generating caller graph for function logMsg_error
Generating call graph for function logMsg_fatal
Generating caller graph for function logMsg_fatal
utilities/logUtilities.h:136: warning: explicit link request to 'currentLogPrio' could not be resolved
Both files are part of the doxygen documentation as you can see from doxygens output and have the #file tag included. I also know that the #var tag for the static variable is not needed, but I get the same errors with or without this tag.
So, how can I link to that static variable?
Best regards and thanks in advance

doxygen - ingroup a whole file including members?

How do i group all the functions, classes, defines etc of a file?
Example file:
/*!
* \file
* \ingroup myGroup
*/
/*!
* this is my function.
*/
int myfunc();
Now, if look at the output, only the file is added to that group. The function is not. i need to add \ingroup myGroup to that file to add it. Can that be done by brackets{} or any way else?
Thans to alberts persistence i found a working way:
/*!
* \file
* this is my testfile
* \ingroup UnitName
* \addtogroup UnitName
* \{
*/
/*!
* this is my function.
*/
int myfunc();
/*! \} */
This generates the wanted output. The File andthe function is added correctly.
It does not work with \ingroup. It puts the function into the files section (i upgraded to the latest version of doxygen with the same outcome.

doxygen #param confused by #file tag

All,
I am trying to get a handle on doxygen tags, and have encountered the following 'issue'.
In the code shown below, if I remove the #file doxytest.c from the second line, all is well. If, however, I leave it in, the output log contains this:
/Users/bp/learn/gendoxy/gendoxy/doxytest.c:10: warning: argument 'int' of command #param is not found in the argument list of foobar0(int folder)
/Users/bp/learn/gendoxy/gendoxy/doxytest.c:10: warning: The following parameters of foobar0(int folder) are not documented:
parameter 'folder'
This makes no sense to me (should it?) This is in a '.c' file, running on a MacOS.
What am I doing wrong? -- I would like to have the #file tag, and no warnings/errors from doxygen.
Or, gasp!, is this a bug?
/*!
* #file doxytest.c
*
* #author bp
* #version 0.0.1
* #copyright (2013) we be nerds,LLC
*/
/*!
* #brief void foobar0 ( int folder )
* does little to better the world.
*
* #param [in] int folder :- one small step
*
*/
void foobar0 ( int folder )
{
for (int ii = 0; ii < folder; ii++)
{
foobar1( ii );
}
}
/*!
* #brief foobar2 ( int x )
* does half of what foobar1 does.
*
*/
void foobar1( int x )
{
return( x /2 );
}
Do not include the variable type in the doxygen comment
* #param [in] folder :- one small step
Otherwise it thinks your documenting the variable 'int', and it also thinks you forgot to document the variable 'folder'.
So yes, you should keep the #file tag. Honestly I find it strange that removing the #file tag made the warning go away.