Files
libucore/include/ucore/utils.h
T
2013-04-08 22:24:19 +02:00

121 lines
2.8 KiB
C

#ifndef UCORE_UTILS_H_
#define UCORE_UTILS_H_
#include <stddef.h>
//Gnerate a compiler error if the compile time
//constant expression fails
#define UC_STATIC_ASSERT(expr) \
do { \
enum { assert_static__ = 1/(expr) }; \
} while (0)
#ifdef DEBUG
#define TRACEF(fmt, ...)\
do { \
fprintf(stdout, "%s:%d (%s)\t" fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\
fflush(stdout);\
} while(0)
#else
#define TRACEF(fmt, ...)
#endif
//MAX of a and b
#define UC_MAX(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
//min of a and b
#define UC_MIN(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; })
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
//given 'ptr' as a pointer to a struct 'member',
//find the struct that ptr is the member of, where
//'type' is the type of the containing struct
//e.g.
//struct foo {
// int i;
// struct bar zap;
//};
// ...
//struct bar *p = ..; //the local p is a pointer to
//a 'zap' member inside a struct foo.
//give us the struct foo*:
//struct foo *f = CONTAINER_OF(p, struct foo, zap);
#define CONTAINER_OF(ptr, type, member) ({ \
typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (void *)__mptr - offsetof(type, member) ); })
/** Align a value.
* @param val value to align
* @param align alignment, must be power of 2
* @return the aligned val
*/
#define UC_ALIGN(val,align) (((val)+(align)-1UL)&~((align)-1UL))
/**
* Test if x is a power of 2
*
* @param x value
* @return 1 if x is a power of 20, 0 if it is not
*/
#define UC_IS_POW2(x) ((x) && !((x) & (x) - 1))
/**
* * Expands @x and turns it into a string.
* */
#define UC_STRINGIFY(x) UC_STRINGIFY_HLP(x)
#define UC_STRINGIFY_HLP(x) #x
/**
* assert() that is not affected by NDEBUG define
*/
#define UC_ASSERT(expr) do {\
if (!(expr) ) {\
fprintf(stderr,\
"UC_ASSERT failed '%s' %s:%d\n", UC_STRINGIFY(expr), __FILE__, __LINE__);\
uc_backtrace_fd(3);\
abort();\
} while (0)
/**
* Macro for asserting code that should not be reached,
* terminates the program if executed
*/
#define UC_NOT_REACED() abort()
/**
* Round up X / y
*
* @param x numerator, must be positive
* @param y denominator
* @return x/y rounded up
*/
#define UC_DIV_ROUND_UP(x, y) (((x) + ((y) - 1))/(y))
/**
* Round x down to nearest multiple of y
*
* @param x numerator, must be positive
* @param y denominator
* @return x rounded to nearest multiple of y
*/
#define UC_ROUND_UP(x, y) (((x) / (y)) * (y))
/**
* Round x down to nearest multiple of y
*
* @param x numerator, must be positive
* @param y denominator
* @return x rounded to nearest multiple of y
*/
#define UC_ROUND_DOWN(x, y) ((x) / (y) * (y))
#endif