chiark / gitweb /
e6734804bd36a8efb7079e02dcdcfeefdce014e9
[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 #define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
83 #define UNIQ __COUNTER__
84
85 /* Rounds up */
86
87 #define ALIGN4(l) (((l) + 3) & ~3)
88 #define ALIGN8(l) (((l) + 7) & ~7)
89
90 #if __SIZEOF_POINTER__ == 8
91 #define ALIGN(l) ALIGN8(l)
92 #elif __SIZEOF_POINTER__ == 4
93 #define ALIGN(l) ALIGN4(l)
94 #else
95 #error "Wut? Pointers are neither 4 nor 8 bytes long?"
96 #endif
97
98 #define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) p))
99 #define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) p))
100 #define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) p))
101
102 static inline size_t ALIGN_TO(size_t l, size_t ali) {
103         return ((l + ali - 1) & ~(ali - 1));
104 }
105
106 #define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p, ali))
107
108 /* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
109 static inline unsigned long ALIGN_POWER2(unsigned long u) {
110         /* clz(0) is undefined */
111         if (u == 1)
112                 return 1;
113
114         /* left-shift overflow is undefined */
115         if (__builtin_clzl(u - 1UL) < 1)
116                 return 0;
117
118         return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL));
119 }
120
121 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
122
123 /*
124  * container_of - cast a member of a structure out to the containing structure
125  * @ptr: the pointer to the member.
126  * @type: the type of the container struct this is embedded in.
127  * @member: the name of the member within the struct.
128  */
129 #define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member)
130 #define __container_of(uniq, ptr, type, member)                         \
131         __extension__ ({                                                \
132                 const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \
133                 (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type,member) ); \
134         })
135
136 #undef MAX
137 #define MAX(a,b)                                        \
138         __extension__ ({                                \
139                         const typeof(a) _a = (a);       \
140                         const typeof(b) _b = (b);       \
141                         _a > _b ? _a : _b;              \
142                 })
143
144 /* evaluates to (void) if _A or _B are not constant or of different types */
145 #define CONST_MAX(_A, _B) \
146         __extension__ (__builtin_choose_expr(                           \
147                 __builtin_constant_p(_A) &&                             \
148                 __builtin_constant_p(_B) &&                             \
149                 __builtin_types_compatible_p(typeof(_A), typeof(_B)),   \
150                 ((_A) > (_B)) ? (_A) : (_B),                            \
151                 (void)0))
152
153 /* takes two types and returns the size of the larger one */
154 #define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; }))
155
156 #define MAX3(x,y,z)                                     \
157         __extension__ ({                                \
158                         const typeof(x) _c = MAX(x,y);  \
159                         MAX(_c, z);                     \
160                 })
161
162 #undef MIN
163 #define MIN(a,b)                                        \
164         __extension__ ({                                \
165                         const typeof(a) _a = (a);       \
166                         const typeof(b) _b = (b);       \
167                         _a < _b ? _a : _b;              \
168                 })
169
170 #define MIN3(x,y,z)                                     \
171         __extension__ ({                                \
172                         const typeof(x) _c = MIN(x,y);  \
173                         MIN(_c, z);                     \
174                 })
175
176 #define LESS_BY(A,B)                                    \
177         __extension__ ({                                \
178                         const typeof(A) _A = (A);       \
179                         const typeof(B) _B = (B);       \
180                         _A > _B ? _A - _B : 0;          \
181                 })
182
183 #ifndef CLAMP
184 #define CLAMP(x, low, high)                                             \
185         __extension__ ({                                                \
186                         const typeof(x) _x = (x);                       \
187                         const typeof(low) _low = (low);                 \
188                         const typeof(high) _high = (high);              \
189                         ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
190                 })
191 #endif
192
193 #define assert_se(expr)                                                 \
194         do {                                                            \
195                 if (_unlikely_(!(expr)))                                \
196                         log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
197         } while (false)                                                 \
198
199 /* We override the glibc assert() here. */
200 #undef assert
201 #ifdef NDEBUG
202 #define assert(expr) do {} while(false)
203 #else
204 #define assert(expr) assert_se(expr)
205 #endif
206
207 #define assert_not_reached(t)                                           \
208         do {                                                            \
209                 log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
210         } while (false)
211
212 #if defined(static_assert)
213 /* static_assert() is sometimes defined in a way that trips up
214  * -Wdeclaration-after-statement, hence let's temporarily turn off
215  * this warning around it. */
216 #define assert_cc(expr)                                                 \
217         DISABLE_WARNING_DECLARATION_AFTER_STATEMENT;                    \
218         static_assert(expr, #expr);                                     \
219         REENABLE_WARNING
220 #else
221 #define assert_cc(expr)                                                 \
222         DISABLE_WARNING_DECLARATION_AFTER_STATEMENT;                    \
223         struct CONCATENATE(_assert_struct_, __LINE__) {                 \
224                 char x[(expr) ? 0 : -1];                                \
225         };                                                              \
226         REENABLE_WARNING
227 #endif
228
229 #define assert_return(expr, r)                                          \
230         do {                                                            \
231                 if (_unlikely_(!(expr))) {                              \
232                         log_assert_failed_return(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
233                         return (r);                                     \
234                 }                                                       \
235         } while (false)
236
237 #define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
238 #define INT_TO_PTR(u) ((void *) ((intptr_t) (u)))
239 #define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
240 #define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u)))
241
242 #define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
243 #define LONG_TO_PTR(u) ((void *) ((intptr_t) (u)))
244 #define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
245 #define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
246
247 #define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
248 #define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
249 #define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
250 #define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u)))
251
252 #define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p)))
253 #define INT64_TO_PTR(u) ((void *) ((intptr_t) (u)))
254 #define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p)))
255 #define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u)))
256
257 #define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p)))
258 #define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u)))
259
260 #define memzero(x,l) (memset((x), 0, (l)))
261 #define zero(x) (memzero(&(x), sizeof(x)))
262
263 #define CHAR_TO_STR(x) ((char[2]) { x, 0 })
264
265 #define char_array_0(x) x[sizeof(x)-1] = 0;
266
267 #define IOVEC_SET_STRING(i, s)                  \
268         do {                                    \
269                 struct iovec *_i = &(i);        \
270                 char *_s = (char *)(s);         \
271                 _i->iov_base = _s;              \
272                 _i->iov_len = strlen(_s);       \
273         } while(false)
274
275 static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
276         unsigned j;
277         size_t r = 0;
278
279         for (j = 0; j < n; j++)
280                 r += i[j].iov_len;
281
282         return r;
283 }
284
285 static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
286         unsigned j;
287
288         for (j = 0; j < n; j++) {
289                 size_t sub;
290
291                 if (_unlikely_(k <= 0))
292                         break;
293
294                 sub = MIN(i[j].iov_len, k);
295                 i[j].iov_len -= sub;
296                 i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
297                 k -= sub;
298         }
299
300         return k;
301 }
302
303 #define VA_FORMAT_ADVANCE(format, ap)                                   \
304 do {                                                                    \
305         int _argtypes[128];                                             \
306         size_t _i, _k;                                                  \
307         _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
308         assert(_k < ELEMENTSOF(_argtypes));                             \
309         for (_i = 0; _i < _k; _i++) {                                   \
310                 if (_argtypes[_i] & PA_FLAG_PTR)  {                     \
311                         (void) va_arg(ap, void*);                       \
312                         continue;                                       \
313                 }                                                       \
314                                                                         \
315                 switch (_argtypes[_i]) {                                \
316                 case PA_INT:                                            \
317                 case PA_INT|PA_FLAG_SHORT:                              \
318                 case PA_CHAR:                                           \
319                         (void) va_arg(ap, int);                         \
320                         break;                                          \
321                 case PA_INT|PA_FLAG_LONG:                               \
322                         (void) va_arg(ap, long int);                    \
323                         break;                                          \
324                 case PA_INT|PA_FLAG_LONG_LONG:                          \
325                         (void) va_arg(ap, long long int);               \
326                         break;                                          \
327                 case PA_WCHAR:                                          \
328                         (void) va_arg(ap, wchar_t);                     \
329                         break;                                          \
330                 case PA_WSTRING:                                        \
331                 case PA_STRING:                                         \
332                 case PA_POINTER:                                        \
333                         (void) va_arg(ap, void*);                       \
334                         break;                                          \
335                 case PA_FLOAT:                                          \
336                 case PA_DOUBLE:                                         \
337                         (void) va_arg(ap, double);                      \
338                         break;                                          \
339                 case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:                     \
340                         (void) va_arg(ap, long double);                 \
341                         break;                                          \
342                 default:                                                \
343                         assert_not_reached("Unknown format string argument."); \
344                 }                                                       \
345         }                                                               \
346 } while(false)
347
348  /* Because statfs.t_type can be int on some architectures, we have to cast
349   * the const magic to the type, otherwise the compiler warns about
350   * signed/unsigned comparison, because the magic can be 32 bit unsigned.
351  */
352 #define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
353
354 /* Returns the number of chars needed to format variables of the
355  * specified type as a decimal string. Adds in extra space for a
356  * negative '-' prefix. */
357 #define DECIMAL_STR_MAX(type)                                           \
358         (2+(sizeof(type) <= 1 ? 3 :                                     \
359             sizeof(type) <= 2 ? 5 :                                     \
360             sizeof(type) <= 4 ? 10 :                                    \
361             sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
362
363 #define SET_FLAG(v, flag, b) \
364         (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
365
366 #define IN_SET(x, y, ...)                                               \
367         ({                                                              \
368                 const typeof(y) _y = (y);                               \
369                 const typeof(_y) _x = (x);                              \
370                 unsigned _i;                                            \
371                 bool _found = false;                                    \
372                 for (_i = 0; _i < 1 + sizeof((const typeof(_x)[]) { __VA_ARGS__ })/sizeof(const typeof(_x)); _i++) \
373                         if (((const typeof(_x)[]) { _y, __VA_ARGS__ })[_i] == _x) { \
374                                 _found = true;                          \
375                                 break;                                  \
376                         }                                               \
377                 _found;                                                 \
378         })
379
380 /* Define C11 thread_local attribute even on older gcc compiler
381  * version */
382 #ifndef thread_local
383 /*
384  * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
385  * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
386  */
387 #if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
388 #define thread_local _Thread_local
389 #else
390 #define thread_local __thread
391 #endif
392 #endif
393
394 /* Define C11 noreturn without <stdnoreturn.h> and even on older gcc
395  * compiler versions */
396 #ifndef noreturn
397 #if __STDC_VERSION__ >= 201112L
398 #define noreturn _Noreturn
399 #else
400 #define noreturn __attribute__((noreturn))
401 #endif
402 #endif
403
404 #include "log.h"