Skip to content

file macro.h

Types

Name
structcw_timeout_ms_t
structcw_timeout_ticks_t

Defines

Name
c_container_of(ptr, type, member)
STRINGIFY(x)
TOSTRING(x)
SECOND(a, b, ...)
IS_PROBE(...)
PROBE()
CAT(a, b)
NOT(x)
CW_NOT_PROBE_
BOOL(x)
IF(condition)
CW_IF_IMPL_(condition)
CW_IF_NOT_EMPTY_(...)
CW_IF_PRESENT_(...)
ASSERT(X)
Assert(X)
MIN(x, y)
MAX(x, y)
UNUSED(expr)
CW_NODISCARD
CW_THREAD_ANNOTATION_ATTRIBUTE_(x)
CW_GUARDED_BY(x)
CW_PT_GUARDED_BY(x)
CW_REQUIRES(...)
CW_EXCLUDES(...)
CW_ACQUIRE(...)
CW_RELEASE(...)
CW_NO_THREAD_SAFETY_ANALYSIS
CW_API_STABLE
CW_API_PROVISIONAL
CW_API_DEPRECATED(reason)
CW_MUST_CHECK_ERRNO
CW_TIMEOUT_MS(ms)
CW_TIMEOUT_TICKS(t)
DLLCALL
DLLEXPORT
BYTE_FORMAT
BYTE_SEPARATOR
BYTES_2_FORMAT_SEPARATOR(SEPARATOR)
BYTES_4_FORMAT_SEPARATOR(SEPARATOR)
BYTES_8_FORMAT_SEPARATOR(SEPARATOR)
BYTES_16_FORMAT_SEPARATOR(SEPARATOR)
BYTES_32_FORMAT_SEPARATOR(SEPARATOR)
BYTES_2_FORMAT
BYTES_4_FORMAT
BYTES_8_FORMAT
BYTES_16_FORMAT
BYTES_32_FORMAT
BYTES_2(bytes)
BYTES_4(bytes)
BYTES_8(bytes)
BYTES_16(bytes)
BYTES_32(bytes)
IP32_TO_BYTES_FORMAT
BIT32_TO_BYTES(bits)
IP32_TO_BYTES(ip)
AES_BLOCK_TO_BYTES_FORMAT
AES_BLOCK_TO_BYTES(block)
CW_MAX_PRECISION
CW_MATH_FUNC(x)

Macros Documentation

define c_container_of

cpp
#define c_container_of(
    ptr,
    type,
    member
)
        ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) ); })

define STRINGIFY

cpp
#define STRINGIFY(
    x
)
#x

define TOSTRING

cpp
#define TOSTRING(
    x
)
STRINGIFY(x)

define SECOND

cpp
#define SECOND(
    a,
    b,
    ...
)
b

define IS_PROBE

cpp
#define IS_PROBE(
    ...
)
SECOND(__VA_ARGS__, )

define PROBE

cpp
#define PROBE(
    
)
~, NOT_EMPTY

define CAT

cpp
#define CAT(
    a,
    b
)
a##b

define NOT

cpp
#define NOT(
    x
)
IS_PROBE(CAT(CW_NOT_PROBE_, x))

define CW_NOT_PROBE_

cpp
#define CW_NOT_PROBE_ PROBE()

define BOOL

cpp
#define BOOL(
    x
)
NOT(NOT(x))

define IF

cpp
#define IF(
    condition
)
CW_IF_IMPL_(BOOL(condition))

define CW_IF_IMPL_

cpp
#define CW_IF_IMPL_(
    condition
)
CAT(CW_IF_PRESENT_, condition)

define CW_IF_NOT_EMPTY_

cpp
#define CW_IF_NOT_EMPTY_(
    ...
)

define CW_IF_PRESENT_

cpp
#define CW_IF_PRESENT_(
    ...
)
__VA_ARGS__

define ASSERT

cpp
#define ASSERT(
    X
)

define Assert

cpp
#define Assert(
    X
)

define MIN

cpp
#define MIN(
    x,
    y
)
((x) < (y) ? (x) : (y))

define MAX

cpp
#define MAX(
    x,
    y
)
((x) > (y) ? (x) : (y))

define UNUSED

cpp
#define UNUSED(
    expr
)
    do                \
    {                 \
        (void)(expr); \
    } while (0)

define CW_NODISCARD

cpp
#define CW_NODISCARD

define CW_THREAD_ANNOTATION_ATTRIBUTE_

cpp
#define CW_THREAD_ANNOTATION_ATTRIBUTE_(
    x
)

define CW_GUARDED_BY

cpp
#define CW_GUARDED_BY(
    x
)
CW_THREAD_ANNOTATION_ATTRIBUTE_(guarded_by(x))

define CW_PT_GUARDED_BY

cpp
#define CW_PT_GUARDED_BY(
    x
)
CW_THREAD_ANNOTATION_ATTRIBUTE_(pt_guarded_by(x))

define CW_REQUIRES

cpp
#define CW_REQUIRES(
    ...
)
CW_THREAD_ANNOTATION_ATTRIBUTE_(requires_capability(__VA_ARGS__))

define CW_EXCLUDES

cpp
#define CW_EXCLUDES(
    ...
)
CW_THREAD_ANNOTATION_ATTRIBUTE_(locks_excluded(__VA_ARGS__))

define CW_ACQUIRE

cpp
#define CW_ACQUIRE(
    ...
)
CW_THREAD_ANNOTATION_ATTRIBUTE_(acquire_capability(__VA_ARGS__))

define CW_RELEASE

cpp
#define CW_RELEASE(
    ...
)
CW_THREAD_ANNOTATION_ATTRIBUTE_(release_capability(__VA_ARGS__))

define CW_NO_THREAD_SAFETY_ANALYSIS

cpp
#define CW_NO_THREAD_SAFETY_ANALYSIS CW_THREAD_ANNOTATION_ATTRIBUTE_(no_thread_safety_analysis)

define CW_API_STABLE

cpp
#define CW_API_STABLE

define CW_API_PROVISIONAL

cpp
#define CW_API_PROVISIONAL

define CW_API_DEPRECATED

cpp
#define CW_API_DEPRECATED(
    reason
)

define CW_MUST_CHECK_ERRNO

cpp
#define CW_MUST_CHECK_ERRNO CW_NODISCARD

define CW_TIMEOUT_MS

cpp
#define CW_TIMEOUT_MS(
    ms
)
(ms)

define CW_TIMEOUT_TICKS

cpp
#define CW_TIMEOUT_TICKS(
    t
)
(t)

define DLLCALL

cpp
#define DLLCALL

define DLLEXPORT

cpp
#define DLLEXPORT

define BYTE_FORMAT

cpp
#define BYTE_FORMAT "%.2hX"

define BYTE_SEPARATOR

cpp
#define BYTE_SEPARATOR " "

define BYTES_2_FORMAT_SEPARATOR

cpp
#define BYTES_2_FORMAT_SEPARATOR(
    SEPARATOR
)
BYTE_FORMAT SEPARATOR BYTE_FORMAT

define BYTES_4_FORMAT_SEPARATOR

cpp
#define BYTES_4_FORMAT_SEPARATOR(
    SEPARATOR
)
BYTES_2_FORMAT_SEPARATOR(SEPARATOR) SEPARATOR BYTES_2_FORMAT_SEPARATOR(SEPARATOR)

define BYTES_8_FORMAT_SEPARATOR

cpp
#define BYTES_8_FORMAT_SEPARATOR(
    SEPARATOR
)
BYTES_4_FORMAT_SEPARATOR(SEPARATOR) SEPARATOR BYTES_4_FORMAT_SEPARATOR(SEPARATOR)

define BYTES_16_FORMAT_SEPARATOR

cpp
#define BYTES_16_FORMAT_SEPARATOR(
    SEPARATOR
)
BYTES_8_FORMAT_SEPARATOR(SEPARATOR) SEPARATOR BYTES_8_FORMAT_SEPARATOR(SEPARATOR)

define BYTES_32_FORMAT_SEPARATOR

cpp
#define BYTES_32_FORMAT_SEPARATOR(
    SEPARATOR
)
BYTES_16_FORMAT_SEPARATOR(SEPARATOR) SEPARATOR BYTES_16_FORMAT_SEPARATOR(SEPARATOR)

define BYTES_2_FORMAT

cpp
#define BYTES_2_FORMAT BYTES_2_FORMAT_SEPARATOR(BYTE_SEPARATOR)

define BYTES_4_FORMAT

cpp
#define BYTES_4_FORMAT BYTES_4_FORMAT_SEPARATOR(BYTE_SEPARATOR)

define BYTES_8_FORMAT

cpp
#define BYTES_8_FORMAT BYTES_8_FORMAT_SEPARATOR(BYTE_SEPARATOR)

define BYTES_16_FORMAT

cpp
#define BYTES_16_FORMAT BYTES_16_FORMAT_SEPARATOR(BYTE_SEPARATOR)

define BYTES_32_FORMAT

cpp
#define BYTES_32_FORMAT BYTES_32_FORMAT_SEPARATOR(BYTE_SEPARATOR)

define BYTES_2

cpp
#define BYTES_2(
    bytes
)
(bytes)[0], (bytes)[1]

define BYTES_4

cpp
#define BYTES_4(
    bytes
)
BYTES_2(bytes), BYTES_2(bytes + 2)

define BYTES_8

cpp
#define BYTES_8(
    bytes
)
BYTES_4(bytes), BYTES_4(bytes + 4)

define BYTES_16

cpp
#define BYTES_16(
    bytes
)
BYTES_8(bytes), BYTES_8(bytes + 8)

define BYTES_32

cpp
#define BYTES_32(
    bytes
)
BYTES_16(bytes), BYTES_16(bytes + 16)

define IP32_TO_BYTES_FORMAT

cpp
#define IP32_TO_BYTES_FORMAT BYTES_4_FORMAT_SEPARATOR(".")

define BIT32_TO_BYTES

cpp
#define BIT32_TO_BYTES(
    bits
)
BYTES_4((uint8_t*)&(bits))

define IP32_TO_BYTES

cpp
#define IP32_TO_BYTES(
    ip
)
BIT32_TO_BYTES(ip)

define AES_BLOCK_TO_BYTES_FORMAT

cpp
#define AES_BLOCK_TO_BYTES_FORMAT BYTES_16_FORMAT

define AES_BLOCK_TO_BYTES

cpp
#define AES_BLOCK_TO_BYTES(
    block
)
BIT32_TO_BYTES((block)[0]), BIT32_TO_BYTES((block)[1]), BIT32_TO_BYTES((block)[2]), BIT32_TO_BYTES((block)[3])

define CW_MAX_PRECISION

cpp
#define CW_MAX_PRECISION float

define CW_MATH_FUNC

cpp
#define CW_MATH_FUNC(
    x
)
x##f

Source code

cpp
/*******************************************************************************
 * @file       macro.h
 * @brief
 * @copyright  Copyright (c) 2018-2023. ImagineOn GmbH. www.imagineon.de
 *             All rights reserved.
 ******************************************************************************/

#ifndef COLDWAVEOS_MACRO_H_INCLUDED
#define COLDWAVEOS_MACRO_H_INCLUDED

#include <stdint.h>
#include <stddef.h>

#define c_container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) ); })

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

#define SECOND(a, b, ...) b

#define IS_PROBE(...) SECOND(__VA_ARGS__, )
#define PROBE() ~, NOT_EMPTY

#define CAT(a, b) a##b

#define NOT(x) IS_PROBE(CAT(CW_NOT_PROBE_, x))
#define CW_NOT_PROBE_ PROBE()

#define BOOL(x) NOT(NOT(x))

#define IF(condition) CW_IF_IMPL_(BOOL(condition))
#define CW_IF_IMPL_(condition) CAT(CW_IF_PRESENT_, condition)

#define CW_IF_NOT_EMPTY_(...)
#define CW_IF_PRESENT_(...) __VA_ARGS__

#define ASSERT(X)
#define Assert(X)

#ifndef MIN
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif

#ifndef MAX
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#endif

#ifndef UNUSED
#define UNUSED(expr)  \
    do                \
    {                 \
        (void)(expr); \
    } while (0)
#endif

#if defined(__GNUC__) || defined(__clang__)
#define CW_NODISCARD __attribute__((warn_unused_result))
#else
#define CW_NODISCARD
#endif

#if defined(__clang__) && (!defined(SWIG))
#define CW_THREAD_ANNOTATION_ATTRIBUTE_(x) __attribute__((x))
#else
#define CW_THREAD_ANNOTATION_ATTRIBUTE_(x)
#endif

#define CW_GUARDED_BY(x) CW_THREAD_ANNOTATION_ATTRIBUTE_(guarded_by(x))
#define CW_PT_GUARDED_BY(x) CW_THREAD_ANNOTATION_ATTRIBUTE_(pt_guarded_by(x))
#define CW_REQUIRES(...) CW_THREAD_ANNOTATION_ATTRIBUTE_(requires_capability(__VA_ARGS__))
#define CW_EXCLUDES(...) CW_THREAD_ANNOTATION_ATTRIBUTE_(locks_excluded(__VA_ARGS__))
#define CW_ACQUIRE(...) CW_THREAD_ANNOTATION_ATTRIBUTE_(acquire_capability(__VA_ARGS__))
#define CW_RELEASE(...) CW_THREAD_ANNOTATION_ATTRIBUTE_(release_capability(__VA_ARGS__))
#define CW_NO_THREAD_SAFETY_ANALYSIS CW_THREAD_ANNOTATION_ATTRIBUTE_(no_thread_safety_analysis)

/* ──────────────────────────────────────────────────────────────────────────
 * API stability tier markers
 *
 * Annotate every public function/type with exactly one of these:
 *
 *   CW_API_STABLE      — covered by semver: breaking changes only on a
 *                        major bump. Default for all public API.
 *   CW_API_PROVISIONAL — may change in any release; the change is recorded
 *                        in CHANGELOG.md under "Changed".
 *   CW_API_DEPRECATED("reason / migration hint")
 *                      — emits a -Wdeprecated-declarations warning at
 *                        every callsite. Removal happens at the next
 *                        major bump (and not before one minor release of
 *                        notice).
 *
 * Documentation only — they have no runtime effect, they only steer the
 * compiler diagnostics and signal intent to integrators.
 * ────────────────────────────────────────────────────────────────────────── */
#define CW_API_STABLE
#define CW_API_PROVISIONAL

#if defined(__GNUC__) || defined(__clang__)
#define CW_API_DEPRECATED(reason) __attribute__((deprecated(reason)))
#else
#define CW_API_DEPRECATED(reason)
#endif

/* ──────────────────────────────────────────────────────────────────────────
 * CW_MUST_CHECK_ERRNO
 *
 * Mark a function whose return value is an errno- or osStatus_t-style
 * error code that the caller is required to inspect. Mis-use (calling
 * the function and discarding the return) trips
 * -Werror=unused-result (set in cmake/gcc_cflags.cmake).
 *
 * Use on driver/syscall surfaces that can fail quietly. Functionally
 * equivalent to CW_NODISCARD; spelled separately so a future SAST rule
 * can reason about the annotation semantically (e.g. "error-returning
 * APIs must propagate or log", IEC 62443-4-1 SI-1).
 * ────────────────────────────────────────────────────────────────────────── */
#define CW_MUST_CHECK_ERRNO CW_NODISCARD

/* ──────────────────────────────────────────────────────────────────────────
 * CW_TIMEOUT_MS / CW_TIMEOUT_TICKS
 *
 * Type-safe timeout marker. Many CMSIS-RTOS2 / coldwave APIs accept
 * either a millisecond count *or* a tick count, with the same
 * `uint32_t` parameter type — historically a source of bugs (e.g.
 * passing `100` meaning "100 ms" to an API that expects ticks and so
 * waits ~100 µs).
 *
 * The macros wrap a literal integer in a transient struct so that
 * mis-use becomes a compile-time type error in C++17 / Clang
 * thread-safety builds. In plain C the wrappers degrade to the bare
 * value (zero overhead, no semantic change).
 *
 * Migration: callers stay unchanged; new APIs accept
 * `cw_timeout_ms_t` / `cw_timeout_ticks_t` and read `.value`.
 * ────────────────────────────────────────────────────────────────────────── */
#ifdef __cplusplus
extern "C" {
#endif

typedef struct { uint32_t value; } cw_timeout_ms_t;
typedef struct { uint32_t value; } cw_timeout_ticks_t;

#ifdef __cplusplus
}
#endif

#if defined(__cplusplus)
#define CW_TIMEOUT_MS(ms)    (::cw_timeout_ms_t{ (uint32_t)(ms) })
#define CW_TIMEOUT_TICKS(t)  (::cw_timeout_ticks_t{ (uint32_t)(t) })
#elif defined(__GNUC__) || defined(__clang__)
/* C99 compound literals — zero-cost wrapper. */
#define CW_TIMEOUT_MS(ms)    ((cw_timeout_ms_t){ .value = (uint32_t)(ms) })
#define CW_TIMEOUT_TICKS(t)  ((cw_timeout_ticks_t){ .value = (uint32_t)(t) })
#else
#define CW_TIMEOUT_MS(ms)    (ms)
#define CW_TIMEOUT_TICKS(t)  (t)
#endif

#define DLLCALL
#define DLLEXPORT

#define BYTE_FORMAT "%.2hX"
#define BYTE_SEPARATOR " "

#define BYTES_2_FORMAT_SEPARATOR(SEPARATOR) BYTE_FORMAT SEPARATOR BYTE_FORMAT
#define BYTES_4_FORMAT_SEPARATOR(SEPARATOR) BYTES_2_FORMAT_SEPARATOR(SEPARATOR) SEPARATOR BYTES_2_FORMAT_SEPARATOR(SEPARATOR)
#define BYTES_8_FORMAT_SEPARATOR(SEPARATOR) BYTES_4_FORMAT_SEPARATOR(SEPARATOR) SEPARATOR BYTES_4_FORMAT_SEPARATOR(SEPARATOR)
#define BYTES_16_FORMAT_SEPARATOR(SEPARATOR) BYTES_8_FORMAT_SEPARATOR(SEPARATOR) SEPARATOR BYTES_8_FORMAT_SEPARATOR(SEPARATOR)
#define BYTES_32_FORMAT_SEPARATOR(SEPARATOR) BYTES_16_FORMAT_SEPARATOR(SEPARATOR) SEPARATOR BYTES_16_FORMAT_SEPARATOR(SEPARATOR)

#define BYTES_2_FORMAT BYTES_2_FORMAT_SEPARATOR(BYTE_SEPARATOR)
#define BYTES_4_FORMAT BYTES_4_FORMAT_SEPARATOR(BYTE_SEPARATOR)
#define BYTES_8_FORMAT BYTES_8_FORMAT_SEPARATOR(BYTE_SEPARATOR)
#define BYTES_16_FORMAT BYTES_16_FORMAT_SEPARATOR(BYTE_SEPARATOR)
#define BYTES_32_FORMAT BYTES_32_FORMAT_SEPARATOR(BYTE_SEPARATOR)

#define BYTES_2(bytes) (bytes)[0], (bytes)[1]
#define BYTES_4(bytes) BYTES_2(bytes), BYTES_2(bytes + 2)
#define BYTES_8(bytes) BYTES_4(bytes), BYTES_4(bytes + 4)
#define BYTES_16(bytes) BYTES_8(bytes), BYTES_8(bytes + 8)
#define BYTES_32(bytes) BYTES_16(bytes), BYTES_16(bytes + 16)

#define IP32_TO_BYTES_FORMAT BYTES_4_FORMAT_SEPARATOR(".")

#define BIT32_TO_BYTES(bits) BYTES_4((uint8_t*)&(bits))
#define IP32_TO_BYTES(ip) BIT32_TO_BYTES(ip)

#define AES_BLOCK_TO_BYTES_FORMAT BYTES_16_FORMAT
#define AES_BLOCK_TO_BYTES(block) BIT32_TO_BYTES((block)[0]), BIT32_TO_BYTES((block)[1]), BIT32_TO_BYTES((block)[2]), BIT32_TO_BYTES((block)[3])

#if __DP_FPU
#define CW_MAX_PRECISION double
#define CW_MATH_FUNC(x) x
#else
#define CW_MAX_PRECISION float
#define CW_MATH_FUNC(x) x##f
#endif

#endif //_COLDWAVEOSMACRO_H