chiark / gitweb /
2807bc74e849c65b4f6706c988580fed30a885c3
[elogind.git] / src / shared / macro.h
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 #pragma once
4
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
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
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
18   Lesser General Public License for more details.
19
20   You should have received a copy of the GNU Lesser General Public License
21   along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 ***/
23
24 #include <assert.h>
25 #include <sys/param.h>
26 #include <sys/types.h>
27 #include <sys/uio.h>
28 #include <inttypes.h>
29
30 #define _printf_(a,b) __attribute__ ((format (printf, a, b)))
31 #define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
32 #define _sentinel_ __attribute__ ((sentinel))
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))
43 #define _public_ __attribute__ ((visibility("default")))
44 #define _hidden_ __attribute__ ((visibility("hidden")))
45 #define _weakref_(x) __attribute__((weakref(#x)))
46 #define _alignas_(x) __attribute__((aligned(__alignof(x))))
47 #define _cleanup_(x) __attribute__((cleanup(x)))
48
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
54 #define DISABLE_WARNING_FORMAT_NONLITERAL                               \
55         _Pragma("GCC diagnostic push");                                 \
56         _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
57
58 #define DISABLE_WARNING_MISSING_PROTOTYPES                              \
59         _Pragma("GCC diagnostic push");                                 \
60         _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"")
61
62 #define DISABLE_WARNING_NONNULL                                         \
63         _Pragma("GCC diagnostic push");                                 \
64         _Pragma("GCC diagnostic ignored \"-Wnonnull\"")
65
66 #define DISABLE_WARNING_SHADOW                                          \
67         _Pragma("GCC diagnostic push");                                 \
68         _Pragma("GCC diagnostic ignored \"-Wshadow\"")
69
70 #define REENABLE_WARNING                                                \
71         _Pragma("GCC diagnostic pop")
72
73 /* automake test harness */
74 #define EXIT_TEST_SKIP 77
75
76 #define XSTRINGIFY(x) #x
77 #define STRINGIFY(x) XSTRINGIFY(x)
78
79 #define XCONCATENATE(x, y) x ## y
80 #define CONCATENATE(x, y) XCONCATENATE(x, y)
81
82 /* Rounds up */
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
95 #define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) p))
96 #define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) p))
97 #define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) p))
98
99 static inline size_t ALIGN_TO(size_t l, size_t ali) {
100         return ((l + ali - 1) & ~(ali - 1));
101 }
102
103 #define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p, ali))
104
105 /* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
106 static 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
118 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
119
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  */
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                 })
132
133 #undef MAX
134 #define MAX(a,b)                                        \
135         __extension__ ({                                \
136                         const typeof(a) _a = (a);       \
137                         const typeof(b) _b = (b);       \
138                         _a > _b ? _a : _b;              \
139                 })
140
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
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
153 #define MAX3(x,y,z)                                     \
154         __extension__ ({                                \
155                         const typeof(x) _c = MAX(x,y);  \
156                         MAX(_c, z);                     \
157                 })
158
159 #undef MIN
160 #define MIN(a,b)                                        \
161         __extension__ ({                                \
162                         const typeof(a) _a = (a);       \
163                         const typeof(b) _b = (b);       \
164                         _a < _b ? _a : _b;              \
165                 })
166
167 #define MIN3(x,y,z)                                     \
168         __extension__ ({                                \
169                         const typeof(x) _c = MIN(x,y);  \
170                         MIN(_c, z);                     \
171                 })
172
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;          \
178                 })
179
180 #ifndef CLAMP
181 #define CLAMP(x, low, high)                                             \
182         __extension__ ({                                                \
183                         const typeof(x) _x = (x);                       \
184                         const typeof(low) _low = (low);                 \
185                         const typeof(high) _high = (high);              \
186                         ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
187                 })
188 #endif
189
190 #define assert_se(expr)                                                 \
191         do {                                                            \
192                 if (_unlikely_(!(expr)))                                \
193                         log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
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
203
204 #define assert_not_reached(t)                                           \
205         do {                                                            \
206                 log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
207         } while (false)
208
209 #if defined(static_assert)
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
217 #else
218 #define assert_cc(expr)                                                 \
219         DISABLE_WARNING_DECLARATION_AFTER_STATEMENT;                    \
220         struct CONCATENATE(_assert_struct_, __LINE__) {                 \
221                 char x[(expr) ? 0 : -1];                                \
222         };                                                              \
223         REENABLE_WARNING
224 #endif
225
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                 }                                                       \
232         } while (false)
233
234 #define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
235 #define INT_TO_PTR(u) ((void *) ((intptr_t) (u)))
236 #define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
237 #define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u)))
238
239 #define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
240 #define LONG_TO_PTR(u) ((void *) ((intptr_t) (u)))
241 #define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
242 #define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
243
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)))
248
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)))
253
254 #define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p)))
255 #define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u)))
256
257 #define memzero(x,l) (memset((x), 0, (l)))
258 #define zero(x) (memzero(&(x), sizeof(x)))
259
260 #define CHAR_TO_STR(x) ((char[2]) { x, 0 })
261
262 #define char_array_0(x) x[sizeof(x)-1] = 0;
263
264 #define IOVEC_SET_STRING(i, s)                  \
265         do {                                    \
266                 struct iovec *_i = &(i);        \
267                 char *_s = (char *)(s);         \
268                 _i->iov_base = _s;              \
269                 _i->iov_len = strlen(_s);       \
270         } while(false)
271
272 static 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
282 static 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
300 #define VA_FORMAT_ADVANCE(format, ap)                                   \
301 do {                                                                    \
302         int _argtypes[128];                                             \
303         size_t _i, _k;                                                  \
304         _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
305         assert(_k < ELEMENTSOF(_argtypes));                             \
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
345  /* Because statfs.t_type can be int on some architectures, we have to cast
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  */
349 #define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
350
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. */
354 #define DECIMAL_STR_MAX(type)                                           \
355         (2+(sizeof(type) <= 1 ? 3 :                                     \
356             sizeof(type) <= 2 ? 5 :                                     \
357             sizeof(type) <= 4 ? 10 :                                    \
358             sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
359
360 #define SET_FLAG(v, flag, b) \
361         (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
362
363 #define IN_SET(x, y, ...)                                               \
364         ({                                                              \
365                 const typeof(y) _y = (y);                               \
366                 const typeof(_y) _x = (x);                              \
367                 unsigned _i;                                            \
368                 bool _found = false;                                    \
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) { \
371                                 _found = true;                          \
372                                 break;                                  \
373                         }                                               \
374                 _found;                                                 \
375         })
376
377 /* Define C11 thread_local attribute even on older gcc compiler
378  * version */
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
390
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
401 #include "log.h"