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