macro.h revision aea275c43194b6ac519ef907b62c5c995050fde0
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2010 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _printf_attr_(a,b) __attribute__ ((format (printf, a, b)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _noreturn_ __attribute__((noreturn))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _destructor_ __attribute__ ((destructor))
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define _deprecated_ __attribute__ ((deprecated))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _likely_(x) (__builtin_expect(!!(x),1))
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering#define _unlikely_(x) (__builtin_expect(!!(x),0))
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering#define _public_ __attribute__ ((visibility("default")))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _hidden_ __attribute__ ((visibility("hidden")))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _weakref_(x) __attribute__((weakref(#x)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _introspect_(x) __attribute__((section("introspect." x)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _alignas_(x) __attribute__((aligned(__alignof(x))))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _cleanup_(x) __attribute__((cleanup(x)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/* automake test harness */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/* Rounds up */
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#error "Wut? Pointers are neither 4 nor 8 bytes long?"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) p))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) p))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) p))
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic inline size_t ALIGN_TO(size_t l, size_t ali) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p))
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen * container_of - cast a member of a structure out to the containing structure
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen * @ptr: the pointer to the member.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * @type: the type of the container struct this is embedded in.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * @member: the name of the member within the struct.
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen const typeof( ((type *)0)->member ) *__mptr = (ptr); \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen (type *)( (char *)__mptr - offsetof(type,member) ); \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define MAX3(x,y,z) \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering } while (false) \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering/* We override the glibc assert() here. */
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering } while (false)
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering } while (false)
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering switch (0) { \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering } while (false)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#define UINT_TO_PTR(u) ((void*) ((uintptr_t) (u)))
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#define UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u)))
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define ULONG_TO_PTR(u) ((void*) ((uintptr_t) (u)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers#define INT32_TO_PTR(u) ((void*) ((intptr_t) (u)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define LONG_TO_PTR(u) ((void*) ((intptr_t) (u)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define zero(x) (memzero(&(x), sizeof(x)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define CHAR_TO_STR(x) ((char[2]) { x, 0 })
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define char_array_0(x) x[sizeof(x)-1] = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char *_s = (char *)(s); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } while(false)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (j = 0; j < n; j++)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (j = 0; j < n; j++) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers assert_not_reached("Unknown format string argument."); \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers} while(false)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers/* Remove this macro, when the kernel has f_type as unsigned int or long
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers * for every architecure. Currently some 64bit architecures (like s390x)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * have int in the kernel, but long in userspace for f_type, so glibc
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers * extends the int to long and carries over the sign. Negative numbers are
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers * caused by the 32bit magic constants in linux/magic.h stuffed into the
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * signed int in the kernel and these negative numbers are extended to
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers * long, which cannot be simply compared to the magic constants anymore.
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers const int _c32 = (c); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/* Returns the number of chars needed to format variables of the
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering * specified type as a decimal string. Adds in extra space for a
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * negative '-' prefix. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))