GCC Code Coverage Report


Directory: ./
File: tests/network/nm-utils/nm-macros-internal.h
Date: 2024-05-04 07:58:27
Exec Total Coverage
Lines: 3 3 100.0%
Functions: 1 1 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* NetworkManager -- Network link manager
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA.
18 *
19 * (C) Copyright 2014 Red Hat, Inc.
20 */
21
22 #ifndef __NM_MACROS_INTERNAL_H__
23 #define __NM_MACROS_INTERNAL_H__
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <errno.h>
28
29 #define _nm_packed __attribute__ ((packed))
30 #define _nm_unused __attribute__ ((unused))
31 #define _nm_pure __attribute__ ((pure))
32 #define _nm_const __attribute__ ((const))
33 #define _nm_printf(a,b) __attribute__ ((__format__ (__printf__, a, b)))
34 #define _nm_align(s) __attribute__ ((aligned (s)))
35 #define _nm_alignof(type) __alignof (type)
36 #define _nm_alignas(type) _nm_align (_nm_alignof (type))
37
38 #if __GNUC__ >= 7
39 #define _nm_fallthrough __attribute__ ((fallthrough))
40 #else
41 #define _nm_fallthrough
42 #endif
43
44 /*****************************************************************************/
45
46 #ifdef thread_local
47 #define _nm_thread_local thread_local
48 /*
49 * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
50 * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
51 */
52 #elif __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
53 #define _nm_thread_local _Thread_local
54 #else
55 #define _nm_thread_local __thread
56 #endif
57
58 /*****************************************************************************/
59
60 #include "nm-glib.h"
61
62 /*****************************************************************************/
63
64 #define nm_offsetofend(t,m) (G_STRUCT_OFFSET (t,m) + sizeof (((t *) NULL)->m))
65
66 #define nm_auto(fcn) __attribute__ ((cleanup(fcn)))
67
68 static inline int nm_close (int fd);
69
70 /**
71 * nm_auto_free:
72 *
73 * Call free() on a variable location when it goes out of scope.
74 */
75 #define nm_auto_free nm_auto(_nm_auto_free_impl)
76 GS_DEFINE_CLEANUP_FUNCTION(void*, _nm_auto_free_impl, free)
77
78 static inline void
79 nm_free_secret (char *secret)
80 {
81 if (secret) {
82 memset (secret, 0, strlen (secret));
83 g_free (secret);
84 }
85 }
86
87 static inline void
88 _nm_auto_free_secret_impl (char **v)
89 {
90 nm_free_secret (*v);
91 }
92
93 /**
94 * nm_auto_free_secret:
95 *
96 * Call g_free() on a variable location when it goes out of scope.
97 * Also, previously, calls memset(loc, 0, strlen(loc)) to clear out
98 * the secret.
99 */
100 #define nm_auto_free_secret nm_auto(_nm_auto_free_secret_impl)
101
102 static inline void
103 _nm_auto_unset_gvalue_impl (GValue *v)
104 {
105 g_value_unset (v);
106 }
107 #define nm_auto_unset_gvalue nm_auto(_nm_auto_unset_gvalue_impl)
108
109 static inline void
110 _nm_auto_unref_gtypeclass (gpointer v)
111 {
112 if (v && *((gpointer *) v))
113 g_type_class_unref (*((gpointer *) v));
114 }
115 #define nm_auto_unref_gtypeclass nm_auto(_nm_auto_unref_gtypeclass)
116
117 static inline void
118 _nm_auto_free_gstring_impl (GString **str)
119 {
120 if (*str)
121 g_string_free (*str, TRUE);
122 }
123 #define nm_auto_free_gstring nm_auto(_nm_auto_free_gstring_impl)
124
125 static inline void
126 _nm_auto_close_impl (int *pfd)
127 {
128 if (*pfd >= 0) {
129 int errsv = errno;
130
131 (void) nm_close (*pfd);
132 errno = errsv;
133 }
134 }
135 #define nm_auto_close nm_auto(_nm_auto_close_impl)
136
137 static inline void
138 _nm_auto_fclose_impl (FILE **pfd)
139 {
140 if (*pfd) {
141 int errsv = errno;
142
143 (void) fclose (*pfd);
144 errno = errsv;
145 }
146 }
147 #define nm_auto_fclose nm_auto(_nm_auto_fclose_impl)
148
149 static inline void
150 _nm_auto_protect_errno (int *p_saved_errno)
151 {
152 errno = *p_saved_errno;
153 }
154 #define NM_AUTO_PROTECT_ERRNO(errsv_saved) nm_auto(_nm_auto_protect_errno) _nm_unused const int errsv_saved = (errno)
155
156 /*****************************************************************************/
157
158 /* http://stackoverflow.com/a/11172679 */
159 #define _NM_UTILS_MACRO_FIRST(...) __NM_UTILS_MACRO_FIRST_HELPER(__VA_ARGS__, throwaway)
160 #define __NM_UTILS_MACRO_FIRST_HELPER(first, ...) first
161
162 #define _NM_UTILS_MACRO_REST(...) __NM_UTILS_MACRO_REST_HELPER(__NM_UTILS_MACRO_REST_NUM(__VA_ARGS__), __VA_ARGS__)
163 #define __NM_UTILS_MACRO_REST_HELPER(qty, ...) __NM_UTILS_MACRO_REST_HELPER2(qty, __VA_ARGS__)
164 #define __NM_UTILS_MACRO_REST_HELPER2(qty, ...) __NM_UTILS_MACRO_REST_HELPER_##qty(__VA_ARGS__)
165 #define __NM_UTILS_MACRO_REST_HELPER_ONE(first)
166 #define __NM_UTILS_MACRO_REST_HELPER_TWOORMORE(first, ...) , __VA_ARGS__
167 #define __NM_UTILS_MACRO_REST_NUM(...) \
168 __NM_UTILS_MACRO_REST_SELECT_30TH(__VA_ARGS__, \
169 TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
170 TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
171 TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
172 TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
173 TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
174 TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway)
175 #define __NM_UTILS_MACRO_REST_SELECT_30TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, ...) a30
176
177 /*****************************************************************************/
178
179 /* http://stackoverflow.com/a/2124385/354393 */
180
181 #define NM_NARG(...) \
182 _NM_NARG(__VA_ARGS__,_NM_NARG_RSEQ_N())
183 #define _NM_NARG(...) \
184 _NM_NARG_ARG_N(__VA_ARGS__)
185 #define _NM_NARG_ARG_N( \
186 _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
187 _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
188 _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
189 _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
190 _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
191 _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
192 _61,_62,_63,N,...) N
193 #define _NM_NARG_RSEQ_N() \
194 63,62,61,60, \
195 59,58,57,56,55,54,53,52,51,50, \
196 49,48,47,46,45,44,43,42,41,40, \
197 39,38,37,36,35,34,33,32,31,30, \
198 29,28,27,26,25,24,23,22,21,20, \
199 19,18,17,16,15,14,13,12,11,10, \
200 9,8,7,6,5,4,3,2,1,0
201
202 /*****************************************************************************/
203
204 #if defined (__GNUC__)
205 #define _NM_PRAGMA_WARNING_DO(warning) G_STRINGIFY(GCC diagnostic ignored warning)
206 #elif defined (__clang__)
207 #define _NM_PRAGMA_WARNING_DO(warning) G_STRINGIFY(clang diagnostic ignored warning)
208 #endif
209
210 /* you can only suppress a specific warning that the compiler
211 * understands. Otherwise you will get another compiler warning
212 * about invalid pragma option.
213 * It's not that bad however, because gcc and clang often have the
214 * same name for the same warning. */
215
216 #if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
217 #define NM_PRAGMA_WARNING_DISABLE(warning) \
218 _Pragma("GCC diagnostic push") \
219 _Pragma(_NM_PRAGMA_WARNING_DO(warning))
220 #elif defined (__clang__)
221 #define NM_PRAGMA_WARNING_DISABLE(warning) \
222 _Pragma("clang diagnostic push") \
223 _Pragma(_NM_PRAGMA_WARNING_DO("-Wunknown-warning-option")) \
224 _Pragma(_NM_PRAGMA_WARNING_DO(warning))
225 #else
226 #define NM_PRAGMA_WARNING_DISABLE(warning)
227 #endif
228
229 #if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
230 #define NM_PRAGMA_WARNING_REENABLE \
231 _Pragma("GCC diagnostic pop")
232 #elif defined (__clang__)
233 #define NM_PRAGMA_WARNING_REENABLE \
234 _Pragma("clang diagnostic pop")
235 #else
236 #define NM_PRAGMA_WARNING_REENABLE
237 #endif
238
239 /*****************************************************************************/
240
241 /**
242 * NM_G_ERROR_MSG:
243 * @error: (allow-none): the #GError instance
244 *
245 * All functions must follow the convention that when they
246 * return a failure, they must also set the GError to a valid
247 * message. For external API however, we want to be extra
248 * careful before accessing the error instance. Use NM_G_ERROR_MSG()
249 * which is safe to use on NULL.
250 *
251 * Returns: the error message.
252 **/
253 static inline const char *
254 NM_G_ERROR_MSG (GError *error)
255 {
256 return error ? (error->message ? : "(null)") : "(no-error)"; \
257 }
258
259 /*****************************************************************************/
260
261 /* macro to return strlen() of a compile time string. */
262 #define NM_STRLEN(str) ( sizeof ("" str) - 1 )
263
264 /* returns the length of a NULL terminated array of pointers,
265 * like g_strv_length() does. The difference is:
266 * - it operats on arrays of pointers (of any kind, requiring no cast).
267 * - it accepts NULL to return zero. */
268 #define NM_PTRARRAY_LEN(array) \
269 ({ \
270 typeof (*(array)) *const _array = (array); \
271 gsize _n = 0; \
272 \
273 if (_array) { \
274 _nm_unused gconstpointer _type_check_is_pointer = _array[0]; \
275 \
276 while (_array[_n]) \
277 _n++; \
278 } \
279 _n; \
280 })
281
282 /* Note: @value is only evaluated when *out_val is present.
283 * Thus,
284 * NM_SET_OUT (out_str, g_strdup ("hallo"));
285 * does the right thing.
286 */
287 #define NM_SET_OUT(out_val, value) \
288 G_STMT_START { \
289 typeof(*(out_val)) *_out_val = (out_val); \
290 \
291 if (_out_val) { \
292 *_out_val = (value); \
293 } \
294 } G_STMT_END
295
296 /*****************************************************************************/
297
298 #ifndef _NM_CC_SUPPORT_AUTO_TYPE
299 #if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 )))
300 #define _NM_CC_SUPPORT_AUTO_TYPE 1
301 #else
302 #define _NM_CC_SUPPORT_AUTO_TYPE 0
303 #endif
304 #endif
305
306 #ifndef _NM_CC_SUPPORT_GENERIC
307 #if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 ))) || (defined (__clang__))
308 #define _NM_CC_SUPPORT_GENERIC 1
309 #else
310 #define _NM_CC_SUPPORT_GENERIC 0
311 #endif
312 #endif
313
314 #if _NM_CC_SUPPORT_AUTO_TYPE
315 #define _nm_auto_type __auto_type
316 #endif
317
318 #if _NM_CC_SUPPORT_GENERIC
319 #define _NM_CONSTCAST_FULL_1(type, obj_expr, obj) \
320 (_Generic ((obj_expr), \
321 const void *const: ((const type *) (obj)), \
322 const void * : ((const type *) (obj)), \
323 void *const: (( type *) (obj)), \
324 void * : (( type *) (obj)), \
325 const type *const: ((const type *) (obj)), \
326 const type * : ((const type *) (obj)), \
327 type *const: (( type *) (obj)), \
328 type * : (( type *) (obj))))
329 #define _NM_CONSTCAST_FULL_2(type, obj_expr, obj, alias_type2) \
330 (_Generic ((obj_expr), \
331 const void *const: ((const type *) (obj)), \
332 const void * : ((const type *) (obj)), \
333 void *const: (( type *) (obj)), \
334 void * : (( type *) (obj)), \
335 const alias_type2 *const: ((const type *) (obj)), \
336 const alias_type2 * : ((const type *) (obj)), \
337 alias_type2 *const: (( type *) (obj)), \
338 alias_type2 * : (( type *) (obj)), \
339 const type *const: ((const type *) (obj)), \
340 const type * : ((const type *) (obj)), \
341 type *const: (( type *) (obj)), \
342 type * : (( type *) (obj))))
343 #define _NM_CONSTCAST_FULL_3(type, obj_expr, obj, alias_type2, alias_type3) \
344 (_Generic ((obj_expr), \
345 const void *const: ((const type *) (obj)), \
346 const void * : ((const type *) (obj)), \
347 void *const: (( type *) (obj)), \
348 void * : (( type *) (obj)), \
349 const alias_type2 *const: ((const type *) (obj)), \
350 const alias_type2 * : ((const type *) (obj)), \
351 alias_type2 *const: (( type *) (obj)), \
352 alias_type2 * : (( type *) (obj)), \
353 const alias_type3 *const: ((const type *) (obj)), \
354 const alias_type3 * : ((const type *) (obj)), \
355 alias_type3 *const: (( type *) (obj)), \
356 alias_type3 * : (( type *) (obj)), \
357 const type *const: ((const type *) (obj)), \
358 const type * : ((const type *) (obj)), \
359 type *const: (( type *) (obj)), \
360 type * : (( type *) (obj))))
361 #define _NM_CONSTCAST_FULL_4(type, obj_expr, obj, alias_type2, alias_type3, alias_type4) \
362 (_Generic ((obj_expr), \
363 const void *const: ((const type *) (obj)), \
364 const void * : ((const type *) (obj)), \
365 void *const: (( type *) (obj)), \
366 void * : (( type *) (obj)), \
367 const alias_type2 *const: ((const type *) (obj)), \
368 const alias_type2 * : ((const type *) (obj)), \
369 alias_type2 *const: (( type *) (obj)), \
370 alias_type2 * : (( type *) (obj)), \
371 const alias_type3 *const: ((const type *) (obj)), \
372 const alias_type3 * : ((const type *) (obj)), \
373 alias_type3 *const: (( type *) (obj)), \
374 alias_type3 * : (( type *) (obj)), \
375 const alias_type4 *const: ((const type *) (obj)), \
376 const alias_type4 * : ((const type *) (obj)), \
377 alias_type4 *const: (( type *) (obj)), \
378 alias_type4 * : (( type *) (obj)), \
379 const type *const: ((const type *) (obj)), \
380 const type * : ((const type *) (obj)), \
381 type *const: (( type *) (obj)), \
382 type * : (( type *) (obj))))
383 #define _NM_CONSTCAST_FULL_x(type, obj_expr, obj, n, ...) (_NM_CONSTCAST_FULL_##n (type, obj_expr, obj, ##__VA_ARGS__))
384 #define _NM_CONSTCAST_FULL_y(type, obj_expr, obj, n, ...) (_NM_CONSTCAST_FULL_x (type, obj_expr, obj, n, ##__VA_ARGS__))
385 #define NM_CONSTCAST_FULL( type, obj_expr, obj, ...) (_NM_CONSTCAST_FULL_y (type, obj_expr, obj, NM_NARG (dummy, ##__VA_ARGS__), ##__VA_ARGS__))
386 #else
387 #define NM_CONSTCAST_FULL( type, obj_expr, obj, ...) ((type *) (obj))
388 #endif
389
390 #define NM_CONSTCAST(type, obj, ...) \
391 NM_CONSTCAST_FULL(type, (obj), (obj), ##__VA_ARGS__)
392
393 #if _NM_CC_SUPPORT_GENERIC
394 #define NM_UNCONST_PTR(type, arg) \
395 _Generic ((arg), \
396 const type *: ((type *) (arg)), \
397 type *: ((type *) (arg)))
398 #else
399 #define NM_UNCONST_PTR(type, arg) \
400 ((type *) (arg))
401 #endif
402
403 #if _NM_CC_SUPPORT_GENERIC
404 #define NM_UNCONST_PPTR(type, arg) \
405 _Generic ((arg), \
406 const type * *: ((type **) (arg)), \
407 type * *: ((type **) (arg)), \
408 const type *const*: ((type **) (arg)), \
409 type *const*: ((type **) (arg)))
410 #else
411 #define NM_UNCONST_PPTR(type, arg) \
412 ((type **) (arg))
413 #endif
414
415 #define NM_GOBJECT_CAST(type, obj, is_check, ...) \
416 ({ \
417 const void *_obj = (obj); \
418 \
419 nm_assert (_obj || (is_check (_obj))); \
420 NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \
421 })
422
423 #define NM_GOBJECT_CAST_NON_NULL(type, obj, is_check, ...) \
424 ({ \
425 const void *_obj = (obj); \
426 \
427 nm_assert (is_check (_obj)); \
428 NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \
429 })
430
431 #if _NM_CC_SUPPORT_GENERIC
432 /* returns @value, if the type of @value matches @type.
433 * This requires support for C11 _Generic(). If no support is
434 * present, this returns @value directly.
435 *
436 * It's useful to check the let the compiler ensure that @value is
437 * of a certain type. */
438 #define _NM_ENSURE_TYPE(type, value) (_Generic ((value), type: (value)))
439 #else
440 #define _NM_ENSURE_TYPE(type, value) (value)
441 #endif
442
443 #if _NM_CC_SUPPORT_GENERIC
444 #define NM_PROPAGATE_CONST(test_expr, ptr) \
445 (_Generic ((test_expr), \
446 const typeof (*(test_expr)) *: ((const typeof (*(ptr)) *) (ptr)), \
447 default: (_Generic ((test_expr), \
448 typeof (*(test_expr)) *: (ptr)))))
449 #else
450 #define NM_PROPAGATE_CONST(test_expr, ptr) (ptr)
451 #endif
452
453 /*****************************************************************************/
454
455 #define _NM_IN_SET_EVAL_1( op, _x, y) (_x == (y))
456 #define _NM_IN_SET_EVAL_2( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_1 (op, _x, __VA_ARGS__)
457 #define _NM_IN_SET_EVAL_3( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_2 (op, _x, __VA_ARGS__)
458 #define _NM_IN_SET_EVAL_4( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_3 (op, _x, __VA_ARGS__)
459 #define _NM_IN_SET_EVAL_5( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_4 (op, _x, __VA_ARGS__)
460 #define _NM_IN_SET_EVAL_6( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_5 (op, _x, __VA_ARGS__)
461 #define _NM_IN_SET_EVAL_7( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_6 (op, _x, __VA_ARGS__)
462 #define _NM_IN_SET_EVAL_8( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_7 (op, _x, __VA_ARGS__)
463 #define _NM_IN_SET_EVAL_9( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_8 (op, _x, __VA_ARGS__)
464 #define _NM_IN_SET_EVAL_10(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_9 (op, _x, __VA_ARGS__)
465 #define _NM_IN_SET_EVAL_11(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_10 (op, _x, __VA_ARGS__)
466 #define _NM_IN_SET_EVAL_12(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_11 (op, _x, __VA_ARGS__)
467 #define _NM_IN_SET_EVAL_13(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_12 (op, _x, __VA_ARGS__)
468 #define _NM_IN_SET_EVAL_14(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_13 (op, _x, __VA_ARGS__)
469 #define _NM_IN_SET_EVAL_15(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_14 (op, _x, __VA_ARGS__)
470 #define _NM_IN_SET_EVAL_16(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_15 (op, _x, __VA_ARGS__)
471
472 #define _NM_IN_SET_EVAL_N2(op, _x, n, ...) (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__))
473 #define _NM_IN_SET_EVAL_N(op, type, x, n, ...) \
474 ({ \
475 type _x = (x); \
476 \
477 /* trigger a -Wenum-compare warning */ \
478 nm_assert (TRUE || _x == (x)); \
479 \
480 !!_NM_IN_SET_EVAL_N2(op, _x, n, __VA_ARGS__); \
481 })
482
483 #define _NM_IN_SET(op, type, x, ...) _NM_IN_SET_EVAL_N(op, type, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
484
485 /* Beware that this does short-circuit evaluation (use "||" instead of "|")
486 * which has a possibly unexpected non-function-like behavior.
487 * Use NM_IN_SET_SE if you need all arguments to be evaluted. */
488 #define NM_IN_SET(x, ...) _NM_IN_SET(||, typeof (x), x, __VA_ARGS__)
489
490 /* "SE" stands for "side-effect". Contrary to NM_IN_SET(), this does not do
491 * short-circuit evaluation, which can make a difference if the arguments have
492 * side-effects. */
493 #define NM_IN_SET_SE(x, ...) _NM_IN_SET(|, typeof (x), x, __VA_ARGS__)
494
495 /* the *_TYPED forms allow to explicitly select the type of "x". This is useful
496 * if "x" doesn't support typeof (bitfields) or you want to gracefully convert
497 * a type using automatic type conversion rules (but not forcing the conversion
498 * with a cast). */
499 #define NM_IN_SET_TYPED(type, x, ...) _NM_IN_SET(||, type, x, __VA_ARGS__)
500 #define NM_IN_SET_SE_TYPED(type, x, ...) _NM_IN_SET(|, type, x, __VA_ARGS__)
501
502 /*****************************************************************************/
503
504 static inline gboolean
505 _NM_IN_STRSET_streq (const char *x, const char *s)
506 {
507 return s && strcmp (x, s) == 0;
508 }
509
510 #define _NM_IN_STRSET_EVAL_1( op, _x, y) _NM_IN_STRSET_streq (_x, y)
511 #define _NM_IN_STRSET_EVAL_2( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_1 (op, _x, __VA_ARGS__)
512 #define _NM_IN_STRSET_EVAL_3( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_2 (op, _x, __VA_ARGS__)
513 #define _NM_IN_STRSET_EVAL_4( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_3 (op, _x, __VA_ARGS__)
514 #define _NM_IN_STRSET_EVAL_5( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_4 (op, _x, __VA_ARGS__)
515 #define _NM_IN_STRSET_EVAL_6( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_5 (op, _x, __VA_ARGS__)
516 #define _NM_IN_STRSET_EVAL_7( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_6 (op, _x, __VA_ARGS__)
517 #define _NM_IN_STRSET_EVAL_8( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_7 (op, _x, __VA_ARGS__)
518 #define _NM_IN_STRSET_EVAL_9( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_8 (op, _x, __VA_ARGS__)
519 #define _NM_IN_STRSET_EVAL_10(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_9 (op, _x, __VA_ARGS__)
520 #define _NM_IN_STRSET_EVAL_11(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_10 (op, _x, __VA_ARGS__)
521 #define _NM_IN_STRSET_EVAL_12(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_11 (op, _x, __VA_ARGS__)
522 #define _NM_IN_STRSET_EVAL_13(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_12 (op, _x, __VA_ARGS__)
523 #define _NM_IN_STRSET_EVAL_14(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_13 (op, _x, __VA_ARGS__)
524 #define _NM_IN_STRSET_EVAL_15(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_14 (op, _x, __VA_ARGS__)
525 #define _NM_IN_STRSET_EVAL_16(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_15 (op, _x, __VA_ARGS__)
526
527 #define _NM_IN_STRSET_EVAL_N2(op, _x, n, ...) (_NM_IN_STRSET_EVAL_##n(op, _x, __VA_ARGS__))
528 #define _NM_IN_STRSET_EVAL_N(op, x, n, ...) \
529 ({ \
530 const char *_x = (x); \
531 ( ((_x == NULL) && _NM_IN_SET_EVAL_N2 (op, ((const char *) NULL), n, __VA_ARGS__)) \
532 || ((_x != NULL) && _NM_IN_STRSET_EVAL_N2 (op, _x, n, __VA_ARGS__)) \
533 ); \
534 })
535
536 /* Beware that this does short-circuit evaluation (use "||" instead of "|")
537 * which has a possibly unexpected non-function-like behavior.
538 * Use NM_IN_STRSET_SE if you need all arguments to be evaluted. */
539 #define NM_IN_STRSET(x, ...) _NM_IN_STRSET_EVAL_N(||, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
540
541 /* "SE" stands for "side-effect". Contrary to NM_IN_STRSET(), this does not do
542 * short-circuit evaluation, which can make a difference if the arguments have
543 * side-effects. */
544 #define NM_IN_STRSET_SE(x, ...) _NM_IN_STRSET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
545
546 #define NM_STRCHAR_ALL(str, ch_iter, predicate) \
547 ({ \
548 gboolean _val = TRUE; \
549 const char *_str = (str); \
550 \
551 if (_str) { \
552 for (;;) { \
553 const char ch_iter = _str[0]; \
554 \
555 if (ch_iter != '\0') { \
556 if (predicate) {\
557 _str++; \
558 continue; \
559 } \
560 _val = FALSE; \
561 } \
562 break; \
563 } \
564 } \
565 _val; \
566 })
567
568 #define NM_STRCHAR_ANY(str, ch_iter, predicate) \
569 ({ \
570 gboolean _val = FALSE; \
571 const char *_str = (str); \
572 \
573 if (_str) { \
574 for (;;) { \
575 const char ch_iter = _str[0]; \
576 \
577 if (ch_iter != '\0') { \
578 if (predicate) { \
579 ; \
580 } else { \
581 _str++; \
582 continue; \
583 } \
584 _val = TRUE; \
585 } \
586 break; \
587 } \
588 } \
589 _val; \
590 })
591
592 /*****************************************************************************/
593
594 /* NM_CACHED_QUARK() returns the GQuark for @string, but caches
595 * it in a static variable to speed up future lookups.
596 *
597 * @string must be a string literal.
598 */
599 #define NM_CACHED_QUARK(string) \
600 ({ \
601 static GQuark _nm_cached_quark = 0; \
602 \
603 (G_LIKELY (_nm_cached_quark != 0) \
604 ? _nm_cached_quark \
605 : (_nm_cached_quark = g_quark_from_static_string (""string""))); \
606 })
607
608 /* NM_CACHED_QUARK_FCN() is essentially the same as G_DEFINE_QUARK
609 * with two differences:
610 * - @string must be a quoted string-literal
611 * - @fcn must be the full function name, while G_DEFINE_QUARK() appends
612 * "_quark" to the function name.
613 * Both properties of G_DEFINE_QUARK() are non favorable, because you can no
614 * longer grep for string/fcn -- unless you are aware that you are searching
615 * for G_DEFINE_QUARK() and omit quotes / append _quark(). With NM_CACHED_QUARK_FCN(),
616 * ctags/cscope can locate the use of @fcn (though it doesn't recognize that
617 * NM_CACHED_QUARK_FCN() defines it).
618 */
619 #define NM_CACHED_QUARK_FCN(string, fcn) \
620 GQuark \
621 fcn (void) \
622 { \
623 return NM_CACHED_QUARK (string); \
624 }
625
626 /*****************************************************************************/
627
628 #define nm_streq(s1, s2) (strcmp (s1, s2) == 0)
629 #define nm_streq0(s1, s2) (g_strcmp0 (s1, s2) == 0)
630
631 /*****************************************************************************/
632
633 static inline GString *
634 nm_gstring_prepare (GString **l)
635 {
636 if (*l)
637 g_string_set_size (*l, 0);
638 else
639 *l = g_string_sized_new (30);
640 return *l;
641 }
642
643 static inline const char *
644 nm_str_not_empty (const char *str)
645 {
646 return str && str[0] ? str : NULL;
647 }
648
649 static inline char *
650 nm_strdup_not_empty (const char *str)
651 {
652 return str && str[0] ? g_strdup (str) : NULL;
653 }
654
655 static inline char *
656 nm_str_realloc (char *str)
657 {
658 gs_free char *s = str;
659
660 /* Returns a new clone of @str and frees @str. The point is that @str
661 * possibly points to a larger chunck of memory. We want to freshly allocate
662 * a buffer.
663 *
664 * We could use realloc(), but that might not do anything or leave
665 * @str in its memory pool for chunks of a different size (bad for
666 * fragmentation).
667 *
668 * This is only useful when we want to keep the buffer around for a long
669 * time and want to re-allocate a more optimal buffer. */
670
671 return g_strdup (s);
672 }
673
674 /*****************************************************************************/
675
676 #define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \
677 (cond) ? (prefix) : "", \
678 (cond) ? (str) : (str_else), \
679 (cond) ? (suffix) : ""
680 #define NM_PRINT_FMT_QUOTE_STRING(arg) NM_PRINT_FMT_QUOTED((arg), "\"", (arg), "\"", "(null)")
681
682 /*****************************************************************************/
683
684 /* glib/C provides the following kind of assertions:
685 * - assert() -- disable with NDEBUG
686 * - g_return_if_fail() -- disable with G_DISABLE_CHECKS
687 * - g_assert() -- disable with G_DISABLE_ASSERT
688 * but they are all enabled by default and usually even production builds have
689 * these kind of assertions enabled. It also means, that disabling assertions
690 * is an untested configuration, and might have bugs.
691 *
692 * Add our own assertion macro nm_assert(), which is disabled by default and must
693 * be explicitly enabled. They are useful for more expensive checks or checks that
694 * depend less on runtime conditions (that is, are generally expected to be true). */
695
696 #ifndef NM_MORE_ASSERTS
697 #define NM_MORE_ASSERTS 0
698 #endif
699
700 #if NM_MORE_ASSERTS
701 #define nm_assert(cond) G_STMT_START { g_assert (cond); } G_STMT_END
702 #define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } else { g_assert (FALSE && (cond)); } } G_STMT_END
703 #define nm_assert_not_reached() G_STMT_START { g_assert_not_reached (); } G_STMT_END
704 #else
705 #define nm_assert(cond) G_STMT_START { if (FALSE) { if (cond) { } } } G_STMT_END
706 #define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } } G_STMT_END
707 #define nm_assert_not_reached() G_STMT_START { ; } G_STMT_END
708 #endif
709
710 /*****************************************************************************/
711
712 #define NM_GOBJECT_PROPERTIES_DEFINE_BASE(...) \
713 typedef enum { \
714 _PROPERTY_ENUMS_0, \
715 __VA_ARGS__ \
716 _PROPERTY_ENUMS_LAST, \
717 } _PropertyEnums; \
718 static GParamSpec *obj_properties[_PROPERTY_ENUMS_LAST] = { NULL, }
719
720 #define NM_GOBJECT_PROPERTIES_DEFINE(obj_type, ...) \
721 NM_GOBJECT_PROPERTIES_DEFINE_BASE (__VA_ARGS__); \
722 static inline void \
723 _notify (obj_type *obj, _PropertyEnums prop) \
724 { \
725 nm_assert (G_IS_OBJECT (obj)); \
726 nm_assert ((gsize) prop < G_N_ELEMENTS (obj_properties)); \
727 g_object_notify_by_pspec ((GObject *) obj, obj_properties[prop]); \
728 }
729
730 /*****************************************************************************/
731
732 #define _NM_GET_PRIVATE(self, type, is_check, ...) (&(NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv))
733 #if _NM_CC_SUPPORT_AUTO_TYPE
734 #define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) \
735 ({ \
736 _nm_auto_type _self = NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__); \
737 \
738 NM_PROPAGATE_CONST (_self, _self->_priv); \
739 })
740 #else
741 #define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) (NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv)
742 #endif
743
744 /*****************************************************************************/
745
746 static inline gpointer
747 nm_g_object_ref (gpointer obj)
748 {
749 /* g_object_ref() doesn't accept NULL. */
750 if (obj)
751 g_object_ref (obj);
752 return obj;
753 }
754 #define nm_g_object_ref(obj) ((typeof (obj)) nm_g_object_ref (obj))
755
756 static inline void
757 nm_g_object_unref (gpointer obj)
758 {
759 /* g_object_unref() doesn't accept NULL. Usually, we workaround that
760 * by using g_clear_object(), but sometimes that is not convenient
761 * (for example as destroy function for a hash table that can contain
762 * NULL values). */
763 if (obj)
764 g_object_unref (obj);
765 }
766
767 /* Assigns GObject @obj to destination @pdst, and takes an additional ref.
768 * The previous value of @pdst is unrefed.
769 *
770 * It makes sure to first increase the ref-count of @obj, and handles %NULL
771 * @obj correctly.
772 * */
773 #define nm_g_object_ref_set(pp, obj) \
774 ({ \
775 typeof (*(pp)) *const _pp = (pp); \
776 typeof (**_pp) *const _obj = (obj); \
777 typeof (**_pp) *_p; \
778 gboolean _changed = FALSE; \
779 \
780 if ( _pp \
781 && ((_p = *_pp) != _obj)) { \
782 if (_obj) { \
783 nm_assert (G_IS_OBJECT (_obj)); \
784 g_object_ref (_obj); \
785 } \
786 if (_p) { \
787 nm_assert (G_IS_OBJECT (_p)); \
788 *_pp = NULL; \
789 g_object_unref (_p); \
790 } \
791 *_pp = _obj; \
792 _changed = TRUE; \
793 } \
794 _changed; \
795 })
796
797 #define nm_clear_pointer(pp, destroy) \
798 ({ \
799 typeof (*(pp)) *_pp = (pp); \
800 typeof (*_pp) _p; \
801 gboolean _changed = FALSE; \
802 \
803 if ( _pp \
804 && (_p = *_pp)) { \
805 _nm_unused gconstpointer _p_check_is_pointer = _p; \
806 \
807 *_pp = NULL; \
808 /* g_clear_pointer() assigns @destroy first to a local variable, so that
809 * you can call "g_clear_pointer (pp, (GDestroyNotify) destroy);" without
810 * gcc emitting a warning. We don't do that, hence, you cannot cast
811 * "destroy" first.
812 *
813 * On the upside: you are not supposed to cast fcn, because the pointer
814 * types are preserved. If you really need a cast, you should cast @pp.
815 * But that is hardly ever necessary. */ \
816 (destroy) (_p); \
817 \
818 _changed = TRUE; \
819 } \
820 _changed; \
821 })
822
823 /* basically, replaces
824 * g_clear_pointer (&location, g_free)
825 * with
826 * nm_clear_g_free (&location)
827 *
828 * Another advantage is that by using a macro and typeof(), it is more
829 * typesafe and gives you for example a compiler warning when pp is a const
830 * pointer or points to a const-pointer.
831 */
832 #define nm_clear_g_free(pp) \
833 nm_clear_pointer (pp, g_free)
834
835 #define nm_clear_g_object(pp) \
836 nm_clear_pointer (pp, g_object_unref)
837
838 static inline gboolean
839 nm_clear_g_source (guint *id)
840 {
841 guint v;
842
843 if ( id
844 && (v = *id)) {
845 *id = 0;
846 g_source_remove (v);
847 return TRUE;
848 }
849 return FALSE;
850 }
851
852 static inline gboolean
853 nm_clear_g_signal_handler (gpointer self, gulong *id)
854 {
855 gulong v;
856
857 if ( id
858 && (v = *id)) {
859 *id = 0;
860 g_signal_handler_disconnect (self, v);
861 return TRUE;
862 }
863 return FALSE;
864 }
865
866 static inline gboolean
867 nm_clear_g_variant (GVariant **variant)
868 {
869 GVariant *v;
870
871 if ( variant
872 && (v = *variant)) {
873 *variant = NULL;
874 g_variant_unref (v);
875 return TRUE;
876 }
877 return FALSE;
878 }
879
880 static inline gboolean
881 nm_clear_g_cancellable (GCancellable **cancellable)
882 {
883 GCancellable *v;
884
885 if ( cancellable
886 && (v = *cancellable)) {
887 *cancellable = NULL;
888 g_cancellable_cancel (v);
889 g_object_unref (v);
890 return TRUE;
891 }
892 return FALSE;
893 }
894
895 /*****************************************************************************/
896
897 /* Determine whether @x is a power of two (@x being an integer type).
898 * Basically, this returns TRUE, if @x has exactly one bit set.
899 * For negative values and zero, this always returns FALSE. */
900 #define nm_utils_is_power_of_two(x) ({ \
901 typeof(x) __x = (x); \
902 \
903 ( (__x > ((typeof(__x)) 0)) \
904 && ((__x & (__x - (((typeof(__x)) 1)))) == ((typeof(__x)) 0))); \
905 })
906
907 /*****************************************************************************/
908
909 #define NM_UTILS_LOOKUP_DEFAULT(v) return (v)
910 #define NM_UTILS_LOOKUP_DEFAULT_WARN(v) g_return_val_if_reached (v)
911 #define NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT(v) { nm_assert_not_reached (); return (v); }
912 #define NM_UTILS_LOOKUP_ITEM(v, n) (void) 0; case v: return (n); (void) 0
913 #define NM_UTILS_LOOKUP_STR_ITEM(v, n) NM_UTILS_LOOKUP_ITEM(v, ""n"")
914 #define NM_UTILS_LOOKUP_ITEM_IGNORE(v) (void) 0; case v: break; (void) 0
915 #define NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER() (void) 0; default: break; (void) 0
916
917 #define _NM_UTILS_LOOKUP_DEFINE(scope, fcn_name, lookup_type, result_type, unknown_val, ...) \
918 scope result_type \
919 fcn_name (lookup_type val) \
920 { \
921 switch (val) { \
922 (void) 0, \
923 __VA_ARGS__ \
924 (void) 0; \
925 }; \
926 { unknown_val; } \
927 }
928
929 #define NM_UTILS_LOOKUP_STR_DEFINE(fcn_name, lookup_type, unknown_val, ...) \
930 _NM_UTILS_LOOKUP_DEFINE (, fcn_name, lookup_type, const char *, unknown_val, __VA_ARGS__)
931 #define NM_UTILS_LOOKUP_STR_DEFINE_STATIC(fcn_name, lookup_type, unknown_val, ...) \
932 _NM_UTILS_LOOKUP_DEFINE (static, fcn_name, lookup_type, const char *, unknown_val, __VA_ARGS__)
933
934 /* Call the string-lookup-table function @fcn_name. If the function returns
935 * %NULL, the numeric index is converted to string using a alloca() buffer.
936 * Beware: this macro uses alloca(). */
937 #define NM_UTILS_LOOKUP_STR(fcn_name, idx) \
938 ({ \
939 typeof (idx) _idx = (idx); \
940 const char *_s; \
941 \
942 _s = fcn_name (_idx); \
943 if (!_s) { \
944 _s = g_alloca (30); \
945 \
946 g_snprintf ((char *) _s, 30, "(%lld)", (long long) _idx); \
947 } \
948 _s; \
949 })
950
951 /*****************************************************************************/
952
953 /* check if @flags has exactly one flag (@check) set. You should call this
954 * only with @check being a compile time constant and a power of two. */
955 #define NM_FLAGS_HAS(flags, check) \
956 ( G_STATIC_ASSERT_EXPR ((check) > 0 && ((check) & ((check) - 1)) == 0), NM_FLAGS_ANY ((flags), (check)) )
957
958 #define NM_FLAGS_ANY(flags, check) ( ( ((flags) & (check)) != 0 ) ? TRUE : FALSE )
959 #define NM_FLAGS_ALL(flags, check) ( ( ((flags) & (check)) == (check) ) ? TRUE : FALSE )
960
961 #define NM_FLAGS_SET(flags, val) ({ \
962 const typeof(flags) _flags = (flags); \
963 const typeof(flags) _val = (val); \
964 \
965 _flags | _val; \
966 })
967
968 #define NM_FLAGS_UNSET(flags, val) ({ \
969 const typeof(flags) _flags = (flags); \
970 const typeof(flags) _val = (val); \
971 \
972 _flags & (~_val); \
973 })
974
975 #define NM_FLAGS_ASSIGN(flags, val, assign) ({ \
976 const typeof(flags) _flags = (flags); \
977 const typeof(flags) _val = (val); \
978 \
979 (assign) \
980 ? _flags | (_val) \
981 : _flags & (~_val); \
982 })
983
984 /*****************************************************************************/
985
986 #define _NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, ORIG_FUNC, VERSIONED_FUNC, ARGS_TYPED, ARGS) \
987 RETURN_TYPE VERSIONED_FUNC ARGS_TYPED; \
988 RETURN_TYPE VERSIONED_FUNC ARGS_TYPED \
989 { \
990 return ORIG_FUNC ARGS; \
991 } \
992 RETURN_TYPE ORIG_FUNC ARGS_TYPED; \
993 __asm__(".symver "G_STRINGIFY(VERSIONED_FUNC)", "G_STRINGIFY(ORIG_FUNC)"@"G_STRINGIFY(VERSION))
994
995 #define NM_BACKPORT_SYMBOL(VERSION, RETURN_TYPE, FUNC, ARGS_TYPED, ARGS) \
996 _NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, FUNC, _##FUNC##_##VERSION, ARGS_TYPED, ARGS)
997
998 /*****************************************************************************/
999
1000 #define nm_str_skip_leading_spaces(str) \
1001 ({ \
1002 typeof (*(str)) *_str = (str); \
1003 _nm_unused const char *_str_type_check = _str; \
1004 \
1005 if (_str) { \
1006 while (g_ascii_isspace (_str[0])) \
1007 _str++; \
1008 } \
1009 _str; \
1010 })
1011
1012 static inline char *
1013 nm_strstrip (char *str)
1014 {
1015 /* g_strstrip doesn't like NULL. */
1016 return str ? g_strstrip (str) : NULL;
1017 }
1018
1019 static inline const char *
1020 nm_strstrip_avoid_copy (const char *str, char **str_free)
1021 {
1022 gsize l;
1023 char *s;
1024
1025 nm_assert (str_free && !*str_free);
1026
1027 if (!str)
1028 return NULL;
1029
1030 str = nm_str_skip_leading_spaces (str);
1031 l = strlen (str);
1032 if ( l == 0
1033 || !g_ascii_isspace (str[l - 1]))
1034 return str;
1035 while ( l > 0
1036 && g_ascii_isspace (str[l - 1]))
1037 l--;
1038
1039 s = g_new (char, l + 1);
1040 memcpy (s, str, l);
1041 s[l] = '\0';
1042 *str_free = s;
1043 return s;
1044 }
1045
1046 /* g_ptr_array_sort()'s compare function takes pointers to the
1047 * value. Thus, you cannot use strcmp directly. You can use
1048 * nm_strcmp_p().
1049 *
1050 * Like strcmp(), this function is not forgiving to accept %NULL. */
1051 static inline int
1052 nm_strcmp_p (gconstpointer a, gconstpointer b)
1053 {
1054 const char *s1 = *((const char **) a);
1055 const char *s2 = *((const char **) b);
1056
1057 return strcmp (s1, s2);
1058 }
1059
1060 /* like nm_strcmp_p(), suitable for g_ptr_array_sort_with_data().
1061 * g_ptr_array_sort() just casts nm_strcmp_p() to a function of different
1062 * signature. I guess, in glib there are knowledgeable people that ensure
1063 * that this additional argument doesn't cause problems due to different ABI
1064 * for every architecture that glib supports.
1065 * For NetworkManager, we'd rather avoid such stunts.
1066 **/
1067 static inline int
1068 nm_strcmp_p_with_data (gconstpointer a, gconstpointer b, gpointer user_data)
1069 {
1070 const char *s1 = *((const char **) a);
1071 const char *s2 = *((const char **) b);
1072
1073 return strcmp (s1, s2);
1074 }
1075
1076 static inline int
1077 nm_cmp_uint32_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data)
1078 {
1079 const guint32 a = *((const guint32 *) p_a);
1080 const guint32 b = *((const guint32 *) p_b);
1081
1082 if (a < b)
1083 return -1;
1084 if (a > b)
1085 return 1;
1086 return 0;
1087 }
1088
1089 static inline int
1090 nm_cmp_int2ptr_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data)
1091 {
1092 /* p_a and p_b are two pointers to a pointer, where the pointer is
1093 * interpreted as a integer using GPOINTER_TO_INT().
1094 *
1095 * That is the case of a hash-table that uses GINT_TO_POINTER() to
1096 * convert integers as pointers, and the resulting keys-as-array
1097 * array. */
1098 const int a = GPOINTER_TO_INT (*((gconstpointer *) p_a));
1099 const int b = GPOINTER_TO_INT (*((gconstpointer *) p_b));
1100
1101 if (a < b)
1102 return -1;
1103 if (a > b)
1104 return 1;
1105 return 0;
1106 }
1107
1108 /*****************************************************************************/
1109
1110 /* Taken from systemd's UNIQ_T and UNIQ macros. */
1111
1112 #define NM_UNIQ_T(x, uniq) G_PASTE(__unique_prefix_, G_PASTE(x, uniq))
1113 #define NM_UNIQ __COUNTER__
1114
1115 /*****************************************************************************/
1116
1117 /* glib's MIN()/MAX() macros don't have function-like behavior, in that they evaluate
1118 * the argument possibly twice.
1119 *
1120 * Taken from systemd's MIN()/MAX() macros. */
1121
1122 #define NM_MIN(a, b) __NM_MIN(NM_UNIQ, a, NM_UNIQ, b)
1123 #define __NM_MIN(aq, a, bq, b) \
1124 ({ \
1125 typeof (a) NM_UNIQ_T(A, aq) = (a); \
1126 typeof (b) NM_UNIQ_T(B, bq) = (b); \
1127 ((NM_UNIQ_T(A, aq) < NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \
1128 })
1129
1130 #define NM_MAX(a, b) __NM_MAX(NM_UNIQ, a, NM_UNIQ, b)
1131 #define __NM_MAX(aq, a, bq, b) \
1132 ({ \
1133 typeof (a) NM_UNIQ_T(A, aq) = (a); \
1134 typeof (b) NM_UNIQ_T(B, bq) = (b); \
1135 ((NM_UNIQ_T(A, aq) > NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \
1136 })
1137
1138 #define NM_CLAMP(x, low, high) __NM_CLAMP(NM_UNIQ, x, NM_UNIQ, low, NM_UNIQ, high)
1139 #define __NM_CLAMP(xq, x, lowq, low, highq, high) \
1140 ({ \
1141 typeof(x)NM_UNIQ_T(X,xq) = (x); \
1142 typeof(low) NM_UNIQ_T(LOW,lowq) = (low); \
1143 typeof(high) NM_UNIQ_T(HIGH,highq) = (high); \
1144 \
1145 ( (NM_UNIQ_T(X,xq) > NM_UNIQ_T(HIGH,highq)) \
1146 ? NM_UNIQ_T(HIGH,highq) \
1147 : (NM_UNIQ_T(X,xq) < NM_UNIQ_T(LOW,lowq)) \
1148 ? NM_UNIQ_T(LOW,lowq) \
1149 : NM_UNIQ_T(X,xq)); \
1150 })
1151
1152 /*****************************************************************************/
1153
1154 static inline guint
1155 nm_encode_version (guint major, guint minor, guint micro)
1156 {
1157 /* analog to the preprocessor macro NM_ENCODE_VERSION(). */
1158 return (major << 16) | (minor << 8) | micro;
1159 }
1160
1161 static inline void
1162 nm_decode_version (guint version, guint *major, guint *minor, guint *micro)
1163 {
1164 *major = (version & 0xFFFF0000u) >> 16;
1165 *minor = (version & 0x0000FF00u) >> 8;
1166 *micro = (version & 0x000000FFu);
1167 }
1168
1169 /*****************************************************************************/
1170
1171 /* taken from systemd's DECIMAL_STR_MAX()
1172 *
1173 * Returns the number of chars needed to format variables of the
1174 * specified type as a decimal string. Adds in extra space for a
1175 * negative '-' prefix (hence works correctly on signed
1176 * types). Includes space for the trailing NUL. */
1177 #define NM_DECIMAL_STR_MAX(type) \
1178 (2+(sizeof(type) <= 1 ? 3 : \
1179 sizeof(type) <= 2 ? 5 : \
1180 sizeof(type) <= 4 ? 10 : \
1181 sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
1182
1183 /*****************************************************************************/
1184
1185 /* if @str is NULL, return "(null)". Otherwise, allocate a buffer using
1186 * alloca() of and fill it with @str. @str will be quoted with double quote.
1187 * If @str is longer then @trunc_at, the string is truncated and the closing
1188 * quote is instead '^' to indicate truncation.
1189 *
1190 * Thus, the maximum stack allocated buffer will be @trunc_at+3. */
1191 #define nm_strquote_a(trunc_at, str) \
1192 ({ \
1193 const char *const _str = (str); \
1194 \
1195 (_str \
1196 ? ({ \
1197 const gsize _trunc_at = (trunc_at); \
1198 const gsize _strlen_trunc = NM_MIN (strlen (_str), _trunc_at); \
1199 char *_buf; \
1200 \
1201 _buf = g_alloca (_strlen_trunc + 3); \
1202 _buf[0] = '"'; \
1203 memcpy (&_buf[1], _str, _strlen_trunc); \
1204 _buf[_strlen_trunc + 1] = _str[_strlen_trunc] ? '^' : '"'; \
1205 _buf[_strlen_trunc + 2] = '\0'; \
1206 _buf; \
1207 }) \
1208 : "(null)"); \
1209 })
1210
1211 #define nm_sprintf_buf(buf, format, ...) \
1212 ({ \
1213 char * _buf = (buf); \
1214 int _buf_len; \
1215 \
1216 /* some static assert trying to ensure that the buffer is statically allocated.
1217 * It disallows a buffer size of sizeof(gpointer) to catch that. */ \
1218 G_STATIC_ASSERT (G_N_ELEMENTS (buf) == sizeof (buf) && sizeof (buf) != sizeof (char *)); \
1219 _buf_len = g_snprintf (_buf, sizeof (buf), \
1220 ""format"", ##__VA_ARGS__); \
1221 nm_assert (_buf_len < sizeof (buf)); \
1222 _buf; \
1223 })
1224
1225 #define nm_sprintf_bufa(n_elements, format, ...) \
1226 ({ \
1227 char *_buf; \
1228 int _buf_len; \
1229 typeof (n_elements) _n_elements = (n_elements); \
1230 \
1231 _buf = g_alloca (_n_elements); \
1232 _buf_len = g_snprintf (_buf, _n_elements, \
1233 ""format"", ##__VA_ARGS__); \
1234 nm_assert (_buf_len < _n_elements); \
1235 _buf; \
1236 })
1237
1238 /* aims to alloca() a buffer and fill it with printf(format, name).
1239 * Note that format must not contain any format specifier except
1240 * "%s".
1241 * If the resulting string would be too large for stack allocation,
1242 * it allocates a buffer with g_malloc() and assigns it to *p_val_to_free. */
1243 #define nm_construct_name_a(format, name, p_val_to_free) \
1244 ({ \
1245 const char *const _name = (name); \
1246 char **const _p_val_to_free = (p_val_to_free); \
1247 const gsize _name_len = strlen (_name); \
1248 char *_buf2; \
1249 \
1250 nm_assert (_p_val_to_free && !*_p_val_to_free); \
1251 if (NM_STRLEN (format) + _name_len < 200) \
1252 _buf2 = nm_sprintf_bufa (NM_STRLEN (format) + _name_len, format, _name); \
1253 else { \
1254 _buf2 = g_strdup_printf (format, _name); \
1255 *_p_val_to_free = _buf2; \
1256 } \
1257 (const char *) _buf2; \
1258 })
1259
1260 /*****************************************************************************/
1261
1262 /**
1263 * The boolean type _Bool is C99 while we mostly stick to C89. However, _Bool is too
1264 * convenient to miss and is effectively available in gcc and clang. So, just use it.
1265 *
1266 * Usually, one would include "stdbool.h" to get the "bool" define which aliases
1267 * _Bool. We provide this define here, because we want to make use of it anywhere.
1268 * (also, stdbool.h is again C99).
1269 *
1270 * Using _Bool has advantages over gboolean:
1271 *
1272 * - commonly _Bool is one byte large, instead of gboolean's 4 bytes (because gboolean
1273 * is a typedef for gint). Especially when having boolean fields in a struct, we can
1274 * thereby easily save some space.
1275 *
1276 * - _Bool type guarantees that two "true" expressions compare equal. E.g. the follwing
1277 * will not work:
1278 * gboolean v1 = 1;
1279 * gboolean v2 = 2;
1280 * g_assert_cmpint (v1, ==, v2); // will fail
1281 * For that, we often to use !! to coerce gboolean values to 0 or 1:
1282 * g_assert_cmpint (!!v2, ==, TRUE);
1283 * With _Bool type, this will be handled properly by the compiler.
1284 *
1285 * - For structs, we might want to safe even more space and use bitfields:
1286 * struct s1 {
1287 * gboolean v1:1;
1288 * };
1289 * But the problem here is that gboolean is signed, so that
1290 * v1 will be either 0 or -1 (not 1, TRUE). Thus, the following
1291 * fails:
1292 * struct s1 s = { .v1 = TRUE, };
1293 * g_assert_cmpint (s1.v1, ==, TRUE);
1294 * It will however work just fine with bool/_Bool while retaining the
1295 * notion of having a boolean value.
1296 *
1297 * Also, add the defines for "true" and "false". Those are nicely highlighted by the editor
1298 * as special types, contrary to glib's "TRUE"/"FALSE".
1299 */
1300
1301 #ifndef bool
1302 #define bool _Bool
1303 #define true 1
1304 #define false 0
1305 #endif
1306
1307
1308 #ifdef _G_BOOLEAN_EXPR
1309 /* g_assert() uses G_LIKELY(), which in turn uses _G_BOOLEAN_EXPR().
1310 * As glib's implementation uses a local variable _g_boolean_var_,
1311 * we cannot do
1312 * g_assert (some_macro ());
1313 * where some_macro() itself expands to ({g_assert(); ...}).
1314 * In other words, you cannot have a g_assert() inside a g_assert()
1315 * without getting a -Werror=shadow failure.
1316 *
1317 * Workaround that by re-defining _G_BOOLEAN_EXPR()
1318 **/
1319 #undef _G_BOOLEAN_EXPR
1320 #define __NM_G_BOOLEAN_EXPR_IMPL(v, expr) \
1321 ({ \
1322 int NM_UNIQ_T(V, v); \
1323 \
1324 if (expr) \
1325 NM_UNIQ_T(V, v) = 1; \
1326 else \
1327 NM_UNIQ_T(V, v) = 0; \
1328 NM_UNIQ_T(V, v); \
1329 })
1330 #define _G_BOOLEAN_EXPR(expr) __NM_G_BOOLEAN_EXPR_IMPL (NM_UNIQ, expr)
1331 #endif
1332
1333 /*****************************************************************************/
1334
1335 /**
1336 * nm_steal_int:
1337 * @p_val: pointer to an int type.
1338 *
1339 * Returns: *p_val and sets *p_val to zero the same time.
1340 * Accepts %NULL, in which case also numeric 0 will be returned.
1341 */
1342 #define nm_steal_int(p_val) \
1343 ({ \
1344 typeof (p_val) const _p_val = (p_val); \
1345 typeof (*_p_val) _val = 0; \
1346 \
1347 if ( _p_val \
1348 && (_val = *_p_val)) { \
1349 *_p_val = 0; \
1350 } \
1351 _val; \
1352 })
1353
1354 static inline int
1355 nm_steal_fd (int *p_fd)
1356 {
1357 int fd;
1358
1359 if ( p_fd
1360 && ((fd = *p_fd) >= 0)) {
1361 *p_fd = -1;
1362 return fd;
1363 }
1364 return -1;
1365 }
1366
1367 /**
1368 * nm_close:
1369 *
1370 * Like close() but throws an assertion if the input fd is
1371 * invalid. Closing an invalid fd is a programming error, so
1372 * it's better to catch it early.
1373 */
1374 static inline int
1375 11 nm_close (int fd)
1376 {
1377 int r;
1378
1379 11 r = close (fd);
1380 nm_assert (r != -1 || fd < 0 || errno != EBADF);
1381 11 return r;
1382 }
1383
1384 #endif /* __NM_MACROS_INTERNAL_H__ */
1385