Add links to typedefs in doxygen - c

In the following example, the generated doxygen file will only turn #mystruct and mystruct into links to the definition of mystruct. Is there anyway to have the same behavior for mytype, myenum and FIRST_ELEMENT or is that an inherent limitation of doxygen?
typedef enum myenum {
FIRST_ELEMENT, /**< Some example. */
SECOND_ELEMENT, /**< Some other example. */
} myenum;
typedef int16_t mytype; /**< some example */
typedef struct mystruct {
mytype x; /**< my member */
} mystruct;
/**
* #brief My test function.
*
* This function uses #mytype, #mystruct and #myenum.
*
* #param[in] x input 1.
* #param[in] y input 2.
* #param[in] z input 3 expected to be #FIRST_ELEMENT.
*/
void foo(mytype x, mystruct y, myenum z);

Everything that I described actually works as expected.
Documenting the mistake I was making here in case others make the same.
My mistake was that in the code base I had (not the example I showed here) I had my functions grouped together with defgroup and not my type declarations. Apparently not having defgroup around the types allowed the struct definition to still be visible and linked to in the html, but not the other types.

Related

C - Method overloading with different struct type arguments using macro

I'm trying to achieve method overloading in C, preferably using macros so the header/library can handle the definitions and declarations instead of putting that onto the user. Now I've read this answer about using _Generic however the problem is my functions have struct types. So there's no way to evaluate their type using a __typeof__ of _Generic. I wonder if there is any way at all.
This is how my header file looks like (which is all we should be concerned with)-
#pragma once
// Macros for generic like use of the data structure
// Macros for the stack type itself
/*
* Define stack with corresponding type
* Converts Stack(int) to intstack_t
*/
#define Stack(type) type stack_t
// Macros for functions
/*
* Define createStack function
* Converts createStack(int, 5) to create_intstack(5)
*/
#define createStack(type, capacity) create_ ##type ##stack(capacity)
/*
* Define destroyStack function
* Converts destroyStack(someIntStack) to destroy_intstack(someIntStack)
* Where someIntStack is a pointer to a variable of type intstack_t
*/
#define destroyStack(stack) _Generic(stack, intstack_t*: destroy_intstack, charstack_t*: destroy_charstack)(stack)
/*
* Define push function
* Converts push(someIntStack, data) to intstack_push(someIntStack, data)
* Where someIntStack is a pointer to a variable of type intstack_t
*/
#define push(stack, data) _Generic(stack, intstack_t*: intstack_push, charstack_t*: charstack_push)(stack, data)
// Stack structure definition(s)
// int stack definition
typedef struct IntegerStack {
int top;
unsigned capacity;
int* arr;
}intstack_t;
// char stack definition
typedef struct CharacterStack {
int top;
unsigned capacity;
char* arr;
}charstack_t;
//Stack functions
// int stack functions
intstack_t* create_intstack(int);
void destroy_intstack(intstack_t*);
void intstack_push(intstack_t*, int);
// char stack functions
charstack_t* create_charstack(int);
void destroy_charstack(charstack_t*);
void charstack_push(charstack_t*, char);
Majority of the function declarations (and indirectly, their respective macros) have been removed, as they all essentially function the same. I'm only concerned about the push function macro as provided. The other macros are really there to show what kind of usecase I intend. Obviously the macro used in push using _Generic will not work as intstack_t or charstack_t are not primitive types.
The goal is for the user to be able to use push(stack, data) where the stack can be a variable of either type intstack_t* or charstack_t* and the statement push(stack, data) will be transformed into intstack_push(stack, data) or charstack_push(stack, data) respectively.
_Generic will work with any complete type other than a Variable Length Array. And although you cannot associate incomplete types with values in an _Generic invocation, there is no problem with pointers to incomplete types.
So your push macro will work just fine, even if used in a context where instack_t and charstack_t are opaque.
Sample on coliru: http://coliru.stacked-crooked.com/a/7d9b181af2429c5e

Doxygen: C typedef names in description do not become links

I am using Doxygen on C header files, and I have trouble getting the occurrences of typedef names in description text to become links to the respective typedef definition. This works nicely with structures, but not with typedefs.
Example:
struct _my_s1;
/** Description for typedef my_s1. */
typedef struct _my_s1 my_s1;
struct _my_s2;
/** Description for typedef my_s2. */
typedef struct _my_s2 my_s2;
/**
* #brief Structure _my_s1
*/
struct _my_s1 {
my_s2 * s2t; ///< pointer to my_s2
struct _my_s2 * s2s; ///< pointer to struct _my_s2
/**
* #brief Function f2t
* #param s2t A pointer to my_s2.
* #return An integer.
*/
int (*f2t)(my_s2* s2t);
/**
* #brief Function f2s
* #param s2s A pointer to struct _my_s2.
* #return An integer.
*/
int (*f2s)(struct _my_s2* s2s);
};
/**
* #brief Structure _my_s2
*/
struct _my_s2 {
int a; ///< integer
};
In the output, all occurrences of the typedef name my_s2 in any description text become just plain text. All occurrences of struct _my_s2 become links to the structure definition.
I added the description lines for the typedef definitions after reading How should I classify a typedef with Doxygen? (I was speculating that Doxygen maybe needs to have documentation on something before that something can be the target of a link), but adding the description did not help.
How can I have Doxygen create links to typedefs, like it does for structs?
I am using doxygen 1.8.6 on Ubuntu 14.04.
I do not get any errors when running doxygen on the example above (there is also #file and #defgroup, not shown here).
Andy

GTK-doc not rendering a documentation comment for a struct

I have the following code in a .h file:
/**
* udp_result_s:
* #available: indicates the availability of the property stored in #data
* #data: the property value (will only be meaningful if #available indicates its presence)
*
* A transparent struct, representing the result of a query on a UDP object. Note that the #data field will contain unspecified junk *unless* #available is `udp_PRESENT`.
*/
typedef struct udp_result_s
{
/*< public > */
udp_availability available;
void *data;
} udp_result_s;
For some reason I completely fail to understand, this is not showing up in the documentation generated by GTK-doc. Everything else that is supposed to be generated from this file is - am I missing something really obvious?
Try:
typedef struct
{
/*< public > */
udp_availability available;
void *data;
} udp_result_s;
It will work if you separate the struct definition and typedef, like:
/**
* udp_result_s:
* #available: indicates the availability of the property stored in #data
* #data: the property value (will only be meaningful if #available indicates its presence)
*
* A transparent struct, representing the result of a query on a UDP object. Note that the #data field will contain unspecified junk *unless* #available is `udp_PRESENT`.
*/
struct udp_result_s
{
udp_availability available;
void *data;
};
typedef struct udp_result_s udp_result_s;

Document C in Doxygen despite usage of macros?

I have macros in C source files that generate function declarations as well as for structures.
I made the decision to use doxygen in order to document them, but as long as my source file does not explicitly contain the declaration, doxygen is not generating the appropriate documentation.
Here is a little example; I have a macro that is a kind of idiom for a class declaration:
#define CLASS(x) \
typedef struct _##x x; \
typedef struct _##x *P##x; \
typedef struct _##x **PP##x; \
typedef struct _##x
So instead of writing:
/**
* \struct _Vector
* \brief the vector structure handles stuff to store data accessible by an index.
*/
typedef struct _Vector {
/*#{*/
Container container; /**< inherits from container */
size_t allocated_size; /**< the total allocated size of a vector (private usage) */
void* elements; /**< pointer to the allocated memory space (private usage) */
/*#}*/
} Vector, *PVector;
I may write instead:
/**
* \struct _Vector
* \brief the vector structure handles stuff to store data accessible by an index.
*/
CLASS(Vector) {
/*#{*/
Container container; /**< inherits from container */
size_t allocated_size; /**< the total allocated size of a vector (private usage) */
void* elements; /**< pointer to the allocated memory space (private usage) */
/*#}*/
};
But for the second case, doxygen does not generate the documentation regarding my struct members.
How could I find a compliant solution to such an issue?

When are anonymous structs and unions useful in C11?

C11 adds, among other things, 'Anonymous Structs and Unions'.
I poked around but could not find a clear explanation of when anonymous structs and unions would be useful. I ask because I don't completely understand what they are. I get that they are structs or unions without the name afterwards, but I have always (had to?) treat that as an error so I can only conceive a use for named structs.
Anonymous union inside structures are very useful in practice. Consider that you want to implement a discriminated sum type (or tagged union), an aggregate with a boolean and either a float or a char* (i.e. a string), depending upon the boolean flag. With C11 you should be able to code
typedef struct {
bool is_float;
union {
float f;
char* s;
};
} mychoice_t;
double as_float(mychoice_t* ch)
{
if (ch->is_float) return ch->f;
else return atof(ch->s);
}
With C99, you'll have to name the union, and code ch->u.f and ch->u.s which is less readable and more verbose.
Another way to implement some tagged union type is to use casts. The Ocaml runtime gives a lot of examples.
The SBCL implementation of Common Lisp does use some union to implement tagged union types. And GNU make also uses them.
A typical and real world use of anonymous structs and unions are to provide an alternative view to data. For example when implementing a 3D point type:
typedef struct {
union{
struct{
double x;
double y;
double z;
};
double raw[3];
};
}vec3d_t;
vec3d_t v;
v.x = 4.0;
v.raw[1] = 3.0; // Equivalent to v.y = 3.0
v.z = 2.0;
This is useful if you interface to code that expects a 3D vector as a pointer to three doubles. Instead of doing f(&v.x) which is ugly, you can do f(v.raw) which makes your intent clear.
struct bla {
struct { int a; int b; };
int c;
};
the type struct bla has a member of a C11 anonymous structure type.
struct { int a; int b; } has no tag and the object has no name: it is an anonymous structure type.
You can access the members of the anonymous structure this way:
struct bla myobject;
myobject.a = 1; // a is a member of the anonymous structure inside struct bla
myobject.b = 2; // same for b
myobject.c = 3; // c is a member of the structure struct bla
Another useful implementation is when you are dealing with rgba colors, since you might want access each color on its own or as a single int.
typedef struct {
union{
struct {uint8_t a, b, g, r;};
uint32_t val;
};
}Color;
Now you can access the individual rgba values or the entire value, with its highest byte being r. i.e:
int main(void)
{
Color x;
x.r = 0x11;
x.g = 0xAA;
x.b = 0xCC;
x.a = 0xFF;
printf("%X\n", x.val);
return 0;
}
Prints 11AACCFF
I'm not sure why C11 allows anonymous structures inside structures. But Linux uses it with a certain language extension:
/**
* struct blk_mq_ctx - State for a software queue facing the submitting CPUs
*/
struct blk_mq_ctx {
struct {
spinlock_t lock;
struct list_head rq_lists[HCTX_MAX_TYPES];
} ____cacheline_aligned_in_smp;
/* ... other fields without explicit alignment annotations ... */
} ____cacheline_aligned_in_smp;
I'm not sure if that example strictly necessary, except to make the intent clear.
EDIT: I found another similar pattern which is more clear-cut. The anonymous struct feature is used with this attribute:
#if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__)
#define __randomize_layout __attribute__((randomize_layout))
#define __no_randomize_layout __attribute__((no_randomize_layout))
/* This anon struct can add padding, so only enable it under randstruct. */
#define randomized_struct_fields_start struct {
#define randomized_struct_fields_end } __randomize_layout;
#endif
I.e. a language extension / compiler plugin to randomize field order (ASLR-style exploit "hardening"):
struct kiocb {
struct file *ki_filp;
/* The 'ki_filp' pointer is shared in a union for aio */
randomized_struct_fields_start
loff_t ki_pos;
void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
void *private;
int ki_flags;
u16 ki_hint;
u16 ki_ioprio; /* See linux/ioprio.h */
unsigned int ki_cookie; /* for ->iopoll */
randomized_struct_fields_end
};
Well, if you declare variables from that struct only once in your code, why does it need a name?
struct {
int a;
struct {
int b;
int c;
} d;
} e,f;
And you can now write things like e.a,f.d.b,etc.
(I added the inner struct, because I think that this is one of the most usages of anonymous structs)

Resources