macros.h revision 88d7593652b331695a219a0e07124b7c82e3835c
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen#ifndef __MACROS_H
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define __MACROS_H
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen/* several useful macros, mostly from glib.h */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#ifndef NULL
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define NULL ((void *)0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#ifndef FALSE
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define FALSE (0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#ifndef TRUE
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define TRUE (!FALSE)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define BITS_IN_UINT (CHAR_BIT * sizeof(unsigned int))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define MEM_ALIGN(size) \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (((size) + MEM_ALIGN_SIZE-1) & ~((unsigned int) MEM_ALIGN_SIZE-1))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Don't use simply MIN/MAX, as they're often defined elsewhere in include
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen files that are included after this file generating tons of warnings. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define I_MIN(a, b) (((a) < (b)) ? (a) : (b))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define I_MAX(a, b) (((a) > (b)) ? (a) : (b))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#undef CLAMP
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen#undef NVL
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen#define NVL(str, nullstr) ((str) != NULL ? (str) : (nullstr))
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen#define POINTER_TO_INT(p) ((int) (p))
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen#define POINTER_TO_UINT(p) ((unsigned int) ((char *) p - (char *) NULL))
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen#define INT_TO_POINTER(i) ((void *) (i))
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen#define UINT_TO_POINTER(u) ((void *) (u))
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen/* Define VA_COPY() to do the right thing for copying va_list variables. */
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen#ifndef VA_COPY
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen# if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))
bca919b207e27d0d08b431bdb0f2ac099ef8b512Timo Sirainen# define VA_COPY(ap1, ap2) (*(ap1) = *(ap2))
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen# elif defined (VA_COPY_AS_ARRAY)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define VA_COPY(ap1, ap2) i_memmove ((ap1), (ap2), sizeof (va_list))
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen# else /* va_list is a pointer */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define VA_COPY(ap1, ap2) ((ap1) = (ap2))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# endif /* va_list is a pointer */
d22301419109ed4a38351715e6760011421dadecTimo Sirainen#endif
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Provide convenience macros for handling structure
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen * fields through their offsets.
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define STRUCT_OFFSET(struct_p, member) \
3b32bc12710240f86465a00fbb2bd1ef030e6c40Timo Sirainen ((long) ((char *) &((struct_p)->member) - (char *) (struct_p)))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define STRUCT_MEMBER_P(struct_p, struct_offset) \
d22301419109ed4a38351715e6760011421dadecTimo Sirainen ((void *) ((char *) (struct_p) + (long) (struct_offset)))
d22301419109ed4a38351715e6760011421dadecTimo Sirainen#define STRUCT_MEMBER(member_type, struct_p, struct_offset) \
d22301419109ed4a38351715e6760011421dadecTimo Sirainen (*(member_type *) G_STRUCT_MEMBER_P((struct_p), (struct_offset)))
d22301419109ed4a38351715e6760011421dadecTimo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen/* Provide simple macro statement wrappers (adapted from Perl):
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen STMT_START { statements; } STMT_END;
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen can be used as a single statement, as in
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (x) STMT_START { ... } STMT_END; else ...
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen For gcc we will wrap the statements within `({' and `})' braces.
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen For SunOS they will be wrapped within `if (1)' and `else (void) 0',
d22301419109ed4a38351715e6760011421dadecTimo Sirainen and otherwise within `do' and `while (0)'. */
d22301419109ed4a38351715e6760011421dadecTimo Sirainen#if !(defined (STMT_START) && defined (STMT_END))
d22301419109ed4a38351715e6760011421dadecTimo Sirainen# if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
d22301419109ed4a38351715e6760011421dadecTimo Sirainen# define STMT_START (void)(
d22301419109ed4a38351715e6760011421dadecTimo Sirainen# define STMT_END )
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# else
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# if (defined (sun) || defined (__sun__))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define STMT_START if (1)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define STMT_END else (void)0
d22301419109ed4a38351715e6760011421dadecTimo Sirainen# else
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define STMT_START do
d22301419109ed4a38351715e6760011421dadecTimo Sirainen# define STMT_END while (0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# endif
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# endif
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
4b2a4c8c762e3eaddf7fd2abfe7d4cca6e5e3fd8Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Provide macros to feature the GCC function attribute. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define __attr_format__(format_idx, arg_idx) \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __attribute__((format (printf, format_idx, arg_idx)))
d22301419109ed4a38351715e6760011421dadecTimo Sirainen# define __attr_format_arg__(arg_idx) \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __attribute__((format_arg (arg_idx)))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define __attr_unused__ __attribute__((unused))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define __attr_noreturn__ __attribute__((noreturn))
4b2a4c8c762e3eaddf7fd2abfe7d4cca6e5e3fd8Timo Sirainen# define __attr_const__ __attribute__((const))
4b2a4c8c762e3eaddf7fd2abfe7d4cca6e5e3fd8Timo Sirainen#else
4b2a4c8c762e3eaddf7fd2abfe7d4cca6e5e3fd8Timo Sirainen# define __attr_format__(format_idx, arg_idx)
4b2a4c8c762e3eaddf7fd2abfe7d4cca6e5e3fd8Timo Sirainen# define __attr_format_arg__(arg_idx)
4b2a4c8c762e3eaddf7fd2abfe7d4cca6e5e3fd8Timo Sirainen# define __attr_unused__
4b2a4c8c762e3eaddf7fd2abfe7d4cca6e5e3fd8Timo Sirainen# define __attr_noreturn__
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define __attr_const__
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define __attr_unused__
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Wrap the gcc __PRETTY_FUNCTION__ and __FUNCTION__ variables with
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen macros, so we can refer to them as strings unconditionally. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#ifdef __GNUC__
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define GNUC_FUNCTION __FUNCTION__
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define GNUC_PRETTY_FUNCTION __PRETTY_FUNCTION__
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#else
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define GNUC_FUNCTION ""
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define GNUC_PRETTY_FUNCTION ""
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
4b2a4c8c762e3eaddf7fd2abfe7d4cca6e5e3fd8Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Provide macros for error handling. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#ifdef DISABLE_CHECKS
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define i_assert(expr)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define return_if_fail(expr)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen# define return_val_if_fail(expr,val)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#elif defined (__GNUC__) && !defined (__STRICT_ANSI__)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define i_assert(expr) STMT_START{ \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!(expr)) \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_panic("file %s: line %d (%s): assertion failed: (%s)", \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __FILE__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __LINE__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __PRETTY_FUNCTION__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen #expr); }STMT_END
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define return_if_fail(expr) STMT_START{ \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!(expr)) \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen { \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_warning("file %s: line %d (%s): assertion `%s' failed.", \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __FILE__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __LINE__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __PRETTY_FUNCTION__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen #expr); \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return; \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }; }STMT_END
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen#define return_val_if_fail(expr,val) STMT_START{ \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!(expr)) \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen { \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_warning("file %s: line %d (%s): assertion `%s' failed.", \
547e916f4e6f01af682f8b6e032c337f2a699364Timo Sirainen __FILE__, \
547e916f4e6f01af682f8b6e032c337f2a699364Timo Sirainen __LINE__, \
547e916f4e6f01af682f8b6e032c337f2a699364Timo Sirainen __PRETTY_FUNCTION__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen #expr); \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return val; \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }; }STMT_END
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#else /* !__GNUC__ */
46219292a55094fa49aae33eee681ed075d30e17Timo Sirainen
46219292a55094fa49aae33eee681ed075d30e17Timo Sirainen#define i_assert(expr) STMT_START{ \
46219292a55094fa49aae33eee681ed075d30e17Timo Sirainen if (!(expr)) \
46219292a55094fa49aae33eee681ed075d30e17Timo Sirainen i_panic("file %s: line %d: assertion failed: (%s)", \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __FILE__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __LINE__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen #expr); }STMT_END
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define return_if_fail(expr) STMT_START{ \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!(expr)) \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen { \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_warning("file %s: line %d: assertion `%s' failed.", \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __FILE__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __LINE__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen #expr); \
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen return; \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }; }STMT_END
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define return_val_if_fail(expr, val) STMT_START{ \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!(expr)) \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen { \
46219292a55094fa49aae33eee681ed075d30e17Timo Sirainen i_warning("file %s: line %d: assertion `%s' failed.", \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __FILE__, \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen __LINE__, \
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen #expr); \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return val; \
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }; }STMT_END
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen