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