shared: add nm_auto_unset_gvalue macro
[NetworkManager.git] / shared / nm-macros-internal.h
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 <stdlib.h>
26
27 /********************************************************/
28
29 #define nm_auto(fcn) __attribute ((cleanup(fcn)))
30
31 /**
32  * nm_auto_free:
33  *
34  * Call free() on a variable location when it goes out of scope.
35  */
36 #define nm_auto_free nm_auto(_nm_auto_free_impl)
37 GS_DEFINE_CLEANUP_FUNCTION(void*, _nm_auto_free_impl, free)
38
39 static inline void
40 _nm_auto_unset_gvalue_impl (GValue *v)
41 {
42         g_value_unset (v);
43 }
44 #define nm_auto_unset_gvalue nm_auto(_nm_auto_unset_gvalue_impl)
45
46 /********************************************************/
47
48 /* http://stackoverflow.com/a/11172679 */
49 #define  _NM_UTILS_MACRO_FIRST(...)                           __NM_UTILS_MACRO_FIRST_HELPER(__VA_ARGS__, throwaway)
50 #define __NM_UTILS_MACRO_FIRST_HELPER(first, ...)             first
51
52 #define  _NM_UTILS_MACRO_REST(...)                            __NM_UTILS_MACRO_REST_HELPER(__NM_UTILS_MACRO_REST_NUM(__VA_ARGS__), __VA_ARGS__)
53 #define __NM_UTILS_MACRO_REST_HELPER(qty, ...)                __NM_UTILS_MACRO_REST_HELPER2(qty, __VA_ARGS__)
54 #define __NM_UTILS_MACRO_REST_HELPER2(qty, ...)               __NM_UTILS_MACRO_REST_HELPER_##qty(__VA_ARGS__)
55 #define __NM_UTILS_MACRO_REST_HELPER_ONE(first)
56 #define __NM_UTILS_MACRO_REST_HELPER_TWOORMORE(first, ...)    , __VA_ARGS__
57 #define __NM_UTILS_MACRO_REST_NUM(...) \
58     __NM_UTILS_MACRO_REST_SELECT_20TH(__VA_ARGS__, \
59                 TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
60                 TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
61                 TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\
62                 TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway)
63 #define __NM_UTILS_MACRO_REST_SELECT_20TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, ...) a20
64
65 /********************************************************/
66
67 /* http://stackoverflow.com/a/2124385/354393 */
68
69 #define NM_NARG(...) \
70          _NM_NARG(__VA_ARGS__,_NM_NARG_RSEQ_N())
71 #define _NM_NARG(...) \
72          _NM_NARG_ARG_N(__VA_ARGS__)
73 #define _NM_NARG_ARG_N( \
74           _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
75          _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
76          _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
77          _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
78          _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
79          _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
80          _61,_62,_63,N,...) N
81 #define _NM_NARG_RSEQ_N() \
82          63,62,61,60,                   \
83          59,58,57,56,55,54,53,52,51,50, \
84          49,48,47,46,45,44,43,42,41,40, \
85          39,38,37,36,35,34,33,32,31,30, \
86          29,28,27,26,25,24,23,22,21,20, \
87          19,18,17,16,15,14,13,12,11,10, \
88          9,8,7,6,5,4,3,2,1,0
89
90 /********************************************************/
91
92 #if defined (__GNUC__)
93 #define _NM_PRAGMA_WARNING_DO(warning)       G_STRINGIFY(GCC diagnostic ignored warning)
94 #elif defined (__clang__)
95 #define _NM_PRAGMA_WARNING_DO(warning)       G_STRINGIFY(clang diagnostic ignored warning)
96 #endif
97
98 /* you can only suppress a specific warning that the compiler
99  * understands. Otherwise you will get another compiler warning
100  * about invalid pragma option.
101  * It's not that bad however, because gcc and clang often have the
102  * same name for the same warning. */
103
104 #if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
105 #define NM_PRAGMA_WARNING_DISABLE(warning) \
106         _Pragma("GCC diagnostic push") \
107         _Pragma(_NM_PRAGMA_WARNING_DO(warning))
108 #elif defined (__clang__)
109 #define NM_PRAGMA_WARNING_DISABLE(warning) \
110         _Pragma("clang diagnostic push") \
111         _Pragma(_NM_PRAGMA_WARNING_DO(warning))
112 #else
113 #define NM_PRAGMA_WARNING_DISABLE(warning)
114 #endif
115
116 #if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
117 #define NM_PRAGMA_WARNING_REENABLE \
118     _Pragma("GCC diagnostic pop")
119 #elif defined (__clang__)
120 #define NM_PRAGMA_WARNING_REENABLE \
121     _Pragma("clang diagnostic pop")
122 #else
123 #define NM_PRAGMA_WARNING_REENABLE
124 #endif
125
126 /********************************************************/
127
128 /**
129  * NM_G_ERROR_MSG:
130  * @error: (allow none): the #GError instance
131  *
132  * All functions must follow the convention that when they
133  * return a failure, they must also set the GError to a valid
134  * message. For external API however, we want to be extra
135  * careful before accessing the error instance. Use NM_G_ERROR_MSG()
136  * which is safe to use on NULL.
137  *
138  * Returns: the error message.
139  **/
140 static inline const char *
141 NM_G_ERROR_MSG (GError *error)
142 {
143         return error ? (error->message ? : "(null)") : "(no-error)"; \
144 }
145
146 /********************************************************/
147
148 /* macro to return strlen() of a compile time string. */
149 #define NM_STRLEN(str)     ( sizeof ("" str) - 1 )
150
151 #define NM_SET_OUT(out_val, value) \
152         G_STMT_START { \
153                 typeof(*(out_val)) *_out_val = (out_val); \
154                 \
155                 if (_out_val) { \
156                         *_out_val = (value); \
157                 } \
158         } G_STMT_END
159
160 /********************************************************/
161
162 #define _NM_IN_SET_EVAL_1(op, _x, y1)                               \
163     (_x == (y1))
164
165 #define _NM_IN_SET_EVAL_2(op, _x, y1, y2)                           \
166     (   (_x == (y1))                                                \
167      op (_x == (y2))                                                \
168     )
169
170 #define _NM_IN_SET_EVAL_3(op, _x, y1, y2, y3)                       \
171     (   (_x == (y1))                                                \
172      op (_x == (y2))                                                \
173      op (_x == (y3))                                                \
174     )
175
176 #define _NM_IN_SET_EVAL_4(op, _x, y1, y2, y3, y4)                   \
177     (   (_x == (y1))                                                \
178      op (_x == (y2))                                                \
179      op (_x == (y3))                                                \
180      op (_x == (y4))                                                \
181     )
182
183 #define _NM_IN_SET_EVAL_5(op, _x, y1, y2, y3, y4, y5)               \
184     (   (_x == (y1))                                                \
185      op (_x == (y2))                                                \
186      op (_x == (y3))                                                \
187      op (_x == (y4))                                                \
188      op (_x == (y5))                                                \
189     )
190
191 #define _NM_IN_SET_EVAL_6(op, _x, y1, y2, y3, y4, y5, y6)           \
192     (   (_x == (y1))                                                \
193      op (_x == (y2))                                                \
194      op (_x == (y3))                                                \
195      op (_x == (y4))                                                \
196      op (_x == (y5))                                                \
197      op (_x == (y6))                                                \
198     )
199
200 #define _NM_IN_SET_EVAL_N2(op, _x, n, ...)        _NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__)
201 #define _NM_IN_SET_EVAL_N(op, x, n, ...)                            \
202     ({                                                              \
203         typeof(x) _x = (x);                                         \
204         !!_NM_IN_SET_EVAL_N2(op, _x, n, __VA_ARGS__);               \
205     })
206
207 /* Beware that this does short-circuit evaluation (use "||" instead of "|")
208  * which has a possibly unexpected non-function-like behavior.
209  * Use NM_IN_SET_SE if you need all arguments to be evaluted. */
210 #define NM_IN_SET(x, ...)               _NM_IN_SET_EVAL_N(||, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
211
212 /* "SE" stands for "side-effect". Contrary to NM_IN_SET(), this does not do
213  * short-circuit evaluation, which can make a difference if the arguments have
214  * side-effects. */
215 #define NM_IN_SET_SE(x, ...)            _NM_IN_SET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
216
217 /********************************************************/
218
219 static inline gboolean
220 _NM_IN_STRSET_streq (const char *x, const char *s)
221 {
222         return s && strcmp (x, s) == 0;
223 }
224
225 #define _NM_IN_STRSET_EVAL_1(op, _x, y1)                            \
226     _NM_IN_STRSET_streq (_x, y1)
227
228 #define _NM_IN_STRSET_EVAL_2(op, _x, y1, y2)                        \
229     (   _NM_IN_STRSET_streq (_x, y1)                                \
230      op _NM_IN_STRSET_streq (_x, y2)                                \
231     )
232
233 #define _NM_IN_STRSET_EVAL_3(op, _x, y1, y2, y3)                    \
234     (   _NM_IN_STRSET_streq (_x, y1)                                \
235      op _NM_IN_STRSET_streq (_x, y2)                                \
236      op _NM_IN_STRSET_streq (_x, y3)                                \
237     )
238
239 #define _NM_IN_STRSET_EVAL_4(op, _x, y1, y2, y3, y4)                \
240     (   _NM_IN_STRSET_streq (_x, y1)                                \
241      op _NM_IN_STRSET_streq (_x, y2)                                \
242      op _NM_IN_STRSET_streq (_x, y3)                                \
243      op _NM_IN_STRSET_streq (_x, y4)                                \
244     )
245
246 #define _NM_IN_STRSET_EVAL_5(op, _x, y1, y2, y3, y4, y5)            \
247     (   _NM_IN_STRSET_streq (_x, y1)                                \
248      op _NM_IN_STRSET_streq (_x, y2)                                \
249      op _NM_IN_STRSET_streq (_x, y3)                                \
250      op _NM_IN_STRSET_streq (_x, y4)                                \
251      op _NM_IN_STRSET_streq (_x, y5)                                \
252     )
253
254 #define _NM_IN_STRSET_EVAL_6(op, _x, y1, y2, y3, y4, y5, y6)        \
255     (   _NM_IN_STRSET_streq (_x, y1)                                \
256      op _NM_IN_STRSET_streq (_x, y2)                                \
257      op _NM_IN_STRSET_streq (_x, y3)                                \
258      op _NM_IN_STRSET_streq (_x, y4)                                \
259      op _NM_IN_STRSET_streq (_x, y5)                                \
260      op _NM_IN_STRSET_streq (_x, y6)                                \
261     )
262
263 #define _NM_IN_STRSET_EVAL_N2(op, _x, n, ...) _NM_IN_STRSET_EVAL_##n(op, _x, __VA_ARGS__)
264 #define _NM_IN_STRSET_EVAL_N(op, x, n, ...)                       \
265     ({                                                            \
266         const char *_x = (x);                                     \
267         (   ((_x == NULL) && _NM_IN_SET_EVAL_N2    (op, (const char *) NULL, n, __VA_ARGS__)) \
268          || ((_x != NULL) && _NM_IN_STRSET_EVAL_N2 (op, _x,                  n, __VA_ARGS__)) \
269         ); \
270     })
271
272 /* Beware that this does short-circuit evaluation (use "||" instead of "|")
273  * which has a possibly unexpected non-function-like behavior.
274  * Use NM_IN_STRSET_SE if you need all arguments to be evaluted. */
275 #define NM_IN_STRSET(x, ...)               _NM_IN_STRSET_EVAL_N(||, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
276
277 /* "SE" stands for "side-effect". Contrary to NM_IN_STRSET(), this does not do
278  * short-circuit evaluation, which can make a difference if the arguments have
279  * side-effects. */
280 #define NM_IN_STRSET_SE(x, ...)            _NM_IN_STRSET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
281
282 /*****************************************************************************/
283
284 #define nm_streq(s1, s2)  (strcmp (s1, s2) == 0)
285 #define nm_streq0(s1, s2) (g_strcmp0 (s1, s2) == 0)
286
287 /*****************************************************************************/
288
289 #define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \
290         (cond) ? (prefix) : "", \
291         (cond) ? (str) : (str_else), \
292         (cond) ? (suffix) : ""
293 #define NM_PRINT_FMT_QUOTE_STRING(arg) NM_PRINT_FMT_QUOTED((arg), "\"", (arg), "\"", "(null)")
294
295 /*****************************************************************************/
296
297 #if NM_MORE_ASSERTS
298 #define nm_assert(cond) G_STMT_START { g_assert (cond); } G_STMT_END
299 #define nm_assert_not_reached() G_STMT_START { g_assert_not_reached (); } G_STMT_END
300 #else
301 #define nm_assert(cond) G_STMT_START { if (FALSE) { if (cond) { } } } G_STMT_END
302 #define nm_assert_not_reached() G_STMT_START { ; } G_STMT_END
303 #endif
304
305 /*****************************************************************************/
306
307 #define NM_GOBJECT_PROPERTIES_DEFINE_BASE(...) \
308 typedef enum { \
309         _PROPERTY_ENUMS_0, \
310         __VA_ARGS__ \
311         _PROPERTY_ENUMS_LAST, \
312 } _PropertyEnums; \
313 static GParamSpec *obj_properties[_PROPERTY_ENUMS_LAST] = { NULL, }
314
315 #define NM_GOBJECT_PROPERTIES_DEFINE(obj_type, ...) \
316 NM_GOBJECT_PROPERTIES_DEFINE_BASE (__VA_ARGS__); \
317 static inline void \
318 _notify (obj_type *obj, _PropertyEnums prop) \
319 { \
320         nm_assert (G_IS_OBJECT (obj)); \
321         nm_assert ((gsize) prop < G_N_ELEMENTS (obj_properties)); \
322         g_object_notify_by_pspec ((GObject *) obj, obj_properties[prop]); \
323 }
324
325 /*****************************************************************************/
326
327 #define nm_unauto(pp)                                               \
328     ({                                                              \
329         G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer));        \
330         gpointer *_pp = (gpointer *) (pp);                          \
331         gpointer _p = *_pp;                                         \
332                                                                     \
333         *_pp = NULL;                                                \
334         _p;                                                         \
335     })
336
337 /*****************************************************************************/
338
339 static inline gpointer
340 nm_g_object_ref (gpointer obj)
341 {
342         /* g_object_ref() doesn't accept NULL. */
343         if (obj)
344                 g_object_ref (obj);
345         return obj;
346 }
347
348 static inline void
349 nm_g_object_unref (gpointer obj)
350 {
351         /* g_object_unref() doesn't accept NULL. Usully, we workaround that
352          * by using g_clear_object(), but sometimes that is not convinient
353          * (for example as as destroy function for a hash table that can contain
354          * NULL values). */
355         if (obj)
356                 g_object_unref (obj);
357 }
358
359 static inline gboolean
360 nm_clear_g_source (guint *id)
361 {
362         if (id && *id) {
363                 g_source_remove (*id);
364                 *id = 0;
365                 return TRUE;
366         }
367         return FALSE;
368 }
369
370 static inline gboolean
371 nm_clear_g_signal_handler (gpointer self, gulong *id)
372 {
373         if (id && *id) {
374                 g_signal_handler_disconnect (self, *id);
375                 *id = 0;
376                 return TRUE;
377         }
378         return FALSE;
379 }
380
381 static inline gboolean
382 nm_clear_g_variant (GVariant **variant)
383 {
384         if (variant && *variant) {
385                 g_variant_unref (*variant);
386                 *variant = NULL;
387                 return TRUE;
388         }
389         return FALSE;
390 }
391
392 static inline gboolean
393 nm_clear_g_cancellable (GCancellable **cancellable)
394 {
395         if (cancellable && *cancellable) {
396                 g_cancellable_cancel (*cancellable);
397                 g_object_unref (*cancellable);
398                 *cancellable = NULL;
399                 return TRUE;
400         }
401         return FALSE;
402 }
403
404 /*****************************************************************************/
405
406 /* Determine whether @x is a power of two (@x being an integer type).
407  * For the special cases @x equals zero or one, it also returns true.
408  * For negative @x, always returns FALSE. That only applies, if the data
409  * type of @x is signed. */
410 #define nm_utils_is_power_of_two(x) ({ \
411                 typeof(x) __x = (x); \
412                 \
413                 /* Check if the value is negative. In that case, return FALSE.
414                  * The first expression is a compile time constant, depending on whether
415                  * the type is signed. The second expression is a clumsy way for (__x >= 0),
416                  * which causes a compiler warning for unsigned types. */ \
417                     ( ( ((typeof(__x)) -1) > ((typeof(__x)) 0) ) || (__x > 0) || (__x == 0) ) \
418                  && ((__x & (__x - 1)) == 0); \
419         })
420
421 /*****************************************************************************/
422
423 /* check if @flags has exactly one flag (@check) set. You should call this
424  * only with @check being a compile time constant and a power of two. */
425 #define NM_FLAGS_HAS(flags, check)  \
426     ( (G_STATIC_ASSERT_EXPR ( ((check) != 0) && ((check) & ((check)-1)) == 0 )), (NM_FLAGS_ANY ((flags), (check))) )
427
428 #define NM_FLAGS_ANY(flags, check)  ( ( ((flags) & (check)) != 0       ) ? TRUE : FALSE )
429 #define NM_FLAGS_ALL(flags, check)  ( ( ((flags) & (check)) == (check) ) ? TRUE : FALSE )
430
431 #define NM_FLAGS_SET(flags, val)  ({ \
432                 const typeof(flags) _flags = (flags); \
433                 const typeof(flags) _val = (val); \
434                 \
435                 _flags | _val; \
436         })
437
438 #define NM_FLAGS_UNSET(flags, val)  ({ \
439                 const typeof(flags) _flags = (flags); \
440                 const typeof(flags) _val = (val); \
441                 \
442                 _flags & (~_val); \
443         })
444
445 #define NM_FLAGS_ASSIGN(flags, val, assign)  ({ \
446                 const typeof(flags) _flags = (flags); \
447                 const typeof(flags) _val = (val); \
448                 \
449                 (assign) \
450                         ? _flags | (_val) \
451                         : _flags & (~_val); \
452         })
453
454 /*****************************************************************************/
455
456 #define _NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, ORIG_FUNC, VERSIONED_FUNC, ARGS_TYPED, ARGS) \
457 RETURN_TYPE VERSIONED_FUNC ARGS_TYPED; \
458 RETURN_TYPE VERSIONED_FUNC ARGS_TYPED \
459 { \
460     return ORIG_FUNC ARGS; \
461 } \
462 RETURN_TYPE ORIG_FUNC ARGS_TYPED; \
463 __asm__(".symver "G_STRINGIFY(VERSIONED_FUNC)", "G_STRINGIFY(ORIG_FUNC)"@"G_STRINGIFY(VERSION))
464
465 #define NM_BACKPORT_SYMBOL(VERSION, RETURN_TYPE, FUNC, ARGS_TYPED, ARGS) \
466 _NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, FUNC, _##FUNC##_##VERSION, ARGS_TYPED, ARGS)
467
468 /*****************************************************************************/
469
470 static inline char *
471 nm_strstrip (char *str)
472 {
473         /* g_strstrip doesn't like NULL. */
474         return str ? g_strstrip (str) : NULL;
475 }
476
477 /*****************************************************************************/
478
479 static inline guint
480 nm_encode_version (guint major, guint minor, guint micro) {
481         /* analog to the preprocessor macro NM_ENCODE_VERSION(). */
482         return (major << 16) | (minor << 8) | micro;
483 }
484
485 static inline void
486 nm_decode_version (guint version, guint *major, guint *minor, guint *micro) {
487         *major = (version & 0xFFFF0000u) >> 16;
488         *minor = (version & 0x0000FF00u) >>  8;
489         *micro = (version & 0x000000FFu);
490 }
491 /*****************************************************************************/
492
493 #define nm_sprintf_buf(buf, format, ...) ({ \
494                 char * _buf = (buf); \
495                 \
496                 /* some static assert trying to ensure that the buffer is statically allocated.
497                  * It disallows a buffer size of sizeof(gpointer) to catch that. */ \
498                 G_STATIC_ASSERT (G_N_ELEMENTS (buf) == sizeof (buf) && sizeof (buf) != sizeof (char *)); \
499                 g_snprintf (_buf, sizeof (buf), \
500                             ""format"", ##__VA_ARGS__); \
501                 _buf; \
502         })
503
504 #define nm_sprintf_bufa(n_elements, format, ...) \
505         ({ \
506                 char *_buf; \
507                 \
508                 G_STATIC_ASSERT (sizeof (char[MAX ((n_elements), 1)]) == (n_elements)); \
509                 _buf = g_alloca (n_elements); \
510                 g_snprintf (_buf, n_elements, \
511                             ""format"", ##__VA_ARGS__); \
512                 _buf; \
513         })
514
515 /*****************************************************************************/
516
517 /**
518  * The boolean type _Bool is C99 while we mostly stick to C89. However, _Bool is too
519  * convinient to miss and is effectively available in gcc and clang. So, just use it.
520  *
521  * Usually, one would include "stdbool.h" to get the "bool" define which aliases
522  * _Bool. We provide this define here, because we want to make use of it anywhere.
523  * (also, stdbool.h is again C99).
524  *
525  * Using _Bool has advantages over gboolean:
526  *
527  * - commonly _Bool is one byte large, instead of gboolean's 4 bytes (because gboolean
528  *   is a typedef for gint). Especially when having boolean fields in a struct, we can
529  *   thereby easily save some space.
530  *
531  * - _Bool type guarantees that two "true" expressions compare equal. E.g. the follwing
532  *   will not work:
533  *        gboolean v1 = 1;
534  *        gboolean v2 = 2;
535  *        g_assert_cmpint (v1, ==, v2); // will fail
536  *   For that, we often to use !! to coerce gboolean values to 0 or 1:
537  *        g_assert_cmpint (!!v2, ==, TRUE);
538  *   With _Bool type, this will be handled properly by the compiler.
539  *
540  * - For structs, we might want to safe even more space and use bitfields:
541  *       struct s1 {
542  *           gboolean v1:1;
543  *       };
544  *   But the problem here is that gboolean is signed, so that
545  *   v1 will be either 0 or -1 (not 1, TRUE). Thus, the following
546  *   fails:
547  *      struct s1 s = { .v1 = TRUE, };
548  *      g_assert_cmpint (s1.v1, ==, TRUE);
549  *   It will however work just fine with bool/_Bool while retaining the
550  *   notion of having a boolean value.
551  *
552  * Also, add the defines for "true" and "false". Those are nicely highlighted by the editor
553  * as special types, contrary to glib's "TRUE"/"FALSE".
554  */
555
556 #ifndef bool
557 #define bool _Bool
558 #define true    1
559 #define false   0
560 #endif
561
562 /*****************************************************************************/
563
564 #endif /* __NM_MACROS_INTERNAL_H__ */