macro.h 10.3 KB
Newer Older
1
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
Lennart Poettering's avatar
Lennart Poettering committed
2

3
#pragma once
Lennart Poettering's avatar
Lennart Poettering committed
4

5
6
7
8
9
10
/***
  This file is part of systemd.

  Copyright 2010 Lennart Poettering

  systemd is free software; you can redistribute it and/or modify it
11
12
  under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation; either version 2.1 of the License, or
13
14
15
16
17
  (at your option) any later version.

  systemd is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  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
22
23
  along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/

Lennart Poettering's avatar
Lennart Poettering committed
24
#include <assert.h>
Frederic Crozat's avatar
Frederic Crozat committed
25
#include <sys/param.h>
Lennart Poettering's avatar
Lennart Poettering committed
26
#include <sys/types.h>
27
28
#include <sys/uio.h>
#include <inttypes.h>
Lennart Poettering's avatar
Lennart Poettering committed
29

30
31
32
33
34
35
36
37
38
39
40
41
42
#define _printf_attr_(a,b) __attribute__ ((format (printf, a, b)))
#define _sentinel_ __attribute__ ((sentinel))
#define _noreturn_ __attribute__((noreturn))
#define _unused_ __attribute__ ((unused))
#define _destructor_ __attribute__ ((destructor))
#define _pure_ __attribute__ ((pure))
#define _const_ __attribute__ ((const))
#define _deprecated_ __attribute__ ((deprecated))
#define _packed_ __attribute__ ((packed))
#define _malloc_ __attribute__ ((malloc))
#define _weak_ __attribute__ ((weak))
#define _likely_(x) (__builtin_expect(!!(x),1))
#define _unlikely_(x) (__builtin_expect(!!(x),0))
43
44
#define _public_ __attribute__ ((visibility("default")))
#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))))
Lennart Poettering's avatar
Lennart Poettering committed
48

49
50
51
#define XSTRINGIFY(x) #x
#define STRINGIFY(x) XSTRINGIFY(x)

Lennart Poettering's avatar
Lennart Poettering committed
52
/* Rounds up */
cee1's avatar
cee1 committed
53
54
55
#define ALIGN(l) ALIGN_TO((l), sizeof(void*))
static inline size_t ALIGN_TO(size_t l, size_t ali) {
        return ((l + ali - 1) & ~(ali - 1));
56
57
}

Lennart Poettering's avatar
Lennart Poettering committed
58
59
#define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))

Kay Sievers's avatar
Kay Sievers committed
60
61
62
63
64
65
66
67
68
69
70
/*
 * container_of - cast a member of a structure out to the containing structure
 * @ptr: the pointer to the member.
 * @type: the type of the container struct this is embedded in.
 * @member: the name of the member within the struct.
 *
 */
#define container_of(ptr, type, member) ({ \
        const typeof( ((type *)0)->member ) *__mptr = (ptr); \
        (type *)( (char *)__mptr - offsetof(type,member) );})

71
#ifndef MAX
Lennart Poettering's avatar
Lennart Poettering committed
72
73
74
75
76
77
#define MAX(a,b)                                \
        __extension__ ({                        \
                        typeof(a) _a = (a);     \
                        typeof(b) _b = (b);     \
                        _a > _b ? _a : _b;      \
                })
78
#endif
Lennart Poettering's avatar
Lennart Poettering committed
79

80
81
82
83
#define MAX3(a,b,c)                             \
        MAX(MAX(a,b),c)

#ifndef MIN
Lennart Poettering's avatar
Lennart Poettering committed
84
85
86
87
88
89
#define MIN(a,b)                                \
        __extension__ ({                        \
                        typeof(a) _a = (a);     \
                        typeof(b) _b = (b);     \
                        _a < _b ? _a : _b;      \
                })
90
91
92
93
#endif

#define MIN3(a,b,c)                             \
        MIN(MIN(a,b),c)
Lennart Poettering's avatar
Lennart Poettering committed
94
95
96
97
98
99
100
101
102

#define CLAMP(x, low, high)                                             \
        __extension__ ({                                                \
                        typeof(x) _x = (x);                             \
                        typeof(low) _low = (low);                       \
                        typeof(high) _high = (high);                    \
                        ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
                })

103
104
#define assert_se(expr)                                                 \
        do {                                                            \
105
                if (_unlikely_(!(expr)))                                \
Michal Schmidt's avatar
Michal Schmidt committed
106
                        log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
107
108
109
110
111
112
113
114
115
        } while (false)                                                 \

/* We override the glibc assert() here. */
#undef assert
#ifdef NDEBUG
#define assert(expr) do {} while(false)
#else
#define assert(expr) assert_se(expr)
#endif
Lennart Poettering's avatar
Lennart Poettering committed
116

117
118
#define assert_not_reached(t)                                           \
        do {                                                            \
Michal Schmidt's avatar
Michal Schmidt committed
119
                log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
120
        } while (false)
Lennart Poettering's avatar
Lennart Poettering committed
121

122
123
124
125
#if defined(static_assert)
#define assert_cc(expr)                         \
        do {                                    \
                static_assert(expr, #expr);     \
Lennart Poettering's avatar
Lennart Poettering committed
126
        } while (false)
127
128
129
130
131
132
133
134
135
136
#else
#define assert_cc(expr)                         \
        do {                                    \
                switch (0) {                    \
                case 0:                         \
                case !!(expr):                  \
                        ;                       \
                }                               \
        } while (false)
#endif
Lennart Poettering's avatar
Lennart Poettering committed
137
138
139
140
141
142
143

#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
#define UINT_TO_PTR(u) ((void*) ((uintptr_t) (u)))

#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
#define UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u)))

144
145
146
#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
#define ULONG_TO_PTR(u) ((void*) ((uintptr_t) (u)))

Lennart Poettering's avatar
Lennart Poettering committed
147
148
149
150
151
152
#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
#define INT_TO_PTR(u) ((void*) ((intptr_t) (u)))

#define TO_INT32(p) ((int32_t) ((intptr_t) (p)))
#define INT32_TO_PTR(u) ((void*) ((intptr_t) (u)))

153
154
155
#define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
#define LONG_TO_PTR(u) ((void*) ((intptr_t) (u)))

156
157
158
#define memzero(x,l) (memset((x), 0, (l)))
#define zero(x) (memzero(&(x), sizeof(x)))

159
160
#define char_array_0(x) x[sizeof(x)-1] = 0;

161
#define IOVEC_SET_STRING(i, s)                  \
162
        do {                                    \
163
164
165
166
                struct iovec *_i = &(i);        \
                char *_s = (char *)(s);         \
                _i->iov_base = _s;              \
                _i->iov_len = strlen(_s);       \
167
        } while(false)
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
        unsigned j;
        size_t r = 0;

        for (j = 0; j < n; j++)
                r += i[j].iov_len;

        return r;
}

static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
        unsigned j;

        for (j = 0; j < n; j++) {
                size_t sub;

                if (_unlikely_(k <= 0))
                        break;

                sub = MIN(i[j].iov_len, k);
                i[j].iov_len -= sub;
                i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
                k -= sub;
        }

        return k;
}

197
198
#define _cleanup_free_ __attribute__((cleanup(freep)))
#define _cleanup_fclose_ __attribute__((cleanup(fclosep)))
199
#define _cleanup_pclose_ __attribute__((cleanup(pclosep)))
200
#define _cleanup_close_ __attribute__((cleanup(closep)))
201
#define _cleanup_closedir_ __attribute__((cleanup(closedirp)))
202
#define _cleanup_umask_ __attribute__((cleanup(umaskp)))
203
#define _cleanup_set_free_ __attribute__((cleanup(set_freep)))
204
#define _cleanup_set_free_free_ __attribute__((cleanup(set_free_freep)))
205
#define _cleanup_strv_free_ __attribute__((cleanup(strv_freep)))
206

207
208
209
#define VA_FORMAT_ADVANCE(format, ap)                                   \
do {                                                                    \
        int _argtypes[128];                                             \
210
211
        size_t _i, _k;                                                  \
        _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
212
        assert(_k < ELEMENTSOF(_argtypes));                             \
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
        for (_i = 0; _i < _k; _i++) {                                   \
                if (_argtypes[_i] & PA_FLAG_PTR)  {                     \
                        (void) va_arg(ap, void*);                       \
                        continue;                                       \
                }                                                       \
                                                                        \
                switch (_argtypes[_i]) {                                \
                case PA_INT:                                            \
                case PA_INT|PA_FLAG_SHORT:                              \
                case PA_CHAR:                                           \
                        (void) va_arg(ap, int);                         \
                        break;                                          \
                case PA_INT|PA_FLAG_LONG:                               \
                        (void) va_arg(ap, long int);                    \
                        break;                                          \
                case PA_INT|PA_FLAG_LONG_LONG:                          \
                        (void) va_arg(ap, long long int);               \
                        break;                                          \
                case PA_WCHAR:                                          \
                        (void) va_arg(ap, wchar_t);                     \
                        break;                                          \
                case PA_WSTRING:                                        \
                case PA_STRING:                                         \
                case PA_POINTER:                                        \
                        (void) va_arg(ap, void*);                       \
                        break;                                          \
                case PA_FLOAT:                                          \
                case PA_DOUBLE:                                         \
                        (void) va_arg(ap, double);                      \
                        break;                                          \
                case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:                     \
                        (void) va_arg(ap, long double);                 \
                        break;                                          \
                default:                                                \
                        assert_not_reached("Unknown format string argument."); \
                }                                                       \
        }                                                               \
} while(false)

252
#include "log.h"