]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/macro.h
macro: add a macro to test whether a value is in a specified list
[thirdparty/systemd.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 _noreturn_ __attribute__((noreturn))
34 #define _unused_ __attribute__ ((unused))
35 #define _destructor_ __attribute__ ((destructor))
36 #define _pure_ __attribute__ ((pure))
37 #define _const_ __attribute__ ((const))
38 #define _deprecated_ __attribute__ ((deprecated))
39 #define _packed_ __attribute__ ((packed))
40 #define _malloc_ __attribute__ ((malloc))
41 #define _weak_ __attribute__ ((weak))
42 #define _likely_(x) (__builtin_expect(!!(x),1))
43 #define _unlikely_(x) (__builtin_expect(!!(x),0))
44 #define _public_ __attribute__ ((visibility("default")))
45 #define _hidden_ __attribute__ ((visibility("hidden")))
46 #define _weakref_(x) __attribute__((weakref(#x)))
47 #define _alignas_(x) __attribute__((aligned(__alignof(x))))
48 #define _cleanup_(x) __attribute__((cleanup(x)))
49
50 /* automake test harness */
51 #define EXIT_TEST_SKIP 77
52
53 #define XSTRINGIFY(x) #x
54 #define STRINGIFY(x) XSTRINGIFY(x)
55
56 #define XCONCATENATE(x, y) x ## y
57 #define CONCATENATE(x, y) XCONCATENATE(x, y)
58
59 #define UNIQUE(prefix) CONCATENATE(prefix, __LINE__)
60
61 /* Rounds up */
62
63 #define ALIGN4(l) (((l) + 3) & ~3)
64 #define ALIGN8(l) (((l) + 7) & ~7)
65
66 #if __SIZEOF_POINTER__ == 8
67 #define ALIGN(l) ALIGN8(l)
68 #elif __SIZEOF_POINTER__ == 4
69 #define ALIGN(l) ALIGN4(l)
70 #else
71 #error "Wut? Pointers are neither 4 nor 8 bytes long?"
72 #endif
73
74 #define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) p))
75 #define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) p))
76 #define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) p))
77
78 static inline size_t ALIGN_TO(size_t l, size_t ali) {
79 return ((l + ali - 1) & ~(ali - 1));
80 }
81
82 #define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p))
83
84 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
85
86 /*
87 * container_of - cast a member of a structure out to the containing structure
88 * @ptr: the pointer to the member.
89 * @type: the type of the container struct this is embedded in.
90 * @member: the name of the member within the struct.
91 *
92 */
93 #define container_of(ptr, type, member) \
94 __extension__ ({ \
95 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
96 (type *)( (char *)__mptr - offsetof(type,member) ); \
97 })
98
99 #undef MAX
100 #define MAX(a,b) \
101 __extension__ ({ \
102 typeof(a) _a = (a); \
103 typeof(b) _b = (b); \
104 _a > _b ? _a : _b; \
105 })
106
107 #define MAX3(x,y,z) \
108 __extension__ ({ \
109 typeof(x) _c = MAX(x,y); \
110 MAX(_c, z); \
111 })
112
113 #undef MIN
114 #define MIN(a,b) \
115 __extension__ ({ \
116 typeof(a) _a = (a); \
117 typeof(b) _b = (b); \
118 _a < _b ? _a : _b; \
119 })
120
121 #ifndef CLAMP
122 #define CLAMP(x, low, high) \
123 __extension__ ({ \
124 typeof(x) _x = (x); \
125 typeof(low) _low = (low); \
126 typeof(high) _high = (high); \
127 ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
128 })
129 #endif
130
131 #define assert_se(expr) \
132 do { \
133 if (_unlikely_(!(expr))) \
134 log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
135 } while (false) \
136
137 /* We override the glibc assert() here. */
138 #undef assert
139 #ifdef NDEBUG
140 #define assert(expr) do {} while(false)
141 #else
142 #define assert(expr) assert_se(expr)
143 #endif
144
145 #define assert_not_reached(t) \
146 do { \
147 log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
148 } while (false)
149
150 #if defined(static_assert)
151 #define assert_cc(expr) static_assert(expr, #expr)
152 #else
153 #define assert_cc(expr) struct UNIQUE(_assert_struct_) { char x[(expr) ? 0 : -1]; };
154 #endif
155
156 #define assert_return(expr, r) \
157 do { \
158 if (_unlikely_(!(expr))) \
159 return (r); \
160 } while (false)
161
162 #define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
163 #define INT_TO_PTR(u) ((void *) ((intptr_t) (u)))
164 #define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
165 #define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u)))
166
167 #define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
168 #define LONG_TO_PTR(u) ((void *) ((intptr_t) (u)))
169 #define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
170 #define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
171
172 #define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
173 #define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
174 #define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
175 #define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u)))
176
177 #define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p)))
178 #define INT64_TO_PTR(u) ((void *) ((intptr_t) (u)))
179 #define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p)))
180 #define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u)))
181
182 #define memzero(x,l) (memset((x), 0, (l)))
183 #define zero(x) (memzero(&(x), sizeof(x)))
184
185 #define CHAR_TO_STR(x) ((char[2]) { x, 0 })
186
187 #define char_array_0(x) x[sizeof(x)-1] = 0;
188
189 #define IOVEC_SET_STRING(i, s) \
190 do { \
191 struct iovec *_i = &(i); \
192 char *_s = (char *)(s); \
193 _i->iov_base = _s; \
194 _i->iov_len = strlen(_s); \
195 } while(false)
196
197 static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
198 unsigned j;
199 size_t r = 0;
200
201 for (j = 0; j < n; j++)
202 r += i[j].iov_len;
203
204 return r;
205 }
206
207 static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
208 unsigned j;
209
210 for (j = 0; j < n; j++) {
211 size_t sub;
212
213 if (_unlikely_(k <= 0))
214 break;
215
216 sub = MIN(i[j].iov_len, k);
217 i[j].iov_len -= sub;
218 i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
219 k -= sub;
220 }
221
222 return k;
223 }
224
225 #define VA_FORMAT_ADVANCE(format, ap) \
226 do { \
227 int _argtypes[128]; \
228 size_t _i, _k; \
229 _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
230 assert(_k < ELEMENTSOF(_argtypes)); \
231 for (_i = 0; _i < _k; _i++) { \
232 if (_argtypes[_i] & PA_FLAG_PTR) { \
233 (void) va_arg(ap, void*); \
234 continue; \
235 } \
236 \
237 switch (_argtypes[_i]) { \
238 case PA_INT: \
239 case PA_INT|PA_FLAG_SHORT: \
240 case PA_CHAR: \
241 (void) va_arg(ap, int); \
242 break; \
243 case PA_INT|PA_FLAG_LONG: \
244 (void) va_arg(ap, long int); \
245 break; \
246 case PA_INT|PA_FLAG_LONG_LONG: \
247 (void) va_arg(ap, long long int); \
248 break; \
249 case PA_WCHAR: \
250 (void) va_arg(ap, wchar_t); \
251 break; \
252 case PA_WSTRING: \
253 case PA_STRING: \
254 case PA_POINTER: \
255 (void) va_arg(ap, void*); \
256 break; \
257 case PA_FLOAT: \
258 case PA_DOUBLE: \
259 (void) va_arg(ap, double); \
260 break; \
261 case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \
262 (void) va_arg(ap, long double); \
263 break; \
264 default: \
265 assert_not_reached("Unknown format string argument."); \
266 } \
267 } \
268 } while(false)
269
270 /* Because statfs.t_type can be int on some architectures, we have to cast
271 * the const magic to the type, otherwise the compiler warns about
272 * signed/unsigned comparison, because the magic can be 32 bit unsigned.
273 */
274 #define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
275
276 /* Returns the number of chars needed to format variables of the
277 * specified type as a decimal string. Adds in extra space for a
278 * negative '-' prefix. */
279 #define DECIMAL_STR_MAX(type) \
280 (2+(sizeof(type) <= 1 ? 3 : \
281 sizeof(type) <= 2 ? 5 : \
282 sizeof(type) <= 4 ? 10 : \
283 sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
284
285 #define SET_FLAG(v, flag, b) \
286 (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
287
288 #define IN_SET(x, ...) ({ \
289 typeof(x) _x = (x); \
290 unsigned _i; \
291 bool _found = false; \
292 for (_i = 0; _i < sizeof((typeof(_x)[]) { __VA_ARGS__ })/sizeof(typeof(_x)); _i++) \
293 if (((typeof(_x)[]) { __VA_ARGS__ })[_i] == _x) { \
294 _found = true; \
295 break; \
296 } \
297 _found; \
298 })
299
300
301 #include "log.h"