Add gcml.h
This commit is contained in:
commit
879d292673
314
gcml.h
Normal file
314
gcml.h
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
#ifndef COMMON_MACROS_H
|
||||||
|
#define COMMON_MACROS_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// General Utility Macros
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the minimum of two values.
|
||||||
|
*/
|
||||||
|
#define MIN(a, b) (( (a) < (b) ) ? (a) : (b))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the maximum of two values.
|
||||||
|
*/
|
||||||
|
#define MAX(a, b) (( (a) > (b) ) ? (a) : (b))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calculates the number of elements in an array.
|
||||||
|
*/
|
||||||
|
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Suppresses compiler warnings for unused variables.
|
||||||
|
*/
|
||||||
|
#define UNUSED(x) (void)(x)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Aligns a value `x` up to the nearest multiple of `align`.
|
||||||
|
*/
|
||||||
|
#define ALIGN_UP(x, align) (((x) + ((align)-1)) & ~((align)-1))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Aligns a value `x` down to the nearest multiple of `align`.
|
||||||
|
*/
|
||||||
|
#define ALIGN_DOWN(x, align) ((x) & ~((align)-1))
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Debugging and Logging Macros
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
/**
|
||||||
|
* @brief Prints debug messages with file name, line number, and function name.
|
||||||
|
*/
|
||||||
|
#define DEBUG_PRINT(fmt, ...) \
|
||||||
|
fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt "\n", \
|
||||||
|
__FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_PRINT(fmt, ...) // No operation in release builds
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logs informational messages.
|
||||||
|
*/
|
||||||
|
#define LOG_INFO(fmt, ...) \
|
||||||
|
fprintf(stdout, "INFO: " fmt "\n", ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logs warning messages.
|
||||||
|
*/
|
||||||
|
#define LOG_WARN(fmt, ...) \
|
||||||
|
fprintf(stderr, "WARNING: " fmt "\n", ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logs error messages.
|
||||||
|
*/
|
||||||
|
#define LOG_ERROR(fmt, ...) \
|
||||||
|
fprintf(stderr, "ERROR: " fmt "\n", ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logs fatal error messages and exits the program.
|
||||||
|
*/
|
||||||
|
#define LOG_FATAL(fmt, ...) do { \
|
||||||
|
fprintf(stderr, "FATAL: " fmt "\n", ##__VA_ARGS__); \
|
||||||
|
exit(EXIT_FAILURE); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Assertion Macros
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Asserts a condition and logs an error message if the condition is false.
|
||||||
|
*/
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#define ASSERT(cond, fmt, ...) do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
fprintf(stderr, "Assertion failed: (%s), function %s, file %s, line %d.\n", \
|
||||||
|
#cond, __func__, __FILE__, __LINE__); \
|
||||||
|
fprintf(stderr, fmt "\n", ##__VA_ARGS__); \
|
||||||
|
abort(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define ASSERT(cond, fmt, ...) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Stringification Macros
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts a macro argument to a string.
|
||||||
|
*/
|
||||||
|
#define STRINGIFY(x) #x
|
||||||
|
#define TOSTRING(x) STRINGIFY(x)
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Token Pasting Macros
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Concatenates two tokens.
|
||||||
|
*/
|
||||||
|
#define CONCAT(a, b) a ## b
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Concatenates three tokens.
|
||||||
|
*/
|
||||||
|
#define CONCAT3(a, b, c) a ## b ## c
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Memory Management Macros
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates memory and checks for allocation failure.
|
||||||
|
* @param ptr The pointer to assign the allocated memory.
|
||||||
|
* @param size The size in bytes to allocate.
|
||||||
|
*/
|
||||||
|
#define SAFE_MALLOC(ptr, size) do { \
|
||||||
|
(ptr) = malloc(size); \
|
||||||
|
if ((ptr) == NULL) { \
|
||||||
|
LOG_FATAL("Memory allocation failed for size %zu", (size_t)(size)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates zero-initialized memory and checks for allocation failure.
|
||||||
|
* @param ptr The pointer to assign the allocated memory.
|
||||||
|
* @param count The number of elements to allocate.
|
||||||
|
* @param type The type of each element.
|
||||||
|
*/
|
||||||
|
#define SAFE_CALLOC(ptr, count, type) do { \
|
||||||
|
(ptr) = calloc((count), sizeof(type)); \
|
||||||
|
if ((ptr) == NULL) { \
|
||||||
|
LOG_FATAL("Memory allocation (calloc) failed for count %zu of type %s", \
|
||||||
|
(size_t)(count), #type); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees memory and sets the pointer to NULL.
|
||||||
|
* @param ptr The pointer to free.
|
||||||
|
*/
|
||||||
|
#define SAFE_FREE(ptr) do { \
|
||||||
|
free(ptr); \
|
||||||
|
ptr = NULL; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Type Casting Macros
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Safely casts a pointer to a specific type.
|
||||||
|
* @param ptr The pointer to cast.
|
||||||
|
* @param type The target type.
|
||||||
|
*/
|
||||||
|
#define SAFE_CAST(ptr, type) ((type)(ptr))
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Bit Manipulation Macros
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a bit at a specific position.
|
||||||
|
* @param x The variable.
|
||||||
|
* @param pos The bit position.
|
||||||
|
*/
|
||||||
|
#define SET_BIT(x, pos) ((x) |= (1U << (pos)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears a bit at a specific position.
|
||||||
|
* @param x The variable.
|
||||||
|
* @param pos The bit position.
|
||||||
|
*/
|
||||||
|
#define CLEAR_BIT(x, pos) ((x) &= ~(1U << (pos)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Toggles a bit at a specific position.
|
||||||
|
* @param x The variable.
|
||||||
|
* @param pos The bit position.
|
||||||
|
*/
|
||||||
|
#define TOGGLE_BIT(x, pos) ((x) ^= (1U << (pos)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if a bit at a specific position is set.
|
||||||
|
* @param x The variable.
|
||||||
|
* @param pos The bit position.
|
||||||
|
* @return Non-zero if the bit is set, zero otherwise.
|
||||||
|
*/
|
||||||
|
#define CHECK_BIT(x, pos) (((x) >> (pos)) & 1U)
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Compile-Time Assertion Macro
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Performs a compile-time assertion.
|
||||||
|
* @param expr The expression to evaluate.
|
||||||
|
* @param msg The message to display if the assertion fails.
|
||||||
|
*/
|
||||||
|
#define STATIC_ASSERT(expr, msg) _Static_assert(expr, msg)
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Deprecation Warning Macros
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks a function as deprecated with a custom message.
|
||||||
|
*/
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
|
#define DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define DEPRECATED(msg) __declspec(deprecated(msg))
|
||||||
|
#else
|
||||||
|
#pragma message("WARNING: DEPRECATED macro is not supported for this compiler.")
|
||||||
|
#define DEPRECATED(msg)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Loop Macros
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Iterates over each element in an array.
|
||||||
|
* @param item The loop variable.
|
||||||
|
* @param array The array to iterate over.
|
||||||
|
*/
|
||||||
|
#define FOREACH(item, array) \
|
||||||
|
for (size_t keep = 1, \
|
||||||
|
count = ARRAY_SIZE(array), \
|
||||||
|
i = 0; \
|
||||||
|
keep && i < count; \
|
||||||
|
keep = !keep, i++) \
|
||||||
|
for (item = (array) + i; keep; keep = !keep)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Repeats a block of code `n` times.
|
||||||
|
* @param n The number of times to repeat.
|
||||||
|
* @param block The block of code to execute.
|
||||||
|
*/
|
||||||
|
#define REPEAT(n, block) \
|
||||||
|
for (size_t _i = 0; _i < (n); ++_i) { block; }
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Swap Macro
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Swaps two variables of the same type.
|
||||||
|
* @param a The first variable.
|
||||||
|
* @param b The second variable.
|
||||||
|
*/
|
||||||
|
#define SWAP(a, b) do { \
|
||||||
|
typeof(a) _swap_temp = (a); \
|
||||||
|
(a) = (b); \
|
||||||
|
(b) = _swap_temp; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Execute Once Macro
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Executes a block of code only once.
|
||||||
|
* @param block The block of code to execute.
|
||||||
|
*/
|
||||||
|
#define DO_ONCE(block) \
|
||||||
|
do { \
|
||||||
|
static int _do_once_flag = 0; \
|
||||||
|
if (!_do_once_flag) { \
|
||||||
|
_do_once_flag = 1; \
|
||||||
|
block \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Utility Macros
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calculates the offset of a member within a struct.
|
||||||
|
* @param type The struct type.
|
||||||
|
* @param member The member within the struct.
|
||||||
|
*/
|
||||||
|
#define OFFSET_OF(type, member) ((size_t) &(((type *)0)->member))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the containing struct from a member pointer.
|
||||||
|
* @param ptr The pointer to the member.
|
||||||
|
* @param type The type of the containing struct.
|
||||||
|
* @param member The member within the struct.
|
||||||
|
*/
|
||||||
|
#define CONTAINER_OF(ptr, type, member) \
|
||||||
|
((type *)((char *)(ptr) - OFFSET_OF(type, member)))
|
||||||
|
|
||||||
|
#endif // COMMON_MACROS_H
|
Loading…
Reference in New Issue
Block a user