Doxygen: Each line in code listings starts with an asterisk (*) - doxygen

I am using doxygen to create a HTML documentation for a C++ library.
Right now I have the problem that code listings created with \code ... \endcode produce listings where each line starts with an asterisk.
Example:
Have a look at the following code sample:
\code
int a = 5;
int b = func(a);
\endcode
Output:
Have a look at the following code sample:
* int a = 5;
* int b = func(a);
I cannot explain this behaviour -- especially because I use /// instead of /** to mark lines as doxygen documentation. The issue happens for both formattings though.
Does anyone know how to resolve this?
(I am using doxygen 1.8.5)

This is indeed an unfortunate regression in 1.8.5.
I've just pushed a fix to GitHub. Please let me know if it fixes the problem.

It seems this is a bug. Bugzilla entry.
Also this bug could be related.
I managed to get a workaround by changing the following snippet
/// Have a look at the following code sample:
/// \code
/// int a = 5;
/// int b = func(a);
/// \endcode
to the following (note that there are only two slashes):
/// Have a look at the following code sample:
// \code
// int a = 5;
// int b = func(a);
/// \endcode
I am not happy with this because it requires to re-layout all comments and the formatting feels very much unnatural.

Related

Can Sal annotate that parameter members may be mutated?

I am writing a reference-counted linked list of characters data structure in C for practice. I want to try using Sal in it to annotate function parameters for this practice.
I have an input paremeter(named This), which I want to annotate to make it clear that the specified parameter's members must be mutable in order for the function to behave as expected.
The situation is analogous to the code below.
#include <Windows.h>
typedef struct Box {
ULONG val;
} Box;
ULONG Box_decrement(_In_ Box *This) {
return InterlockedDecrement(&(This->val));
}
int main(int argc, char **argv) {
Box b = {2};
Box_decrement(&b);
return (BYTE)b.val;
};
Is there an existing Sal annotation that can be used to annotate the This parameter of the Box_increment function to make it clear from the function signature that the function modifies one or more members of the Box that has been passed to it?
Something like _InternallyMutable_(but exist):
#include <Windows.h>
typedef struct Box {
ULONG val;
} Box;
ULONG Box_decrement(_InternallyMutable_ _In_ Box *This) {
return InterlockedDecrement(&(This->val));
}
int main(int argc, char **argv) {
Box b = {2};
Box_decrement(&b);
return (BYTE)b.val;
};
Best solution so far(unfortunately, there does not seem to be any equivelent in SAL to denote Internally_mutable, there is Unchanged which is the opposite):
#include <Windows.h>
#define _Internally_mutable_(expr) _At_(expr, _Out_range_(!=, _Old_(expr)))
typedef struct Box {
ULONG val;
} Box;
ULONG Box_decrement(_In_ _InternallyMutable_(This) Box *This) {
return InterlockedDecrement(&(This->val));
}
int main(int argc, char **argv) {
Box b = {2};
Box_decrement(&b);
return (BYTE)b.val;
};
Yes! You can. SAL is a wonderful DSL that lets you do basically anything you want if you're psychic enough to infer it from the little bits in the Windows SDK. I've even in the past been able to write super simple custom annotations to detect invalid HANDLE usage with _Post_satisfies_ and friends.
This code seems to work:
_At_(value, _Out_range_(!=, _Old_(value)))
void change_value_supposed_to(int& value) noexcept {
//value += 1;
}
...Running with all native rules in code analysis, I get a warning like this:
Warning C28196 The requirement that '_Param_(1)!=(("pre"), _Param_(1))' is not satisfied. (The expression does not evaluate to true.)
(there, substitute value with your variable)
For _Internally_mutable_, I can do it in the "above the function" style of SAL:
#define _Internally_mutable_(expr) _At_(expr, _Out_range_(!=, _Old_(expr)))
_Internally_mutable_(value)
void change_value_supposed_to_internally_mutable(int& value) noexcept {
//value += 1;
(void)value;
}
...but not inline WITHOUT being repetitive, as you wanted. Not sure why right now - _Curr_ doesn't seem to be working? - I may need another layer of indirection or something. Here's what it looks like:
#define _Internally_mutable_inline_(value) _Out_range_(!=, _Old_(value))
void change_value_supposed_to_internally_mutable_inline(_Internally_mutable_inline_(value) int& value) noexcept {
//value += 1;
(void)value;
}
How I figured this out:
sal.h defines an _Unchanged_ annotation (despite doing web dev for several years now and little C++, I remembered this when I saw your question in a google alert for SAL!):
// annotation to express that a value (usually a field of a mutable class)
// is not changed by a function call
#define _Unchanged_(e) _SAL2_Source_(_Unchanged_, (e), _At_(e, _Post_equal_to_(_Old_(e)) _Const_))
...if you look at this macro closely, you'll see that it just substitutes as:
_At_(e, _Post_equal_to_(_Old_(e)) _Const_)
...and further unrolling it, you'll see _Post_equal_to_ is:
#define _Post_equal_to_(expr) _SAL2_Source_(_Post_equal_to_, (expr), _Out_range_(==, expr))
Do you see it? All it's doing is saying the _Out_range_ is equal to the expression you specify. _Out_range_ (and all the other range SAL macros) appear to accept all of the standard C operators. That behavior is not documented, but years of reading through the Windows SDK headers shows me it's intentional! Here, all we need to do is use the not equals operator with the _Old_ intrinsic, and the analyzer's solver should be able to figure it out!
_Unchanged_ itself is broken?
To my great confusion, _Unchanged_ itself seems broken:
_Unchanged_(value)
void change_value_not_supposed_to(_Inout_ int& value) noexcept {
value += 1;
}
...that produces NO warning. Without the _Inout_, code analysis is convinced that value is uninitialized on function entry. This makes no sense of course, and I'm calling this directly from main in the same file. Twiddling with inlining or link time code generation doesn't seem to help
I've played a lot with it, and various combinations of _Inout_, even _Post_satisfies_. I should file a bug, but I'm already distracted here, I'm supposed to be doing something else right now :)
Link back here if anybody does file a bug. I don't even know what the MSVC/Compiler teams use for bug reporting these days.
Fun facts
5-6 years ago I tried to convince Microsoft to open source the SAL patents! It would have been great, I would have implemented them in Clang, so we'd all be able to use it across platforms! I might have even kicked off a career in static-analysis with it. But alas, they didn't want to do it in the end. Open sourcing them would have meant they might have to support it and/or any extensions the community might have introduced, and I kinda understand why they didn't want that. It's a shame, I love SAL, and so do many others!

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 warning "does not have an associated number"

I am using doxygen 1.8.9.1 and bibtex to generate the reference list. It looks doxygen (or bibtex) don't support longer key.
For example, my bib file looks like
#incollection{mcmaster_phenology_,
title = {The {DSSAT} cropping system model},
volume = {18},
journaltitle = {European Journal of Agronomy},
author = {A, F.},
}
#article{mcmaster_phenology_1,
title = {The {DSSAT} cropping system model},
volume = {18},
journaltitle = {European Journal of Agronomy},
author = {A, F.},
}
My text.cs file looks
namespace Test
{
/// <summary>
/// A test class
/// </summary>
/// <remarks>
/// This is test citation, see \cite mcmaster_phenology_ and
/// \cite mcmaster_phenology_1.
/// </remarks>
public class TestClass
{
}
}
The warning message is:
warning: \cite command to 'mcmaster_phenology_1' does not have an associated number
The final html is
This is test citation, see [1] and [mcmaster_phenology_1].
Seems the maximum length of key is 19 characters. It looks a bug for me. How should I fix it? Thank for any suggestions.

Make Doxygen document a struct/class defined inside a macro call

I have this PACKED macro, that receives a struct definition and returns it with a compiler annotation to make it packed.
For example:
/**
* ...
*/
PACKED(struct A {
/**
* ...
*/
int x;
});
I have tried several Doxygen options to include that documentation, but I've had no success so far. Closest I've come up with is this:
ENABLE_PREPROCESSING = YES
PREDEFINED = PACKED(type)=type
MACRO_EXPANSION = YES
But that messes up the struct and members' documentation (confirmed via doxygen -d Preprocessor).
Ideas?
Turns out it's a bug in Doxygen.
One possible workaround is to use #class, and so on.

How to support custom options with protobuf-net?

I use protobuf-net and ProtoGen.exe to parse following .proto file (given by another project)
enum RGBFlags { FLAG_RED = 1; FLAG_GREEN = 2; FLAG_BLUE = 4; }
message SomeMessage {
// Values from RGBFlags only allowed
optional int32 flags = 2;
}
My fellow programmers in C++ don't care about type safety and treat flags field as a plain integer. I wanted to be more strict and try to avoid such code:
SomeMessage foo = new SomeMessage();
foo.flags = (int)RGBFlags.FLAG_BLUE | (int)RGBFlags.FLAG_GREEN;
I thought that I could use protbuf custom options to amend proto code and modify XSLT transform of ProtoGet to generate necessary `[Flags]' annotations.
extend google.protobuf.EnumOptions {
optional bool generate_bit_field = 60000;
}
enum RGBFlags {
option (generate_bit_field) = true;
FLAG_RED = 1; FLAG_GREEN = 2; FLAG_BLUE = 4;
}
message SomeMessage {
// Values from RGBFlags only allowed
optional int32 flags = 2;
}
Problem is that all custom options appear as uninterpreted_option in the temporary file in ProtoGen.
Any idea what I could do to get [Flags] annotations in my code?
Re flags; the raw protobuf spec doesn't really have support for composite enum values, so in some ways I understand why they are doing it that way. And sadly there is no such this as partial enum, so you can't add the [Flags] in a separate code file.
Re custom options; it is an excellent question, and support for custom options has been raised before. It is definitely something I'd like to add, but relative to other features it simply isn't a massively demanded item, so (due to limited resource) it has not (yet) been investigated fully.
Therefore, I don't have a great answer for you; that feature isn't really there much right now. You could hard-code that one scenario in your xslt (for your specific types). Or wait until I get around to it (I don't have a specific timescale). Or take a peek yourself.