macro.h revision aea275c43194b6ac519ef907b62c5c995050fde0
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#pragma once
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2010 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart 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
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
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/>.
8bdbb8d9cbe1d35708385573d70984ab4533812dLennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <assert.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <sys/param.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <sys/types.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <sys/uio.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <inttypes.h>
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _printf_attr_(a,b) __attribute__ ((format (printf, a, b)))
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define _sentinel_ __attribute__ ((sentinel))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _noreturn_ __attribute__((noreturn))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _unused_ __attribute__ ((unused))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _destructor_ __attribute__ ((destructor))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _pure_ __attribute__ ((pure))
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define _const_ __attribute__ ((const))
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define _deprecated_ __attribute__ ((deprecated))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _packed_ __attribute__ ((packed))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define _malloc_ __attribute__ ((malloc))
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#define _weak_ __attribute__ ((weak))
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
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/* automake test harness */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define EXIT_TEST_SKIP 77
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define XSTRINGIFY(x) #x
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define STRINGIFY(x) XSTRINGIFY(x)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/* Rounds up */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define ALIGN4(l) (((l) + 3) & ~3)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define ALIGN8(l) (((l) + 7) & ~7)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#if __SIZEOF_POINTER__ == 8
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define ALIGN(l) ALIGN8(l)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#elif __SIZEOF_POINTER__ == 4
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define ALIGN(l) ALIGN4(l)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#else
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#error "Wut? Pointers are neither 4 nor 8 bytes long?"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#endif
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
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))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic inline size_t ALIGN_TO(size_t l, size_t ali) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return ((l + ali - 1) & ~(ali - 1));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p))
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen/*
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.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define container_of(ptr, type, member) \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering __extension__ ({ \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen const typeof( ((type *)0)->member ) *__mptr = (ptr); \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen (type *)( (char *)__mptr - offsetof(type,member) ); \
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering })
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#undef MAX
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define MAX(a,b) \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering __extension__ ({ \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering typeof(a) _a = (a); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering typeof(b) _b = (b); \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _a > _b ? _a : _b; \
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering })
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define MAX3(x,y,z) \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen __extension__ ({ \
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering typeof(x) _c = MAX(x,y); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MAX(_c, z); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering })
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#undef MIN
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define MIN(a,b) \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering __extension__ ({ \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering typeof(a) _a = (a); \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen typeof(b) _b = (b); \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _a < _b ? _a : _b; \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen })
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#ifndef CLAMP
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#define CLAMP(x, low, high) \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering __extension__ ({ \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering typeof(x) _x = (x); \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering typeof(low) _low = (low); \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering typeof(high) _high = (high); \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering })
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#endif
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#define assert_se(expr) \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering do { \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (_unlikely_(!(expr))) \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering } while (false) \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering/* We override the glibc assert() here. */
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#undef assert
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering#ifdef NDEBUG
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering#define assert(expr) do {} while(false)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#else
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define assert(expr) assert_se(expr)
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering#endif
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define assert_not_reached(t) \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering do { \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering } while (false)
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering#if defined(static_assert)
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering#define assert_cc(expr) \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering do { \
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering static_assert(expr, #expr); \
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering } while (false)
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering#else
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering#define assert_cc(expr) \
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering do { \
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering switch (0) { \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering case 0: \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering case !!(expr): \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering ; \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering } \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering } while (false)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#endif
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#define UINT_TO_PTR(u) ((void*) ((uintptr_t) (u)))
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
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
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define ULONG_TO_PTR(u) ((void*) ((uintptr_t) (u)))
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers#define INT_TO_PTR(u) ((void*) ((intptr_t) (u)))
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers#define TO_INT32(p) ((int32_t) ((intptr_t) (p)))
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers#define INT32_TO_PTR(u) ((void*) ((intptr_t) (u)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define LONG_TO_PTR(u) ((void*) ((intptr_t) (u)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define memzero(x,l) (memset((x), 0, (l)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define zero(x) (memzero(&(x), sizeof(x)))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define CHAR_TO_STR(x) ((char[2]) { x, 0 })
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define char_array_0(x) x[sizeof(x)-1] = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define IOVEC_SET_STRING(i, s) \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering do { \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct iovec *_i = &(i); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char *_s = (char *)(s); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _i->iov_base = _s; \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _i->iov_len = strlen(_s); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } while(false)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned j;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering size_t r = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (j = 0; j < n; j++)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r += i[j].iov_len;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned j;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (j = 0; j < n; j++) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering size_t sub;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (_unlikely_(k <= 0))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sub = MIN(i[j].iov_len, k);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering i[j].iov_len -= sub;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering k -= sub;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return k;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define VA_FORMAT_ADVANCE(format, ap) \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringdo { \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering int _argtypes[128]; \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering size_t _i, _k; \
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(_k < ELEMENTSOF(_argtypes)); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (_i = 0; _i < _k; _i++) { \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (_argtypes[_i] & PA_FLAG_PTR) { \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers (void) va_arg(ap, void*); \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers continue; \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers } \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers switch (_argtypes[_i]) { \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers case PA_INT: \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers case PA_INT|PA_FLAG_SHORT: \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers case PA_CHAR: \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers (void) va_arg(ap, int); \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers break; \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers case PA_INT|PA_FLAG_LONG: \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers (void) va_arg(ap, long int); \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers break; \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen case PA_INT|PA_FLAG_LONG_LONG: \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen (void) va_arg(ap, long long int); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break; \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case PA_WCHAR: \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (void) va_arg(ap, wchar_t); \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers break; \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers case PA_WSTRING: \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers case PA_STRING: \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers case PA_POINTER: \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers (void) va_arg(ap, void*); \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen break; \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers case PA_FLOAT: \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen case PA_DOUBLE: \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (void) va_arg(ap, double); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break; \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (void) va_arg(ap, long double); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break; \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering default: \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers assert_not_reached("Unknown format string argument."); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers } \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers} while(false)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
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 */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define F_TYPE_CMP(f, c) \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers __extension__ ({ \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers __SWORD_TYPE _f = (f); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const __SWORD_TYPE _c = (c); \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers const int _c32 = (c); \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen (_f == _c || _f == _c32 ); \
27e72d6b22890ba4a8cbc05c49667cd1cccf1461Simon Peeters })
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
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
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#define DECIMAL_STR_MAX(type) \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen (1+(sizeof(type) <= 1 ? 3 : \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen sizeof(type) <= 2 ? 5 : \
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers sizeof(type) <= 4 ? 10 : \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "log.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering