chiark / gitweb /
4e5d0f4f2f8d304e10403b34a31378785c087e37
[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_attr_(a,b) __attribute__ ((format (printf, a, b)))
31 #define _sentinel_ __attribute__ ((sentinel))
32 #define _noreturn_ __attribute__((noreturn))
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 _introspect_(x) __attribute__((section("introspect." x)))
47 #define _alignas_(x) __attribute__((aligned(__alignof(x))))
48
49 /* automake test harness */
50 #define EXIT_TEST_SKIP 77
51
52 #define XSTRINGIFY(x) #x
53 #define STRINGIFY(x) XSTRINGIFY(x)
54
55 /* Rounds up */
56 #define ALIGN(l) ALIGN_TO((l), sizeof(void*))
57 static inline size_t ALIGN_TO(size_t l, size_t ali) {
58         return ((l + ali - 1) & ~(ali - 1));
59 }
60
61 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
62
63 /*
64  * container_of - cast a member of a structure out to the containing structure
65  * @ptr: the pointer to the member.
66  * @type: the type of the container struct this is embedded in.
67  * @member: the name of the member within the struct.
68  *
69  */
70 #define container_of(ptr, type, member) ({ \
71         const typeof( ((type *)0)->member ) *__mptr = (ptr); \
72         (type *)( (char *)__mptr - offsetof(type,member) );})
73
74 #undef MAX
75 #define MAX(a,b)                                 \
76         __extension__ ({                         \
77                         typeof(a) _a = (a);      \
78                         typeof(b) _b = (b);      \
79                         _a > _b ? _a : _b;       \
80                 })
81
82 #define MAX3(x,y,z)                              \
83         __extension__ ({                         \
84                         typeof(x) _c = MAX(x,y); \
85                         MAX(_c, z);              \
86                 })
87
88 #undef MIN
89 #define MIN(a,b)                                \
90         __extension__ ({                        \
91                         typeof(a) _a = (a);     \
92                         typeof(b) _b = (b);     \
93                         _a < _b ? _a : _b;      \
94                 })
95
96 #ifndef CLAMP
97 #define CLAMP(x, low, high)                                             \
98         __extension__ ({                                                \
99                         typeof(x) _x = (x);                             \
100                         typeof(low) _low = (low);                       \
101                         typeof(high) _high = (high);                    \
102                         ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
103                 })
104 #endif
105
106 #define assert_se(expr)                                                 \
107         do {                                                            \
108                 if (_unlikely_(!(expr)))                                \
109                         log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
110         } while (false)                                                 \
111
112 /* We override the glibc assert() here. */
113 #undef assert
114 #ifdef NDEBUG
115 #define assert(expr) do {} while(false)
116 #else
117 #define assert(expr) assert_se(expr)
118 #endif
119
120 #define assert_not_reached(t)                                           \
121         do {                                                            \
122                 log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
123         } while (false)
124
125 #if defined(static_assert)
126 #define assert_cc(expr)                         \
127         do {                                    \
128                 static_assert(expr, #expr);     \
129         } while (false)
130 #else
131 #define assert_cc(expr)                         \
132         do {                                    \
133                 switch (0) {                    \
134                 case 0:                         \
135                 case !!(expr):                  \
136                         ;                       \
137                 }                               \
138         } while (false)
139 #endif
140
141 #define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
142 #define UINT_TO_PTR(u) ((void*) ((uintptr_t) (u)))
143
144 #define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
145 #define UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u)))
146
147 #define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
148 #define ULONG_TO_PTR(u) ((void*) ((uintptr_t) (u)))
149
150 #define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
151 #define INT_TO_PTR(u) ((void*) ((intptr_t) (u)))
152
153 #define TO_INT32(p) ((int32_t) ((intptr_t) (p)))
154 #define INT32_TO_PTR(u) ((void*) ((intptr_t) (u)))
155
156 #define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
157 #define LONG_TO_PTR(u) ((void*) ((intptr_t) (u)))
158
159 #define memzero(x,l) (memset((x), 0, (l)))
160 #define zero(x) (memzero(&(x), sizeof(x)))
161
162 #define CHAR_TO_STR(x) ((char[2]) { x, 0 })
163
164 #define char_array_0(x) x[sizeof(x)-1] = 0;
165
166 #define IOVEC_SET_STRING(i, s)                  \
167         do {                                    \
168                 struct iovec *_i = &(i);        \
169                 char *_s = (char *)(s);         \
170                 _i->iov_base = _s;              \
171                 _i->iov_len = strlen(_s);       \
172         } while(false)
173
174 static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
175         unsigned j;
176         size_t r = 0;
177
178         for (j = 0; j < n; j++)
179                 r += i[j].iov_len;
180
181         return r;
182 }
183
184 static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
185         unsigned j;
186
187         for (j = 0; j < n; j++) {
188                 size_t sub;
189
190                 if (_unlikely_(k <= 0))
191                         break;
192
193                 sub = MIN(i[j].iov_len, k);
194                 i[j].iov_len -= sub;
195                 i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
196                 k -= sub;
197         }
198
199         return k;
200 }
201
202 #define _cleanup_free_ __attribute__((cleanup(freep)))
203 #define _cleanup_fclose_ __attribute__((cleanup(fclosep)))
204 #define _cleanup_pclose_ __attribute__((cleanup(pclosep)))
205 #define _cleanup_close_ __attribute__((cleanup(closep)))
206 #define _cleanup_closedir_ __attribute__((cleanup(closedirp)))
207 #define _cleanup_umask_ __attribute__((cleanup(umaskp)))
208 #define _cleanup_set_free_ __attribute__((cleanup(set_freep)))
209 #define _cleanup_set_free_free_ __attribute__((cleanup(set_free_freep)))
210 #define _cleanup_strv_free_ __attribute__((cleanup(strv_freep)))
211 #define _cleanup_journal_close_ __attribute__((cleanup(journal_closep)))
212
213 #define VA_FORMAT_ADVANCE(format, ap)                                   \
214 do {                                                                    \
215         int _argtypes[128];                                             \
216         size_t _i, _k;                                                  \
217         _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
218         assert(_k < ELEMENTSOF(_argtypes));                             \
219         for (_i = 0; _i < _k; _i++) {                                   \
220                 if (_argtypes[_i] & PA_FLAG_PTR)  {                     \
221                         (void) va_arg(ap, void*);                       \
222                         continue;                                       \
223                 }                                                       \
224                                                                         \
225                 switch (_argtypes[_i]) {                                \
226                 case PA_INT:                                            \
227                 case PA_INT|PA_FLAG_SHORT:                              \
228                 case PA_CHAR:                                           \
229                         (void) va_arg(ap, int);                         \
230                         break;                                          \
231                 case PA_INT|PA_FLAG_LONG:                               \
232                         (void) va_arg(ap, long int);                    \
233                         break;                                          \
234                 case PA_INT|PA_FLAG_LONG_LONG:                          \
235                         (void) va_arg(ap, long long int);               \
236                         break;                                          \
237                 case PA_WCHAR:                                          \
238                         (void) va_arg(ap, wchar_t);                     \
239                         break;                                          \
240                 case PA_WSTRING:                                        \
241                 case PA_STRING:                                         \
242                 case PA_POINTER:                                        \
243                         (void) va_arg(ap, void*);                       \
244                         break;                                          \
245                 case PA_FLOAT:                                          \
246                 case PA_DOUBLE:                                         \
247                         (void) va_arg(ap, double);                      \
248                         break;                                          \
249                 case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:                     \
250                         (void) va_arg(ap, long double);                 \
251                         break;                                          \
252                 default:                                                \
253                         assert_not_reached("Unknown format string argument."); \
254                 }                                                       \
255         }                                                               \
256 } while(false)
257
258 #include "log.h"