macros.h revision 8939d20e53167fe5f308d41154085d1e0bbcf82a
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen#ifndef MACROS_H
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#define MACROS_H
60bdf7c0422caeb08cc615c60b659d4d1ff30614Timo Sirainen
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen/* several useful macros, mostly from glib.h */
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#ifndef NULL
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# define NULL ((void *)0)
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#endif
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen#ifndef FALSE
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# define FALSE (0)
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#endif
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#ifndef TRUE
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# define TRUE (!FALSE)
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#endif
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#define N_ELEMENTS(arr) \
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen (sizeof(arr) / sizeof((arr)[0]))
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen#define BITS_IN_UINT (CHAR_BIT * sizeof(unsigned int))
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen#define BITS_IN_SIZE_T (CHAR_BIT * sizeof(size_t))
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#define MEM_ALIGN(size) \
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen (((size) + MEM_ALIGN_SIZE-1) & ~((unsigned int) MEM_ALIGN_SIZE-1))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#define PTR_OFFSET(ptr, offset) \
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen ((void *) (((unsigned char *) (ptr)) + (offset)))
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen#define CONST_PTR_OFFSET(ptr, offset) \
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen ((const void *) (((const unsigned char *) (ptr)) + (offset)))
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen/* Don't use simply MIN/MAX, as they're often defined elsewhere in include
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen files that are included after this file generating tons of warnings. */
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen#define I_MIN(a, b) (((a) < (b)) ? (a) : (b))
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen#define I_MAX(a, b) (((a) > (b)) ? (a) : (b))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#undef CLAMP
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#define CLAMP(x, low, high) \
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#undef NVL
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#define NVL(str, nullstr) ((str) != NULL ? (str) : (nullstr))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen/* make it easier to cast from/to pointers. assumes that
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen sizeof(size_t) == sizeof(void *) and they're both the largest datatypes
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen that are allowed to be used. so, long long isn't safe with these. */
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#define POINTER_CAST(i) \
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen ((void *) ((char *) NULL + (i)))
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen#define POINTER_CAST_TO(p, type) \
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen ((type) ((const char *) (p) - (const char *) NULL))
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen/* Define VA_COPY() to do the right thing for copying va_list variables.
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen config.h may have already defined VA_COPY as va_copy or __va_copy. */
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#ifndef VA_COPY
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# if defined (__GNUC__) && defined (__PPC__) && \
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen (defined (_CALL_SYSV) || defined (_WIN32))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# define VA_COPY(ap1, ap2) (*(ap1) = *(ap2))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# elif defined (VA_COPY_AS_ARRAY)
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# define VA_COPY(ap1, ap2) memmove ((ap1), (ap2), sizeof (va_list))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# else /* va_list is a pointer */
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# define VA_COPY(ap1, ap2) ((ap1) = (ap2))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# endif /* va_list is a pointer */
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen#endif
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen/* Provide convenience macros for handling structure
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen * fields through their offsets.
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen */
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#define STRUCT_MEMBER_P(struct_p, struct_offset) \
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen ((void *) ((char *) (struct_p) + (long) (struct_offset)))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#define STRUCT_MEMBER(member_type, struct_p, struct_offset) \
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen (*(member_type *) G_STRUCT_MEMBER_P((struct_p), (struct_offset)))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen/* Provide simple macro statement wrappers (adapted from Perl):
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen STMT_START { statements; } STMT_END;
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen can be used as a single statement, as in
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen if (x) STMT_START { ... } STMT_END; else ...
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen For gcc we will wrap the statements within `({' and `})' braces.
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen For SunOS they will be wrapped within `if (1)' and `else (void) 0',
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen and otherwise within `do' and `while (0)'. */
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen#if !(defined (STMT_START) && defined (STMT_END))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# if defined (__GNUC__) && !defined (__cplusplus) && \
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen !defined (__STRICT_ANSI__) && !defined (PEDANTIC)
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# define STMT_START (void)(
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# define STMT_END )
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# else
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# if (defined (sun) || defined (__sun__))
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# define STMT_START if (1)
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# define STMT_END else (void)0
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# else
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen# define STMT_START do
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen# define STMT_END while (0)
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen# endif
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen# endif
c8555d0f669c5732c8b9f5bece7b41fc65545f33Timo Sirainen#endif
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen/* Provide macros to feature the GCC function attribute. */
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
596f582a422eddef951ee445f9a0ed3d4bf14ff8Timo Sirainen# define ATTRS_DEFINED
# define ATTR_FORMAT(format_idx, arg_idx) \
__attribute__((format (printf, format_idx, arg_idx)))
# define ATTR_FORMAT_ARG(arg_idx) \
__attribute__((format_arg (arg_idx)))
# define ATTR_SCANF(format_idx, arg_idx) \
__attribute__((format (scanf, format_idx, arg_idx)))
# define ATTR_UNUSED __attribute__((unused))
# define ATTR_NORETURN __attribute__((noreturn))
# define ATTR_CONST __attribute__((const))
#else
# define ATTR_FORMAT(format_idx, arg_idx)
# define ATTR_FORMAT_ARG(arg_idx)
# define ATTR_SCANF
# define ATTR_UNUSED
# define ATTR_NORETURN
# define ATTR_CONST
# define ATTR_UNUSED
#endif
#if __GNUC__ > 2
# define ATTR_MALLOC __attribute__((malloc))
#else
# define ATTR_MALLOC
#endif
#if __GNUC__ > 3
/* GCC 4.0 and later */
# define ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
# define ATTR_SENTINEL __attribute__((sentinel))
#else
# define ATTR_WARN_UNUSED_RESULT
# define ATTR_SENTINEL
#endif
/* C99-style struct member definitions */
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || __GNUC__ > 2
# define MEMBER(name) .name =
#else
# define MEMBER(name)
#endif
/* Macros to provide type safety for callback functions' context parameters */
#ifdef __GNUC__
# define CONTEXT_TYPE_SAFETY
#endif
#ifdef CONTEXT_TYPE_SAFETY
# define CONTEXT_CALLBACK(name, callback_type, callback, context, ...) \
({(void)(1 ? 0 : callback(context)); \
name(__VA_ARGS__, (callback_type *)callback, context); })
#else
# define CONTEXT_CALLBACK(name, callback_type, callback, context, ...) \
name(__VA_ARGS__, (callback_type *)callback, context)
#endif
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0)
# define HAVE_TYPEOF
# define COMPILE_ERROR_IF_TRUE(condition) \
(sizeof(char[1 - 2 * !!(condition)]) - 1)
# define COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(_a, _b) \
COMPILE_ERROR_IF_TRUE( \
!__builtin_types_compatible_p(typeof(_a), typeof(_b)))
#else
# define COMPILE_ERROR_IF_TRUE(condition) 0
# define COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(_a, _b) 0
#endif
/* Wrap the gcc __PRETTY_FUNCTION__ and __FUNCTION__ variables with
macros, so we can refer to them as strings unconditionally. */
#ifdef __GNUC__
# define GNUC_FUNCTION __FUNCTION__
# define GNUC_PRETTY_FUNCTION __PRETTY_FUNCTION__
#else
# define GNUC_FUNCTION ""
# define GNUC_PRETTY_FUNCTION ""
#endif
#if __GNUC__ > 2
# define unlikely(expr) __builtin_expect(!!(expr), 0)
# define likely(expr) __builtin_expect(!!(expr), 1)
#else
# define unlikely(expr) expr
# define likely(expr) expr
#endif
/* Provide macros for error handling. */
#ifdef DISABLE_ASSERTS
# define i_assert(expr)
#elif defined (__GNUC__) && !defined (__STRICT_ANSI__)
#define i_assert(expr) STMT_START{ \
if (unlikely(!(expr))) \
i_panic("file %s: line %d (%s): assertion failed: (%s)", \
__FILE__, \
__LINE__, \
__PRETTY_FUNCTION__, \
#expr); }STMT_END
#else /* !__GNUC__ */
#define i_assert(expr) STMT_START{ \
if (unlikely(!(expr))) \
i_panic("file %s: line %d: assertion failed: (%s)", \
__FILE__, \
__LINE__, \
#expr); }STMT_END
#endif
#define i_unreached() \
i_panic("file %s: line %d: unreached", __FILE__, __LINE__)
#endif