Configure Doxygen to hide certain names or keywords - c

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

Related

How to use Doxygen with Prolog

I was struggling trying to make doxygen work with prolog.
At first I was only trying to include an "external and unknown" file, but as doxygen users know, it won't print a thing if it can't find useful (documented) functions.
Searching stackoverflow for both tags gives no single answer, and so I decided to ask, even if I already solved the puzzle, so people will have a hit in case of search.
I will let this question here, as people can suggest simple workarounds, and we may learn a bit more about the subject, but I'll use it to register my own answer after some (hard) efforts. Thanks.
To explain where I did start:
My first (almost) successful approach worked fine in a program that used both C and PROLOG.
It almost worked because latter on I saw this approach would not work in a PROLOG only project.
Anyway, what I did was simply add this
INPUT = README.md groups.dox c-and-pl.c c-and-pl.pl
FILE_PATTERNS = *.pl
EXTENSION_MAPPING += pl=c
EXTRACT_ALL = YES
EXTRACT_STATIC = YES
SOURCE_BROWSER = YES
And PROLOG code would look like:
/**
* #file cpl.pl
* #ingroup GroupUnique
* #brief CPL - C calls Prolog (Prolog module)
* #cond SKIPPROLOG
*/
/* brief explanation in a normal (non-doxygen) comment */
clause(A) :-
rule(X),
test(A, X).
and(so, on).
/** #endcond */
This would work because C would create the site anyway, and PROLOG page would be just a brief, no clauses, but a link to see the complete code, with normal comments explaining the clauses.
Why this doesn't work for a pure PROLOG project? And how to do that?
My second attempt to solve it involved the creation of a new file, a copy of the original PROLOG source, but with comments in doxygen format, and converting PROLOG clauses in something C-like.
Call the source source.pl and the second copy source.dox. You would write the PROLOG program as you usually do, using doxygen before the first occurrence of each clause, atom, module, etc.
Then cp source.pl source.dox and edit source.dox converting all clauses in something like:
/**
* \file source.pl
* \ingroup GroupUnique
*/
/**
* \ingroup GroupUnique
* \brief Defining factorial module
*/
module(fatorial, [fatpl/2]);
This takes time and are prone to errors, but it was a workaround. Problem is that doxygen now lists source.pl twice. But the functions can be documented. Use this configuration:
INPUT = README.md groups.dox source.pl source.dox
You need to keep source.pl because it is there the real source to be seen. And source.dox would be more like a C header file.
Not good. The work to transform manually a source.pl into a source.dox led me to write my own compiler (well, technically a filter, that uses only lexical tokens).
The program is available open source at github:
https://github.com/drbeco/doxygenprolog
and is cited here in the official pages among other filters: doxygen helpers
And a little note here, in the official SWI-Prolog site:
SWI-Prolog news
To make doxygen work with an unknown language you need:
Install this filter in someplace PATH can find.
Edit your doxygen .cfg to have:
OPTIMIZE_OUTPUT_FOR_C = NO
INPUT = README.md groups.dox source.pl
EXTRACT_ALL = YES
EXTRACT_STATIC = YES
FILE_PATTERNS = *.pl *.prolog *.swipl
FILTER_PATTERNS = *.pl="dox4pl"
Now you can run your doxygen as you normally do with other languages.

c preprocessor to determine project or exe name

I have a C resource file called resources.rc, which contains the following line to specify the icon used for a project
1000 ICON "icon222.ico"
I would like to use this same resource file for several projects using
a pre processor conditional depending on the project..
e.g
#if __PROJECT__ == "myapp.exe"
1000 ICON "icon222.ico"
#endif
#if __PROJECT__ == "myotherapp.exe"
1000 ICON "icon777.ico"
#endif
Is there a standard C macro or definition that could be used to
achieve something like this ?
As far as I known there is no predefined macro carring a project specific value setup by VC.
So just select one yourself like MYPROJECTNAME and #define it differently in each of your projects and then do test this in your rc file as by your posting.
I'm not sure anymore whether VC uses the pre-processor on the rc file automagically or if you need to apply some mods to VC's build process to have it do this.
Update:
To have this feature added using ${EXENAME} in terms of having global (solition wide) settings for VC a way to go might be shown here: Visual c++ 2008: how to have global settings defined in a solution or/and here: Can I pass a preprocessor definition to the resource compiler through the command line?

Using lint comments with doxygen

For documentation, we usually have to create an additional document describing what we did when any lint messages were disabled in code (e.g. /* lint --e228).
It would make it much easier to use it with doxygen (as we create this anyhow).
Though, I wasn't able to find any solution on how to make doxygen using these lint comments.
Did anyone try this?
Is there any solution how to use the stric '/*lint' but anyhow add it to doxygen?
Thanks!
This can be accomplished by defining a macro to expand into the lint expression comment, but making the macro expand into a different comment when expanded by doxygen.
The trick is to use the -save instruction to PC-lintTM or FlexeLintTM:
#ifndef LINT_CONTROL
#define LINT_CONTROL(X) /*lint -save X */ //lint X
#endif
int main () {
int a; LINT_CONTROL(-e530)
return a != a;
}
Then, in your doxygen configuration file, you can enable expansion of certain preprocessor macros. In particular, we can change LINT_CONTROL to expand into a doxygen-ated comment instead.
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = "LINT_CONTROL(X)=//! lint control: X"
Alternatively, if you have FlexeLintTM, then you can modify the shrouded source so that a doxygen comment can be used to trigger the lint control. The technique is described on the Gimpel Software Discussion Forum. (This link seems dead, and the new discussion forum seems to no longer contain the referenced discussion any longer.)
PC-lint and FlexeLint are trademarks of Gimpel Software.

How can I get Eclipse to index code inside #ifdef .... #endif

I'm using eclipse to work on some c code and it is not indexing code inside conditional compilation blocks like this:
#ifdef USE_FEATURE_A
int feature_a(...) {
some = code(here);
}
#endif
How can I get eclipse to index the feature_a function?
You could tell eclipse that USE_FEATURE_A is defined. Open your project properties and go to the "C/C++ General->Paths and Symbols" page, under the "Symbols" tab click the "Add" button and put USE_FEATURE_A in the name feild and click OK.
Note: this will cause it not to index any #else sides to your preprocessor stuff... so unless they are all like the one in question you can't AFAIK, but if they are they you're good. (Eclipse contains a C preprocessor that it uses to analyize your code all the stuff above does is essentially the same as adding -DUSE_FEATURE_A to your command line so Eclipse's preprocessor will behave differently from the one in your compiler)
This is an easier and in my opinion more elegant solution to the one selected as the solution:
If someone has the same problem (as I had), this can (now?) easily be solved by going to Window->Preference->C/C++/Indexer and enable "Index all header variants".
Then click Project->C/C++ Indexer->rebuild and clean and build your project. This should resolve all error originating from preprocessor commands.
For what it's worth, getting eclipse to parse conditionally compiled code is much harder to do than would appear at first glance. I found a paper on by IBM from 2007 where they said they will prioritize for the "next release".
Handling Conditional Compilation in CDT's Core
I had this same problem, but the code conditionally eliminated by preprocessing was perfectly valid c code and I wanted it formatted... This was my solution:
1) Global find/replace of #if to #JUNKif
2) Ctrl-Shift-F to reformat the source
3) Another global find/replace of #JUNKif to #if
One way to index code under flag in Eclipse(Kepler) c/c++Editor.
You can enable the compilation flags in Eclipse editor so that code under them can be indexed.
Properties > Preprocessor Include Paths > CDT User settings Entries
Click on ADD and add the Preprocessor Macro and you can specify its value.
Best way I guess is to use the Indexer option : Project Properties>C/C++ General>Indexer.
You can choose Enable project specific settings
I prefer choosing "Use active build configuration" so that all files which are actually built in the project are indexed.
Anyhow you can also choose to index all files in the project even if they are not included in the build ...

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

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.

Resources