hs-bindgen-1.0.0.0: test-artefacts/headers/test_01.h
/* This example header contains various definitions
* to smoke test hs-bindgen code generation end-to-end.
* See test-th and test-pp tests.
*/
/**
* @file test_01.h
*
* @brief Example header containing various definitions to smoke test hs-bindgen code generation end-to-end.
* @details This file demonstrates various Doxygen documentation features
* including commands, lists, code examples, and more.
*
* @note This is a test file for documentation generation
* @warning Do not use in production without review
*/
#ifndef TEST_01_H
#define TEST_01_H
/* Standard headers. */
#include <stdlib.h>
/**
* @struct StructBasic
* @brief Basic structure with two fields.
* @details This structure demonstrates simple field documentation
* with inline comments.
*
* Example usage:
*
* @code
* struct StructBasic sb;
* sb.field1 = 42;
* sb.field2 = 'A';
* @endcode
*
* @invariant field1 should be positive in normal usage
* @since 1.0
*/
struct StructBasic {
int field1; /**< Integer field. @note Usually positive */
char field2; /**< Character field. Valid range: @b A-Z */
};
/**
* @struct StructFixedSizeArray
* @brief Structure containing a fixed size array.
*
* @attention The array size is fixed at compile time
*
* Memory layout:
* - 4 bytes for integer x
* - 5 bytes for character array
* - Padding may be added by compiler
*/
struct StructFixedSizeArray {
int x; /**< Integer value. @sa StructBasic::field1 */
char ys[5]; /**< Fixed size character array of length 5
@warning Not null-terminated by default */
};
/**
* @def PLUS(x,y)
* @brief Macro that adds two values and adds 1L to the result.
* @details This macro demonstrates parameter documentation and
* potential issues with macro expansion.
*
* @param[in] x First operand (should be parenthesized)
* @param[in] y Second operand (should be parenthesized)
* @return The result of x + y + 1L
*
* @warning This macro doesn't parenthesize arguments, so be careful with:
* @code
* PLUS(a & b, c | d) // Probably not what you want!
* @endcode
*
* @todo Add parentheses for safety
*/
#define PLUS(x,y) x + y + 1L
/**
* @struct StructBitfield
* @brief Structure with bitfield definitions.
* @details Demonstrates various bitfield sizes and their documentation.
*
* Total size considerations:
* -# Regular int field: 32 bits
* -# Bitfields packed together: 7 bits total
* -# Compiler may add padding
*
* @par Thread Safety:
* Bitfield access is not atomic. Use appropriate synchronization.
*/
struct StructBitfield {
int a; /**< Integer field (full width) */
unsigned int b : 1; /**< 1-bit flag. @c 0 = false, @c 1 = true */
unsigned int c : 1; /**< 1-bit flag. Values: {0, 1} */
int d : 5; /**< 5-bit signed field. Range: [-16, 15] */
};
/**
* @brief Multiply and add function (fused multiply-add).
* @details Computes @f$ result = x \times y + z @f$
*
* This function demonstrates:
* - Parameter direction documentation
* - Mathematical formulas
* - Example code
*
* @param[in] x First multiplier
* @param[in] y Second multiplier
* @param[in] z Addend
* @return The result of (x * y) + z
*
* @par Example:
* @code
* int result = my_fma(3, 4, 5); // Returns 17
* @endcode
*
* @note No overflow checking is performed
* @see https://en.wikipedia.org/wiki/Multiply%E2%80%93accumulate_operation
*/
static inline int my_fma(int x, int y, int z) {
return x * y + z;
}
/**
* @struct StructFLAM
* @brief Structure with a flexible array member.
* @details Contains a length field and a flexible array of long integers.
* This is a C99 feature.
*
* @par Memory Management:
* Must be allocated dynamically with extra space for the array:
* @code
* size_t size = sizeof(struct StructFLAM) + n * sizeof(long);
* struct StructFLAM *p = malloc(size);
* @endcode
*
* @remark Flexible array members must be the last member
* @since C99
*/
struct StructFLAM {
int length; /**< Number of elements in the flexible array
@invariant length >= 0 */
long numbers[]; /**< Flexible array member of long integers
@warning Must not be accessed beyond length */
};
/**
* @brief Allocate a StructFLAM with space for n elements.
* @details Initializes the numbers array with values from 0 to n-1.
* This demonstrates proper allocation of flexible array members.
*
* Algorithm:
* -# Allocate memory for structure plus array
* -# Set length field
* -# Initialize array elements sequentially
*
* @param[in] n Number of elements to allocate in the flexible array
* @pre n >= 0
* @return Pointer to the allocated StructFLAM, or NULL if allocation fails
* @retval NULL if allocation fails or n < 0
* @retval non-NULL pointer to initialized structure
*
* @par Error Handling:
* Check return value for NULL before use.
*
* @b Example:
* @code
* struct StructFLAM *arr = flam_alloc(10);
* if (arr) {
* // Use arr
* flam_free(arr);
* }
* @endcode
*
* @sa flam_free()
*/
static inline struct StructFLAM *flam_alloc(int n) {
struct StructFLAM *ptr = malloc(sizeof(struct StructFLAM) + sizeof(long) * n);
if (ptr) {
ptr->length = n;
for (int i = 0; i < n; ++i) {
ptr->numbers[i] = i; /**< Initialize each element with its index */
}
}
return ptr;
}
/**
* @brief Free a previously allocated StructFLAM.
*
* @param[in,out] ptr Pointer to the StructFLAM to free
* @pre ptr must be either NULL or a valid pointer returned by flam_alloc()
* @post ptr is no longer valid after this call
*
* @note Safe to call with NULL pointer
* @sa flam_alloc()
*/
static inline void flam_free(struct StructFLAM *ptr) {
free(ptr);
}
/**
* @brief Reverses the elements in the flexible array member in place.
*
* @param s Pointer to the structure containing the numbers to reverse.
* If @p s is NULL or @c s->length < 2, the function returns immediately.
*/
static inline void reverse(struct StructFLAM *s) {
if (!s || s->length < 2) return;
for (int i = 0, j = s->length - 1; i < j; i++, j--) {
long temp = s->numbers[i];
s->numbers[i] = s->numbers[j];
s->numbers[j] = temp;
}
}
/**
* @union longDouble
* @brief Union representing a value as either a long long or a double.
* @details This union demonstrates type punning capabilities.
*
* @warning Type punning through unions may have undefined behavior
* in some cases. Use with caution.
*
* Size: @c sizeof(double) or @c sizeof(long long), whichever is larger
*/
union longLongOrDouble {
long long l; /**< Value interpreted as long long (typically 64 bits) */
double d; /**< Value interpreted as double (IEEE 754 double precision) */
};
/**
* @defgroup enumerations Enumeration Types
* @brief Various enumeration examples
* @details These enumerations demonstrate different patterns and documentation styles.
* @{
*/
/**
* @enum EnumBasic
* @brief Basic enumeration with sequential values starting at 0.
*
* This enumeration uses default values:
* - First element starts at 0
* - Subsequent elements increment by 1
*/
enum EnumBasic {
ENUM_BASIC_A, /**< First value (implicitly 0) */
ENUM_BASIC_B, /**< Second value (implicitly 1) */
ENUM_BASIC_C /**< Third value (implicitly 2) */
};
/**
* @enum EnumNeg
* @brief Enumeration starting with a negative value.
*
* Demonstrates that enums can have negative values.
*
*/
enum EnumNeg {
ENUM_NEG_A = -1, /**< Negative starting value */
ENUM_NEG_B, /**< Zero (incremented from -1) */
ENUM_NEG_C /**< Positive value */
};
/**
* @enum EnumNonSeq
* @brief Enumeration with non-sequential values.
* @details Used for status codes or magic numbers.
*
* Common uses:
* - HTTP status codes
* - Error codes
* - Protocol constants
*/
enum EnumNonSeq {
ENUM_NON_SEQ_A = 200, /**< @brief OK status
@details Similar to HTTP 200 */
ENUM_NON_SEQ_B = 301, /**< @brief Redirect status
@details Similar to HTTP 301 */
ENUM_NON_SEQ_C = 404 /**< @brief Not found status
@details Similar to HTTP 404 */
};
/**
* @enum EnumSame
* @brief Enumeration with multiple constants sharing the same value.
* @warning Be careful when switching on these values
*
* @deprecated Consider using unique values to avoid confusion
*/
enum EnumSame {
ENUM_SAME_A = 0, /**< Initial state */
ENUM_SAME_B = 100, /**< State B */
ENUM_SAME_C = 100, /**< State C @warning Same value as ENUM_SAME_B */
ENUM_SAME_D = 200 /**< Final state */
};
/** @} */ // end of enumerations group
/**
* @struct thing
* @brief Simple structure with a single integer field.
* @details This structure is used to demonstrate function parameters
* and return values with structures.
*
* @par Design Rationale:
* Kept simple to test structure passing mechanisms.
*/
struct thing {
int x; /**< Integer field. Can be negative. */
};
/**
* @brief Returns the integer field of a thing.
* @details Simple accessor function.
*
* @param[in] x A struct thing (passed by value)
* @return The value of x.x
*
* @par Performance Note:
* Structure is passed by value, which may be inefficient for larger structures.
*/
static inline int thing_fun_1(struct thing x) {
return x.x;
}
/**
* @brief Creates a struct thing initialized with the given integer.
*
* @param[in] x Integer to initialize the thing's field
* @return A struct thing with field x set to the parameter
*
* @code
* struct thing t = thing_fun_2(42);
* assert(t.x == 42);
* @endcode
*/
static inline struct thing thing_fun_2(int x) {
struct thing res = { .x = x };
return res;
}
/**
* @brief Returns a struct thing with the field doubled.
* @details Demonstrates structure transformation.
*
* @param[in] x A struct thing
* @return A struct thing with field x equal to input x.x multiplied by 2
*
* @note May overflow if x.x > INT_MAX/2
*
* @par Example Chain:
* @code
* struct thing t1 = thing_fun_2(10);
* struct thing t2 = thing_fun_3(t1); // t2.x == 20
* struct thing t3 = thing_fun_3(t2); // t3.x == 40
* @endcode
*/
static inline struct thing thing_fun_3(struct thing x) {
struct thing res = { .x = x.x * 2 };
return res;
}
/**
* @brief Sums an integer and the elements of a fixed-size array of length 3.
* @details The first element of the array is doubled before summing.
*
* @param[in] x Integer value
* @param[in,out] xs Array of 3 integers (first element modified!)
* @return Sum of x and the modified array elements
*
* @warning This function modifies the input array!
*
* @par Side Effects:
* - @c xs[0] is multiplied by 2
* - Other array elements unchanged
*
* @code
* int arr[3] = {1, 2, 3};
* int result = sum3(10, arr);
* // result == 10 + 2 + 2 + 3 == 17
* // arr is now {2, 2, 3}
* @endcode
*/
static inline int sum3(int x, const int xs[3]) {
const int x0 = xs[0] * 2;
return x + x0 + xs[1] + xs[2];
}
/**
* @typedef triple
* @brief Type alias for an array of 3 integers.
* @details Demonstrates typedef with arrays.
*
* @note Array parameters decay to pointers in C
*
* Usage patterns:
* -# Stack allocation: @c triple t = {1, 2, 3};
* -# Initialization: @c triple t = {0}; // All zeros
* -# Parameter passing: Decays to @c int*
*/
typedef int triple[3];
/**
* @brief Sums an integer and the elements of a triple array.
* @details The first element of the array is tripled before summing.
*
* Comparison with sum3():
* - sum3: multiplies first element by 2
* - sum3b: multiplies first element by 3
*
* @param[in] x Integer value
* @param[in,out] xs Triple array of integers
* @return Sum of x and the modified array elements
*
* @pre xs must point to at least 3 integers
* @post xs[0] = original xs[0] * 3
*
* @see sum3()
*/
static inline int sum3b(int x, const triple xs) {
int x0 = xs[0] * 3;
return x + x0 + xs[1] + xs[2];
}
#endif /* TEST_01_H */