macro.h revision 34c38d2aaa2535cb40d0157b0e4a84e6be72ee9a
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#pragma once
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen/***
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen This file is part of systemd.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen Copyright 2010 Lennart Poettering
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen systemd is free software; you can redistribute it and/or modify it
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen under the terms of the GNU Lesser General Public License as published by
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen (at your option) any later version.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen systemd is distributed in the hope that it will be useful, but
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen Lesser General Public License for more details.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen You should have received a copy of the GNU Lesser General Public License
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen***/
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen#include <assert.h>
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen#include <sys/param.h>
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#include <sys/types.h>
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#include <sys/uio.h>
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen#include <inttypes.h>
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen#include <stdbool.h>
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen#define _printf_(a,b) __attribute__ ((format (printf, a, b)))
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen#define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define _sentinel_ __attribute__ ((sentinel))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define _unused_ __attribute__ ((unused))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define _destructor_ __attribute__ ((destructor))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define _pure_ __attribute__ ((pure))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define _const_ __attribute__ ((const))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define _deprecated_ __attribute__ ((deprecated))
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen#define _packed_ __attribute__ ((packed))
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen#define _malloc_ __attribute__ ((malloc))
3aeb37bc4f32b5edc334f2ac7c5d3c7b0a121328Tom Gundersen#define _weak_ __attribute__ ((weak))
c6f7c917a1b494d4455800823472227463f87438Tom Gundersen#define _likely_(x) (__builtin_expect(!!(x),1))
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering#define _unlikely_(x) (__builtin_expect(!!(x),0))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define _public_ __attribute__ ((visibility("default")))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define _hidden_ __attribute__ ((visibility("hidden")))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define _weakref_(x) __attribute__((weakref(#x)))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define _alignas_(x) __attribute__((aligned(__alignof(x))))
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen#define _cleanup_(x) __attribute__((cleanup(x)))
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen/* Temporarily disable some warnings */
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT \
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen _Pragma("GCC diagnostic push"); \
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen _Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"")
97f2d76d4f4dfab8b0629c09926a05a1e5621125Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define DISABLE_WARNING_FORMAT_NONLITERAL \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen _Pragma("GCC diagnostic push"); \
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek#define DISABLE_WARNING_MISSING_PROTOTYPES \
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek _Pragma("GCC diagnostic push"); \
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"")
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek#define DISABLE_WARNING_NONNULL \
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek _Pragma("GCC diagnostic push"); \
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek _Pragma("GCC diagnostic ignored \"-Wnonnull\"")
5b9d4dc05560ddda89e48b6b39365824b15e1300Tom Gundersen
5b9d4dc05560ddda89e48b6b39365824b15e1300Tom Gundersen#define DISABLE_WARNING_SHADOW \
5b9d4dc05560ddda89e48b6b39365824b15e1300Tom Gundersen _Pragma("GCC diagnostic push"); \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen _Pragma("GCC diagnostic ignored \"-Wshadow\"")
5b9d4dc05560ddda89e48b6b39365824b15e1300Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define DISABLE_WARNING_INCOMPATIBLE_POINTER_TYPES \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen _Pragma("GCC diagnostic push"); \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen _Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"")
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define REENABLE_WARNING \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen _Pragma("GCC diagnostic pop")
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen/* automake test harness */
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define EXIT_TEST_SKIP 77
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
977085794d2996320e345433403de75f662b0622Tom Gundersen#define XSTRINGIFY(x) #x
977085794d2996320e345433403de75f662b0622Tom Gundersen#define STRINGIFY(x) XSTRINGIFY(x)
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen#define XCONCATENATE(x, y) x ## y
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define CONCATENATE(x, y) XCONCATENATE(x, y)
5b9d4dc05560ddda89e48b6b39365824b15e1300Tom Gundersen
5b9d4dc05560ddda89e48b6b39365824b15e1300Tom Gundersen#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define UNIQ __COUNTER__
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen/* Rounds up */
977085794d2996320e345433403de75f662b0622Tom Gundersen
977085794d2996320e345433403de75f662b0622Tom Gundersen#define ALIGN4(l) (((l) + 3) & ~3)
977085794d2996320e345433403de75f662b0622Tom Gundersen#define ALIGN8(l) (((l) + 7) & ~7)
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#if __SIZEOF_POINTER__ == 8
866ee3682213789f85b877700457fdca05695a0eTom Gundersen#define ALIGN(l) ALIGN8(l)
866ee3682213789f85b877700457fdca05695a0eTom Gundersen#elif __SIZEOF_POINTER__ == 4
866ee3682213789f85b877700457fdca05695a0eTom Gundersen#define ALIGN(l) ALIGN4(l)
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#else
866ee3682213789f85b877700457fdca05695a0eTom Gundersen#error "Wut? Pointers are neither 4 nor 8 bytes long?"
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#endif
977085794d2996320e345433403de75f662b0622Tom Gundersen
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) (p)))
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) (p)))
866ee3682213789f85b877700457fdca05695a0eTom Gundersen#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) (p)))
866ee3682213789f85b877700457fdca05695a0eTom Gundersen
866ee3682213789f85b877700457fdca05695a0eTom Gundersenstatic inline size_t ALIGN_TO(size_t l, size_t ali) {
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen return ((l + ali - 1) & ~(ali - 1));
866ee3682213789f85b877700457fdca05695a0eTom Gundersen}
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen
977085794d2996320e345433403de75f662b0622Tom Gundersen#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) (p), (ali)))
977085794d2996320e345433403de75f662b0622Tom Gundersen
977085794d2996320e345433403de75f662b0622Tom Gundersen/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
977085794d2996320e345433403de75f662b0622Tom Gundersenstatic inline unsigned long ALIGN_POWER2(unsigned long u) {
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen /* clz(0) is undefined */
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (u == 1)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return 1;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen /* left-shift overflow is undefined */
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (__builtin_clzl(u - 1UL) < 1)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return 0;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL));
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen}
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define ELEMENTSOF(x) \
d2df0d0ed3a88e491405b403e6022e6619750130Tom Gundersen __extension__ (__builtin_choose_expr( \
edf029b7fd9a5853a87d3ca99aac2922bb8a277eTom Gundersen !__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen sizeof(x)/sizeof((x)[0]), \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen (void)0))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen/*
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen * container_of - cast a member of a structure out to the containing structure
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen * @ptr: the pointer to the member.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen * @type: the type of the container struct this is embedded in.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen * @member: the name of the member within the struct.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen */
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member)
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering#define __container_of(uniq, ptr, type, member) \
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen __extension__ ({ \
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type,member) ); \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen })
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#undef MAX
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define __MAX(aq, a, bq, b) \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen __extension__ ({ \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen const typeof(a) UNIQ_T(A, aq) = (a); \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen const typeof(b) UNIQ_T(B, bq) = (b); \
ecb08ec6a5c52f2d940f3b8147e2a480affd46e1Zbigniew Jędrzejewski-Szmek UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \
6e37cd2f4af8928d905203108a4331e375d7127cThomas Hindoe Paaboel Andersen })
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen/* evaluates to (void) if _A or _B are not constant or of different types */
187dc6e554f2d5b4b5a3bee72c73ff5df6418aa6Thomas Hindoe Paaboel Andersen#define CONST_MAX(_A, _B) \
187dc6e554f2d5b4b5a3bee72c73ff5df6418aa6Thomas Hindoe Paaboel Andersen __extension__ (__builtin_choose_expr( \
187dc6e554f2d5b4b5a3bee72c73ff5df6418aa6Thomas Hindoe Paaboel Andersen __builtin_constant_p(_A) && \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen __builtin_constant_p(_B) && \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen __builtin_types_compatible_p(typeof(_A), typeof(_B)), \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen ((_A) > (_B)) ? (_A) : (_B), \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen (void)0))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
ecb08ec6a5c52f2d940f3b8147e2a480affd46e1Zbigniew Jędrzejewski-Szmek/* takes two types and returns the size of the larger one */
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; }))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
ed88bcfb7c15029f9fc95ee2380759a9eb782d46Zbigniew Jędrzejewski-Szmek#define MAX3(x,y,z) \
ed88bcfb7c15029f9fc95ee2380759a9eb782d46Zbigniew Jędrzejewski-Szmek __extension__ ({ \
ed88bcfb7c15029f9fc95ee2380759a9eb782d46Zbigniew Jędrzejewski-Szmek const typeof(x) _c = MAX(x,y); \
ed88bcfb7c15029f9fc95ee2380759a9eb782d46Zbigniew Jędrzejewski-Szmek MAX(_c, z); \
ed88bcfb7c15029f9fc95ee2380759a9eb782d46Zbigniew Jędrzejewski-Szmek })
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
ecb08ec6a5c52f2d940f3b8147e2a480affd46e1Zbigniew Jędrzejewski-Szmek#undef MIN
ecb08ec6a5c52f2d940f3b8147e2a480affd46e1Zbigniew Jędrzejewski-Szmek#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define __MIN(aq, a, bq, b) \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen __extension__ ({ \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen const typeof(a) UNIQ_T(A, aq) = (a); \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen const typeof(b) UNIQ_T(B, bq) = (b); \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen UNIQ_T(A,aq) < UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \
e9f3d2d508bfd9fb5b54e82994bda365a71eb864Zbigniew Jędrzejewski-Szmek })
e9f3d2d508bfd9fb5b54e82994bda365a71eb864Zbigniew Jędrzejewski-Szmek
e9f3d2d508bfd9fb5b54e82994bda365a71eb864Zbigniew Jędrzejewski-Szmek#define MIN3(x,y,z) \
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek __extension__ ({ \
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek const typeof(x) _c = MIN(x,y); \
ecb08ec6a5c52f2d940f3b8147e2a480affd46e1Zbigniew Jędrzejewski-Szmek MIN(_c, z); \
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek })
98a375f6d5cac24eb80d6d4e00699851324afdecTom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b))
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define __LESS_BY(aq, a, bq, b) \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen __extension__ ({ \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen const typeof(a) UNIQ_T(A, aq) = (a); \
ecb08ec6a5c52f2d940f3b8147e2a480affd46e1Zbigniew Jędrzejewski-Szmek const typeof(b) UNIQ_T(B, bq) = (b); \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) - UNIQ_T(B,bq) : 0; \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen })
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#undef CLAMP
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high))
f8a0bb5285024b6ce372c3157e761e6543ebdcd2Andreas Henriksson#define __CLAMP(xq, x, lowq, low, highq, high) \
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek __extension__ ({ \
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen const typeof(x) UNIQ_T(X,xq) = (x); \
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen const typeof(low) UNIQ_T(LOW,lowq) = (low); \
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen const typeof(high) UNIQ_T(HIGH,highq) = (high); \
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering UNIQ_T(X,xq) > UNIQ_T(HIGH,highq) ? \
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering UNIQ_T(HIGH,highq) : \
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen UNIQ_T(X,xq) < UNIQ_T(LOW,lowq) ? \
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering UNIQ_T(LOW,lowq) : \
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering UNIQ_T(X,xq); \
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen })
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek/* [(x + y - 1) / y] suffers from an integer overflow, even though the
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen * computation should be possible in the given type. Therefore, we use
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen * [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen * quotient and the remainder, so both should be equally fast. */
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen#define DIV_ROUND_UP(_x, _y) \
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen __extension__ ({ \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen const typeof(_x) __x = (_x); \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen const typeof(_y) __y = (_y); \
edf029b7fd9a5853a87d3ca99aac2922bb8a277eTom Gundersen (__x / __y + !!(__x % __y)); \
edf029b7fd9a5853a87d3ca99aac2922bb8a277eTom Gundersen })
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define assert_message_se(expr, message) \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen do { \
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen if (_unlikely_(!(expr))) \
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen log_assert_failed(message, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen } while (false)
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen#define assert_se(expr) assert_message_se(expr, #expr)
97f2d76d4f4dfab8b0629c09926a05a1e5621125Tom Gundersen
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek/* We override the glibc assert() here. */
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#undef assert
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek#ifdef NDEBUG
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define assert(expr) do {} while(false)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#else
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define assert(expr) assert_message_se(expr, #expr)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#endif
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define assert_not_reached(t) \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen do { \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen } while (false)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#if defined(static_assert)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen/* static_assert() is sometimes defined in a way that trips up
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen * -Wdeclaration-after-statement, hence let's temporarily turn off
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen * this warning around it. */
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define assert_cc(expr) \
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen static_assert(expr, #expr); \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen REENABLE_WARNING
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#else
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define assert_cc(expr) \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen struct CONCATENATE(_assert_struct_, __COUNTER__) { \
b3e013148603aa670bc2c060ac63d48e54d76fc2Tom Gundersen char x[(expr) ? 0 : -1]; \
edbb03e95a3c31bf719d5c6c46eec14d0bcb9c8fTom Gundersen }; \
edbb03e95a3c31bf719d5c6c46eec14d0bcb9c8fTom Gundersen REENABLE_WARNING
edbb03e95a3c31bf719d5c6c46eec14d0bcb9c8fTom Gundersen#endif
505f8da7325591defe5f751f328bd26915267602Tom Gundersen
b3e013148603aa670bc2c060ac63d48e54d76fc2Tom Gundersen#define assert_log(expr, message) ((_likely_(expr)) \
9b1c2626cef16722603bded9bb52033aba34dd74Tom Gundersen ? (true) \
bf175aafd20c9ef974709ef12c5acf836121af33Tom Gundersen : (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false))
b3e013148603aa670bc2c060ac63d48e54d76fc2Tom Gundersen
b3e013148603aa670bc2c060ac63d48e54d76fc2Tom Gundersen#define assert_return(expr, r) \
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen do { \
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen if (!assert_log(expr, #expr)) \
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen return (r); \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen } while (false)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#define assert_return_errno(expr, r, err) \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen do { \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (!assert_log(expr, #expr)) { \
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen errno = err; \
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen return (r); \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen } \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen } while (false)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen#define INT_TO_PTR(u) ((void *) ((intptr_t) (u)))
f1ac700248f231b7bdac2aafe8c35650efddb89fTom Gundersen#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
f1ac700248f231b7bdac2aafe8c35650efddb89fTom Gundersen#define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u)))
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen#define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen#define LONG_TO_PTR(u) ((void *) ((intptr_t) (u)))
f1ac700248f231b7bdac2aafe8c35650efddb89fTom Gundersen#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
f1ac700248f231b7bdac2aafe8c35650efddb89fTom Gundersen#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
f1ac700248f231b7bdac2aafe8c35650efddb89fTom Gundersen
f1ac700248f231b7bdac2aafe8c35650efddb89fTom Gundersen#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u)))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p)))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define INT64_TO_PTR(u) ((void *) ((intptr_t) (u)))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p)))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u)))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p)))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u)))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen/* The following macros add 1 when converting things, since UID 0 is a
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen * valid UID, while the pointer NULL is special */
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define PTR_TO_UID(p) ((uid_t) (((uintptr_t) (p))-1))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define UID_TO_PTR(u) ((void*) (((uintptr_t) (u))+1))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define PTR_TO_GID(p) ((gid_t) (((uintptr_t) (p))-1))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define GID_TO_PTR(u) ((void*) (((uintptr_t) (u))+1))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define PTR_TO_PID(p) ((pid_t) ((uintptr_t) p))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define PID_TO_PTR(p) ((void*) ((uintptr_t) p))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define memzero(x,l) (memset((x), 0, (l)))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define zero(x) (memzero(&(x), sizeof(x)))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define CHAR_TO_STR(x) ((char[2]) { x, 0 })
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen#define char_array_0(x) x[sizeof(x)-1] = 0;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen#define IOVEC_SET_STRING(i, s) \
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering do { \
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen struct iovec *_i = &(i); \
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen char *_s = (char *)(s); \
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering _i->iov_base = _s; \
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen _i->iov_len = strlen(_s); \
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering } while(false)
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering
b5db00e52ee2e20578839e4e4488f7b9af9abc38Umut Tezduyar Lindskogstatic inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen unsigned j;
55428d84f31b52da1c50b7469f14e15740547f20Tom Gundersen size_t r = 0;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering for (j = 0; j < n; j++)
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering r += i[j].iov_len;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen return r;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen}
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersenstatic inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen unsigned j;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen for (j = 0; j < n; j++) {
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen size_t sub;
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen if (_unlikely_(k <= 0))
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen break;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen sub = MIN(i[j].iov_len, k);
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen i[j].iov_len -= sub;
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen k -= sub;
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen }
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen return k;
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen}
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen
977085794d2996320e345433403de75f662b0622Tom Gundersen#define VA_FORMAT_ADVANCE(format, ap) \
977085794d2996320e345433403de75f662b0622Tom Gundersendo { \
977085794d2996320e345433403de75f662b0622Tom Gundersen int _argtypes[128]; \
977085794d2996320e345433403de75f662b0622Tom Gundersen size_t _i, _k; \
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen assert(_k < ELEMENTSOF(_argtypes)); \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen for (_i = 0; _i < _k; _i++) { \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (_argtypes[_i] & PA_FLAG_PTR) { \
733f7a2c69c794a81978a08a79916c224ba355a6Tom Gundersen (void) va_arg(ap, void*); \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen continue; \
733f7a2c69c794a81978a08a79916c224ba355a6Tom Gundersen } \
733f7a2c69c794a81978a08a79916c224ba355a6Tom Gundersen \
733f7a2c69c794a81978a08a79916c224ba355a6Tom Gundersen switch (_argtypes[_i]) { \
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen case PA_INT: \
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen case PA_INT|PA_FLAG_SHORT: \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen case PA_CHAR: \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen (void) va_arg(ap, int); \
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen break; \
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen case PA_INT|PA_FLAG_LONG: \
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen (void) va_arg(ap, long int); \
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen break; \
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen case PA_INT|PA_FLAG_LONG_LONG: \
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen (void) va_arg(ap, long long int); \
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen break; \
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen case PA_WCHAR: \
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen (void) va_arg(ap, wchar_t); \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen break; \
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen case PA_WSTRING: \
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen case PA_STRING: \
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen case PA_POINTER: \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen (void) va_arg(ap, void*); \
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen break; \
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen case PA_FLOAT: \
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen case PA_DOUBLE: \
e51660ae56bb747ece2cab8fe6eec37f4d06a438Tom Gundersen (void) va_arg(ap, double); \
e51660ae56bb747ece2cab8fe6eec37f4d06a438Tom Gundersen break; \
e51660ae56bb747ece2cab8fe6eec37f4d06a438Tom Gundersen case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen (void) va_arg(ap, long double); \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen break; \
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen default: \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen assert_not_reached("Unknown format string argument."); \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen } \
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen } \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen} while(false)
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen /* Because statfs.t_type can be int on some architectures, we have to cast
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen * the const magic to the type, otherwise the compiler warns about
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen * signed/unsigned comparison, because the magic can be 32 bit unsigned.
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen */
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen/* Returns the number of chars needed to format variables of the
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen * specified type as a decimal string. Adds in extra space for a
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen * negative '-' prefix (hence works correctly on signed
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen * types). Includes space for the trailing NUL. */
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define DECIMAL_STR_MAX(type) \
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen (2+(sizeof(type) <= 1 ? 3 : \
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen sizeof(type) <= 2 ? 5 : \
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen sizeof(type) <= 4 ? 10 : \
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen#define SET_FLAG(v, flag, b) \
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen#define IN_SET(x, y, ...) \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen ({ \
92d927f850d4b668b44f3e5f41e266d934d03726Tom Gundersen static const typeof(y) _array[] = { (y), __VA_ARGS__ }; \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen const typeof(y) _x = (x); \
a669ea9860900d5cdebbc4cb9aaea72db7e28a02Tom Gundersen unsigned _i; \
a669ea9860900d5cdebbc4cb9aaea72db7e28a02Tom Gundersen bool _found = false; \
a669ea9860900d5cdebbc4cb9aaea72db7e28a02Tom Gundersen for (_i = 0; _i < ELEMENTSOF(_array); _i++) \
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen if (_array[_i] == _x) { \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen _found = true; \
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen break; \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen } \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen _found; \
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen })
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen
a669ea9860900d5cdebbc4cb9aaea72db7e28a02Tom Gundersen/* Return a nulstr for a standard cascade of configuration directories,
a669ea9860900d5cdebbc4cb9aaea72db7e28a02Tom Gundersen * suitable to pass to conf_files_list_nulstr or config_parse_many. */
a669ea9860900d5cdebbc4cb9aaea72db7e28a02Tom Gundersen#define CONF_DIRS_NULSTR(n) \
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen "/etc/" n ".d\0" \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen "/run/" n ".d\0" \
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen "/usr/local/lib/" n ".d\0" \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen "/usr/lib/" n ".d\0" \
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen CONF_DIR_SPLIT_USR(n)
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen#ifdef HAVE_SPLIT_USR
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen#define CONF_DIR_SPLIT_USR(n) "/lib/" n ".d\0"
d2df0d0ed3a88e491405b403e6022e6619750130Tom Gundersen#else
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen#define CONF_DIR_SPLIT_USR(n)
d2df0d0ed3a88e491405b403e6022e6619750130Tom Gundersen#endif
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen/* Define C11 thread_local attribute even on older gcc compiler
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen * version */
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#ifndef thread_local
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen/*
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen */
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#define thread_local _Thread_local
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#else
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#define thread_local __thread
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#endif
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#endif
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen/* Define C11 noreturn without <stdnoreturn.h> and even on older gcc
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen * compiler versions */
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#ifndef noreturn
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#if __STDC_VERSION__ >= 201112L
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#define noreturn _Noreturn
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#else
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#define noreturn __attribute__((noreturn))
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#endif
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#endif
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#define UID_INVALID ((uid_t) -1)
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen#define GID_INVALID ((gid_t) -1)
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mack#define MODE_INVALID ((mode_t) -1)
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersenstatic inline bool UID_IS_INVALID(uid_t uid) {
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen /* We consider both the old 16bit -1 user and the newer 32bit
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen * -1 user invalid, since they are or used to be incompatible
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen * with syscalls such as setresuid() or chown(). */
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen return uid == (uid_t) ((uint32_t) -1) || uid == (uid_t) ((uint16_t) -1);
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mack}
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
e51660ae56bb747ece2cab8fe6eec37f4d06a438Tom Gundersenstatic inline bool GID_IS_INVALID(gid_t gid) {
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen return gid == (gid_t) ((uint32_t) -1) || gid == (gid_t) ((uint16_t) -1);
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen}
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen static inline void func##p(type *p) { \
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen if (*p) \
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen func(*p); \
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen } \
struct __useless_struct_to_allow_trailing_semicolon__
#define CMSG_FOREACH(cmsg, mh) \
for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
#include "log.h"