Doxygen 1.8.18 - Nested structure link generation - c

I am using doxygen 1.8.18 and want to have a link in html generated documentation for a variable within a nested stucture. I'm trying to make a link for the following scenario:
typdef struct{
ui8 var;
} Struct2_ts;
typdef struct{
Struct2_ts Struct2;
} Struct1_ts;
Creating link for the variable and the structure where it is defined is functional:
#Struct2_ts.var //this works
However my goal is to create a link for the variable in nested structure:
#Struct1_ts.Struct2_ts.var //not working
#Struct1_ts.Struct2.var //not working
Is this supported or am I just doing it wrong?
All the files where stuctures are defined are included by doxyfile configuration. Is there another setting which affects this in doxyfile?
Tried going through https://www.doxygen.nl/manual/autolink.html and creating the link in a different way.

The 1.8.18 version is already a bit older, the current version is 1.9.5 (so advise is, independent of the problem, an update would not hurt).
I'm not 100% sure what you would like to see but I imagine it is one of the links as show here:
I used for this the following source code:
/// \file
///
/// nested \ref Struct2_ts.var "Struct1_ts.Struct2_ts.var"
///
/// nested \ref Struct2_ts.var "Struct1_ts.Struct2.var"
typdef struct Struct2_ts {
ui8 var;
} Struct2_ts;
typdef struct{
Struct2_ts Struct2;
} Struct1_ts;
and the settings:
QUIET = YES
EXTRACT_ALL = YES
Doxygen does not, always, follow the variables as shown, so the auto linking is not always working for the nested cases. You should also use a named struct and not an anonymous struct
With the \ref command one can specify where the links points to and what the text is that should be shown in a hyperlink.

Related

Any alternatives to maintaining two separate structs with different names?

Say I have an existing C header that defines a struct with a generic name, inside generic.h like this:
typedef struct generic_name_s {
int count;
} generic_name_t;
I'd like to make generic_name_t type available to users of my SDK, but with a specific name instead of the generic one, so I don't pollute the namespace. I cannot simply use:
typedef generic_name_t specific_name_t;
since that would require including generic.h inside specific.h, and the namespace I'm exporting to only allows exporting headers that conform to the specific naming conventions (i.e. users of my library can only include specific.h and not generic.h).
One option is to maintain two separate copies of the struct, one with the generic and one with the specific name, but that seems error-prone. Is there a cleaner way to do this?
I've tried forward-declaring specific_name_t in specific.h:
typedef struct generic_name_s specific_name_t;
And then in specific.c, I #include "generic.h", which I thought would complete the definition of struct generic_name_s, but when a user of the library uses it (by doing "#include <specific.h>"), they still cannot access the struct members "variable has incomplete type".

Library file (.a) where the contents of the structure changes

I am creating an algorithm in C that is confidential and cannot be shared with external customers. So, I decided to go with creating a library (.a) file which compiles my algorithm and lets others use it without modifying it. It basically alters the data of a variable within a structure. Now, the structure as such is visible externally (The structure is defined in a separate header file which is included in my .c file) and is generated based on user's configuration. But the said variable is always present within the structure - only remaining data is changed based on user's configuration.
The problem is that if the structure is not exactly the one I used to create the library file, the code fails.
So is there a way to create a library file to modify the data inside a structure, if the structure itself is not available in the beginning?
Any help is greatly appreciated...
Technically all structures you use must be character by character equal everywhere. If you have any difference between the same structure in two (or more) translation units that will lead to undefined behavior.
There are ways around that though, for example by using nested structures. For example you could create one structure to contain your private data, and then another structure whose first member is an instance of the first private structure.
For example something like this:
struct private_data
{
// TODO: The private members here
};
struct public_data
{
struct private_data private;
// TODO: The public members here
};
This is in effect similar to inheritance of an object-oriented language. A pointer to the public_data structure can be cast as a pointer to the private_data structure and passed to the functions that need it.
To keep the private data, well, private you could use opaque data types and opaque pointers:
// Forward declaration of the actual private data
struct actual_private_data;
// The "public" private structure
struct private_data
{
// Pointer to the actual private data
struct actual_private_data *private;
};
It's important to note that this only works for the private data used for the library. If the public data structure contains data that needs to be accessed by the library as well, you might want to rename the private_data structure and put the common data there. Note that this common data must be in all variants of the structure, it can't be auto-generated differently than what is used in the library.
If you are interested only in one data member of a structure,Then get the address of that variable in your confidential application and modify it's value.

Specman e: All files start with the word "package" - what does it mean?

in my verification environment all e files starts with the word "package", i.e.:
<'
package spi;
.
.
.
'>
Do you know what does it mean?
Thank you for your help.
package is an encapsulation concept in e. It is similar to a namespace in C++. This means that, for example a struct called foo inside one package is totally different from a struct called foo inside a different package.
In addition to creating namespaces (that avoid name clashes), it also allows to use access control on types and struct members.
A type, a field, a method, or an event can be declared as package-private, for example:
package type color: [RED, GREEN];
struct packet {
package foo() is { ... };
};
A type or a struct member declared with the package access modifier, can only be accessed from within the same package. By the way, for struct members there are also private and protected access modifiers. protected means that the field or the method cannot be accessed from within a different struct, and private just means both package and protected. (Notice that the meaning of these access modifiers is different than in C++ or in Java; for example, in C++ the difference between protected and private is whether the member can be accessed from within the same exact class, or from within the class and its subclasses).

doxygen - documentation after members (///<) does not work

Heya,
I'm trying to document my C code with doxygen, however using the "documentation after members" style doesn't seem to work for me. The doxygen documentation says:
Putting documentation after members
If you want to document the members of a file, struct, union, class, or enum, it is sometimes desired to place the documentation block after the member instead of before. For this purpose you have to put an additional < marker in the comment block. Note that this also works for the parameters of a function.
Here are some examples:
[...]
Most often one only wants to put a brief description after a member. This is done as follows:
int var; //!< Brief description after the member
or
int var; ///< Brief description after the member
Minmal source example:
/** #file test.c */
void foo(void) {
uint8_t bar; ///< Some random variable
}
My Doxyfile is pasted here.
Instead of getting some description of the variable in the documentation, I get this:
2.1.1 Function Documentation
2.1.1.1 void foo ( void )
< Some random variable
Anyone happens to have an idea why?
The member documentation syntax is meant for, well, members.
Members are values in a class or struct (or however your language might call it). Local variables are not members and thus not covered by doxygen.
The reason for this is that usually the members of a class are critical for its state, so you desperately want to document those, as derived classes might use protected members for example.
Functions on the other hand don't need such documentation for their local variables. After all, those are local. A function should thereby be defined by its total observable behaviour, as the local variables aren't important for the user:
struct object_type{
struct object_state_type state; ///< the object's state
};
void bad_documentation(void) {
uint8_t bar; ///< Some random variable
}
/// \brief Initializes the global state of the omnipotence object.
void good_documentation(void) {
uint8_t bar;
/** \remark The object needs to be initialized exactly once,
* otherwise we have some problems.
*/
assert(some_global_var != 0);
/** One can check `some_global_var` whether the global object
* has been initialized
*/
some_global_var = 1;
/// Finally, the object going to be initialized.
impl_obj_state_init(&the_global_object.state);
}
Doxygen allows you to document members of a file, struct, union, class, or enum. The code you have displayed is showing a local variable of a method and not a member of one of those entities.

How do I create an array of namespaces?

How can I create an array of namespaces? And because it seems like a long shot, if this is impossible, is there something similar to a namespace that can be made into an array?
The namespace, if it helps, contains these variables:
const int maxx=// depends on the particular namespace
// I need an array to go through each namespace and
// pick out the variable
const int maxy=// depends on particular namespace
//prgm is a class I made
prgm sector[maxx][maxy];
// another array of prgms. int is my shorthand of saying "depends on
// particular namespace", so is char.
prgm programs[int]={prgm1(int,int,char),prgm2(int,int,char)...
So any help would be welcome.
You could use reflection, but I think you should rethink your design.
I am not sure what language you are talking about, but in many (most?) languages, references to constants are replaced by the constant value at compile time. So they are no longer present at runtime and even reflection won't help.
You could create a class in each namespace that exposes the constants as (static) properties. Then you can use reflection to search the class in each namespace and obtain the constant values from the properties.
But, as mentioned by others, you should really rethink your design. Finally, namespaces are usually not accessable via reflection because they just extend the class names of the contained classes (and other stuff). Or is there a (non-esoteric) language that exposes namespaces as entities via reflection?
For .NET the reference for the System.Type.Namespace property states the following.
A namespace is a logical design-time naming convenience, used mainly to define scope in an application and organize classes and other types in a single hierarchical structure. From the viewpoint of the runtime, there are no namespaces.
Is this supposed to be C++? Sounds like you need to define a class, not a namespace, then create instances (objects) of that class and put them in an array.
So the sector variable gets tricky, since it is sized based on the value of maxx and maxy parameters that would be passed to the constructor of the class. You can take care of that problem by using a container class or a dynamically-allocated multi-dimensional array instead.
If you talk about C++, in there you can't pass namespaces as entities around. But you can do so with types, as type argument to templates. In this case, an MPL sequence could help together with MPL algorithms:
struct c1 { typedef int_<2> value_x; };
struct c2 { typedef int_<3> value_x; };
struct c3 { typedef int_<1> value_x; };
template<typename C> struct get_x : C::value_x { };
typedef vector<c1, c2, c3> scope_vec;
typedef max_element<
transform_view< scope_vec , get_x<_1> >
>::type iter;
You may then create your array like
prgm programs[deref< iter >::type::value];
Note that the search within that type-vector happens at compile time. So the value of the array is determined at compile time either.

Resources