macros.h revision 255c47a461434ac075efa4fd481d888f193b73ba
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen/* several useful macros, mostly from glib.h */
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# define NULL ((void *)0)
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen (((size) + MEM_ALIGN_SIZE-1) & ~((size_t) MEM_ALIGN_SIZE-1))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen ((void *) (((unsigned char *) (ptr)) + (offset)))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen ((const void *) (((const unsigned char *) (ptr)) + (offset)))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen/* Don't use simply MIN/MAX, as they're often defined elsewhere in include
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen files that are included after this file generating tons of warnings. */
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen#define I_MIN(a, b) (((a) < (b)) ? (a) : (b))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen#define I_MAX(a, b) (((a) > (b)) ? (a) : (b))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen/* make it easier to cast from/to pointers. assumes that
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen sizeof(size_t) == sizeof(void *) and they're both the largest datatypes
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen that are allowed to be used. so, long long isn't safe with these. */
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen ((void *) ((char *) NULL + (i)))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen ((type) ((const char *) (p) - (const char *) NULL))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen/* Define VA_COPY() to do the right thing for copying va_list variables.
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen config.h may have already defined VA_COPY as va_copy or __va_copy. */
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# if defined (__GNUC__) && defined (__PPC__) && \
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# define VA_COPY(ap1, ap2) memmove ((ap1), (ap2), sizeof (va_list))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# else /* va_list is a pointer */
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# endif /* va_list is a pointer */
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen/* Provide convenience macros for handling structure
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen * fields through their offsets.
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen#define STRUCT_MEMBER_P(struct_p, struct_offset) \
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen ((void *) ((char *) (struct_p) + (long) (struct_offset)))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen#define CONST_STRUCT_MEMBER_P(struct_p, struct_offset) \
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen ((const void *) ((const char *) (struct_p) + (long) (struct_offset)))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen/* Provide simple macro statement wrappers (adapted from Perl):
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen STMT_START { statements; } STMT_END;
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen can be used as a single statement, as in
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen if (x) STMT_START { ... } STMT_END; else ...
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen For gcc we will wrap the statements within `({' and `})' braces.
f55988edb669c6bcfdfd91f2f7f57e875168f6b2Timo Sirainen For SunOS they will be wrapped within `if (1)' and `else (void) 0',
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen and otherwise within `do' and `while (0)'. */
f55988edb669c6bcfdfd91f2f7f57e875168f6b2Timo Sirainen#if !(defined (STMT_START) && defined (STMT_END))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# if defined (__GNUC__) && !defined (__cplusplus) && \
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen !defined (__STRICT_ANSI__) && !defined (PEDANTIC)
f55988edb669c6bcfdfd91f2f7f57e875168f6b2Timo Sirainen# define STMT_START (void)(
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# define STMT_END else (void)0
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# define STMT_END while (0)
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen/* Provide macros to feature the GCC function attribute. */
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen __attribute__((format (printf, format_idx, arg_idx)))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen __attribute__((format (scanf, format_idx, arg_idx)))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen __attribute__((format (strftime, format_idx, 0)))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# define ATTR_NORETURN __attribute__((noreturn))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# define ATTR_NULL(...) __attribute__((null(__VA_ARGS__)))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# define ATTR_NOWARN_UNUSED_RESULT __attribute__((nowarn_unused_result))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen/* GCC 4.0 and later */
f55988edb669c6bcfdfd91f2f7f57e875168f6b2Timo Sirainen# define ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# define ATTR_SENTINEL __attribute__((sentinel))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen/* GCC 4.3 and later */
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen/* GCC 4.9 and later */
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen# define ATTR_RETURNS_NONNULL __attribute__((returns_nonnull))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen/* Macros to provide type safety for callback functions' context parameters */
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3))
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen (COMPILE_ERROR_IF_TRUE(!__builtin_types_compatible_p( \
9afebd21ced1d43f638e08a1411c9a89e526231fTimo Sirainen#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0)) && !defined(__cplusplus)
#ifdef DISABLE_ASSERTS
__FILE__, \
__LINE__, \
__FUNCTION__, \
__FILE__, \
__LINE__, \
} STMT_END
#define i_unreached() \