]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/macro.h
shared: drop UNIQUE()
[thirdparty/systemd.git] / src / shared / macro.h
CommitLineData
03467c88 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
60918275 2
c2f1db8f 3#pragma once
60918275 4
a7334b09
LP
5/***
6 This file is part of systemd.
7
8 Copyright 2010 Lennart Poettering
9
10 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
11 under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
13 (at your option) any later version.
14
15 systemd is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 18 Lesser General Public License for more details.
a7334b09 19
5430f7f2 20 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22***/
23
60918275 24#include <assert.h>
6a39419f 25#include <sys/param.h>
60918275 26#include <sys/types.h>
c31e1495
LP
27#include <sys/uio.h>
28#include <inttypes.h>
60918275 29
44b601bc 30#define _printf_(a,b) __attribute__ ((format (printf, a, b)))
750ef272 31#define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
93a46b0b 32#define _sentinel_ __attribute__ ((sentinel))
93a46b0b
LP
33#define _unused_ __attribute__ ((unused))
34#define _destructor_ __attribute__ ((destructor))
35#define _pure_ __attribute__ ((pure))
36#define _const_ __attribute__ ((const))
37#define _deprecated_ __attribute__ ((deprecated))
38#define _packed_ __attribute__ ((packed))
39#define _malloc_ __attribute__ ((malloc))
40#define _weak_ __attribute__ ((weak))
41#define _likely_(x) (__builtin_expect(!!(x),1))
42#define _unlikely_(x) (__builtin_expect(!!(x),0))
40473a70
LP
43#define _public_ __attribute__ ((visibility("default")))
44#define _hidden_ __attribute__ ((visibility("hidden")))
ad780f19 45#define _weakref_(x) __attribute__((weakref(#x)))
19d1e4ee 46#define _alignas_(x) __attribute__((aligned(__alignof(x))))
dfb33a97 47#define _cleanup_(x) __attribute__((cleanup(x)))
60918275 48
7ebe131a
LP
49/* Temporarily disable some warnings */
50#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT \
51 _Pragma("GCC diagnostic push"); \
52 _Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"")
53
bcfce235
LP
54#define DISABLE_WARNING_FORMAT_NONLITERAL \
55 _Pragma("GCC diagnostic push"); \
56 _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
57
f0f2e63b
LP
58#define DISABLE_WARNING_MISSING_PROTOTYPES \
59 _Pragma("GCC diagnostic push"); \
60 _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"")
61
8fca4e30
LP
62#define DISABLE_WARNING_NONNULL \
63 _Pragma("GCC diagnostic push"); \
64 _Pragma("GCC diagnostic ignored \"-Wnonnull\"")
65
d442e2ec
DH
66#define DISABLE_WARNING_SHADOW \
67 _Pragma("GCC diagnostic push"); \
68 _Pragma("GCC diagnostic ignored \"-Wshadow\"")
69
7ebe131a
LP
70#define REENABLE_WARNING \
71 _Pragma("GCC diagnostic pop")
72
49e5de64
ZJS
73/* automake test harness */
74#define EXIT_TEST_SKIP 77
75
bef2733f
LP
76#define XSTRINGIFY(x) #x
77#define STRINGIFY(x) XSTRINGIFY(x)
78
ab9cbe34
LS
79#define XCONCATENATE(x, y) x ## y
80#define CONCATENATE(x, y) XCONCATENATE(x, y)
81
60918275 82/* Rounds up */
9be9c7cf
LP
83
84#define ALIGN4(l) (((l) + 3) & ~3)
85#define ALIGN8(l) (((l) + 7) & ~7)
86
87#if __SIZEOF_POINTER__ == 8
88#define ALIGN(l) ALIGN8(l)
89#elif __SIZEOF_POINTER__ == 4
90#define ALIGN(l) ALIGN4(l)
91#else
92#error "Wut? Pointers are neither 4 nor 8 bytes long?"
93#endif
94
49aa47c7
LP
95#define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) p))
96#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) p))
e86b80b8
LP
97#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) p))
98
37f85e66 99static inline size_t ALIGN_TO(size_t l, size_t ali) {
100 return ((l + ali - 1) & ~(ali - 1));
22be093f
LP
101}
102
1c231f56 103#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p, ali))
49aa47c7 104
625e870b
DH
105/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
106static inline unsigned long ALIGN_POWER2(unsigned long u) {
107 /* clz(0) is undefined */
108 if (u == 1)
109 return 1;
110
111 /* left-shift overflow is undefined */
112 if (__builtin_clzl(u - 1UL) < 1)
113 return 0;
114
115 return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL));
116}
117
60918275
LP
118#define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
119
bbc98d32
KS
120/*
121 * container_of - cast a member of a structure out to the containing structure
122 * @ptr: the pointer to the member.
123 * @type: the type of the container struct this is embedded in.
124 * @member: the name of the member within the struct.
125 *
126 */
fa70beaa
LP
127#define container_of(ptr, type, member) \
128 __extension__ ({ \
129 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
130 (type *)( (char *)__mptr - offsetof(type,member) ); \
131 })
bbc98d32 132
9607d947 133#undef MAX
fdcba430
DH
134#define MAX(a,b) \
135 __extension__ ({ \
136 const typeof(a) _a = (a); \
137 const typeof(b) _b = (b); \
138 _a > _b ? _a : _b; \
60918275
LP
139 })
140
7242d742
DH
141/* evaluates to (void) if _A or _B are not constant or of different types */
142#define CONST_MAX(_A, _B) \
143 __extension__ (__builtin_choose_expr( \
144 __builtin_constant_p(_A) && \
145 __builtin_constant_p(_B) && \
146 __builtin_types_compatible_p(typeof(_A), typeof(_B)), \
147 ((_A) > (_B)) ? (_A) : (_B), \
148 (void)0))
149
40a1eebd
DH
150/* takes two types and returns the size of the larger one */
151#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; }))
152
fdcba430
DH
153#define MAX3(x,y,z) \
154 __extension__ ({ \
155 const typeof(x) _c = MAX(x,y); \
156 MAX(_c, z); \
9607d947 157 })
3b63d2d3 158
9607d947 159#undef MIN
fdcba430
DH
160#define MIN(a,b) \
161 __extension__ ({ \
162 const typeof(a) _a = (a); \
163 const typeof(b) _b = (b); \
164 _a < _b ? _a : _b; \
60918275
LP
165 })
166
fdcba430
DH
167#define MIN3(x,y,z) \
168 __extension__ ({ \
169 const typeof(x) _c = MIN(x,y); \
170 MIN(_c, z); \
7df23077
DH
171 })
172
fdcba430
DH
173#define LESS_BY(A,B) \
174 __extension__ ({ \
175 const typeof(A) _A = (A); \
176 const typeof(B) _B = (B); \
177 _A > _B ? _A - _B : 0; \
348ced90
ZJS
178 })
179
907809fc 180#ifndef CLAMP
60918275
LP
181#define CLAMP(x, low, high) \
182 __extension__ ({ \
fdcba430
DH
183 const typeof(x) _x = (x); \
184 const typeof(low) _low = (low); \
185 const typeof(high) _high = (high); \
60918275
LP
186 ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
187 })
907809fc 188#endif
60918275 189
dd8f71ee
LP
190#define assert_se(expr) \
191 do { \
93a46b0b 192 if (_unlikely_(!(expr))) \
b7f33638 193 log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
dd8f71ee
LP
194 } while (false) \
195
196/* We override the glibc assert() here. */
197#undef assert
198#ifdef NDEBUG
199#define assert(expr) do {} while(false)
200#else
201#define assert(expr) assert_se(expr)
202#endif
60918275 203
dd8f71ee
LP
204#define assert_not_reached(t) \
205 do { \
b7f33638 206 log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
dd8f71ee 207 } while (false)
60918275 208
f791c684 209#if defined(static_assert)
7ebe131a
LP
210/* static_assert() is sometimes defined in a way that trips up
211 * -Wdeclaration-after-statement, hence let's temporarily turn off
212 * this warning around it. */
213#define assert_cc(expr) \
214 DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \
215 static_assert(expr, #expr); \
216 REENABLE_WARNING
f791c684 217#else
7ebe131a
LP
218#define assert_cc(expr) \
219 DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \
418bcb0c 220 struct CONCATENATE(_assert_struct_, __LINE__) { \
7ebe131a
LP
221 char x[(expr) ? 0 : -1]; \
222 }; \
223 REENABLE_WARNING
f791c684 224#endif
60918275 225
80514f9c
LP
226#define assert_return(expr, r) \
227 do { \
228 if (_unlikely_(!(expr))) { \
229 log_assert_failed_return(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
230 return (r); \
231 } \
18387b59
LP
232 } while (false)
233
a3dc3547
KS
234#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
235#define INT_TO_PTR(u) ((void *) ((intptr_t) (u)))
60918275 236#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
a3dc3547 237#define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u)))
60918275 238
a3dc3547
KS
239#define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
240#define LONG_TO_PTR(u) ((void *) ((intptr_t) (u)))
c6c18be3 241#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
a3dc3547 242#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
c6c18be3 243
a3dc3547
KS
244#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
245#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
246#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
247#define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u)))
60918275 248
a3dc3547
KS
249#define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p)))
250#define INT64_TO_PTR(u) ((void *) ((intptr_t) (u)))
251#define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p)))
252#define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u)))
c6c18be3 253
74b2466e
LP
254#define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p)))
255#define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u)))
256
476fe607
LP
257#define memzero(x,l) (memset((x), 0, (l)))
258#define zero(x) (memzero(&(x), sizeof(x)))
259
a9c55a88
LP
260#define CHAR_TO_STR(x) ((char[2]) { x, 0 })
261
034c6ed7
LP
262#define char_array_0(x) x[sizeof(x)-1] = 0;
263
bff7c062 264#define IOVEC_SET_STRING(i, s) \
2fa086a8 265 do { \
bff7c062
LP
266 struct iovec *_i = &(i); \
267 char *_s = (char *)(s); \
268 _i->iov_base = _s; \
269 _i->iov_len = strlen(_s); \
9b3c575e 270 } while(false)
2fa086a8 271
c31e1495
LP
272static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
273 unsigned j;
274 size_t r = 0;
275
276 for (j = 0; j < n; j++)
277 r += i[j].iov_len;
278
279 return r;
280}
281
282static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
283 unsigned j;
284
285 for (j = 0; j < n; j++) {
286 size_t sub;
287
288 if (_unlikely_(k <= 0))
289 break;
290
291 sub = MIN(i[j].iov_len, k);
292 i[j].iov_len -= sub;
293 i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
294 k -= sub;
295 }
296
297 return k;
298}
299
cecd32f6
LP
300#define VA_FORMAT_ADVANCE(format, ap) \
301do { \
302 int _argtypes[128]; \
963ddb91
LP
303 size_t _i, _k; \
304 _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
cecd32f6 305 assert(_k < ELEMENTSOF(_argtypes)); \
963ddb91
LP
306 for (_i = 0; _i < _k; _i++) { \
307 if (_argtypes[_i] & PA_FLAG_PTR) { \
308 (void) va_arg(ap, void*); \
309 continue; \
310 } \
311 \
312 switch (_argtypes[_i]) { \
313 case PA_INT: \
314 case PA_INT|PA_FLAG_SHORT: \
315 case PA_CHAR: \
316 (void) va_arg(ap, int); \
317 break; \
318 case PA_INT|PA_FLAG_LONG: \
319 (void) va_arg(ap, long int); \
320 break; \
321 case PA_INT|PA_FLAG_LONG_LONG: \
322 (void) va_arg(ap, long long int); \
323 break; \
324 case PA_WCHAR: \
325 (void) va_arg(ap, wchar_t); \
326 break; \
327 case PA_WSTRING: \
328 case PA_STRING: \
329 case PA_POINTER: \
330 (void) va_arg(ap, void*); \
331 break; \
332 case PA_FLOAT: \
333 case PA_DOUBLE: \
334 (void) va_arg(ap, double); \
335 break; \
336 case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \
337 (void) va_arg(ap, long double); \
338 break; \
339 default: \
340 assert_not_reached("Unknown format string argument."); \
341 } \
342 } \
343} while(false)
344
e5f476db 345 /* Because statfs.t_type can be int on some architectures, we have to cast
bdd29249
HH
346 * the const magic to the type, otherwise the compiler warns about
347 * signed/unsigned comparison, because the magic can be 32 bit unsigned.
348 */
c51cf056 349#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
bdd29249 350
fa70beaa
LP
351/* Returns the number of chars needed to format variables of the
352 * specified type as a decimal string. Adds in extra space for a
353 * negative '-' prefix. */
fa70beaa 354#define DECIMAL_STR_MAX(type) \
5bcb0f2b 355 (2+(sizeof(type) <= 1 ? 3 : \
fa70beaa
LP
356 sizeof(type) <= 2 ? 5 : \
357 sizeof(type) <= 4 ? 10 : \
358 sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
359
264ad849
LP
360#define SET_FLAG(v, flag, b) \
361 (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
362
dc36d78e 363#define IN_SET(x, y, ...) \
059d9fbb 364 ({ \
dc36d78e
LP
365 const typeof(y) _y = (y); \
366 const typeof(_y) _x = (x); \
059d9fbb
LP
367 unsigned _i; \
368 bool _found = false; \
dc36d78e
LP
369 for (_i = 0; _i < 1 + sizeof((const typeof(_x)[]) { __VA_ARGS__ })/sizeof(const typeof(_x)); _i++) \
370 if (((const typeof(_x)[]) { _y, __VA_ARGS__ })[_i] == _x) { \
059d9fbb
LP
371 _found = true; \
372 break; \
373 } \
374 _found; \
cabb7806
LP
375 })
376
919ce0b7
SL
377/* Define C11 thread_local attribute even on older gcc compiler
378 * version */
ec202eae
SL
379#ifndef thread_local
380/*
381 * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
382 * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
383 */
384#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
385#define thread_local _Thread_local
386#else
387#define thread_local __thread
388#endif
389#endif
cabb7806 390
919ce0b7
SL
391/* Define C11 noreturn without <stdnoreturn.h> and even on older gcc
392 * compiler versions */
393#ifndef noreturn
394#if __STDC_VERSION__ >= 201112L
395#define noreturn _Noreturn
396#else
397#define noreturn __attribute__((noreturn))
398#endif
399#endif
400
dd8f71ee 401#include "log.h"