#ifndef INCLUDED_OS_MACROS_H #define INCLUDED_OS_MACROS_H #ifndef INCLUDED_STDIO_H #define INCLUDED_STDIO_H #include #endif /*INCLUDED_STDIO_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ #define OS_STR_HELPER(x) #x #define OS_STR(x) OS_STR_HELPER(x) /* BITS */ #define OS_BIT(n) (1<<(n)) #define OS_BIT_SET(x,p) ((x)|(1<<(p))) #define OS_BIT_CLEAR(x,p) ((x)&(~(1<<(p)))) #define OS_BIT_GET(x,p) (((x)>>(p))&1) #define OS_BIT_TOGGLE(x,p) ((x)^(1<<(p))) /* ARRAYS */ #define OS_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) #define OS_SET(d, n, v) do{ int i_, n_; \ for ( n_ = (n), i_ = 0; n_ > 0; --n_, ++i_) \ (d)[i_] = (v); } while(0) #define OS_ZERO(d, n) OS_SET(d, n, 0) #define OS_COLUMNS(S,E) ( (E) - (S) + 1 ) #define OS_IS_ARRAY(a) ((void *)&a == (void *)a) /* DEBUG */ #ifndef NDEBUG extern void about(void); #define OS_ASSERT(expr, ...) \ do { \ if (!(expr)) { \ if(sizeof(#__VA_ARGS__) > 1){ \ fprintf(stderr, "[FAILED] Exp: %s - ", #expr); \ fprintf(stderr, "Msg: " __VA_ARGS__); \ fprintf(stderr, " - "__FILE__":%d - " __DATE__ " " __TIME__"\n", __LINE__); \ }else{ \ fprintf(stderr, "[FAILED] Exp: %s - "__FILE__":%d - " __DATE__ " " __TIME__ "\n", #expr, __LINE__); \ } \ about(); \ } \ } while (0) #define OS_SAFE_ASSERT(expr, ...) \ do { \ if (!(expr)) { \ if(sizeof(#__VA_ARGS__) > 1){ \ fprintf(stderr, "[FAILED] Exp: %s - ", #expr); \ fprintf(stderr, "Msg: " __VA_ARGS__); \ fprintf(stderr, " - "__FILE__":%d - " __DATE__ " " __TIME__"\n", __LINE__); \ }else{ \ fprintf(stderr, "[FAILED] Exp: %s - "__FILE__":%d - " __DATE__ " " __TIME__ "\n", #expr, __LINE__); \ } \ } \ } while (0) #else #define OS_ASSERT(expr, ...) #define OS_SAFE_ASSERT(expr, ...) #endif /* ALIGN */ #define OS_ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) #define OS_ALIGN_DOWN(x, align) ((x) & ~((align) - 1)) /* MATH */ #define OS_MIN(x, y) (((x) < (y)) ? (x) : (y)) #define OS_MAX(x, y) (((x) > (y)) ? (x) : (y)) #define OS_IS_NAN(x) ((x) != (x)) #define OS_COMPARE(x, y) (((x) > (y)) - ((x) < (y))) #define OS_SIGN(x) OS_COMPARE(x, 0) #define OS_IS_ODD( num ) ((num) & 1) #define OS_IS_EVEN( num ) (!OS_IS_ODD( (num) )) #define OS_IS_BETWEEN(n,L,H) ((unsigned char)((n) >= (L) && (n) <= (H))) #define OS_CONSTRAIN(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define OS_IS_POWER_OF_2(x) (((x) & ((x)-1))==0) /* UNIQUE */ #define OS_CONCAT_INNER(a, b) a ## b #define OS_CONCAT(a, b) OS_CONCAT_INNER(a, b) #define OS_UNIQUE(prefix) OS_CONCAT(prefix, __LINE__) /* DEFER, useful to init and clean a block of scoped code */ /* Please see https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2895.htm for a more in depth guide explaining non-standard cleanup functions */ #define OS_DEFER2(head, tail, i) for(int i=(head,0);!i;tail,i++) #define OS_DEFER(head, tail) OS_DEFER2(head, tail, OS_UNIQUE(__deferVar__)) /* STMT, useful for creating multiple statements macros */ #define OS_STMT( stuff ) do { stuff } while (0) /* ONCE */ #define OS_ONCE2(stmts, i) {static int i = 1;\ if(i){stmts\ i = 0;}} #define OS_ONCE(stmts) OS_ONCE2(stmts, OS_UNIQUE(__onceVar__)) /* C in C++ Environment */ #ifdef __cplusplus # define OS_EXTERN_C_START extern "C" { # define OS_EXTERN_C_END } #else # define OS_EXTERN_C_START # define OS_EXTERN_C_END #endif /* MARKS */ #define OS_PRIVILEGE #define OS_NONE_PRIVILEGE #define OS_OPTIONAL #define OS_UNUSED(x) ((void)(x)) #ifndef OS_I #define OS_I volatile const #endif #ifndef OS_O #define OS_O volatile #endif #ifndef OS_IO #define OS_IO volatile #endif #define OS_OFFSETOF(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) #define OS_CONTAINER_OF(ptr, type, member) ((type *)( (unsigned char *)(ptr) - OS_OFFSETOF(type,member) )) #define OS_BLOCK_DEF(__Name, nBytes, nCount) static uint8_t __Name[nBytes * nCount] #endif /*INCLUDED_OS_MACROS_H*/