Doxygen does not parse __attribute__ correctly - c

I have some functions defined the following way:
* #brief Obtains the current time tick of the OS.
* This is a weak function and is intended to be overridden.
* #return In the weak version always 0. Otherwise should return the current
* OS time tick.
*/
__attribute__((__weak__)) osalUint_t osal_tickGetCurrent(void)
{
return 0;
}
They are defined as "weak". When I generate the doxygen output for a c file with such a definition, the function is not parsed correctly.
Is there a way to make the Doxygen be __attribute__ aware when it comes to functions (and other objects too, such as structs)?

I used as source code:
/// \file
/**
* #brief Obtains the current time tick of the OS.
* This is a weak function and is intended to be overridden.
* #return In the weak version always 0. Otherwise should return the current
* OS time tick.
*/
__attribute__((__weak__)) osalUint_t osal_tickGetCurrent(void)
{
return 0;
}
And as doxygen settings file (Doxyfile):
QUIET = YES
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
PREDEFINED = __attribute__(x)=
and the result is:

Related

Doxygen are not collecting all \todo in global todo list

I have a problem with doxygen. Not all my \todo are collected in the global todo list, but most of them. I have made a simple C-example with a single source and header file, as well as a configuration file, where i have placed todos everywhere i want doxygen to collect them into the global todo list.
My global todo list is missing the shown todos in the below code snippet, meaning the one inside the body of my public function (test_todo12 in myFunc), as well as the ones in the cfg file (test_todo16 and test_todo17), both implemented as shown below.
test.h:
/**
* Definition of test structure.
*/
typedef struct def_struct_
{
int32_t first; /**< First element.*/
int32_t second; /**< Second element. */
int32_t third; /**< third element. */
} def_struct_t;
/**************************************************************************************************/
/**
* \brief My func description.
*
* \param[ in ] test_param Input parameter to myFunc.
*
* \return bool
* \retval false false on non success.
* \retval true true on success.
*
**************************************************************************************************/
bool myFunc( uint32_t test_param );
test.c:
#include <stdint.h>
#include <stdbool.h>
#include "test.h"
#include "test.cfg"
bool myFunc( uint32_t test_param )
{
uint32_t testVar = test_param ;
//! This function does nothing. \todo test_todo12
testVar++;
return true;
}
test.cfg:
/** test cfg
* \todo test_todo16
*/
static def_struct_t test_cfg[2] =
{
.first = 123 //! \todo test_todo17
}
I am using doxygen version 1.8.14
The differences in my doxygen configuration file compared to the default settings are the following (after trying alot of different combinations):
OPTIMIZE_OUTPUT_FOR_C = YES
TOC_INCLUDE_HEADINGS = 1
TYPEDEF_HIDES_STRUCT = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
INTERNAL_DOCS = YES
HIDE_SCOPE_NAMES = YES
WARN_NO_PARAMDOC = YES
RECURSIVE = YES
EXCLUDE_PATTERNS = */README.md
EXAMPLE_RECURSIVE = YES
SOURCE_BROWSER = YES
GENERATE_TREEVIEW = YES
USE_MATHJAX = YES
GENERATE_LATEX = NO
CLASS_DIAGRAMS = NO
HAVE_DOT = YES
UML_LOOK = YES
DOT_PATH = "C:\Program Files (x86)\Graphviz2.38\lib\release\lib"
DOTFILE_DIRS = "C:\Program Files (x86)\Graphviz2.38\lib\release\lib" \ "C:\Program Files (x86)\Graphviz2.38\bin"
PLANTUML_JAR_PATH = C:\tools\plantUML
and added *.cfg \ to FILE_PATTERNS
Link to the full compilable code and doxygen configuration (minimal example for showing this problem): Link to code
When i navigate to the public function "myFunc" i see the todo, it is just missing in the global todo list.
The cfg file does not seem to be included in the doxygen documentation at all, event though it is included in the C file, and theby should be seen as a part of this file? Or is it really necessary to do something extra/special for including these cfg files? If so, does someone know what I am missing?
I hope someone can help me solve my problem, maybe the todo in the public function body is even a bug?
Regards
Jesper
Looks like there are a number of issues here.
the extension cfg is not known to doxygen and only adding it to FILE_PATTERNS is not sufficient, also the language in which it is written has to be made known to doxygen, so EXTENSION_MAPPING = cfg=C.
the variable in the test.cfg is missing a semi-colon (;) at the end. last line should read };
the comment inside the initialization is not considered by doxygen as documenting something (also in the current version 1.8.16 this is not considered). Problem would be where does it belong, for a \todo is would be clear that it can land on the ToDo page, but should it also land with the variable itself? and how about other comments (initializations are now variables). As a side note when using STRIP_CODE_COMMENTS=NO the comment is not shown in the initialization either.

Doxygen: group data structures on file level

I would like to use the Doxygen grouping mechanism for data structures. I'm already using it for functions and it works well so far. What I've experienced so far fits to the documentation regarding member groups of a single type (e.g. function only) or mixed type (e.g. typedefs and functions).
Now I tried to extend these member groups with data structures, and this fails exceptionally. Data structures are always a top section on its own. My tries so far:
Put a data structures definition inside an existing mixed type member group. -> Data structure is still documented in a separate top level section.
/**
* \file doxytest.h
*/
/**
* \name Iteration API
* \brief Some documentation. Group will be on top level.
*/
/// #{
/**
* \brief For no reason this is not part of the member group.
*/
typedef struct {
/**
* \brief Some mask
*/
uint32_t mask;
} filter_t;
/**
* \brief Some variable
*/
extern const uint32_t MODE_FILTER_MASK;
/**
* \brief Curiously this IS part of the member group.
*/
typedef bool (*for_each_cb)(const void *obj, void *opaque);
/**
* \brief Some function
*/
uint32_t filter_id_filter_set(size_t ids_num, ...);
/// #}
Side by Side of final Doxygen output and desired Doxygen output (Photoshopped)
Creating a group solely consisting of data structures. -> Data structures are documented in a separate top level section and the documentation block for this group vanishes completely.
/**
* \file doxytest2.h
*/
/**
* \name Structures
* \brief This documentation block will not show up
* in the final file documentation. It is completely lost.
*/
/// #{
/**
* \brief Won't show up in group/section "Structures"
*/
typedef struct {
/**
* \brief Some mask
*/
uint32_t mask;
} filterA_t;
/**
* \brief Won't show up as well
*/
typedef struct {
/**
* \brief Some mask
*/
uint32_t mask;
} filterB_t;
/// #}
/// Some struct that should not show up in group "Structures"
typedef struct {
int bar;
} someStruct;
Side by Side of final Doxygen output and desired Doxygen output (Photoshopped)
Use a module and add the data structures mit \ingroup. -> Data structure pops up in the module, but the file documentation still looks the same as above
Using \nosubgrouping command on file level documentation. -> No changes at all to file documentation page.
/**
* \file doxytest.h
* \nosubgrouping
*/
I would like that the documentation for file doxytest.h/doxytest2.h displays data structures in the group they were defined in.
The programming language is C, but I'm very limited in terms of changing the code to fit documentation needs. Doxygen version is 1.8.16. The configuration file is almost default. (I left out stuff like project name and input settings)
OPTIMIZE_OUTPUT_FOR_C = YES
EXTRACT_ALL = YES
EXTRACT_STATIC = YES
SORT_MEMBER_DOCS = NO
DISABLE_INDEX = NO
Any help appreciated.
It took me several months to find, but the answer was deceptively simple.
You just need to enable INLINE_SIMPLE_STRUCTS:
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
# with only public data fields or simple typedef fields will be shown inline in
# the documentation of the scope in which they are defined (i.e. file,
# namespace, or group documentation), provided this scope is documented. If set
# to NO, structs, classes, and unions are shown on a separate page (for HTML and
# Man pages) or section (for LaTeX and RTF).
# The default value is: NO.
INLINE_SIMPLE_STRUCTS = YES
The fact that the data structures are "simple" is only a consideration of every member being publicly accessible, not the number of entries.

How do I document functions with return type of struct properly using doxywizard?

Although I have looked everywhere I think I possibly could to find my answer, I have not been able to figure out how to correctly document the function "struct Entity * NewEntity()" so that it appears documented when doxywizard runs.
It just keeps telling me: "warning: Member NewEntity() (function) of file entity.h is not documented."
Yet, the code is:
/***********************************************************************************************//*
* #fn struct Entity* NewEntity()
*
* #brief Initialises single entity.
* #return null if it fails, else finds empty spot in entity manager to use to make a new entity
* #author br66
* #date 3/30/2017
**************************************************************************************************/
struct Entity* NewEntity()
{
int i;
for (i = 0; i < 255; i++)
{
if (_entityM[i].m_active == 0)
{
// clear that space, just in case there's anything left over from its last use
memset(&_entityM[i], 0, sizeof(struct Entity));
_entityM[i].m_active = 1;
// any entity defaults? stay tooooooned
_entity_max_recorded++;
return &_entityM[i];
}
}
return NULL;
}
Reading the documentation, it tells me to make sure the header file is documented, but it has not changed anything and I still get that warning.
You have two comment blocks. /****...***/ /* #fn... */
The second comment is not looked at by doxygen.
A doxygen comment block should start with an extra '*' /** #fn... */ .

STM32 using callbacks to retrive data from USB CDC VCP

I have generated a project for USB CDC VCP using CubeMX and HAL and now I am trying to figure out how I can implement these two weak functions:
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
These fuctions will be called inside HAL_PCD_IRQHandler. What I want to do is place some code inside them so I can retrive received data from host and also find out about end of transaction.
I have seen that CubeMX has reimplemented these weak functions inside usbd_conf.c like this:
/**
* #brief Data Out stage callback.
* #param hpcd: PCD handle
* #param epnum: Endpoint Number
* #retval None
*/
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
}
/**
* #brief Data In stage callback..
* #param hpcd: PCD handle
* #param epnum: Endpoint Number
* #retval None
*/
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
}
I am wondered to know what do these two functions (USBD_LL_DataOutStage and USBD_LL_DataInStage) do? And how I can edit them to achieve my goal.
I encountered this same issue in STM32Cube_FW_L4_V1.10.0 and after looking at this and some other discussions decided to work around it by replacing the CDC DataIn handler with an alternate implementation that adds a call to CDC_TransmitReady_CB() to wake the transmit task:
// Modified CDC DataIn handler to invoke a callback (CDC_TransmitReady_CB) on TX ready
uint8_t altDataInHandler(USBD_HandleTypeDef *pdev, uint8_t epnum) {
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
if (hcdc == NULL) return USBD_FAIL;
hcdc->TxState = 0;
CDC_TransmitReady_CB();
return USBD_OK;
}
void hackCdcClass() {
USBD_CDC.DataIn = altDataInHandler;
}
Ugly, but it works like a charm.

How to documenting global dependencies for functions?

I've got some C code from a 3rd party vendor (for an embedded platform) that uses global variables (for speed & space optimizations). I'm documenting the code, converting to Doxygen format.
How do I put a note in the function documentation that the function requires on global variables and functions?
Doxygen has special commands for annotating parameters and return values as describe here: Doxygen Special Commands. I did not see any commands for global variables.
Example C code:
extern unsigned char data_buffer[]; //!< Global variable.
/*! Returns the next available data byte.
* \return Next data byte.
*/
unsigned char Get_Byte(void)
{
static unsigned int index = 0;
return data_buffer[index++]; //!< Uses global variable.
}
In the above code, I would like to add Doxygen comments that the function depends on the global variable data_buffer.
You can just add a note to that effect and use the \link directive to direct the reader to the description of the global variable.
Doxygen could do with an #global command to complement #param. Until that day arrives you could approximate it with aliases.
In your Doxygen configuration file add the following aliases:
ALIASES += global_START="<dl class=\"params\"><dt>Globals</dt><dd><table class=\"params\">"
ALIASES += global_{2}="<tr><td class=\"paramname\">\1</td><td>: \2</td></tr>"
ALIASES += global_END="</table></dd></dl>"
Example of usage:
int fxnMAIN_Main(void)
{
/**
* #brief Bla Bla Bla.
*
* #global_START
* #global_{bExampleOne, Description Here}
* #global_{bExampleTwo, Second Description Here}
* #global_END
*
* #retval int : Bla Bla Bla.
*/
// Code Here
}

Resources