]> git.proxmox.com Git - systemd.git/blame - src/basic/macro.h
New upstream version 236
[systemd.git] / src / basic / macro.h
CommitLineData
52ad194e 1/* SPDX-License-Identifier: LGPL-2.1+ */
663996b3
MS
2#pragma once
3
4/***
5 This file is part of systemd.
6
7 Copyright 2010 Lennart Poettering
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21***/
22
663996b3 23#include <inttypes.h>
7035cd9e 24#include <stdbool.h>
db2df898 25#include <sys/param.h>
aa27b158 26#include <sys/sysmacros.h>
db2df898 27#include <sys/types.h>
663996b3 28
60f067b4 29#define _printf_(a,b) __attribute__ ((format (printf, a, b)))
aa27b158
MP
30#ifdef __clang__
31# define _alloc_(...)
32#else
33# define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
34#endif
663996b3 35#define _sentinel_ __attribute__ ((sentinel))
663996b3
MS
36#define _unused_ __attribute__ ((unused))
37#define _destructor_ __attribute__ ((destructor))
38#define _pure_ __attribute__ ((pure))
39#define _const_ __attribute__ ((const))
40#define _deprecated_ __attribute__ ((deprecated))
41#define _packed_ __attribute__ ((packed))
42#define _malloc_ __attribute__ ((malloc))
43#define _weak_ __attribute__ ((weak))
44#define _likely_(x) (__builtin_expect(!!(x),1))
45#define _unlikely_(x) (__builtin_expect(!!(x),0))
46#define _public_ __attribute__ ((visibility("default")))
47#define _hidden_ __attribute__ ((visibility("hidden")))
48#define _weakref_(x) __attribute__((weakref(#x)))
663996b3
MS
49#define _alignas_(x) __attribute__((aligned(__alignof(x))))
50#define _cleanup_(x) __attribute__((cleanup(x)))
52ad194e
MB
51#if __GNUC__ >= 7
52#define _fallthrough_ __attribute__((fallthrough))
53#else
54#define _fallthrough_
55#endif
663996b3 56
60f067b4
JS
57/* Temporarily disable some warnings */
58#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT \
59 _Pragma("GCC diagnostic push"); \
60 _Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"")
61
62#define DISABLE_WARNING_FORMAT_NONLITERAL \
63 _Pragma("GCC diagnostic push"); \
64 _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
65
66#define DISABLE_WARNING_MISSING_PROTOTYPES \
67 _Pragma("GCC diagnostic push"); \
68 _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"")
69
70#define DISABLE_WARNING_NONNULL \
71 _Pragma("GCC diagnostic push"); \
72 _Pragma("GCC diagnostic ignored \"-Wnonnull\"")
73
e842803a
MB
74#define DISABLE_WARNING_SHADOW \
75 _Pragma("GCC diagnostic push"); \
76 _Pragma("GCC diagnostic ignored \"-Wshadow\"")
77
e735f4d4
MP
78#define DISABLE_WARNING_INCOMPATIBLE_POINTER_TYPES \
79 _Pragma("GCC diagnostic push"); \
80 _Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"")
81
60f067b4
JS
82#define REENABLE_WARNING \
83 _Pragma("GCC diagnostic pop")
84
663996b3
MS
85/* automake test harness */
86#define EXIT_TEST_SKIP 77
87
88#define XSTRINGIFY(x) #x
89#define STRINGIFY(x) XSTRINGIFY(x)
90
60f067b4
JS
91#define XCONCATENATE(x, y) x ## y
92#define CONCATENATE(x, y) XCONCATENATE(x, y)
93
5eef597e
MP
94#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
95#define UNIQ __COUNTER__
60f067b4 96
5a920b42
MP
97/* builtins */
98#if __SIZEOF_INT__ == 4
99#define BUILTIN_FFS_U32(x) __builtin_ffs(x);
100#elif __SIZEOF_LONG__ == 4
101#define BUILTIN_FFS_U32(x) __builtin_ffsl(x);
102#else
103#error "neither int nor long are four bytes long?!?"
104#endif
105
663996b3
MS
106/* Rounds up */
107
108#define ALIGN4(l) (((l) + 3) & ~3)
109#define ALIGN8(l) (((l) + 7) & ~7)
110
111#if __SIZEOF_POINTER__ == 8
112#define ALIGN(l) ALIGN8(l)
113#elif __SIZEOF_POINTER__ == 4
114#define ALIGN(l) ALIGN4(l)
115#else
116#error "Wut? Pointers are neither 4 nor 8 bytes long?"
117#endif
118
f47781d8
MP
119#define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) (p)))
120#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) (p)))
121#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) (p)))
663996b3
MS
122
123static inline size_t ALIGN_TO(size_t l, size_t ali) {
124 return ((l + ali - 1) & ~(ali - 1));
125}
126
f47781d8 127#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) (p), (ali)))
60f067b4
JS
128
129/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
130static inline unsigned long ALIGN_POWER2(unsigned long u) {
131 /* clz(0) is undefined */
132 if (u == 1)
133 return 1;
134
135 /* left-shift overflow is undefined */
136 if (__builtin_clzl(u - 1UL) < 1)
137 return 0;
138
139 return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL));
140}
663996b3 141
6300502b
MP
142#define ELEMENTSOF(x) \
143 __extension__ (__builtin_choose_expr( \
144 !__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
145 sizeof(x)/sizeof((x)[0]), \
146 (void)0))
52ad194e
MB
147
148/*
149 * STRLEN - return the length of a string literal, minus the trailing NUL byte.
150 * Contrary to strlen(), this is a constant expression.
151 * @x: a string literal.
152 */
153#define STRLEN(x) (sizeof(""x"") - 1)
154
663996b3
MS
155/*
156 * container_of - cast a member of a structure out to the containing structure
157 * @ptr: the pointer to the member.
158 * @type: the type of the container struct this is embedded in.
159 * @member: the name of the member within the struct.
663996b3 160 */
5eef597e
MP
161#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member)
162#define __container_of(uniq, ptr, type, member) \
663996b3 163 __extension__ ({ \
5eef597e
MP
164 const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \
165 (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type,member) ); \
166 })
663996b3
MS
167
168#undef MAX
5eef597e
MP
169#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
170#define __MAX(aq, a, bq, b) \
171 __extension__ ({ \
172 const typeof(a) UNIQ_T(A, aq) = (a); \
173 const typeof(b) UNIQ_T(B, bq) = (b); \
174 UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \
175 })
176
177/* evaluates to (void) if _A or _B are not constant or of different types */
178#define CONST_MAX(_A, _B) \
179 __extension__ (__builtin_choose_expr( \
180 __builtin_constant_p(_A) && \
181 __builtin_constant_p(_B) && \
182 __builtin_types_compatible_p(typeof(_A), typeof(_B)), \
183 ((_A) > (_B)) ? (_A) : (_B), \
184 (void)0))
185
186/* takes two types and returns the size of the larger one */
187#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; }))
188
189#define MAX3(x,y,z) \
190 __extension__ ({ \
191 const typeof(x) _c = MAX(x,y); \
192 MAX(_c, z); \
663996b3
MS
193 })
194
195#undef MIN
5eef597e
MP
196#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b))
197#define __MIN(aq, a, bq, b) \
198 __extension__ ({ \
199 const typeof(a) UNIQ_T(A, aq) = (a); \
200 const typeof(b) UNIQ_T(B, bq) = (b); \
201 UNIQ_T(A,aq) < UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \
202 })
203
204#define MIN3(x,y,z) \
205 __extension__ ({ \
206 const typeof(x) _c = MIN(x,y); \
207 MIN(_c, z); \
60f067b4
JS
208 })
209
5eef597e
MP
210#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b))
211#define __LESS_BY(aq, a, bq, b) \
212 __extension__ ({ \
213 const typeof(a) UNIQ_T(A, aq) = (a); \
214 const typeof(b) UNIQ_T(B, bq) = (b); \
215 UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) - UNIQ_T(B,bq) : 0; \
216 })
217
218#undef CLAMP
219#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high))
220#define __CLAMP(xq, x, lowq, low, highq, high) \
663996b3 221 __extension__ ({ \
5eef597e
MP
222 const typeof(x) UNIQ_T(X,xq) = (x); \
223 const typeof(low) UNIQ_T(LOW,lowq) = (low); \
224 const typeof(high) UNIQ_T(HIGH,highq) = (high); \
225 UNIQ_T(X,xq) > UNIQ_T(HIGH,highq) ? \
226 UNIQ_T(HIGH,highq) : \
227 UNIQ_T(X,xq) < UNIQ_T(LOW,lowq) ? \
228 UNIQ_T(LOW,lowq) : \
229 UNIQ_T(X,xq); \
230 })
663996b3 231
e735f4d4
MP
232/* [(x + y - 1) / y] suffers from an integer overflow, even though the
233 * computation should be possible in the given type. Therefore, we use
234 * [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the
235 * quotient and the remainder, so both should be equally fast. */
236#define DIV_ROUND_UP(_x, _y) \
237 __extension__ ({ \
238 const typeof(_x) __x = (_x); \
239 const typeof(_y) __y = (_y); \
240 (__x / __y + !!(__x % __y)); \
241 })
242
6300502b 243#define assert_message_se(expr, message) \
663996b3
MS
244 do { \
245 if (_unlikely_(!(expr))) \
6300502b
MP
246 log_assert_failed(message, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
247 } while (false)
248
249#define assert_se(expr) assert_message_se(expr, #expr)
663996b3
MS
250
251/* We override the glibc assert() here. */
252#undef assert
253#ifdef NDEBUG
aa27b158 254#define assert(expr) do {} while (false)
663996b3 255#else
6300502b 256#define assert(expr) assert_message_se(expr, #expr)
663996b3
MS
257#endif
258
259#define assert_not_reached(t) \
260 do { \
261 log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
262 } while (false)
263
264#if defined(static_assert)
60f067b4
JS
265/* static_assert() is sometimes defined in a way that trips up
266 * -Wdeclaration-after-statement, hence let's temporarily turn off
267 * this warning around it. */
268#define assert_cc(expr) \
269 DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \
270 static_assert(expr, #expr); \
271 REENABLE_WARNING
663996b3 272#else
60f067b4
JS
273#define assert_cc(expr) \
274 DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \
e735f4d4 275 struct CONCATENATE(_assert_struct_, __COUNTER__) { \
60f067b4
JS
276 char x[(expr) ? 0 : -1]; \
277 }; \
278 REENABLE_WARNING
663996b3
MS
279#endif
280
6300502b
MP
281#define assert_log(expr, message) ((_likely_(expr)) \
282 ? (true) \
283 : (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false))
86f210e9 284
60f067b4
JS
285#define assert_return(expr, r) \
286 do { \
6300502b 287 if (!assert_log(expr, #expr)) \
60f067b4 288 return (r); \
60f067b4
JS
289 } while (false)
290
e3bff60a
MP
291#define assert_return_errno(expr, r, err) \
292 do { \
6300502b 293 if (!assert_log(expr, #expr)) { \
e3bff60a
MP
294 errno = err; \
295 return (r); \
296 } \
297 } while (false)
298
14228c0d
MB
299#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
300#define INT_TO_PTR(u) ((void *) ((intptr_t) (u)))
663996b3 301#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
14228c0d 302#define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u)))
663996b3 303
14228c0d
MB
304#define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
305#define LONG_TO_PTR(u) ((void *) ((intptr_t) (u)))
663996b3 306#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
14228c0d 307#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
663996b3 308
14228c0d
MB
309#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
310#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
311#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
312#define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u)))
663996b3 313
14228c0d
MB
314#define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p)))
315#define INT64_TO_PTR(u) ((void *) ((intptr_t) (u)))
316#define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p)))
317#define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u)))
663996b3 318
5eef597e
MP
319#define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p)))
320#define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u)))
321
663996b3
MS
322#define CHAR_TO_STR(x) ((char[2]) { x, 0 })
323
324#define char_array_0(x) x[sizeof(x)-1] = 0;
325
663996b3
MS
326/* Returns the number of chars needed to format variables of the
327 * specified type as a decimal string. Adds in extra space for a
e735f4d4
MP
328 * negative '-' prefix (hence works correctly on signed
329 * types). Includes space for the trailing NUL. */
663996b3 330#define DECIMAL_STR_MAX(type) \
60f067b4 331 (2+(sizeof(type) <= 1 ? 3 : \
663996b3
MS
332 sizeof(type) <= 2 ? 5 : \
333 sizeof(type) <= 4 ? 10 : \
334 sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
335
db2df898
MP
336#define DECIMAL_STR_WIDTH(x) \
337 ({ \
338 typeof(x) _x_ = (x); \
339 unsigned ans = 1; \
340 while (_x_ /= 10) \
341 ans++; \
342 ans; \
343 })
344
14228c0d
MB
345#define SET_FLAG(v, flag, b) \
346 (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
347
4c89c718
MP
348#define CASE_F(X) case X:
349#define CASE_F_1(CASE, X) CASE_F(X)
350#define CASE_F_2(CASE, X, ...) CASE(X) CASE_F_1(CASE, __VA_ARGS__)
351#define CASE_F_3(CASE, X, ...) CASE(X) CASE_F_2(CASE, __VA_ARGS__)
352#define CASE_F_4(CASE, X, ...) CASE(X) CASE_F_3(CASE, __VA_ARGS__)
353#define CASE_F_5(CASE, X, ...) CASE(X) CASE_F_4(CASE, __VA_ARGS__)
354#define CASE_F_6(CASE, X, ...) CASE(X) CASE_F_5(CASE, __VA_ARGS__)
355#define CASE_F_7(CASE, X, ...) CASE(X) CASE_F_6(CASE, __VA_ARGS__)
356#define CASE_F_8(CASE, X, ...) CASE(X) CASE_F_7(CASE, __VA_ARGS__)
357#define CASE_F_9(CASE, X, ...) CASE(X) CASE_F_8(CASE, __VA_ARGS__)
358#define CASE_F_10(CASE, X, ...) CASE(X) CASE_F_9(CASE, __VA_ARGS__)
359#define CASE_F_11(CASE, X, ...) CASE(X) CASE_F_10(CASE, __VA_ARGS__)
360#define CASE_F_12(CASE, X, ...) CASE(X) CASE_F_11(CASE, __VA_ARGS__)
361#define CASE_F_13(CASE, X, ...) CASE(X) CASE_F_12(CASE, __VA_ARGS__)
362#define CASE_F_14(CASE, X, ...) CASE(X) CASE_F_13(CASE, __VA_ARGS__)
363#define CASE_F_15(CASE, X, ...) CASE(X) CASE_F_14(CASE, __VA_ARGS__)
364#define CASE_F_16(CASE, X, ...) CASE(X) CASE_F_15(CASE, __VA_ARGS__)
365#define CASE_F_17(CASE, X, ...) CASE(X) CASE_F_16(CASE, __VA_ARGS__)
366#define CASE_F_18(CASE, X, ...) CASE(X) CASE_F_17(CASE, __VA_ARGS__)
367#define CASE_F_19(CASE, X, ...) CASE(X) CASE_F_18(CASE, __VA_ARGS__)
368#define CASE_F_20(CASE, X, ...) CASE(X) CASE_F_19(CASE, __VA_ARGS__)
369
370#define GET_CASE_F(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,NAME,...) NAME
371#define FOR_EACH_MAKE_CASE(...) \
372 GET_CASE_F(__VA_ARGS__,CASE_F_20,CASE_F_19,CASE_F_18,CASE_F_17,CASE_F_16,CASE_F_15,CASE_F_14,CASE_F_13,CASE_F_12,CASE_F_11, \
373 CASE_F_10,CASE_F_9,CASE_F_8,CASE_F_7,CASE_F_6,CASE_F_5,CASE_F_4,CASE_F_3,CASE_F_2,CASE_F_1) \
374 (CASE_F,__VA_ARGS__)
375
376#define IN_SET(x, ...) \
377 ({ \
378 bool _found = false; \
379 /* If the build breaks in the line below, you need to extend the case macros */ \
380 static _unused_ char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){__VA_ARGS__})/sizeof(int)]; \
381 switch(x) { \
382 FOR_EACH_MAKE_CASE(__VA_ARGS__) \
383 _found = true; \
384 break; \
385 default: \
386 break; \
387 } \
388 _found; \
60f067b4
JS
389 })
390
aa27b158
MP
391#define SWAP_TWO(x, y) do { \
392 typeof(x) _t = (x); \
393 (x) = (y); \
394 (y) = (_t); \
395 } while (false)
396
60f067b4
JS
397/* Define C11 thread_local attribute even on older gcc compiler
398 * version */
399#ifndef thread_local
400/*
401 * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
402 * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
403 */
404#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
405#define thread_local _Thread_local
406#else
407#define thread_local __thread
408#endif
409#endif
410
411/* Define C11 noreturn without <stdnoreturn.h> and even on older gcc
412 * compiler versions */
413#ifndef noreturn
414#if __STDC_VERSION__ >= 201112L
415#define noreturn _Noreturn
416#else
417#define noreturn __attribute__((noreturn))
418#endif
419#endif
420
e735f4d4
MP
421#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \
422 static inline void func##p(type *p) { \
423 if (*p) \
424 func(*p); \
425 } \
426 struct __useless_struct_to_allow_trailing_semicolon__
427
663996b3 428#include "log.h"