utils: Add helper macros to read variadic arguments into local variables
[strongswan.git] / src / libstrongswan / utils / utils.h
1 /*
2 * Copyright (C) 2008-2017 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * HSR Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 /**
18 * @defgroup utils_i utils
19 * @{ @ingroup utils
20 */
21
22 #ifndef UTILS_H_
23 #define UTILS_H_
24
25 #define _GNU_SOURCE
26 #include <sys/types.h>
27 #include <stdlib.h>
28 #include <stddef.h>
29 #include <sys/time.h>
30 #include <string.h>
31 #include <stdarg.h>
32
33 #ifdef HAVE_SYS_PARAM_H
34 #include <sys/param.h>
35 #endif
36
37 #ifdef WIN32
38 # include "compat/windows.h"
39 #else
40 # include <arpa/inet.h>
41 # include <sys/socket.h>
42 # include <netdb.h>
43 # include <netinet/in.h>
44 # include <sched.h>
45 # include <poll.h>
46 # include <signal.h>
47 #endif
48
49 #include "utils/types.h"
50 #include "enum.h"
51 #include "utils/atomics.h"
52 #include "utils/align.h"
53 #include "utils/byteorder.h"
54 #include "utils/string.h"
55 #include "utils/memory.h"
56 #include "utils/strerror.h"
57 #include "utils/status.h"
58 #include "utils/object.h"
59 #include "utils/path.h"
60 #include "utils/time.h"
61 #include "utils/tty.h"
62 #ifdef __APPLE__
63 # include "compat/apple.h"
64 #endif
65 #ifdef __ANDROID__
66 # include "compat/android.h"
67 #endif
68
69 /**
70 * Initialize utility functions
71 */
72 void utils_init();
73
74 /**
75 * Deinitialize utility functions
76 */
77 void utils_deinit();
78
79 /**
80 * strongSwan program return codes
81 */
82 #define SS_RC_LIBSTRONGSWAN_INTEGRITY 64
83 #define SS_RC_DAEMON_INTEGRITY 65
84 #define SS_RC_INITIALIZATION_FAILED 66
85
86 #define SS_RC_FIRST SS_RC_LIBSTRONGSWAN_INTEGRITY
87 #define SS_RC_LAST SS_RC_INITIALIZATION_FAILED
88
89 /**
90 * Number of bits in a byte
91 */
92 #define BITS_PER_BYTE 8
93
94 /**
95 * Default length for various auxiliary text buffers
96 */
97 #define BUF_LEN 512
98
99 /**
100 * Build assertion macro for integer expressions, evaluates to 0
101 */
102 #define BUILD_ASSERT(x) (sizeof(char[(x) ? 0 : -1]))
103
104 /**
105 * Build time check to assert a is an array, evaluates to 0
106 *
107 * The address of an array element has a pointer type, which is not compatible
108 * to the array type.
109 */
110 #define BUILD_ASSERT_ARRAY(a) \
111 BUILD_ASSERT(!__builtin_types_compatible_p(typeof(a), typeof(&(a)[0])))
112
113 /**
114 * Debug macro to follow control flow
115 */
116 #define POS printf("%s, line %d\n", __FILE__, __LINE__)
117
118 /**
119 * This macro allows counting the number of arguments passed to a macro.
120 * Combined with the VA_ARGS_DISPATCH() macro this can be used to implement
121 * macro overloading based on the number of arguments.
122 * 0 to 10 arguments are currently supported.
123 */
124 #define VA_ARGS_NUM(...) _VA_ARGS_NUM(0,##__VA_ARGS__,10,9,8,7,6,5,4,3,2,1,0)
125 #define _VA_ARGS_NUM(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,NUM,...) NUM
126
127 /**
128 * This macro can be used to dispatch a macro call based on the number of given
129 * arguments, for instance:
130 *
131 * @code
132 * #define MY_MACRO(...) VA_ARGS_DISPATCH(MY_MACRO, __VA_ARGS__)(__VA_ARGS__)
133 * #define MY_MACRO1(arg) one_arg(arg)
134 * #define MY_MACRO2(arg1,arg2) two_args(arg1,arg2)
135 * @endcode
136 *
137 * MY_MACRO() can now be called with either one or two arguments, which will
138 * resolve to one_arg(arg) or two_args(arg1,arg2), respectively.
139 */
140 #define VA_ARGS_DISPATCH(func, ...) _VA_ARGS_DISPATCH(func, VA_ARGS_NUM(__VA_ARGS__))
141 #define _VA_ARGS_DISPATCH(func, num) __VA_ARGS_DISPATCH(func, num)
142 #define __VA_ARGS_DISPATCH(func, num) func ## num
143
144 /**
145 * Assign variadic arguments to the given variables.
146 *
147 * @note The order and types of the variables are significant and must match the
148 * variadic arguments passed to the function that calls this macro exactly.
149 *
150 * @param last the last argument before ... in the function that calls this
151 * @param ... variable names
152 */
153 #define VA_ARGS_GET(last, ...) ({ \
154 va_list _va_args_get_ap; \
155 va_start(_va_args_get_ap, last); \
156 _VA_ARGS_GET_ASGN(__VA_ARGS__) \
157 va_end(_va_args_get_ap); \
158 })
159
160 /**
161 * Assign variadic arguments from a va_list to the given variables.
162 *
163 * @note The order and types of the variables are significant and must match the
164 * variadic arguments passed to the function that calls this macro exactly.
165 *
166 * @param list the va_list variable in the function that calls this
167 * @param ... variable names
168 */
169 #define VA_ARGS_VGET(list, ...) ({ \
170 va_list _va_args_get_ap; \
171 va_copy(_va_args_get_ap, list); \
172 _VA_ARGS_GET_ASGN(__VA_ARGS__) \
173 va_end(_va_args_get_ap); \
174 })
175
176 #define _VA_ARGS_GET_ASGN(...) VA_ARGS_DISPATCH(_VA_ARGS_GET_ASGN, __VA_ARGS__)(__VA_ARGS__)
177 #define _VA_ARGS_GET_ASGN1(v1) __VA_ARGS_GET_ASGN(v1)
178 #define _VA_ARGS_GET_ASGN2(v1,v2) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2)
179 #define _VA_ARGS_GET_ASGN3(v1,v2,v3) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \
180 __VA_ARGS_GET_ASGN(v3)
181 #define _VA_ARGS_GET_ASGN4(v1,v2,v3,v4) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \
182 __VA_ARGS_GET_ASGN(v3) __VA_ARGS_GET_ASGN(v4)
183 #define _VA_ARGS_GET_ASGN5(v1,v2,v3,v4,v5) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \
184 __VA_ARGS_GET_ASGN(v3) __VA_ARGS_GET_ASGN(v4) __VA_ARGS_GET_ASGN(v5)
185 #define __VA_ARGS_GET_ASGN(v) v = va_arg(_va_args_get_ap, typeof(v));
186
187 /**
188 * Macro to allocate a sized type.
189 */
190 #define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
191
192 /**
193 * Get the number of elements in an array
194 */
195 #define countof(array) (sizeof(array)/sizeof((array)[0]) \
196 + BUILD_ASSERT_ARRAY(array))
197
198 /**
199 * Ignore result of functions tagged with warn_unused_result attributes
200 */
201 #define ignore_result(call) { if(call){}; }
202
203 #if !defined(HAVE_SIGWAITINFO) && !defined(WIN32)
204 /**
205 * Block and wait for a set of signals
206 *
207 * We don't replicate the functionality of siginfo_t. If info is not NULL
208 * -1 is returend and errno is set to EINVAL.
209 *
210 * @param set set of signals to wait for
211 * @param info must be NULL
212 */
213 int sigwaitinfo(const sigset_t *set, void *info);
214 #endif
215
216 /**
217 * Portable function to wait for SIGINT/SIGTERM (or equivalent).
218 */
219 void wait_sigint();
220
221 #ifndef HAVE_CLOSEFROM
222 /**
223 * Close open file descriptors greater than or equal to lowfd.
224 *
225 * @param lowfd start closing file descriptors from here
226 */
227 void closefrom(int lowfd);
228 #endif
229
230 /**
231 * returns null
232 */
233 void *return_null();
234
235 /**
236 * No-Operation function
237 */
238 void nop();
239
240 /**
241 * returns TRUE
242 */
243 bool return_true();
244
245 /**
246 * returns FALSE
247 */
248 bool return_false();
249
250 #endif /** UTILS_H_ @}*/