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