3

I'm documenting my C code with doxygen. For better readability I group documentation of every .c/.h file pair (sometimes also more files) with defgroup and addtogroup (see doxygen in c: grouping of defines). The file pages look fine, but on the group/module pages all variable documentation is doubled. There are 2 entries for every variable that's declared (with extern) in the header file and defined in the .c file (in the summary as well as in the description part). Functions and everything else is listed just once...

How do I get rid of the douplicate variable documentation on group/module pages?

My source files look like this: .h file:

/** @file
*   blabla
*   @author bla
*/
/// @addtogroup MY_GRP
/// @{
#define SOMEDEF1 1
/// @name Special defs
/// @{
#define SOMEDEF2 2
/// @}
enum someenum {
    foo,
    bar
};

extern int some_variables;

extern void some_proc(int baz);

/// @}

.c file:

/** @file
 *  blabla
 *  @author bla
 */
/** @defgroup MY_GRP A test group.
  * Description
  */
/// @{
#include "my.h"

/// Important variable.
int some_variable;

/** Important proc
 *  Description
 *  @param baz need this
 */
void some_proc(int baz) {
// code
}

/// @}
Community
  • 1
  • 1
Bytemaster
  • 83
  • 1
  • 9
  • Out of curiosity, why do you declare `some_proc()` via extern as well as `some_viarables()`? That extern on `some_proc()` seems unnecessary. The files other files that include the header will not need to redeclare `some_proc()` via extern in any case. – Nick Jan 08 '15 at 17:10
  • You're right: It's not necessary, but it also does no harm. IMHO it is more clear and more consistent that way. – Bytemaster Feb 03 '15 at 08:36

2 Answers2

2

Could not really solve the problem but found me a workarround: I use the INPUT_FILTER option with grep -Eve "extern" (cygwin) to sort out all lines with "extern" functions or variable declarations. Since I only document actual function implementations and variable definitions everything with "extern" in front of it has no documentation anyways and can be removed for doxygen. This indeed also removes all duplicate entries for variables in the doxygen output.

Bytemaster
  • 83
  • 1
  • 9
  • Thanks for posting your solution! I was thinking along those lines by invoking a perl script that does something like ` =~ s/extern//g;`. But I thought the same thing, it sounds like a hack, and what if you don't want to filter every extern - but perhaps you could define a wrapper for externs that you don't want to filter. Alternatively, you could have used the doxygen processor to do something similar, you could have defined a symbol in doxygen that activates preprocessor code to effectively overwrite extern with nothing. – Nick Jan 30 '15 at 21:27
  • I have a follow up question for you - does this also filter what's getting pushed to the source browser, or no? There is an option `FILTER_SOURCE_FILES` that may be related to this. – Nick Jan 30 '15 at 21:28
  • For your 1st Comment: Indeed, this is a dirty hack and personally I think this looks like a bug in doxygen. I'm just surprised noone else seems to have this problem. I tried something like `#ifndef __DOXYGEN`, too, but it did nothing. For your 2nd Comment: Sorry, I don't use the source browser. My guess is the filter is only applied to code in the source code browser if `FILTER_SOURCE_FILES` is set. – Bytemaster Feb 02 '15 at 14:47
  • the `#ifndef __DOXYGEN` not working may have been because of `MACRO_PREPROCESSING` - but that is enabled by default (You've probably already looked into that). I am assuming you added the definition `__DOXYGEN` into your doxyfile so that it is global. – Nick Feb 05 '15 at 17:55
  • Indeed, `INPUT_FILTER = sed "s/^extern.*//g"` will do the work, too. – meolic Aug 21 '15 at 10:13
0

Instead of using INPUT_FILTER configuration value with sed or grep command (which is working fine on Linux, on Windows this requires Cygwin or MSYS2, and it's slower...), I am currently using the following hack:

  • Set PREDEFINED = extern=//
  • Set EXPAND_AS_DEFINED = extern

This way any line starting with extern is disabled using a C++ comment.

benjarobin
  • 4,410
  • 27
  • 21
  • why using `//` and not `// extern` or just define `extern` as the empty string? – albert Jul 15 '19 at 08:15
  • @albert Defining `extern` to `// extern` is exactly the same thing that defining to `//`, and if `extern` is defined as the empty string, this does not solve the problem, this is just worst, produce the following warning: `warning: Member xxxx of group yyyy is not documented.` – benjarobin Jul 20 '19 at 09:38