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