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