macros.h revision 95ec0fd4789bd249b106e282a32a08f4d1827f63
#ifndef MACROS_H
#define MACROS_H
/* several useful macros, mostly from glib.h */
#ifndef NULL
# define NULL ((void *)0)
#endif
#ifndef FALSE
# define FALSE (!1)
#endif
#ifndef TRUE
#endif
#define N_ELEMENTS(arr) \
files that are included after this file generating tons of warnings. */
#define I_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define I_MAX(a, b) (((a) > (b)) ? (a) : (b))
sizeof(size_t) == sizeof(void *) and they're both the largest datatypes
that are allowed to be used. so, long long isn't safe with these. */
#define POINTER_CAST(i) \
((void *) ((char *) NULL + (i)))
#define POINTER_CAST_TO(p, type) \
/* Define VA_COPY() to do the right thing for copying va_list variables.
config.h may have already defined VA_COPY as va_copy or __va_copy. */
#ifndef VA_COPY
(defined (_CALL_SYSV) || defined (_WIN32))
# elif defined (VA_COPY_AS_ARRAY)
# else /* va_list is a pointer */
# endif /* va_list is a pointer */
#endif
/* Provide convenience macros for handling structure
* fields through their offsets.
*/
((void *) ((char *) (struct_p) + (long) (struct_offset)))
((const void *) ((const char *) (struct_p) + (long) (struct_offset)))
/* Provide simple macro statement wrappers (adapted from Perl):
STMT_START { statements; } STMT_END;
can be used as a single statement, as in
if (x) STMT_START { ... } STMT_END; else ...
For gcc we will wrap the statements within `({' and `})' braces.
For SunOS they will be wrapped within `if (1)' and `else (void) 0',
and otherwise within `do' and `while (0)'. */
#if !(defined (STMT_START) && defined (STMT_END))
# if defined (__GNUC__) && !defined (__cplusplus) && \
!defined (__STRICT_ANSI__) && !defined (PEDANTIC)
# define STMT_START (void)(
# define STMT_END )
# else
# define STMT_START if (1)
# define STMT_END else (void)0
# else
# define STMT_START do
# define STMT_END while (0)
# endif
# endif
#endif
/* Provide macros to feature the GCC function attribute. */
# define ATTRS_DEFINED
# define ATTR_FORMAT_ARG(arg_idx) \
# define ATTR_STRFTIME(format_idx) \
# define ATTR_CONST __attribute__((const))
#else
# define ATTR_FORMAT_ARG(arg_idx)
# define ATTR_STRFTIME(format_idx)
# define ATTR_UNUSED
# define ATTR_NORETURN
# define ATTR_CONST
# define ATTR_PURE
#endif
#ifdef HAVE_ATTR_NULL
#else
# define ATTR_NULL(...)
#endif
#else
# define ATTR_NOWARN_UNUSED_RESULT
#endif
#if __GNUC__ > 2
#else
# define ATTR_MALLOC
#endif
#if __GNUC__ > 3
/* GCC 4.0 and later */
#else
# define ATTR_WARN_UNUSED_RESULT
# define ATTR_SENTINEL
#endif
/* GCC 4.3 and later */
#else
# define ATTR_HOT
# define ATTR_COLD
#endif
/* GCC 4.9 and later */
#else
# define ATTR_RETURNS_NONNULL
#endif
/* Macros to provide type safety for callback functions' context parameters */
#ifdef HAVE_TYPE_CHECKS
#else
#endif
# define COMPILE_ERROR_IF_TRUE(condition) \
#else
# define COMPILE_ERROR_IF_TRUE(condition) 0
#endif
#ifdef HAVE_TYPE_CHECKS
#else
#endif
#if __GNUC__ > 2
#else
#endif
#else
# define ATTR_UNSIGNED_WRAPS
#endif
/* Provide macros for error handling. */
#ifdef DISABLE_ASSERTS
#else
i_panic("file %s: line %d (%s): assertion failed: (%s)", \
__FILE__, \
__LINE__, \
__func__, \
#endif
/* Close the fd and set it to -1. This assert-crashes if fd == 0, and is a
no-op if fd == -1. Normally fd == 0 would happen only if an uninitialized
fd is attempted to be closed, which is a bug. */
if (*fd != -1) { \
i_error("close(%d[%s:%d]) failed: %m", \
} \
} STMT_END
#define i_unreached() \
/* Convenience macros to test the versions of dovecot. */
#if defined DOVECOT_VERSION_MAJOR && defined DOVECOT_VERSION_MINOR
#else
#endif
#ifdef __cplusplus
# define STATIC_ARRAY
#endif
/* Convenience wrappers for initializing a struct */
#define i_zero_safe(p) safe_memset(p, 0, sizeof(*(p)))
#endif